forked from doctly/switchboard
-
Notifications
You must be signed in to change notification settings - Fork 3
175 lines (158 loc) · 6.6 KB
/
Copy pathbuild.yml
File metadata and controls
175 lines (158 loc) · 6.6 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
164
165
166
167
168
169
170
171
172
173
174
175
name: Build & Release
on:
push:
tags: ['v*']
pull_request:
branches: [main]
permissions:
contents: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
platform: mac
# Pinned, not `windows-latest`: that label has rolled over to Windows
# Server 2025, whose image no longer ships the Visual Studio C++
# toolchain node-gyp needs. On it, electron-builder's install-app-deps
# dies with "Could not find any Visual Studio installation to use"
# while rebuilding node-pty, so the Windows build never produces an
# artifact. 2022 still carries the toolchain.
- os: windows-2022
platform: win
# Linux is split per-arch to avoid electron-builder bundling native
# modules from the wrong architecture. When multiple targets (AppImage
# + deb) are built for multiple arches in one invocation, the native
# module rebuild only runs between arch switches for the first target
# type — the second target type reuses whatever was last compiled,
# which can be the wrong arch. See #18.
- os: ubuntu-latest
platform: linux
arch: x64
- os: ubuntu-24.04-arm
platform: linux
arch: arm64
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install setuptools (node-gyp distutils fix)
run: python -m pip install setuptools
- name: Install pacman build tooling (Linux)
if: matrix.platform == 'linux'
run: sudo apt-get update && sudo apt-get install -y libarchive-tools
- name: Install dependencies
run: npm ci
- name: Bundle CodeMirror
run: npm run bundle:codemirror
- name: Build
run: npx electron-builder --${{ matrix.platform }} --publish never
env:
# Passing CSC_LINK="" (empty) makes electron-builder treat the cwd as a
# cert file ("… not a file") on tag builds. Only set the signing vars
# when a cert secret actually exists; otherwise leave them unset and let
# mac.identity:null (package.json) produce a clean unsigned build.
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
CSC_IDENTITY_AUTO_DISCOVERY: ${{ matrix.platform == 'mac' && secrets.CSC_LINK != '' }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist-${{ matrix.platform }}${{ matrix.arch && format('-{0}', matrix.arch) || '' }}
path: |
dist/*.dmg
dist/*.dmg.blockmap
dist/*.zip
dist/*.zip.blockmap
dist/*.exe
dist/*.exe.blockmap
dist/*.AppImage
dist/*.deb
dist/*.pacman
dist/latest*.yml
if-no-files-found: ignore
publish:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
# Full history + tags: the release notes are derived from the commit range
# between the previous tag and this one.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Create the draft once. Tolerate "already exists" so a re-run after a
# partial failure still proceeds to (re-)upload the assets.
gh release create "${GITHUB_REF_NAME}" \
--draft \
--title "${GITHUB_REF_NAME#v}" \
--notes "" \
|| echo "release already exists — proceeding to asset upload"
# Upload each asset individually with retries. A single whole-batch
# `gh release create ... dist/*` aborts entirely when uploads.github.com
# returns an intermittent 401 on one asset (typically a .blockmap),
# leaving a partial release. Per-file + retry makes publishing reliable.
rc=0
for f in dist/*; do
[ -f "$f" ] || continue
ok=0
for i in 1 2 3 4 5; do
if gh release upload "${GITHUB_REF_NAME}" "$f" --clobber; then ok=1; break; fi
echo "::warning::upload $(basename "$f") attempt $i failed; retrying in 10s"
sleep 10
done
if [ "$ok" != 1 ]; then echo "::error::failed to upload $(basename "$f") after retries"; rc=1; fi
done
exit $rc
# v0.0.63 to v0.0.65 all shipped with an empty body: the step above creates
# the draft with --notes "" and nothing ever filled it in. Derive the body
# from the tag range instead, and fail loudly rather than write an empty one.
- name: Fill in release notes
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
TAG="${GITHUB_REF_NAME}"
# The tag that precedes this one on this tag's own history, not the
# repository's newest tag.
PREV_TAG="$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)"
if [ -n "$PREV_TAG" ]; then RANGE="${PREV_TAG}..${TAG}"; else RANGE="$TAG"; fi
# main is a chain of PR squash-merges, one subject per PR. The version
# bump commit ("v0.0.65 (#189)") is release plumbing, not a change.
git log --no-merges --format='%s' "$RANGE" \
| grep -Ev '^v[0-9]+\.[0-9]+\.[0-9]+([^0-9].*)?$' > subjects.txt || true
if [ ! -s subjects.txt ]; then
echo "::error::no release-worthy commits in ${RANGE}; refusing to write an empty release body"
exit 1
fi
{
echo "## What's changed"
echo
sed 's/^/- /' subjects.txt
if [ -n "$PREV_TAG" ]; then
echo
echo "**Full changelog**: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/${PREV_TAG}...${TAG}"
fi
} > release-notes.md
# Stays a draft: edit only replaces the body.
gh release edit "$TAG" --notes-file release-notes.md