Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
workflow_call:
inputs:
runs-on:
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Public/open-source repos opt out by passing '[\"ubuntu-24.04\"]'."
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Ignored for public repos, which always run on '[\"ubuntu-24.04\"]'."
type: string
# Self-hosted by default since 2026-09-20, matching claude.yml.
#
Expand All @@ -34,11 +34,14 @@
# advisory regardless: the claude-code-action step below is
# continue-on-error, so it cannot block a PR on either runner.
#
# PUBLIC REPOS SHOULD OPT OUT, and not only for the free minutes:
# running fork PRs on a self-hosted pool is the hazard GitHub warns
# about. No public repo consumes this reusable today (checked across
# the three orgs and nkg/*), so the default is safe as it stands --
# but a new public consumer must pass '["ubuntu-24.04"]'.
# PUBLIC REPOS never use this input. The job's runs-on forces
# ["ubuntu-24.04"] whenever github.event.repository.visibility is
# "public": fork PRs on a self-hosted pool are the hazard GitHub
# warns about, hosted minutes are free there, and a public caller
# that omits `runs-on` would otherwise queue for 24h on a pool with
# no runner registered. An event whose payload carries no
# repository object falls back to this input, so public callers
# should still pass a hosted `runs-on` as well.
#
# Revisit when credits reset; hosted is the right default the moment
# it can actually start a job.
Expand All @@ -57,7 +60,7 @@
type: boolean
default: false
plugin-marketplace:
description: "Optional plugin marketplace. Empty by default — the code-review plugin is broken on current Claude Code (spawns a non-existent claude-haiku agent), so we use a direct review prompt instead."

Check warning on line 63 in .github/workflows/claude-code-review.yml

View workflow job for this annotation

GitHub Actions / lint / yamllint

63:201 [line-length] line too long (212 > 200 characters)
type: string
default: ""
plugins:
Expand Down Expand Up @@ -87,7 +90,7 @@
contains(inputs.filter-authors, github.event.pull_request.user.login) ||
(inputs.filter-first-time-only && (github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' || github.event.pull_request.author_association == 'FIRST_TIMER'))
)
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ fromJSON(github.event.repository.visibility == 'public' && '["ubuntu-24.04"]' || inputs.runs-on) }}
timeout-minutes: ${{ inputs.timeout-minutes }}
# `claude-code-action` posts review comments back on the PR, so it
# needs write on pull-requests and issues. The `claude.yml` (bot)
Expand Down Expand Up @@ -124,10 +127,10 @@
# on Claude Code 2.1.x — it spawns a non-existent claude-haiku agent
# and posts nothing). Single line so it survives format(); a caller
# passing `prompt` overrides it.
prompt: ${{ inputs.prompt != '' && inputs.prompt || format('Review pull request {0}#{1} for bugs, security issues, performance problems, and missing test coverage. Follow the repo''s CLAUDE.md conventions if present. Post each specific problem as an inline comment with the mcp__github_inline_comment__create_inline_comment tool, and leave one short top-level summary via `gh pr comment`. Only flag real issues; if there are none, say so briefly.', github.repository, github.event.pull_request.number) }}

Check warning on line 130 in .github/workflows/claude-code-review.yml

View workflow job for this annotation

GitHub Actions / lint / yamllint

130:201 [line-length] line too long (514 > 200 characters)
# Without an explicit --allowedTools the inline-comment MCP tool is
# denied, so Claude runs but posts nothing ("No buffered inline
# comments" + permission_denials). Default to Anthropic's documented
# PR-review tool set (examples/pr-review-comprehensive.yml); a caller
# passing claude-args overrides it entirely.
claude_args: ${{ inputs.claude-args != '' && inputs.claude-args || '--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"' }}

Check warning on line 136 in .github/workflows/claude-code-review.yml

View workflow job for this annotation

GitHub Actions / lint / yamllint

136:201 [line-length] line too long (208 > 200 characters)
17 changes: 12 additions & 5 deletions .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ on:
workflow_call:
inputs:
runs-on:
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Public/open-source repos opt out by passing '[\"ubuntu-latest\"]'."
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Ignored for public repos, which always run on '[\"ubuntu-latest\"]'."
type: string
# Self-hosted by default since 2026-09-20. Actions credits are
# exhausted across HordiaLabs, Sproncy and Regularmusic, so a hosted
Expand All @@ -39,9 +39,16 @@ on:
# running nothing at all: 4 calls (Sproncy: sproncy-schemas, sproncy-secrets-dashboard, sproncy-transcription, sproncy-website-scrapers).
#
# Every other consumer already passes `runs-on` explicitly, so this
# changes behaviour only for those that did not. Public repos should
# pass '["ubuntu-latest"]' -- fork PRs on a self-hosted pool are the
# hazard GitHub warns about; no public repo consumes this today.
# changes behaviour only for those that did not.
#
# Public repos never use this input. The job's runs-on forces
# ["ubuntu-latest"] whenever github.event.repository.visibility is
# "public": fork PRs on a self-hosted pool are the hazard GitHub
# warns about, hosted minutes are free there, and a public caller
# that omits `runs-on` would otherwise queue for 24h on a pool with
# no runner registered. An event whose payload carries no
# repository object falls back to this input, so public callers
# should still pass a hosted `runs-on` as well.
default: '["self-hosted", "linux", "x64"]'
merge-strategy:
description: "squash | merge | rebase"
Expand Down Expand Up @@ -73,7 +80,7 @@ jobs:
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.actor.login == 'dependabot[bot]')
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ fromJSON(github.event.repository.visibility == 'public' && '["ubuntu-latest"]' || inputs.runs-on) }}
timeout-minutes: 10
permissions:
contents: write
Expand Down
19 changes: 13 additions & 6 deletions .github/workflows/lint-workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
workflow_call:
inputs:
runs-on:
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Public/open-source repos opt out by passing '[\"ubuntu-latest\"]'."
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Ignored for public repos, which always run on '[\"ubuntu-latest\"]'."
type: string
# Self-hosted by default since 2026-09-20. Actions credits are
# exhausted across HordiaLabs, Sproncy and Regularmusic, so a hosted
Expand All @@ -17,9 +17,16 @@ on:
# running nothing at all: 1 call (Sproncy/agent-skills).
#
# Every other consumer already passes `runs-on` explicitly, so this
# changes behaviour only for those that did not. Public repos should
# pass '["ubuntu-latest"]' -- fork PRs on a self-hosted pool are the
# hazard GitHub warns about; no public repo consumes this today.
# changes behaviour only for those that did not.
#
# Public repos never use this input. The job's runs-on forces
# ["ubuntu-latest"] whenever github.event.repository.visibility is
# "public": fork PRs on a self-hosted pool are the hazard GitHub
# warns about, hosted minutes are free there, and a public caller
# that omits `runs-on` would otherwise queue for 24h on a pool with
# no runner registered. An event whose payload carries no
# repository object falls back to this input, so public callers
# should still pass a hosted `runs-on` as well.
default: '["self-hosted", "linux", "x64"]'
actionlint-version:
type: string
Expand All @@ -39,7 +46,7 @@ on:

jobs:
actionlint:
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ fromJSON(github.event.repository.visibility == 'public' && '["ubuntu-latest"]' || inputs.runs-on) }}
timeout-minutes: 10
permissions:
contents: read
Expand Down Expand Up @@ -68,7 +75,7 @@ jobs:

yamllint:
if: inputs.run-yamllint
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ fromJSON(github.event.repository.visibility == 'public' && '["ubuntu-latest"]' || inputs.runs-on) }}
timeout-minutes: 10
permissions:
contents: read
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/secret-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
workflow_call:
inputs:
runs-on:
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Public/open-source repos opt out by passing '[\"ubuntu-latest\"]'."
description: "Runner label(s) as a JSON array string (parsed with fromJSON). Defaults to the self-hosted pool. Ignored for public repos, which always run on '[\"ubuntu-latest\"]'."
type: string
# Self-hosted by default since 2026-09-20. Actions credits are
# exhausted across HordiaLabs, Sproncy and Regularmusic, so a hosted
Expand All @@ -23,9 +23,16 @@ on:
# running nothing at all: 6 calls (Sproncy: GitHub-runners, agent-skills, sproncy-schemas, sproncy-secrets-dashboard, sproncy-transcription, sproncy-website-scrapers).
#
# Every other consumer already passes `runs-on` explicitly, so this
# changes behaviour only for those that did not. Public repos should
# pass '["ubuntu-latest"]' -- fork PRs on a self-hosted pool are the
# hazard GitHub warns about; no public repo consumes this today.
# changes behaviour only for those that did not.
#
# Public repos never use this input. The job's runs-on forces
# ["ubuntu-latest"] whenever github.event.repository.visibility is
# "public": fork PRs on a self-hosted pool are the hazard GitHub
# warns about, hosted minutes are free there, and a public caller
# that omits `runs-on` would otherwise queue for 24h on a pool with
# no runner registered. An event whose payload carries no
# repository object falls back to this input, so public callers
# should still pass a hosted `runs-on` as well.
default: '["self-hosted", "linux", "x64"]'
betterleaks-version:
type: string
Expand Down Expand Up @@ -66,7 +73,7 @@ on:

jobs:
scan:
runs-on: ${{ fromJSON(inputs.runs-on) }}
runs-on: ${{ fromJSON(github.event.repository.visibility == 'public' && '["ubuntu-latest"]' || inputs.runs-on) }}
timeout-minutes: 15
permissions:
contents: read
Expand Down
22 changes: 21 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@ project uses [SemVer](https://semver.org/) for the `vMAJOR.MINOR.PATCH` tags.

## [Unreleased]

## [3.7.0] - 2026-10-19

### Changed

- **Public repos always get GitHub-hosted runners from `secret-scan.yml`,
`lint-workflows.yml`, `dependabot-auto-merge.yml` and
`claude-code-review.yml`.** Each job's `runs-on` now overrides the input
with `["ubuntu-latest"]` (`["ubuntu-24.04"]` for the review) whenever
`github.event.repository.visibility` is `public`. The comments added in
3.6.0 said no public repo consumes these, which was wrong: six `nkg/*`
public repos call `secret-scan` or `lint-workflows`. The ones that left
`runs-on` unset (`lint-workflows` in `nkg/gha-token-server` and
`nkg/distrobuilder-proxmox-lxc-images`), or had no self-hosted runner
registered (`nkg/gha-nomad-dispatcher`), queued for 24h and were cancelled
on every run. Self-hosted would also have run fork PRs on our own hosts.
Private callers are unchanged. An event with no `repository` in its payload
falls back to the input, so public callers should keep passing a hosted
`runs-on`. (#93)

### Fixed

- **`docker-build.yml` no longer tags an image before Trivy has scanned it.**
Expand Down Expand Up @@ -1319,7 +1338,8 @@ README; everything below is the actual content of this repo.
- Bumped `actions/checkout` from `@v4` to `@v6` across all existing
workflows for consistency with new files.

[Unreleased]: https://github.com/nkg/github-actions/compare/v3.6.0...HEAD
[Unreleased]: https://github.com/nkg/github-actions/compare/v3.7.0...HEAD
[3.7.0]: https://github.com/nkg/github-actions/compare/v3.6.0...v3.7.0
[3.6.0]: https://github.com/nkg/github-actions/compare/v3.5.0...v3.6.0
[3.5.0]: https://github.com/nkg/github-actions/compare/v3.4.0...v3.5.0
[3.4.0]: https://github.com/nkg/github-actions/compare/v3.3.0...v3.4.0
Expand Down
Loading