Skip to content

Commit 01e1524

Browse files
committed
feat: add homebrew cask release action
Change-Id: I6e76a8fa519f378cda92b4edffa64c17294e01b9 Signed-off-by: Thomas Kosiewski <[email protected]>
1 parent 84d6ad3 commit 01e1524

File tree

6 files changed

+167
-8
lines changed

6 files changed

+167
-8
lines changed

.github/workflows/ci.yml

+2
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,5 @@ jobs:
7575
uses: ./.github/actions/nix-devshell
7676

7777
- run: make lint
78+
env:
79+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release.yml

+34-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
name: release
22

33
on:
4+
push:
5+
branches:
6+
- main
47
release:
58
types: [published]
69

710
permissions: {}
811

912
jobs:
1013
build:
14+
name: Build Coder Desktop
1115
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
1216
if: ${{ github.repository_owner == 'coder' }}
1317
permissions:
@@ -40,7 +44,34 @@ jobs:
4044
run: make release
4145

4246
- name: Upload Release Assets
43-
run: gh release upload "$RELEASE_TAG" "$out"/*
47+
run: gh release upload "$RELEASE_TAG" "$out"/* --clobber
4448
env:
45-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46-
RELEASE_TAG: ${{ github.event.release.tag_name }}
49+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || 'dogfood' }}
51+
52+
update-cask:
53+
name: Update homebrew-coder cask
54+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
55+
if: ${{ github.repository_owner == 'coder' }}
56+
needs: build
57+
steps:
58+
- name: Checkout
59+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
60+
with:
61+
fetch-depth: 1
62+
persist-credentials: false
63+
64+
- name: Setup Nix
65+
uses: ./.github/actions/nix-devshell
66+
67+
- name: Update homebrew-coder
68+
env:
69+
GH_TOKEN: ${{ secrets.CODERCI_GITHUB_TOKEN }}
70+
RELEASE_TAG: ${{ github.event_name == 'release' && github.event.release.tag_name || 'dogfood' }}
71+
ASSIGNEE: ${{ github.actor }}
72+
run: |
73+
git config --global user.email "[email protected]"
74+
git config --global user.name "Coder CI"
75+
gh auth setup-git
76+
77+
./scripts/update-cask.sh --version "$RELEASE_TAG" --assignee "$ASSIGNEE"

Coder Desktop/Coder Desktop.xctestplan

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
{
2020
"target" : {
2121
"containerPath" : "container:Coder Desktop.xcodeproj",
22-
"identifier" : "AA3B40972D2FC8560099996A",
22+
"identifier" : "5151F2C6964AB885B71A2AE4",
2323
"name" : "CoderSDKTests"
2424
}
2525
},
@@ -28,21 +28,21 @@
2828
"parallelizable" : true,
2929
"target" : {
3030
"containerPath" : "container:Coder Desktop.xcodeproj",
31-
"identifier" : "961679182CFF100E00B2B6DF",
31+
"identifier" : "11762B23091AD2D3C71D48A9",
3232
"name" : "Coder DesktopUITests"
3333
}
3434
},
3535
{
3636
"target" : {
3737
"containerPath" : "container:Coder Desktop.xcodeproj",
38-
"identifier" : "AA3B3DA72D2D23860099996A",
38+
"identifier" : "941FE7A4B097CD66FD100DA4",
3939
"name" : "VPNLibTests"
4040
}
4141
},
4242
{
4343
"target" : {
4444
"containerPath" : "container:Coder Desktop.xcodeproj",
45-
"identifier" : "9616790E2CFF100E00B2B6DF",
45+
"identifier" : "CEF327EDA9B70DF13F678CB3",
4646
"name" : "Coder DesktopTests"
4747
}
4848
}

Coder Desktop/VPN/PacketTunnelProvider.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ import VPNLib
66
let CTLIOCGINFO: UInt = 0xC064_4E03
77

88
class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
9-
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "provider")
9+
// Debugging instructions and best practices: https://developer.apple.com/forums/thread/725805
10+
static let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "packet-tunnel")
11+
12+
override init() {
13+
logger = Self.logger
14+
logger.log(level: .debug, "first light")
15+
super.init()
16+
}
17+
18+
private let logger: Logger
1019
private var manager: Manager?
1120
// a `tunnelRemoteAddress` is required, but not currently used.
1221
private var currentSettings: NEPacketTunnelNetworkSettings = .init(tunnelRemoteAddress: "127.0.0.1")

Coder Desktop/VPN/main.swift

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ xpcListener.delegate = globalXPCListenerDelegate
5353
xpcListener.resume()
5454

5555
autoreleasepool {
56+
let logger = PacketTunnelProvider.logger
57+
logger.log(level: .debug, "first light")
5658
NEProvider.startSystemExtensionMode()
5759
}
5860

scripts/update-cask.sh

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
echo "Usage: $0 [--version <version>] [--assignee <github handle>]"
6+
echo " --version <version> Set the VERSION variable to fetch and generate the cask file for"
7+
echo " --assignee <github handle> Set the ASSIGNE variable to assign the PR to (optional)"
8+
echo " -h, --help Display this help message"
9+
}
10+
11+
VERSION=""
12+
ASSIGNE=""
13+
14+
# Parse command line arguments
15+
while [[ "$#" -gt 0 ]]; do
16+
case $1 in
17+
--version)
18+
VERSION="$2"
19+
shift 2
20+
;;
21+
--assignee)
22+
ASSIGNE="$2"
23+
shift 2
24+
;;
25+
-h | --help)
26+
usage
27+
exit 0
28+
;;
29+
*)
30+
echo "Unknown parameter passed: $1"
31+
usage
32+
exit 1
33+
;;
34+
esac
35+
done
36+
37+
# Assert version is not empty and starts with v
38+
[ -z "$VERSION" ] && {
39+
echo "Error: VERSION cannot be empty"
40+
exit 1
41+
}
42+
[[ "$VERSION" =~ ^v || "$VERSION" == "dogfood" ]] || {
43+
echo "Error: VERSION must start with a 'v'"
44+
exit 1
45+
}
46+
47+
# Download the Coder Desktop dmg
48+
GH_RELEASE_FOLDER=$(mktemp -d)
49+
50+
gh release download "$VERSION" \
51+
--repo coder/coder-desktop-macos \
52+
--dir "$GH_RELEASE_FOLDER" \
53+
--pattern 'Coder.Desktop.dmg'
54+
55+
HASH=$(shasum -a 256 "$GH_RELEASE_FOLDER"/Coder.Desktop.dmg | awk '{print $1}' | tr -d '\n')
56+
57+
# Check out the homebrew tap repo
58+
TAP_CHECHOUT_FOLDER=$(mktemp -d)
59+
60+
gh repo clone "coder/homebrew-coder" "$TAP_CHECHOUT_FOLDER"
61+
62+
cd "$TAP_CHECHOUT_FOLDER"
63+
64+
BREW_BRANCH="auto-release/desktop-$VERSION"
65+
66+
# Check if a PR already exists.
67+
# Continue on a main branch release, as the sha256 will change.
68+
pr_count="$(gh pr list --search "head:$BREW_BRANCH" --json id,closed | jq -r ".[] | select(.closed == false) | .id" | wc -l)"
69+
if [[ "$pr_count" -gt 0 && "$VERSION" != "dogfood" ]]; then
70+
echo "Bailing out as PR already exists" 2>&1
71+
exit 0
72+
fi
73+
74+
git checkout -b "$BREW_BRANCH"
75+
76+
# If this is a main branch build, append a dogfood suffix to the cask.
77+
SUFFIX=""
78+
CONFLICTS_WITH="coder-desktop-dogfood"
79+
if [[ "$VERSION" == "dogfood" ]]; then
80+
SUFFIX="-dogfood"
81+
CONFLICTS_WITH="coder-desktop"
82+
fi
83+
84+
mkdir -p "$TAP_CHECHOUT_FOLDER"/Casks
85+
86+
# Overwrite the cask file
87+
cat >"$TAP_CHECHOUT_FOLDER"/Casks/coder-desktop${SUFFIX}.rb <<EOF
88+
cask "coder-desktop${SUFFIX}" do
89+
version "${VERSION}"
90+
sha256 "${HASH}"
91+
92+
url "https://github.com/coder/coder-desktop-macos/releases/download/#{version}/Coder.Desktop.dmg"
93+
name "Coder Desktop"
94+
desc "Coder Desktop client"
95+
homepage "https://github.com/coder/coder-desktop-macos"
96+
97+
depends_on macos: ">= :sonoma"
98+
99+
app "Coder Desktop.app"
100+
conflicts_with cask: "coder/coder/${CONFLICTS_WITH}"
101+
end
102+
EOF
103+
104+
git add .
105+
git commit -m "Coder Desktop $VERSION"
106+
git push -u origin -f "$BREW_BRANCH"
107+
108+
# Create a PR only if none exists
109+
if [[ "$pr_count" -eq 0 ]]; then
110+
gh pr create \
111+
--base master --head "$BREW_BRANCH" \
112+
--title "Coder Desktop $VERSION" \
113+
--body "This automatic PR was triggered by the release of Coder Desktop $VERSION" \
114+
${ASSIGNE:+ --assignee "$ASSIGNE" --reviewer "$ASSIGNE"}
115+
fi

0 commit comments

Comments
 (0)