-
-
Notifications
You must be signed in to change notification settings - Fork 0
189 lines (178 loc) · 8.28 KB
/
Copy pathaffinescript-verify.yml
File metadata and controls
189 lines (178 loc) · 8.28 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
# SPDX-License-Identifier: MPL-2.0
name: AffineScript Verify
# Direct pushes only on integration branches. Feature-branch validation
# is fully covered by pull_request — running a full AffineScript verify
# on every WIP push to every branch in every consumer repo was a dominant
# estate-wide drain on the shared Actions concurrency pool. No coverage
# is lost: PRs and post-merge main/master still verify.
on:
push:
branches: [main, master]
pull_request:
# Estate guardrail: cancel superseded runs so re-pushes / rebased PR
# updates do not pile up queued runs against the shared account-wide
# Actions concurrency pool. Applied only to read-only check workflows
# (no publish/mutation), so cancelling a superseded run is always safe.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
# Compile-verifies changed `.affine` files with the canonical AffineScript
# compiler (hyperpolymath/affinescript). The compiler is pinned to a commit
# SHA for reproducibility; bump COMPILER_REF deliberately.
#
# SPLIT GATE (Wave 8, standards#446 honest-gating): the initial
# ReScript->AffineScript port (PR #62) predates the compiler, so some legacy
# ports still fail `affinescript check`. Blindly flipping the whole job to
# blocking would red every PR that touches a legacy port — manufactured noise.
# Instead the gate distinguishes:
# * ADDED .affine files (diff-filter=A) -> BLOCKING. New code has no excuse
# not to compile; a failing added file fails this job.
# * MODIFIED legacy files (diff-filter=CMR) -> advisory warnings until the
# port backlog clears (flip LEGACY_BLOCKING=true then).
# * Toolchain failures (compiler checkout/opam/build) -> advisory: the step
# reports "toolchain unavailable" and the verify step SKIPS (loudly) rather
# than blocking unrelated changes on OCaml infra flake.
env:
LEGACY_BLOCKING: "false"
COMPILER_REPO: hyperpolymath/affinescript
COMPILER_REF: d2875a552f1d389b4a60c4adfdc02ae53e36aca3
jobs:
verify:
timeout-minutes: 20
name: AffineScript Verify
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout standards
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 0
- name: Determine changed .affine files
id: changed
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
BASE="${{ github.event.pull_request.base.sha }}"
else
BASE="${{ github.event.before }}"
fi
if [ -z "$BASE" ] || ! git cat-file -e "$BASE^{commit}" 2>/dev/null \
|| printf '%s' "$BASE" | grep -qE '^0+$'; then
BASE="$(git rev-parse HEAD^ 2>/dev/null || git rev-parse HEAD)"
fi
# Split-gate inputs: ADDED files gate hard; modified legacy files are
# advisory until the port backlog clears (see header).
ADDED="$(git diff --name-only --diff-filter=A "$BASE" HEAD -- '*.affine' || true)"
MODIFIED="$(git diff --name-only --diff-filter=CMR "$BASE" HEAD -- '*.affine' || true)"
FILES="$(printf '%s\n%s\n' "$ADDED" "$MODIFIED" | sed '/^$/d')"
if [ -z "$FILES" ]; then
echo "any=false" >> "$GITHUB_OUTPUT"
echo "No changed .affine files — nothing to verify."
else
echo "any=true" >> "$GITHUB_OUTPUT"
echo "Changed .affine files (added gate hard; modified advisory):"
echo "$FILES"
{ echo 'files<<EOF'; echo "$FILES"; echo 'EOF'; } >> "$GITHUB_OUTPUT"
{ echo 'added<<EOF'; echo "$ADDED"; echo 'EOF'; } >> "$GITHUB_OUTPUT"
fi
- name: Checkout AffineScript compiler
if: steps.changed.outputs.any == 'true'
# advisory: compiler checkout is report-only until the port backlog
# is cleared and BLOCKING flips to true.
continue-on-error: true
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ env.COMPILER_REPO }}
ref: ${{ env.COMPILER_REF }}
path: .affinescript-compiler
- name: Set up OCaml
if: steps.changed.outputs.any == 'true'
# advisory: setup failures should surface as signal without blocking
# unrelated standards changes while AffineScript verification matures.
continue-on-error: true
uses: ocaml/setup-ocaml@15d660006c1d3110d77c34b7faa3bddefe8b82f0 # v3
with:
ocaml-compiler: "5.1"
- name: Build compiler
id: build
if: steps.changed.outputs.any == 'true'
# advisory: toolchain failures are infra flake, not code failures —
# they must not block unrelated changes. The verify step below skips
# LOUDLY (never a silent green claim) when the compiler is unavailable.
continue-on-error: true
working-directory: .affinescript-compiler
run: |
opam install . --deps-only
opam exec -- dune build
echo "ok=true" >> "$GITHUB_OUTPUT"
- name: Verify changed .affine files (added files gate; legacy advisory)
if: steps.changed.outputs.any == 'true'
# No working-directory: if the (advisory) compiler checkout failed, the
# dir may not exist — the guard below must run BEFORE any cd.
run: |
set -u
if [ "${{ steps.build.outputs.ok }}" != "true" ] || [ ! -d .affinescript-compiler ]; then
echo "::warning::AffineScript toolchain unavailable (compiler checkout/opam/build failed) — verification SKIPPED, not passed."
{
echo "## AffineScript Verify"
echo "⚠️ **SKIPPED — toolchain unavailable.** The compiler did not build;"
echo "no \`.affine\` file was verified. This is an infra flake, not a pass."
} >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
cd .affinescript-compiler
# is_added <file>: is this file in the added set? (added files gate hard)
is_added() {
case $'\n'"${ADDED_SET}"$'\n' in *$'\n'"$1"$'\n'*) return 0 ;; *) return 1 ;; esac
}
ADDED_SET="$(cat <<'EOF'
${{ steps.changed.outputs.added }}
EOF
)"
ADDED_SET="$(printf '%s\n' "$ADDED_SET" | sed 's/^[[:space:]]*//' | sed '/^$/d')"
added_fail=""
legacy_fail=""
while IFS= read -r f; do
[ -z "$f" ] && continue
abs="$GITHUB_WORKSPACE/$f"
echo "::group::check $f"
if opam exec -- dune exec affinescript -- check "$abs" 2>&1; then
echo "✅ $f"
elif is_added "$f"; then
echo "::error file=$f::AffineScript check failed (ADDED file — blocking)"
echo "❌ $f failed (added file — blocking)"
added_fail="$added_fail$f"$'\n'
else
echo "::warning file=$f::AffineScript check failed (legacy port — advisory until backlog clears)"
echo "⚠️ $f failed (legacy port — advisory)"
legacy_fail="$legacy_fail$f"$'\n'
fi
echo "::endgroup::"
done <<'EOF'
${{ steps.changed.outputs.files }}
EOF
{
echo "## AffineScript Verify (split gate)"
if [ -z "$added_fail" ] && [ -z "$legacy_fail" ]; then
echo "All changed \`.affine\` files passed \`affinescript check\`."
fi
if [ -n "$added_fail" ]; then
echo "### ❌ ADDED files failing (BLOCKING — new code must compile)"
echo "$added_fail" | sed '/^$/d' | sed 's/^/- /'
fi
if [ -n "$legacy_fail" ]; then
echo "### ⚠️ Legacy ports failing (advisory until the port backlog clears)"
echo "$legacy_fail" | sed '/^$/d' | sed 's/^/- /'
fi
} >> "$GITHUB_STEP_SUMMARY"
if [ -n "$added_fail" ]; then
echo "AffineScript verification failed for ADDED files (blocking)."
exit 1
fi
if [ -n "$legacy_fail" ] && [ "$LEGACY_BLOCKING" = "true" ]; then
echo "Legacy port failures are blocking (LEGACY_BLOCKING=true)."
exit 1
fi
echo "Verification complete (added files clean)."