Skip to content

Commit a79e34c

Browse files
authored
chore: build releases on a single Linux runner (switch to rcodesign) (coder#3890)
* chore: build, sign and notarize darwin binaries on linux * chore: download rcodesign during release * chore: change nfpm install to be a download instead of compile * chore: delete apple cert secrets after build * fix: fix dependencies in archive.sh and build_go.sh * chore: reduce output from rcodesign
1 parent ac279b3 commit a79e34c

File tree

8 files changed

+199
-232
lines changed

8 files changed

+199
-232
lines changed

.github/workflows/release.yaml

Lines changed: 66 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
# GitHub release workflow.
2-
#
3-
# This workflow is a bit complicated because we have to build darwin binaries on
4-
# a mac runner, but the mac runners are extremely slow. So instead of running
5-
# the entire release on a mac (which will take an hour to run), we run only the
6-
# mac build on a mac, and the rest on a linux runner. The final release is then
7-
# published using a final linux runner.
82
name: release
93
on:
104
push:
@@ -31,7 +25,7 @@ env:
3125
CODER_RELEASE: ${{ github.event.inputs.snapshot && 'false' || 'true' }}
3226

3327
jobs:
34-
linux-windows:
28+
release:
3529
runs-on: ubuntu-latest
3630
env:
3731
# Necessary for Docker manifest
@@ -72,21 +66,58 @@ jobs:
7266
js-${{ runner.os }}-
7367
7468
- name: Install nfpm
75-
run: go install github.com/goreleaser/nfpm/v2/cmd/nfpm@v2.16.0
69+
run: |
70+
set -euo pipefail
71+
wget -O /tmp/nfpm.deb https://github.com/goreleaser/nfpm/releases/download/v2.18.1/nfpm_amd64.deb
72+
sudo dpkg -i /tmp/nfpm.deb
7673
- name: Install zstd
7774
run: sudo apt-get install -y zstd
7875

79-
- name: Build Linux and Windows Binaries
76+
- name: Install rcodesign
77+
run: |
78+
set -euo pipefail
79+
80+
# Install a prebuilt binary of rcodesign for linux amd64. Once the
81+
# following PR is merged and released upstream, we can download
82+
# directly from GitHub releases instead:
83+
# https://github.com/indygreg/PyOxidizer/pull/635
84+
wget -O /tmp/rcodesign https://cdn.discordapp.com/attachments/283356472258199552/1016767245717872700/rcodesign
85+
sudo install --mode 755 /tmp/rcodesign /usr/local/bin/rcodesign
86+
87+
- name: Setup Apple Developer certificate and API key
88+
run: |
89+
set -euo pipefail
90+
touch /tmp/{apple_cert.p12,apple_cert_password.txt,apple_apikey.p8}
91+
chmod 600 /tmp/{apple_cert.p12,apple_cert_password.txt,apple_apikey.p8}
92+
echo "$AC_CERTIFICATE_P12_BASE64" | base64 -d > /tmp/apple_cert.p12
93+
echo "$AC_CERTIFICATE_PASSWORD" > /tmp/apple_cert_password.txt
94+
echo "$AC_APIKEY_P8_BASE64" | base64 -d > /tmp/apple_apikey.p8
95+
env:
96+
AC_CERTIFICATE_P12_BASE64: ${{ secrets.AC_CERTIFICATE_P12_BASE64 }}
97+
AC_CERTIFICATE_PASSWORD: ${{ secrets.AC_CERTIFICATE_PASSWORD }}
98+
AC_APIKEY_P8_BASE64: ${{ secrets.AC_APIKEY_P8_BASE64 }}
99+
100+
- name: Build binaries
80101
run: |
81102
set -euo pipefail
82103
go mod download
83104
84105
version="$(./scripts/version.sh)"
85106
make gen/mark-fresh
86107
make -j \
87-
-W coderd/database/querier.go \
88-
build/coder_"$version"_linux_{amd64,arm64,armv7}.{tar.gz,apk,deb,rpm} \
89-
build/coder_"$version"_windows_{amd64,arm64}.zip \
108+
build/coder_"$version"_linux_{amd64,armv7,arm64}.{tar.gz,apk,deb,rpm} \
109+
build/coder_"$version"_{darwin,windows}_{amd64,arm64}.zip \
110+
build/coder_helm_"$version".tgz
111+
env:
112+
CODER_SIGN_DARWIN: "1"
113+
AC_CERTIFICATE_FILE: /tmp/apple_cert.p12
114+
AC_CERTIFICATE_PASSWORD_FILE: /tmp/apple_cert_password.txt
115+
AC_APIKEY_ISSUER_ID: ${{ secrets.AC_APIKEY_ISSUER_ID }}
116+
AC_APIKEY_ID: ${{ secrets.AC_APIKEY_ID }}
117+
AC_APIKEY_FILE: /tmp/apple_apikey.p8
118+
119+
- name: Delete Apple Developer certificate and API key
120+
run: rm -f /tmp/{apple_cert.p12,apple_cert_password.txt,apple_apikey.p8}
90121

91122
- name: Build Linux Docker images
92123
run: |
@@ -112,157 +143,37 @@ jobs:
112143
# push it
113144
if [[ "$(git tag | grep '^v' | grep -vE '(rc|dev|-|\+|\/)' | sort -r --version-sort | head -n1)" == "v$(./scripts/version.sh)" ]]; then
114145
./scripts/build_docker_multiarch.sh \
115-
--target "$(./scripts/image_tag.sh --version latest)" \
116146
--push \
147+
--target "$(./scripts/image_tag.sh --version latest)" \
117148
$(cat build/coder_"$version"_linux_{amd64,arm64,armv7}.tag)
118149
fi
119150
120-
- name: Upload binary artifacts
121-
uses: actions/upload-artifact@v3
151+
- name: ls build
152+
run: ls -lh build
153+
154+
- name: Publish release
155+
run: |
156+
./scripts/publish_release.sh \
157+
${{ (github.event.inputs.dry_run || github.event.inputs.snapshot) && '--dry-run' }} \
158+
./build/*.zip \
159+
./build/*.tar.gz \
160+
./build/*.tgz \
161+
./build/*.apk \
162+
./build/*.deb \
163+
./build/*.rpm
164+
env:
165+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
166+
167+
- name: Upload artifacts to actions (if dry-run or snapshot)
168+
if: ${{ github.event.inputs.dry_run || github.event.inputs.snapshot }}
169+
uses: actions/upload-artifact@v2
122170
with:
123-
name: linux
171+
name: release-artifacts
124172
path: |
125173
./build/*.zip
126174
./build/*.tar.gz
175+
./build/*.tgz
127176
./build/*.apk
128177
./build/*.deb
129178
./build/*.rpm
130-
131-
# The mac binaries get built on mac runners because they need to be signed,
132-
# and the signing tool only runs on mac. This darwin job only builds the Mac
133-
# binaries and uploads them as job artifacts used by the publish step.
134-
darwin:
135-
runs-on: macos-latest
136-
steps:
137-
- uses: actions/checkout@v3
138-
with:
139-
fetch-depth: 0
140-
141-
# If the event that triggered the build was an annotated tag (which our
142-
# tags are supposed to be), actions/checkout has a bug where the tag in
143-
# question is only a lightweight tag and not a full annotated tag. This
144-
# command seems to fix it.
145-
# https://github.com/actions/checkout/issues/290
146-
- name: Fetch git tags
147-
run: git fetch --tags --force
148-
149-
- uses: actions/setup-go@v3
150-
with:
151-
go-version: "~1.19"
152-
153-
- name: Import Signing Certificates
154-
uses: Apple-Actions/import-codesign-certs@v1
155-
with:
156-
p12-file-base64: ${{ secrets.AC_CERTIFICATE_P12_BASE64 }}
157-
p12-password: ${{ secrets.AC_CERTIFICATE_PASSWORD }}
158-
159-
- name: Cache Node
160-
id: cache-node
161-
uses: actions/cache@v3
162-
with:
163-
path: |
164-
**/node_modules
165-
.eslintcache
166-
key: js-${{ runner.os }}-test-${{ hashFiles('**/yarn.lock') }}
167-
restore-keys: |
168-
js-${{ runner.os }}-
169-
170-
- name: Install dependencies
171-
run: |
172-
set -euo pipefail
173-
# The version of bash that macOS ships with is too old
174-
brew install bash
175-
176-
# The version of make that macOS ships with is too old
177-
brew install make
178-
echo "$(brew --prefix)/opt/make/libexec/gnubin" >> $GITHUB_PATH
179-
180-
# BSD getopt is incompatible with the build scripts
181-
brew install gnu-getopt
182-
echo "$(brew --prefix)/opt/gnu-getopt/bin" >> $GITHUB_PATH
183-
184-
# Used for notarizing the binaries
185-
brew tap mitchellh/gon
186-
brew install mitchellh/gon/gon
187-
188-
# Used for compressing embedded slim binaries
189-
brew install zstd
190-
191-
- name: Build darwin Binaries (with signatures)
192-
run: |
193-
set -euo pipefail
194-
go mod download
195-
196-
version="$(./scripts/version.sh)"
197-
make gen/mark-fresh
198-
make -j \
199-
build/coder_"$version"_darwin_{amd64,arm64}.zip
200-
env:
201-
CODER_SIGN_DARWIN: "1"
202-
AC_USERNAME: ${{ secrets.AC_USERNAME }}
203-
AC_PASSWORD: ${{ secrets.AC_PASSWORD }}
204-
AC_APPLICATION_IDENTITY: BDB050EB749EDD6A80C6F119BF1382ECA119CCCC
205-
206-
- name: Upload Binary Artifacts
207-
uses: actions/upload-artifact@v3
208-
with:
209-
name: darwin
210-
path: ./build/*.zip
211-
212-
publish:
213-
runs-on: ubuntu-latest
214-
needs:
215-
- linux-windows
216-
- darwin
217-
steps:
218-
- uses: actions/checkout@v3
219-
with:
220-
fetch-depth: 0
221-
222-
# If the event that triggered the build was an annotated tag (which our
223-
# tags are supposed to be), actions/checkout has a bug where the tag in
224-
# question is only a lightweight tag and not a full annotated tag. This
225-
# command seems to fix it.
226-
# https://github.com/actions/checkout/issues/290
227-
- name: Fetch git tags
228-
run: git fetch --tags --force
229-
230-
- name: mkdir artifacts
231-
run: mkdir artifacts
232-
233-
- name: Download darwin Artifacts
234-
uses: actions/download-artifact@v3
235-
with:
236-
name: darwin
237-
path: artifacts
238-
239-
- name: Download Linux and Windows Artifacts
240-
uses: actions/download-artifact@v3
241-
with:
242-
name: linux
243-
path: artifacts
244-
245-
- name: ls artifacts
246-
run: ls artifacts
247-
248-
- name: Publish Helm
249-
run: |
250-
set -euxo pipefail
251-
252-
version="$(./scripts/version.sh)"
253-
make -j \
254-
build/coder_helm_"$version".tgz
255-
mv ./build/*.tgz ./artifacts/
256-
257-
- name: Publish Release
258-
run: |
259-
./scripts/publish_release.sh \
260-
${{ (github.event.inputs.dry_run || github.event.inputs.snapshot) && '--dry-run' }} \
261-
./artifacts/*.zip \
262-
./artifacts/*.tar.gz \
263-
./artifacts/*.tgz \
264-
./artifacts/*.apk \
265-
./artifacts/*.deb \
266-
./artifacts/*.rpm
267-
env:
268-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
179+
retention-days: 7

scripts/archive.sh

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
# If the --output parameter is not set, the default output path is the binary
1111
# path (minus any .exe suffix) plus the format extension ".zip" or ".tar.gz".
1212
#
13-
# If --sign-darwin is specified, the zip file is signed with the `codesign`
14-
# utility and then notarized using the `gon` utility, which may take a while.
15-
# $AC_APPLICATION_IDENTITY must be set and the signing certificate must be
16-
# imported for this to work. Also, the input binary must already be signed with
17-
# the `codesign` tool.
13+
# If --sign-darwin is specified, the zip file will be notarized using
14+
# ./notarize_darwin.sh, which may take a while. Read that file for more details
15+
# on the requirements.
1816
#
1917
# If the --agpl parameter is specified, only the AGPL license is included in the
2018
# outputted archive.
@@ -82,20 +80,18 @@ if [[ ! -f "$1" ]]; then
8280
fi
8381
input_file="$(realpath "$1")"
8482

85-
sign_darwin="$([[ "$sign_darwin" == 1 ]] && [[ "$os" == "darwin" ]] && echo 1 || echo 0)"
86-
if [[ "$sign_darwin" == 1 ]] && [[ "${AC_APPLICATION_IDENTITY:-}" == "" ]]; then
87-
error "AC_APPLICATION_IDENTITY must be set when --sign-darwin or CODER_SIGN_DARWIN=1 is supplied"
88-
fi
89-
9083
# Check dependencies
9184
if [[ "$format" == "zip" ]]; then
9285
dependencies zip
9386
fi
9487
if [[ "$format" == "tar.gz" ]]; then
9588
dependencies tar
9689
fi
90+
91+
sign_darwin="$([[ "$sign_darwin" == 1 ]] && [[ "$os" == "darwin" ]] && echo 1 || echo 0)"
9792
if [[ "$sign_darwin" == 1 ]]; then
98-
dependencies jq codesign gon
93+
dependencies rcodesign
94+
requiredenvs AC_APIKEY_ISSUER_ID AC_APIKEY_ID AC_APIKEY_FILE
9995
fi
10096

10197
# Determine default output path.
@@ -139,7 +135,7 @@ rm -rf "$temp_dir"
139135

140136
if [[ "$sign_darwin" == 1 ]]; then
141137
log "Notarizing archive..."
142-
execrelative ./sign_darwin.sh "$output_path"
138+
execrelative ./notarize_darwin.sh "$output_path"
143139
fi
144140

145141
echo "$output_path"

scripts/build_go.sh

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
# builds) and the absolute path to the binary will be printed to stdout on
1717
# completion.
1818
#
19-
# If the --sign-darwin parameter is specified and the OS is darwin, binaries
20-
# will be signed using the `codesign` utility. $AC_APPLICATION_IDENTITY must be
21-
# set and the signing certificate must be imported for this to work.
19+
# If the --sign-darwin parameter is specified and the OS is darwin, the output
20+
# binary will be signed using ./sign_darwin.sh. Read that file for more details
21+
# on the requirements.
2222
#
2323
# If the --agpl parameter is specified, builds only the AGPL-licensed code (no
2424
# Coder enterprise features).
@@ -65,9 +65,6 @@ while true; do
6565
shift
6666
;;
6767
--sign-darwin)
68-
if [[ "${AC_APPLICATION_IDENTITY:-}" == "" ]]; then
69-
error "AC_APPLICATION_IDENTITY must be set when --sign-darwin is supplied"
70-
fi
7168
sign_darwin=1
7269
shift
7370
;;
@@ -92,7 +89,8 @@ fi
9289
# Check dependencies
9390
dependencies go
9491
if [[ "$sign_darwin" == 1 ]]; then
95-
dependencies codesign
92+
dependencies rcodesign
93+
requiredenvs AC_CERTIFICATE_FILE AC_CERTIFICATE_PASSWORD_FILE
9694
fi
9795

9896
build_args=(
@@ -133,13 +131,7 @@ CGO_ENABLED=0 GOOS="$os" GOARCH="$arch" GOARM="$arm_version" go build \
133131
"$cmd_path" 1>&2
134132

135133
if [[ "$sign_darwin" == 1 ]] && [[ "$os" == "darwin" ]]; then
136-
codesign \
137-
-f -v \
138-
-s "$AC_APPLICATION_IDENTITY" \
139-
--timestamp \
140-
--options runtime \
141-
"$output_path" \
142-
1>&2
134+
execrelative ./sign_darwin.sh "$output_path" 1>&2
143135
fi
144136

145137
echo "$output_path"

scripts/lib.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ dependencies() {
8181
fi
8282
}
8383

84+
requiredenvs() {
85+
local fail=0
86+
for env in "$@"; do
87+
if [[ "${!env:-}" == "" ]]; then
88+
log "ERROR: The '$env' environment variable is required, but is not set."
89+
fail=1
90+
fi
91+
done
92+
93+
if [[ "$fail" == 1 ]]; then
94+
log
95+
error "One or more required environment variables are not set, check above log output for more details."
96+
fi
97+
}
98+
8499
# maybedryrun prints the given program and flags, and then, if the first
85100
# argument is 0, executes it. The reason the first argument should be 0 is that
86101
# it is expected that you have a dry_run variable in your script that is set to

0 commit comments

Comments
 (0)