Skip to content

Commit 81f89b3

Browse files
ci: fix Idris2/Agda required-check deadlock (pass-through shim) (#256)
ci: fix required-check deadlock on Idris2/Agda workflows (pass-through shim) "Type-check Idris2 ABI definitions" (idris2-abi-ci.yml) and "Type-check Agda proofs" (agda-meta-checker.yml) are REQUIRED status checks but are path-filtered. A path-filtered REQUIRED check deadlocks every PR that does not touch its paths: branch protection waits for a run that never starts, so echidna's main is unmergeable via normal PR flow. Fix (pass-through shim): drop the pull_request paths-filter so each job ALWAYS runs and the required check always reports. A "Detect relevant changes" step reads the PR's changed files via the GitHub API and gates the heavy steps -- the real type-check runs only when the relevant sources change, otherwise the job passes through in seconds. push triggers stay scoped to main (paths-filtered), so post-merge behaviour is unchanged and feature-branch pushes don't double-fire alongside the pull_request run. Job names are preserved so the existing required-status contexts still match. agda gains pull-requests:read for the detector. (The SHA-pin half of the original work merged separately as cb5e41a; this lands only the deadlock fix, which was stranded on the merged branch.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent e779bb0 commit 81f89b3

2 files changed

Lines changed: 69 additions & 6 deletions

File tree

.github/workflows/agda-meta-checker.yml

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ on:
99
branches: [main]
1010
paths:
1111
- 'meta-checker/**'
12+
# No paths-filter on pull_request: this is a REQUIRED status check, so it must
13+
# report on every PR (a path-filtered required check deadlocks PRs that don't
14+
# touch its paths). The "Detect relevant changes" step path-gates internally.
1215
pull_request:
1316
branches: [main]
14-
paths:
15-
- 'meta-checker/**'
1617
workflow_dispatch:
1718

1819
# Cause-B mitigation (#77): cancel superseded runs so stacked pushes
@@ -23,6 +24,7 @@ concurrency:
2324

2425
permissions:
2526
contents: read
27+
pull-requests: read # change-detector reads the PR's file list (gh api pulls/.../files)
2628

2729
jobs:
2830
verify-proofs:
@@ -33,13 +35,39 @@ jobs:
3335
- name: Checkout
3436
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
3537

38+
# Required-check shim: only the meta-checker/ tree needs the real proof
39+
# check. Non-PR events (push, workflow_dispatch) always run it.
40+
- name: Detect relevant changes
41+
id: detect
42+
env:
43+
GH_TOKEN: ${{ github.token }}
44+
run: |
45+
set -euo pipefail
46+
PATTERN='^meta-checker/'
47+
if [ "${{ github.event_name }}" = "pull_request" ]; then
48+
FILES=$(gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" \
49+
--paginate --jq '.[].filename')
50+
if printf '%s\n' "$FILES" | grep -qE "$PATTERN"; then
51+
echo "relevant=true" >> "$GITHUB_OUTPUT"
52+
echo "meta-checker/ sources changed — running full Agda type-check."
53+
else
54+
echo "relevant=false" >> "$GITHUB_OUTPUT"
55+
echo "No meta-checker changes — pass-through (required-check shim)."
56+
fi
57+
else
58+
echo "relevant=true" >> "$GITHUB_OUTPUT"
59+
echo "Non-PR event — running full Agda type-check."
60+
fi
61+
3662
- name: Setup Haskell
63+
if: steps.detect.outputs.relevant == 'true'
3764
uses: haskell-actions/setup@cd0d9bdd65b20557f41bea4dbe43d0b5fbbfe553 # v2
3865
with:
3966
ghc-version: '9.6'
4067
cabal-version: '3.10'
4168

4269
- name: Cache Agda
70+
if: steps.detect.outputs.relevant == 'true'
4371
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
4472
with:
4573
path: |
@@ -48,6 +76,7 @@ jobs:
4876
key: agda-${{ runner.os }}-${{ hashFiles('meta-checker/**/*.agda') }}
4977

5078
- name: Install Agda
79+
if: steps.detect.outputs.relevant == 'true'
5180
run: |
5281
cabal update
5382
# --overwrite-policy=always: the cached ~/.cabal restore already
@@ -56,6 +85,7 @@ jobs:
5685
cabal install Agda-2.7.0.1 --overwrite-policy=always
5786
5887
- name: Install Agda standard library
88+
if: steps.detect.outputs.relevant == 'true'
5989
run: |
6090
mkdir -p ~/.agda
6191
cd /tmp
@@ -65,6 +95,7 @@ jobs:
6595
echo "standard-library" > ~/.agda/defaults
6696
6797
- name: Type-check meta-checker
98+
if: steps.detect.outputs.relevant == 'true'
6899
run: |
69100
cd meta-checker
70101
echo "$PWD/echidna-meta.agda-lib" >> ~/.agda/libraries

.github/workflows/idris2-abi-ci.yml

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ name: Idris2 ABI Type-Check
33

44
on:
55
push:
6+
branches: [main] # only post-merge; feature-branch PRs are gated by the pull_request run below
67
paths:
78
- 'src/abi/**'
89
- 'src/idris/**'
910
- '.github/workflows/idris2-abi-ci.yml'
11+
# No paths-filter on pull_request: this job is a REQUIRED status check, so it
12+
# must report on every PR (a path-filtered required check deadlocks PRs that
13+
# don't touch its paths — they wait forever for a run that never happens). The
14+
# "Detect relevant changes" step below does the path-gating internally instead,
15+
# so the check always reports while heavy work runs only when sources change.
1016
pull_request:
11-
paths:
12-
- 'src/abi/**'
13-
- 'src/idris/**'
14-
- '.github/workflows/idris2-abi-ci.yml'
1517

1618
# Cause-B mitigation (#77): cancel superseded runs so stacked pushes
1719
# to the same ref don't pile up identical jobs in the queue.
@@ -29,7 +31,33 @@ jobs:
2931
steps:
3032
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
3133

34+
# Required-check shim: decide whether ABI/proof sources actually changed.
35+
# The workflow file itself is intentionally NOT in the pattern, so CI-only
36+
# edits pass through. Non-PR events (push) always run the full check.
37+
- name: Detect relevant changes
38+
id: detect
39+
env:
40+
GH_TOKEN: ${{ github.token }}
41+
run: |
42+
set -euo pipefail
43+
PATTERN='^(src/abi/|src/idris/)'
44+
if [ "${{ github.event_name }}" = "pull_request" ]; then
45+
FILES=$(gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" \
46+
--paginate --jq '.[].filename')
47+
if printf '%s\n' "$FILES" | grep -qE "$PATTERN"; then
48+
echo "relevant=true" >> "$GITHUB_OUTPUT"
49+
echo "Idris2 ABI/proof sources changed — running full type-check."
50+
else
51+
echo "relevant=false" >> "$GITHUB_OUTPUT"
52+
echo "No Idris2 source changes — pass-through (required-check shim)."
53+
fi
54+
else
55+
echo "relevant=true" >> "$GITHUB_OUTPUT"
56+
echo "Non-PR event — running full type-check."
57+
fi
58+
3259
- name: Install Idris2
60+
if: steps.detect.outputs.relevant == 'true'
3361
run: |
3462
# Idris2 v0.8.0 has no pre-built Linux release binary — the
3563
# release-assets array on https://api.github.com/repos/idris-lang/Idris2/releases/tags/v0.8.0
@@ -54,13 +82,15 @@ jobs:
5482
idris2 --version
5583
5684
- name: Type-check all ABI modules via ipkg
85+
if: steps.detect.outputs.relevant == 'true'
5786
run: |
5887
cd src/abi
5988
echo "=== Type-checking ECHIDNA ABI package (16 modules) ==="
6089
idris2 --build echidnaabi.ipkg
6190
echo "✓ All ABI modules type-check successfully"
6291
6392
- name: Type-check Idris2 proof validator (src/idris)
93+
if: steps.detect.outputs.relevant == 'true'
6494
run: |
6595
# Mirrors `just proofs-idris`. --typecheck (not --build) so no codegen
6696
# backend is required; the declared executable's `main` is exercised
@@ -71,6 +101,7 @@ jobs:
71101
echo "✓ Validator modules type-check successfully"
72102
73103
- name: Verify no dangerous patterns
104+
if: steps.detect.outputs.relevant == 'true'
74105
run: |
75106
echo "=== Scanning for dangerous patterns in ABI code ==="
76107
FOUND=0
@@ -88,6 +119,7 @@ jobs:
88119
fi
89120
90121
- name: Count modules and report
122+
if: steps.detect.outputs.relevant == 'true'
91123
run: |
92124
echo "=== ABI Module Summary ==="
93125
IDR_COUNT=$(find src/abi -name "*.idr" | wc -l)

0 commit comments

Comments
 (0)