-
Notifications
You must be signed in to change notification settings - Fork 0
158 lines (142 loc) · 5.97 KB
/
Copy pathci.yml
File metadata and controls
158 lines (142 loc) · 5.97 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
name: ci
# Lightweight checks on every push and pull request: build, vet, and test on
# macOS and Linux, plus full-history secret scanning and a workflow audit.
on:
push:
branches: ['**']
pull_request:
# Cancel superseded runs of the same ref (PRs and branch pushes); a merged
# default-branch push is never cancelled mid-run because each ref has its own group.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }}
permissions:
contents: read
jobs:
# Build + vet + test on both host OSes. Race-enabled unit tests catch data
# races the plain `go test` would miss.
check:
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
with:
go-version: '1.25'
# Enforce the format gate AGENTS.md documents (`gofmt -l .`). Formatting is
# platform-independent, so run it once on the ubuntu leg to avoid duplicate
# work; any file gofmt lists needs `gofmt -w` and fails the job.
- name: Format (gofmt)
if: matrix.os == 'ubuntu-latest'
run: |
set -euo pipefail
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "gofmt: these files are not formatted (run gofmt -w .):" >&2
echo "$unformatted" >&2
exit 1
fi
- name: Build
run: go build ./...
- name: Vet
run: go vet ./...
- name: Test
run: go test ./...
- name: Test (race, internal)
run: go test -race ./internal/...
# Drift gate for the .abcd/development design record. Visible but
# non-blocking for now: the record still carries violations that a
# follow-up fix pass clears before this becomes a hard gate.
- name: Record-lint (drift gate)
if: matrix.os == 'ubuntu-latest'
run: go run ./cmd/record-lint
# Docs-currency gate (itd-60): the internal/core/lint engine over docs/ and
# the repo root, driven via the `abcd docs lint` verb. Blocking — a doc-body
# change-narration, broken relative link, or stray root markdown fails CI.
- name: Docs-lint (currency gate)
if: matrix.os == 'ubuntu-latest'
run: go run ./cmd/abcd docs lint
# Secrets never land in history: full-history scan on every push/PR. Run as a
# pinned, checksum-verified CLI (no PR-comment / SARIF GitHub-API integration),
# so it works on a private repo and survives the private->public flip. A
# non-zero exit means gitleaks found a secret.
gitleaks:
timeout-minutes: 10
runs-on: ubuntu-latest
env:
GITLEAKS_VERSION: 8.24.3
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Install gitleaks (pinned, checksum-verified)
run: |
set -euo pipefail
cd "$RUNNER_TEMP"
base="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}"
curl -sSLf -o "$base" "$url/$base"
curl -sSLf -o checksums.txt "$url/gitleaks_${GITLEAKS_VERSION}_checksums.txt"
grep " $base\$" checksums.txt | sha256sum -c -
tar -xzf "$base" gitleaks
sudo install gitleaks /usr/local/bin/gitleaks
gitleaks version
- name: Scan full history
run: gitleaks git --redact --no-banner .
# Audit the workflows themselves (pwn requests, template injection, cache
# poisoning, unpinned uses). Run as a pinned CLI image (no SARIF upload to
# code-scanning, which a private repo lacks). A non-zero exit means a finding.
zizmor:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Audit workflows
run: |
# zizmor v1.26.1, pinned by digest (the registry publishes version
# releases under :latest; a raw vX.Y.Z tag does not exist).
docker run --rm -v "$GITHUB_WORKSPACE:/src:ro" \
ghcr.io/zizmorcore/zizmor@sha256:d1117e5dbd9ee4970644067b534ab6ab50371f3c6f7f4d05446eb603a6e78f48 \
--persona regular /src
# Deterministic gate for the .abcd/work/reviews/ charter (RD001-RD003). Needs
# full history: RD002 (append-only) checks committed history for post-creation
# edits, so fetch-depth: 0 (the default shallow checkout would miss them).
# Stopgap until the RD codes land in internal/core/lint.
record-lint:
timeout-minutes: 5
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Reviews-charter discipline (RD001-RD003)
run: bash scripts/check-reviews.sh
# Self-discovering smoke harness (evals/): builds the binary, walks the Cobra
# command tree in-process, and runs every command's --help plus the read-only
# verbs against the built binary. Catches a command that compiles but panics when
# actually invoked — which the unit lane (go test ./...) misses, because the
# harness is behind the `smoke` build tag.
smoke:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Go
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6
with:
go-version: '1.25'
- name: Smoke every command
run: make smoke