Skip to content

Commit a50bc96

Browse files
author
bgagent
committed
refactor(ci): move dead-code job to its own workflow + use uv run for vulture
Address PR #520 review feedback: - Extract dead-code detection into dead-code-pr.yml (separate concern from security gate) - Use `uv run vulture` instead of `uvx vulture` for consistency with project conventions
1 parent b895999 commit a50bc96

3 files changed

Lines changed: 65 additions & 53 deletions

File tree

.github/workflows/dead-code-pr.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: dead-code-pr
2+
# Advisory dead-code detection gate (issue #282, cairn MVG gate #6).
3+
# Steps use continue-on-error so findings surface as annotations without
4+
# blocking the merge queue. Flips to required/blocking once the knip
5+
# baseline (knip-baseline.json) is driven to zero. The eslint no-unused-vars
6+
# half of the gate is already blocking via the `build` check.
7+
on:
8+
pull_request: {}
9+
merge_group: {}
10+
workflow_dispatch: {}
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: dead-code-pr-${{ github.event.pull_request.number || github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
dead-code:
21+
name: Dead-code detection (advisory)
22+
runs-on: ubuntu-latest
23+
timeout-minutes: 15
24+
permissions:
25+
contents: read
26+
env:
27+
CI: "true"
28+
MISE_EXPERIMENTAL: "1"
29+
steps:
30+
- name: Checkout
31+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
32+
with:
33+
persist-credentials: false
34+
35+
- name: Install mise
36+
uses: jdx/mise-action@dba19683ed58901619b14f395a24841710cb4925 # v4.1.0
37+
with:
38+
cache: true
39+
40+
- name: Setup Node.js
41+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
42+
with:
43+
node-version: 22.x
44+
45+
- name: Install dependencies
46+
run: mise run install
47+
48+
- name: TS dead-code ratchet (knip, advisory)
49+
continue-on-error: true
50+
run: |
51+
if mise run check:deadcode-ratchet; then
52+
echo "::notice title=knip ratchet::Dead-code count is at or below baseline."
53+
else
54+
echo "::warning title=knip ratchet::Dead-code count increased above the baseline (knip-baseline.json). Run 'yarn knip' locally and remove the new dead code, or suppress a false positive in knip.json."
55+
fi
56+
57+
- name: Python dead-code scan (vulture, advisory)
58+
continue-on-error: true
59+
run: |
60+
if mise //agent:lint:deadcode; then
61+
echo "::notice title=vulture::No Python dead code above the confidence threshold."
62+
else
63+
echo "::warning title=vulture::vulture found unused Python code. Remove it, or add an intentional keep to agent/.vulture_allowlist.py."
64+
fi

.github/workflows/security-pr.yml

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@ name: security-pr
77
# (<~3 min) and can be a required status check without throttling the inner loop.
88
# The heavy image + SAST suite (trivy/grype/semgrep) runs in security.yml and is
99
# tracked separately by #235; the full-history secret sweep also lives there.
10-
#
11-
# The `dead-code` job (issue #282, cairn MVG gate #6) is intentionally ADVISORY:
12-
# its steps use continue-on-error so findings surface as annotations without
13-
# blocking the merge queue. It flips to a required/blocking gate once the knip
14-
# baseline (knip-baseline.json) is driven to zero. The eslint no-unused-vars
15-
# half of the gate is already blocking via the `build` check.
1610
on:
1711
pull_request: {}
1812
# Must also run on merge_group so this check reports inside the merge queue;
@@ -92,49 +86,3 @@ jobs:
9286

9387
- name: Workflow static analysis (zizmor)
9488
run: mise run security:gh-actions
95-
96-
dead-code:
97-
name: Dead-code detection (advisory)
98-
runs-on: ubuntu-latest
99-
timeout-minutes: 15
100-
permissions:
101-
contents: read
102-
env:
103-
CI: "true"
104-
MISE_EXPERIMENTAL: "1"
105-
steps:
106-
- name: Checkout
107-
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
108-
with:
109-
persist-credentials: false
110-
111-
- name: Install mise
112-
uses: jdx/mise-action@dba19683ed58901619b14f395a24841710cb4925 # v4.1.0
113-
with:
114-
cache: true
115-
116-
- name: Setup Node.js
117-
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
118-
with:
119-
node-version: 22.x
120-
121-
- name: Install dependencies
122-
run: mise run install
123-
124-
- name: TS dead-code ratchet (knip, advisory)
125-
continue-on-error: true
126-
run: |
127-
if mise run check:deadcode-ratchet; then
128-
echo "::notice title=knip ratchet::Dead-code count is at or below baseline."
129-
else
130-
echo "::warning title=knip ratchet::Dead-code count increased above the baseline (knip-baseline.json). Run 'yarn knip' locally and remove the new dead code, or suppress a false positive in knip.json."
131-
fi
132-
133-
- name: Python dead-code scan (vulture, advisory)
134-
continue-on-error: true
135-
run: |
136-
if mise //agent:lint:deadcode; then
137-
echo "::notice title=vulture::No Python dead code above the confidence threshold."
138-
else
139-
echo "::warning title=vulture::vulture found unused Python code. Remove it, or add an intentional keep to agent/.vulture_allowlist.py."
140-
fi

agent/mise.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ run = "uv run ty check"
4646

4747
[tasks."lint:deadcode"]
4848
description = "Dead-code detection with vulture (#282, cairn MVG gate #6): unused functions/classes/methods ruff F cannot see. Config + allowlist in pyproject.toml / .vulture_allowlist.py."
49-
run = "uvx vulture"
49+
run = "uv run vulture"
5050

5151
[tasks.test]
5252
description = "Run tests with pytest (coverage floor enforced; use `uv run pytest --no-cov` for focused runs)"

0 commit comments

Comments
 (0)