Skip to content

Commit 28b526e

Browse files
committed
feat: add homebrew cask release action
Change-Id: I6e76a8fa519f378cda92b4edffa64c17294e01b9 Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent d2ed4a9 commit 28b526e

File tree

6 files changed

+160
-6
lines changed

6 files changed

+160
-6
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

+29-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ permissions: {}
88

99
jobs:
1010
build:
11+
name: Build Coder Desktop
1112
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
1213
if: ${{ github.repository_owner == 'coder' }}
1314
permissions:
@@ -42,5 +43,32 @@ jobs:
4243
- name: Upload Release Assets
4344
run: gh release upload "$RELEASE_TAG" "$out"/*
4445
env:
45-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4647
RELEASE_TAG: ${{ github.event.release.tag_name }}
48+
49+
update-cask:
50+
name: Update homebrew-coder cask
51+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest'}}
52+
if: ${{ github.repository_owner == 'coder' }}
53+
needs: build
54+
steps:
55+
- name: Checkout
56+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
57+
with:
58+
fetch-depth: 1
59+
persist-credentials: false
60+
61+
- name: Setup Nix
62+
uses: ./.github/actions/nix-devshell
63+
64+
- name: Update homebrew-coder
65+
env:
66+
GH_TOKEN: ${{ secrets.CODERCI_GITHUB_TOKEN }}
67+
RELEASE_TAG: ${{ github.event.release.tag_name }}
68+
ASSIGNEE: ${{ github.actor }}
69+
run: |
70+
git config --global user.email "ci@coder.com"
71+
git config --global user.name "Coder CI"
72+
gh auth setup-git
73+
74+
./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

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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 ]] || {
43+
echo "Error: VERSION must start with '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+
pr_count="$(gh pr list --search "head:$BREW_BRANCH" --json id,closed | jq -r ".[] | select(.closed == false) | .id" | wc -l)"
68+
if [[ "$pr_count" -gt 0 ]]; then
69+
echo "Bailing out as PR already exists" 2>&1
70+
exit 0
71+
fi
72+
73+
git checkout -b "$BREW_BRANCH"
74+
75+
# If this is a beta or pre-release version, append
76+
# and experimental suffix to the cask.
77+
SUFFIX=""
78+
CONFLICTS_WITH="coder-desktop-experimental"
79+
if [[ $VERSION =~ ^v?[0-9]+\.[0-9]+\.[0-9]+-.*$ ]]; then
80+
SUFFIX="-experimental"
81+
CONFLICTS_WITH="coder-desktop"
82+
fi
83+
84+
mkdir -p "$TAP_CHECHOUT_FOLDER"/Casks
85+
86+
# Overwrite the coder-desktop cask
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
109+
gh pr create \
110+
--base master --head "$BREW_BRANCH" \
111+
--title "Coder Desktop $VERSION" \
112+
--body "This automatic PR was triggered by the release of Coder Desktop $VERSION" \
113+
${ASSIGNE:+ --assignee "$ASSIGNE" --reviewer "$ASSIGNE"}

0 commit comments

Comments
 (0)