Repository navigation
197 lines (187 loc) · 7.39 KB
/
Copy pathci.yml
File metadata and controls
197 lines (187 loc) · 7.39 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
name: CI
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
# Unit gate: the same `make test` developers run locally (race + short + cover
# across every go.work module: proto, client, client/gin, server). Matrix covers
# the go.mod floor and the latest stable Go (security patches).
test:
name: test (go ${{ matrix.go }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go: ["1.26.5", "stable"]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: ${{ matrix.go }}
check-latest: true
- name: Build server binary
run: make build
- name: Test (race + short + cover, all modules)
run: make test
# Convention gate: Conventional Commits on every PR commit, making the
# CONTRIBUTING claim ("commit messages are linted") true in CI instead of
# relying on a maintainer-local commitlint. Dependency-free: a regex over the
# PR range, so a pure-Go repo stays pure-Go. Merge commits are exempt.
commitlint:
name: commit messages
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Conventional Commits on PR commits
env:
BASE: ${{ github.event.pull_request.base.sha }}
HEAD: ${{ github.event.pull_request.head.sha }}
run: |
set -euo pipefail
pattern='^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9/_.-]+\))?(!)?: .+'
fail=0
for sha in $(git rev-list --no-merges "$BASE..$HEAD"); do
subject=$(git log -1 --format=%s "$sha")
if ! printf '%s' "$subject" | grep -qE "$pattern"; then
echo "::error::commit $sha is not Conventional Commits: '$subject'"
fail=1
fi
done
exit $fail
# License gate: the repository is MIT throughout (ADR-0022). Every Go module
# (each go.mod directory) must still ship its own LICENSE file so pkg.go.dev and
# go tooling resolve a license per module. Prevents the drift that once left
# example/ without a LICENSE.
license:
name: license
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Every module ships a LICENSE file
run: |
set -euo pipefail
fail=0
for m in $(find . -name go.mod -not -path './vendor/*' | sed 's#^\./##; s#/go.mod$##'); do
if [ ! -f "$m/LICENSE" ]; then
echo "::error file=$m::module '$m' has no LICENSE file"
fail=1
fi
done
exit $fail
# Public-tree gate: the open-core tree must not name the composing build's
# hosted-service surfaces (payment/plan-commerce vocabulary scrubbed in the
# public split). This grep catches a re-introduction in CI instead of leaving
# it for review — the code-absence invariant (ADR-0022; introduced in 0004,
# which survives the relicensing to MIT). It scans tracked
# source/docs, skipping generated protobuf/connect stubs and the workflow file
# itself (which necessarily spells the forbidden terms in the pattern below).
public-tree:
name: public tree hygiene
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: No hosted-service vocabulary in the public tree
run: |
set -euo pipefail
pattern='stripe|billing|pricing|subscription|org_billing|member_invites|checkout_session'
if git grep -nEi "$pattern" -- '*.go' '*.md' '*.sql' '*.yml' '*.yaml' '*.proto' ':!*.pb.go' ':!*.connect.go' ':!.github/'; then
echo "::error::hosted-service vocabulary found in the public (open-core) tree — see matches above"
exit 1
fi
echo "public tree clean of hosted-service vocabulary"
# Quality gate: the same `make audit` developers run locally (go mod verify +
# golangci-lint with the repo's 10x thresholds + govulncheck, per module).
# Tools are pre-installed at the pinned versions so `make audit` reuses them
# instead of bootstrapping `make tools`.
lint:
name: lint + vuln
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: stable
- name: Install golangci-lint (pinned)
run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Audit (verify + lint + vuln, all modules)
run: make audit
# Supply-chain gate: Trivy over the working tree. It covers what govulncheck
# cannot: advisories against declared module versions regardless of call path,
# Dockerfile misconfiguration (a root runtime user is a HIGH here), and secrets
# committed by accident. Unfixed advisories are ignored so the gate stays
# actionable: it only fails on findings with a released fix.
scan:
name: supply chain scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Trivy (vuln + misconfig + secret)
uses: aquasecurity/trivy-action@v0.36.0
with:
scan-type: fs
scan-ref: .
scanners: vuln,misconfig,secret
severity: HIGH,CRITICAL
ignore-unfixed: true
exit-code: "1"
# Integration gate: exercises the real ClickHouse writer/query layer and the
# Postgres-backed control-plane store (the `//go:build integration` tests)
# against live instances, so both critical paths are covered automatically.
integration:
name: integration (clickhouse + postgres)
runs-on: ubuntu-latest
services:
clickhouse:
image: clickhouse/clickhouse-server:24.8
env:
CLICKHOUSE_DB: maping
CLICKHOUSE_USER: maping
CLICKHOUSE_PASSWORD: maping
CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT: "1"
ports:
- 9000:9000
- 8123:8123
options: >-
--health-cmd "wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1"
--health-interval 5s
--health-timeout 3s
--health-retries 10
postgres:
image: postgres:17
env:
POSTGRES_DB: maping
POSTGRES_USER: maping
POSTGRES_PASSWORD: maping
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U maping -d maping"
--health-interval 5s
--health-timeout 3s
--health-retries 10
steps:
- uses: actions/checkout@v7
- uses: actions/setup-go@v7
with:
go-version: stable
- name: Storage and control-plane integration tests
# Run the same target developers use locally (make integration) so CI and
# local never drift. The target honours these explicitly-set DSNs: in CI
# both services are on localhost (postgres 5432, clickhouse 9000 per the
# service port maps above), whereas locally the target derives the host
# ports from .env (MAPING_PG_PORT=15432). One command, one code path.
env:
MAPING_CLICKHOUSE_DSN: clickhouse://maping:maping@localhost:9000/maping
MAPING_POSTGRES_DSN: postgres://maping:maping@localhost:5432/maping?sslmode=disable
run: make integration