-
Notifications
You must be signed in to change notification settings - Fork 0
138 lines (130 loc) · 5.93 KB
/
Copy pathci.yml
File metadata and controls
138 lines (130 loc) · 5.93 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
# CI for this repository. The user-facing publishing template lives in
# examples/github-actions.yml and is linted here rather than executed, because
# this repository is not yet a snailmail workspace.
name: ci
on:
pull_request:
push:
branches: [main]
workflow_dispatch:
# A job added later inherits this rather than the repository default.
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
# Runs on macOS as well as Linux because several publication paths are
# platform-specific — the atomic directory-entry exchange behind a managed
# release, and executing a retained credential-broker snapshot. Both have
# produced darwin-only breakage that a Linux-only suite cannot see.
#
# Tests skip what the platform lacks, so this leg proves the Go paths; the
# container job below is what exercises the real apt, pip and gpgv clients.
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
# macOS runners ship no Go at all, and a runner's ambient Go can be older
# than go.mod requires. Install exactly what go.mod asks for.
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: go.mod
# Cross-architecture verification executes a foreign-architecture
# container, which the kernel refuses without binfmt_misc handlers. The
# tests skip when they are absent, so without this the coverage silently
# disappears rather than failing.
- name: Register emulation for foreign architectures
if: runner.os == 'Linux'
run: |
set -euo pipefail
sudo apt-get update -qq
sudo apt-get install -y -qq qemu-user-static binfmt-support
test -e /proc/sys/fs/binfmt_misc/qemu-aarch64
- run: make fmt
- run: make vet
- run: make test-race
# The S3 adapters are build-tagged out for smaller binaries; that
# configuration has to keep compiling and passing.
- run: make test-nos3
# A stamped build must report the tag as its version, and an ordinary one
# must refuse to claim a release. Both directions matter: the second is
# what stops a development build being published as a release.
- name: Verify version stamping
run: |
go build -ldflags \
"-X github.com/shellcell/snailmail/internal/version.stamped=v9.9.9" \
-o ./snailmail-stamped ./cmd/snailmail
got=$(./snailmail-stamped version --json | tr -d ' \n')
case "$got" in
*'"version":"9.9.9"'*) echo "stamped: ok" ;;
*) echo "stamped build reported $got"; exit 1 ;;
esac
go build -o ./snailmail-plain ./cmd/snailmail
if ./snailmail-plain version --json | grep -q '"version": *"[^"]'; then
echo "an unstamped build claimed a release version"; exit 1
fi
echo "unstamped: ok"
# Builds the image and runs the suite inside it, which also exercises the
# signed-Debian stage against a real apt.
container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- run: docker build --target test --tag "snailmail-ci-test:${GITHUB_SHA}" .
# The binary is distributed for platforms no test job runs on.
cross-compile:
runs-on: ubuntu-latest
strategy:
matrix:
target: [linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, freebsd/amd64]
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
# The release version is read from the Git tag, and checkout fetches
# no tags by default. Without this every build stamps as untagged.
fetch-depth: 0
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: go.mod
- run: go vet ./... && GOOS="${TARGET%/*}" GOARCH="${TARGET#*/}" go build ./...
env:
TARGET: ${{ matrix.target }}
# Build the binary the way a release builds it, so a broken -ldflags path
# fails here rather than by shipping a binary that cannot name itself.
# No --always: it emits a bare commit hash when no tag is reachable, and a
# digit-led hash is shaped exactly like a release version.
- name: Build stamped binary
run: |
stamp=$(git describe --tags --dirty 2>/dev/null || true)
echo "stamp: ${stamp:-<none>}"
GOOS="${TARGET%/*}" GOARCH="${TARGET#*/}" go build \
-ldflags "-X github.com/shellcell/snailmail/internal/version.stamped=${stamp}" \
-o "snailmail_${TARGET%/*}_${TARGET#*/}" ./cmd/snailmail
env:
TARGET: ${{ matrix.target }}
# A reachable advisory in a signing dependency is the failure this catches;
# one shipped in circl and was found by hand rather than by CI. It runs in the
# digest-pinned build image because `go run tool@version` builds the tool with
# the runner's ambient toolchain, which can be older than go.mod requires and
# then cannot load these packages at all.
vulncheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- run: docker build --target vulncheck .
lint-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: go.mod
# A pinned Go tool rather than a third-party action: one less action to
# trust, and the identical command runs locally. Runners provide
# shellcheck, which actionlint invokes on every run block.
- run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.7 examples/*.yml