Skip to content

Commit 352c6e1

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

File tree

3 files changed

+151
-3
lines changed

3 files changed

+151
-3
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
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

Lines changed: 34 additions & 3 deletions
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 || 'preview' }}
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 || 'preview' }}
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"

scripts/update-cask.sh

Lines changed: 115 additions & 0 deletions
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" == "preview" ]] || {
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" != "preview" ]]; 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 preview suffix to the cask.
77+
SUFFIX=""
78+
CONFLICTS_WITH="coder-desktop-preview"
79+
if [[ "$VERSION" == "preview" ]]; then
80+
SUFFIX="-preview"
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)