-
-
Notifications
You must be signed in to change notification settings - Fork 2
224 lines (199 loc) · 8.1 KB
/
Copy pathdev-build.yml
File metadata and controls
224 lines (199 loc) · 8.1 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# Binaries on demand, built from whatever branch you pick.
#
# What it is for. Somebody reports a bug, the fix lands on a branch, and they
# want to try it before there is a release. Clicking Run workflow here builds
# that branch and leaves the binaries on the run page for fourteen days.
#
# What it is NOT. Not a release and it must never be mistaken for one. These
# binaries are UNSIGNED - no code signing certificate on Windows, no Apple
# notarisation, no provenance attestation, no bill of materials. Windows
# SmartScreen and macOS Gatekeeper will both object, and that is correct
# behaviour rather than a fault to work around. Releases are made by release.yml
# from a tag, signed on two machines, and published by a person.
#
# Three things are deliberately different from a release, so that an archive
# from here cannot be passed off as one:
#
# - The name carries the COMMIT, not the version. internal/version is a const
# and cannot be stamped at link time, so a build from a fix branch says
# 0.3.0-rc1 inside whatever it really is. The file name is the only place
# that can tell the truth about which code this is, so it says the commit.
# - Every archive carries UNOFFICIAL-BUILD.txt, which says the same in words
# for whoever unpacks it a month later with no memory of where it came from.
# - It has read only permissions and no publishing step at all, so it cannot
# put anything on a release page even by accident.
#
# The test suite is deliberately NOT run first, decided by the owner: the whole
# point is a binary in two minutes, the branch has its own CI on its own pull
# request, and the note inside names the commit so anybody can go and read what
# CI said about it.
name: Build on demand
run-name: "dev build (${{ inputs.what }}) from ${{ github.ref_name }}"
on:
workflow_dispatch:
inputs:
what:
description: "Which binaries to build"
type: choice
default: cli
options:
- cli
- gui
- both
permissions:
contents: read
concurrency:
group: dev-build-${{ github.ref }}
cancel-in-progress: true
env:
GO_VERSION: "1.27.0"
# Fourteen days rather than the default ninety. These are throwaway builds
# handed to one person, and an unsigned binary should not sit for a quarter of
# a year behind a link somebody can pass on as if it were official.
KEEP_DAYS: "14"
jobs:
cli:
name: command line binaries
if: inputs.what == 'cli' || inputs.what == 'both'
runs-on: ubuntu-latest
timeout-minutes: 30
env:
# Same as the release: no C and no toolkit in the command line binary, so
# one runner cross compiles every target.
CGO_ENABLED: "0"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ env.GO_VERSION }}
- name: build and package every target
run: |
set -euo pipefail
short="$(git rev-parse --short HEAD)"
mkdir -p dist
# darwin is what the compiler is told, macos is what a person reading
# a download recognises. Same rename as the release makes.
friendly() {
case "$1" in
darwin) echo "macos" ;;
*) echo "$1" ;;
esac
}
# The same platforms the release builds, and a guard holds the two
# lists together - a fix nobody can get for their machine is not a fix.
for target in \
windows/amd64 windows/arm64 \
linux/amd64 linux/arm64 \
darwin/arm64
do
os="${target%/*}"
arch="${target#*/}"
label="$(friendly "$os")"
work="$(mktemp -d)"
binary="tfg"
if [ "$os" = "windows" ]; then
binary="tfg.exe"
fi
GOOS="$os" GOARCH="$arch" go build -tags "$(cat .github/build-tags)" -trimpath -o "${work}/${binary}" ./cmd/tfg
cp LICENSE THIRD-PARTY-NOTICES.md README.md "${work}/"
.github/scripts/unofficial_note.sh "${work}/UNOFFICIAL-BUILD.txt" "${short}"
base="tfg_dev-${short}_${label}_${arch}"
if [ "$os" = "windows" ]; then
(cd "${work}" && zip -q -r "${GITHUB_WORKSPACE}/dist/${base}.zip" .)
else
tar -czf "dist/${base}.tar.gz" -C "${work}" .
fi
echo "packaged ${base}"
done
ls -l dist
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: unofficial-cli
path: dist/*
if-no-files-found: error
retention-days: 14
gui:
name: window binary on ${{ matrix.os }}
if: inputs.what == 'gui' || inputs.what == 'both'
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
# One system failing should not throw away the binaries that did build.
# Somebody waiting for a Windows build does not care that the Mac runner
# was busy.
fail-fast: false
matrix:
os:
- windows-latest
- ubuntu-latest
- macos-latest
env:
# The window reaches OpenGL through C, so this one cannot be cross
# compiled the way the command line binary is.
CGO_ENABLED: "1"
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version: ${{ env.GO_VERSION }}
- name: graphics and windowing headers
if: runner.os == 'Linux'
# Taken from the toolkit's own CI. No GitHub runner carries these by
# default, and without them the toolkit's app package does not compile.
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
libgl1-mesa-dev \
libwayland-dev \
libx11-dev \
libxkbcommon-dev \
xorg-dev
- name: build and package
run: |
set -euo pipefail
short="$(git rev-parse --short HEAD)"
os="$(go env GOOS)"
arch="$(go env GOARCH)"
label="$os"
if [ "$os" = "darwin" ]; then
label="macos"
fi
work="$(mktemp -d)"
mkdir -p dist
if [ "$os" = "windows" ]; then
# The linker flags come from the file and nowhere else, so a build
# from here and a release cannot drift. Without them Windows hangs a
# black console window behind the program.
go build -tags "$(cat .github/build-tags)" -trimpath -ldflags="$(cat .github/gui-ldflags)" \
-o "${work}/tfg-gui.exe" ./cmd/tfg-gui
else
go build -tags "$(cat .github/build-tags)" -trimpath -o "${work}/tfg-gui" ./cmd/tfg-gui
fi
# A bundle on macOS even though nothing here is signed. Without one
# the Finder has no icon to draw and the program behaves like a
# terminal tool, which makes it useless for the person most likely to
# be reporting a window bug in the first place.
if [ "$os" = "darwin" ]; then
.github/scripts/make_app_bundle.sh \
"${work}" "tfg-gui" "com.donislawdev.tfg-gui" "dev-${short}"
fi
cp LICENSE THIRD-PARTY-NOTICES.md README.md "${work}/"
.github/scripts/unofficial_note.sh "${work}/UNOFFICIAL-BUILD.txt" "${short}"
base="tfg-gui_dev-${short}_${label}_${arch}"
if [ "$os" = "windows" ]; then
(cd "${work}" && 7z a -tzip -bso0 "${GITHUB_WORKSPACE}/dist/${base}.zip" .)
else
tar -czf "dist/${base}.tar.gz" -C "${work}" .
fi
echo "packaged ${base}"
ls -l dist
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: unofficial-gui-${{ matrix.os }}
path: dist/*
if-no-files-found: error
retention-days: 14