-
Notifications
You must be signed in to change notification settings - Fork 14
157 lines (145 loc) · 5.83 KB
/
harness.yml
File metadata and controls
157 lines (145 loc) · 5.83 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
name: Harness
# Drift sensors that run alongside the main test workflow but never block a
# merge. These are the "continuous drift" controls from the harness
# engineering article — they observe maintainability decay (vulnerable deps,
# dead code, stale go.mod) without forcing a refactor on every PR.
#
# Each job sets continue-on-error: true. Failures show up as informational
# annotations on the PR. To promote any of these to a required check,
# remove continue-on-error and add to the branch protection rules.
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
schedule:
# Nightly run on main so drift in dependencies surfaces even without
# PR activity (govulncheck advisories land independently of code).
- cron: '0 7 * * *'
workflow_dispatch:
permissions:
contents: read
jobs:
govulncheck:
name: govulncheck (drift)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
run: govulncheck ./...
deadcode:
name: deadcode (drift)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Install deadcode
run: go install golang.org/x/tools/cmd/deadcode@latest
- name: Run deadcode
# -test includes test-only entry points; e2e,vm tags expose callers
# in the destructive e2e suite (testutil.BuildTestBinary etc.).
run: deadcode -test -tags="e2e,vm" ./...
mod-tidy:
name: go mod tidy diff (drift)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Verify go.mod is tidy
run: |
cp go.mod /tmp/go.mod.before
cp go.sum /tmp/go.sum.before
go mod tidy
if ! diff -q go.mod /tmp/go.mod.before >/dev/null || ! diff -q go.sum /tmp/go.sum.before >/dev/null; then
echo "::warning::go.mod / go.sum are not tidy — run 'go mod tidy' and commit the diff."
echo "--- go.mod diff ---"
diff /tmp/go.mod.before go.mod || true
echo "--- go.sum diff ---"
diff /tmp/go.sum.before go.sum || true
exit 1
fi
archtest-stale-baseline:
name: archtest stale baseline (drift)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
- name: Detect stale baseline entries
# archtest prints "stale baseline entr(ies)" via t.Logf when an entry
# references code that no longer exists. Surface that here as a
# warning so we can prune the baseline.
run: |
# -count=1 disables the test cache so t.Logf output always prints,
# otherwise a cached "ok" line would hide stale baseline warnings.
out=$(go test -v -count=1 ./internal/archtest/... 2>&1)
echo "$out"
if echo "$out" | grep -q "stale baseline"; then
echo "::warning::archtest reported stale baseline entries — consider regenerating with ARCHTEST_UPDATE_BASELINE=1 and committing the diff."
exit 1
fi
required-checks-alignment:
name: required-checks alignment (drift)
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Install PyYAML
run: pip install --quiet --user pyyaml
- name: Compare .github/required-checks.txt vs workflow job names
# Catches the desync that bit PR #69: branch protection still
# required `integration (L2)` and `contract schema (L3)` after the
# workflow renamed/removed those jobs, so the squash-merge silently
# blocked waiting for checks that would never report.
#
# `.github/required-checks.txt` is the in-repo source of truth for
# branch protection's required_status_checks.contexts. This sensor
# verifies every line there maps to an actual job `name:` across
# the workflows. Live branch protection is updated via
# `gh api -X PUT .../protection` in the same PR (see MERGE_POLICY).
run: |
set -euo pipefail
required=$(grep -v '^[[:space:]]*\(#\|$\)' .github/required-checks.txt | sort -u)
jobs=$(python3 <<'PY'
import pathlib, yaml
seen = set()
for path in sorted(pathlib.Path('.github/workflows').glob('*.yml')):
wf = yaml.safe_load(path.read_text())
if not isinstance(wf, dict) or not isinstance(wf.get('jobs'), dict):
continue
for job_id, job in wf['jobs'].items():
name = job.get('name', job_id) if isinstance(job, dict) else job_id
seen.add(name)
for n in sorted(seen):
print(n)
PY
)
missing=$(comm -23 <(echo "$required") <(echo "$jobs"))
if [ -n "$missing" ]; then
echo "::warning::.github/required-checks.txt lists checks that no workflow job produces:"
echo "$missing" | sed 's/^/ - /'
echo ""
echo "Either remove these from required-checks.txt (and update branch protection"
echo "via 'gh api -X PUT .../protection'), or add matching jobs to .github/workflows/."
echo "See docs/MERGE_POLICY.md."
exit 1
fi
printf '✓ All %d required checks have matching workflow jobs.\n' "$(echo "$required" | wc -l | tr -d ' ')"