anthropics / anthropics/claude-code-security-review
Install GitHub CLI step can hang the whole job on apt; gh is already present on GitHub-hosted runners
- Dominant language
- Python
- Stars
- 6.2k
- Forks
- 683
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
The action's first step, **Install GitHub CLI**, runs `sudo apt-get update && sudo apt-get install -y gh`. On GitHub-hosted Ubuntu runners `gh` is already preinstalled, so that step is unnecessary — and because `apt-get update` can stall against the Azure archive mirror, it is currently the most likely place for the whole job to hang. The security scan never starts.
We hit this five times in two days on one repository, on diffs as small as 20 lines.
## Evidence
From a job we bounded with `timeout-minutes: 20` (before that, hung runs sat there until they were cancelled — one over an hour):
```
21:08:17Z ##[start-action display=Install GitHub CLI;id=scan.__run]
21:08:17Z Run echo "::group::Install gh CLI"
21:08:17Z sudo apt-get update && sudo apt-get install -y gh
...
21:10:33Z Ign:2 http://azure.archive.ubuntu.com/ubuntu noble InRelease
21:10:34Z Ign:3 http://azure.archive.ubuntu.com/ubuntu noble-updates InRelease
21:10:35Z Get:5 https://archive.ubuntu.com/ubuntu noble-security InRelease [126 kB]
21:28:29Z ##[error]The action has timed out.
21:28:29Z ##[end-action id=scan.__run;outcome=failure;conclusion=failure;duration_ms=1212474]
```
`duration_ms=1212474` — 20.2 minutes, all of it in the apt step. Every subsequent step (`Set up Python`, `Determine ClaudeCode enablement`, `Run ClaudeCode scan`) reports `outcome=skipped`, so no Claude API call was ever made and no tokens were spent.
A re-run of the identical commit minutes later completed the whole job, scan included, in **1m01s**. So this is intermittent mirror behaviour, not a slow scan.
Two things made this hard to diagnose from the outside: the step produces no output while apt is stalled, and the action has no timeout of its own, so on a default runner it can occupy the job for up to six hours while the PR check reads as "still running" rather than failing.
## Suggested fixes
1. **Skip the install when `gh` is already present** — one guard removes the failure mode entirely on GitHub-hosted runners:
```bash
if command -v gh >/dev/null 2>&1; then
echo "gh $(gh --version | head -1) already present, skipping install"
else
sudo apt-get update && sudo apt-get install -y gh
fi
```
2. **Bound the step**, so a stall fails loudly instead of occupying the job: `timeout-minutes` on the install step, and/or `Acquire::http::Timeout` / `Acquire::Retries` in an apt config.
3. Optionally **document that a caller should set `timeout-minutes`**. `claudecode-timeout` bounds the scan but nothing bounds the steps before it, which is where this one lived.
Happy to open a PR for (1) if useful.
## Environment
- Action: `anthropics/claude-code-security-review`, pinned at `0c6a49f1fa56a1d472575da86a94dbc1edb78eda`
- Runner: `ubuntu-latest` (24.04 noble), GitHub-hosted
- Called from a reusable workflow with `comment-pr: true` and `claudecode-timeout: 20`
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.