Repository navigation
139 lines (120 loc) · 5.18 KB
/
Copy pathci.yml
File metadata and controls
139 lines (120 loc) · 5.18 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
name: ci
# Test + validate gate. Runs on:
# - every pull request — validate changes before they can merge.
# - push to main — validate the merge result on the default branch, since the
# release workflow is manual (workflow_dispatch) and does not run on push,
# so a merge would otherwise go unverified.
# - workflow_call — reusable, so the manual release pipeline requires this gate
# before building or publishing any binaries.
on:
push:
branches: [main]
pull_request:
workflow_call:
permissions:
contents: read
jobs:
test:
name: test (${{ matrix.os }})
# Windows is a first-class target and the tool is path/line-ending heavy, so
# exercise the suite on all three OSes. fail-fast is off so one platform's
# failure still lets the others report.
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
# Build/test with a current, patched toolchain. Keep this pin AHEAD of
# go.mod's directive and do NOT switch to go-version-file: go.mod —
# install-compat with older toolchains rides on GOTOOLCHAIN=auto.
# Pinned to 1.26.9: 1.25 is out of support, and GO-2026-6603..6617
# (net/http, net/textproto, crypto/tls) are fixed only from 1.26.9.
# Earlier pins: 1.25.13 for GO-2026-6088 encoding/xml, 1.25.12 for
# GO-2026-5856 crypto/tls.
go-version: '1.26.9'
cache: true
- name: go vet
run: go vet ./...
- name: build
run: go build ./...
# The race detector needs a C toolchain + external linker, which the
# Windows runners don't provide out of the box, so run race+coverage on
# Linux/macOS and a plain (still cgo-free) test pass on Windows.
- name: test (race + coverage)
if: runner.os != 'Windows'
run: go test -race -coverprofile=coverage.out ./...
- name: test (coverage, no race)
if: runner.os == 'Windows'
# Force bash so the coverprofile arg parses like Linux/macOS; the Windows
# runner's default PowerShell mangles `-coverprofile=coverage.out ./...`
# into a bogus `.out` package pattern.
shell: bash
run: go test -coverprofile=coverage.out ./...
lint:
name: lint & vulncheck
# gofmt and the static analyzers only need to run once; keep them on Linux
# (the Windows runner checks code out with CRLF endings, which gofmt -l would
# flag on every file).
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
with:
go-version: '1.26.9' # see the test job's note
cache: true
- name: gofmt
run: |
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "::error::these files are not gofmt-clean:"
echo "$unformatted"
exit 1
fi
# Scan the module (and its dependencies) for known-vulnerable, *reachable*
# code paths. This is meant to fail the build — shipping binaries built on a
# flagged stdlib/dep is exactly what we're guarding against.
- name: govulncheck
run: |
# Pinned, like every action above it. `@latest` is a standing dependency on
# whatever upstream released last: v1.8.0 raised its go directive to 1.26 and
# broke this job on a toolchain nothing else here needed to change. Bump it
# deliberately, alongside the go-version above.
go install golang.org/x/vuln/cmd/govulncheck@v1.7.0
"$(go env GOPATH)/bin/govulncheck" ./...
# golangci-lint runs the conservative set configured in .golangci.yml.
- name: golangci-lint
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
with:
version: v2.12.2
web:
name: view frontend
# internal/view/dist/ is the built frontend `scc view` embeds, committed so a
# `go build` needs no node. This job rebuilds it from web/ and fails when the
# result differs from what is committed — the only thing that keeps the two
# from drifting apart.
runs-on: ubuntu-latest
defaults:
run:
working-directory: web
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: '22'
- name: install
run: npm ci
- name: test
run: npm test
- name: build (typecheck included)
run: npm run build
- name: dist is current
run: |
if [ -n "$(git status --porcelain -- ../internal/view/dist)" ]; then
echo "::error::internal/view/dist/ is stale — run \`npm run build\` in web/ and commit the result"
git status --porcelain -- ../internal/view/dist
exit 1
fi