-
Notifications
You must be signed in to change notification settings - Fork 1
163 lines (147 loc) · 6.38 KB
/
Copy pathrelease-binaries.yml
File metadata and controls
163 lines (147 loc) · 6.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# Releases binaries when application version changes.
name: Release Binaries
on:
push:
branches: [ master ]
permissions:
contents: write
# Keep only the newest release run for the same ref. This avoids competing
# release attempts when several pushes land close together.
concurrency:
group: release-binaries-${{ github.ref }}
cancel-in-progress: true
jobs:
release:
runs-on: [ self-hosted, macOS, ARM64 ]
timeout-minutes: 30
steps:
- name: Checkout Repository
uses: actions/checkout@v6
with:
fetch-depth: 0
# Use the same Go version as the project, declared in go.mod.
- name: Set Up Go Environment
uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
# Reads the app version from the `VERSION` file.
# It must be a plain MAJOR.MINOR.PATCH value, such as 1.2.3.
- name: Read Version
id: version
shell: bash
run: |
version="$(< VERSION)"
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "Version must use MAJOR.MINOR.PATCH format, found: $version" >&2
exit 1
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "tag=v$version" >> "$GITHUB_OUTPUT"
# Compares the release version with current app version.
# If current app version already exist in release, emits a warning, but flow counts as passed.
- name: Check Release Version
id: release
uses: actions/github-script@v8
env:
RELEASE_TAG: ${{ steps.version.outputs.tag }}
with:
script: |
try {
await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: process.env.RELEASE_TAG,
});
core.warning(`Release ${process.env.RELEASE_TAG} already exists. Bump VERSION to publish a new release.`);
core.setOutput('publish', 'false');
} catch (error) {
if (error.status !== 404) {
throw error;
}
core.setOutput('publish', 'true');
}
# Build binaries only for new releases.
- name: Build Binaries
if: steps.release.outputs.publish == 'true'
shell: bash
run: |
mkdir -p dist
GOOS=windows GOARCH=amd64 go build -trimpath -o dist/embed-code-windows.exe main.go
GOOS=linux GOARCH=amd64 go build -trimpath -o dist/embed-code-linux main.go
GOOS=darwin GOARCH=arm64 go build -trimpath -o dist/embed-code-macos-arm64 main.go
GOOS=darwin GOARCH=amd64 go build -trimpath -o dist/embed-code-macos-x64 main.go
chmod +x dist/embed-code-linux dist/embed-code-macos-arm64 dist/embed-code-macos-x64
# Sign the macOS binaries with a Developer ID certificate stored in GitHub
# secrets. The certificate must be exported as a base64-encoded .p12 file.
- name: Sign macOS Binaries
if: steps.release.outputs.publish == 'true'
shell: bash
env:
MACOS_CERTIFICATE_P12_BASE64: ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }}
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
run: |
scripts/release/sign-macos-binary.sh \
dist/embed-code-macos-arm64 \
dist/embed-code-macos-x64
# Publish Linux as a ZIP so Unix executable permissions survive extraction.
- name: Package Linux Binary
if: steps.release.outputs.publish == 'true'
shell: bash
run: |
pushd dist >/dev/null
zip -q embed-code-linux.zip embed-code-linux
rm embed-code-linux
popd >/dev/null
# Notarize the macOS ZIPs that will be published as release assets.
- name: Notarize macOS Binaries
if: steps.release.outputs.publish == 'true'
shell: bash
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
run: |
scripts/release/notarize-macos-zip.sh dist/embed-code-macos-arm64 dist/embed-code-macos-arm64.zip
scripts/release/notarize-macos-zip.sh dist/embed-code-macos-x64 dist/embed-code-macos-x64.zip
rm dist/embed-code-macos-arm64 dist/embed-code-macos-x64
# Create the release for the current commit and attach all generated binaries.
- name: Publish GitHub Release
if: steps.release.outputs.publish == 'true'
uses: actions/github-script@v8
env:
RELEASE_TAG: ${{ steps.version.outputs.tag }}
with:
script: |
const fs = require('fs');
const path = require('path');
const releaseTag = process.env.RELEASE_TAG;
const releaseNotes = `Embed Code ${releaseTag}\n\nThis release contains pre-built Embed Code binaries for macOS ARM64, macOS x64, Linux, and Windows. Linux and macOS binaries are published as ZIP archives.`;
const release = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: releaseTag,
target_commitish: context.sha,
name: `embed-code ${releaseTag}`,
body: releaseNotes,
});
for (const assetName of fs.readdirSync('dist').sort()) {
const assetPath = path.join('dist', assetName);
const assetData = fs.readFileSync(assetPath);
const sizeMb = (assetData.length / 1024 / 1024).toFixed(2);
const startedAt = Date.now();
core.info(`Uploading ${assetName} (${sizeMb} MB).`);
await github.rest.repos.uploadReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.data.id,
name: assetName,
headers: {
'content-type': 'application/octet-stream',
'content-length': assetData.length,
},
data: assetData,
});
const durationSeconds = ((Date.now() - startedAt) / 1000).toFixed(1);
core.info(`Uploaded ${assetName} in ${durationSeconds}s.`);
}