{"id":49108450,"url":"https://github.com/cboone/gh-actions","last_synced_at":"2026-05-02T19:05:07.586Z","repository":{"id":342932269,"uuid":"1171201717","full_name":"cboone/gh-actions","owner":"cboone","description":"GitHub Actions for my repos (gh/cboone/...)","archived":false,"fork":false,"pushed_at":"2026-03-30T20:13:47.000Z","size":275,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T03:05:21.646Z","etag":null,"topics":["github","github-actions"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cboone.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-03T01:18:15.000Z","updated_at":"2026-03-30T20:13:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cboone/gh-actions","commit_stats":null,"previous_names":["cboone/gh-actions"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/cboone/gh-actions","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cboone%2Fgh-actions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cboone%2Fgh-actions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cboone%2Fgh-actions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cboone%2Fgh-actions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cboone","download_url":"https://codeload.github.com/cboone/gh-actions/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cboone%2Fgh-actions/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32074818,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T02:38:07.213Z","status":"ssl_error","status_checked_at":"2026-04-21T02:38:06.559Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["github","github-actions"],"created_at":"2026-04-21T03:05:22.855Z","updated_at":"2026-05-02T19:05:07.579Z","avatar_url":"https://github.com/cboone.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Actions\n\nThere are many, these are mine.\n\n- [Composite Actions](#composite-actions)\n  - [set-up-golangci-lint](#set-up-golangci-lint)\n  - [set-up-goreleaser](#set-up-goreleaser)\n  - [set-up-scrut](#set-up-scrut)\n  - [set-up-actionlint](#set-up-actionlint)\n  - [set-up-shfmt](#set-up-shfmt)\n  - [run-gitleaks](#run-gitleaks)\n  - [run-trufflehog](#run-trufflehog)\n  - [run-markscribe](#run-markscribe)\n  - [run-cspell](#run-cspell)\n  - [run-reuse](#run-reuse)\n  - [create-pull-request](#create-pull-request)\n  - [create-gh-release](#create-gh-release)\n- [Reusable Workflows](#reusable-workflows)\n  - [create-gh-release-from-changelog](#create-gh-release-from-changelog)\n  - [run-go-ci](#run-go-ci)\n  - [release-go-binaries](#release-go-binaries)\n  - [run-rust-ci](#run-rust-ci)\n  - [release-rust-binaries](#release-rust-binaries)\n  - [scan-for-secrets](#scan-for-secrets)\n  - [lint-text](#lint-text)\n  - [lint-shell](#lint-shell)\n  - [lint-github-actions](#lint-github-actions)\n  - [deploy-to-pages](#deploy-to-pages)\n  - [analyze-with-codeql](#analyze-with-codeql)\n  - [run-scrut-tests](#run-scrut-tests)\n  - [publish-to-npm](#publish-to-npm)\n  - [run-zig-ci](#run-zig-ci)\n  - [release-zig-binaries](#release-zig-binaries)\n- [Migration](#migration)\n- [Versioning](#versioning)\n- [License](#license)\n\n## Composite Actions\n\n### set-up-golangci-lint\n\nInstall golangci-lint binary with a pinned version.\n\n#### Inputs\n\n| Name      | Description                      | Required | Default  |\n| --------- | -------------------------------- | -------- | -------- |\n| `version` | golangci-lint version to install | No       | `2.11.4` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/set-up-golangci-lint@v3.0.0\n  with:\n    version: \"2.11.4\"\n- run: golangci-lint run ./...\n```\n\n### set-up-goreleaser\n\nInstall GoReleaser binary with a pinned version.\n\n#### Inputs\n\n| Name      | Description                   | Required | Default  |\n| --------- | ----------------------------- | -------- | -------- |\n| `version` | GoReleaser version to install | No       | `2.15.4` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/set-up-goreleaser@v3.0.0\n  with:\n    version: \"2.15.4\"\n- run: goreleaser release --clean\n```\n\n### set-up-scrut\n\nInstall scrut CLI testing tool with a pinned version.\n\n#### Inputs\n\n| Name      | Description              | Required | Default |\n| --------- | ------------------------ | -------- | ------- |\n| `version` | scrut version to install | No       | `0.4.3` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/set-up-scrut@v3.0.0\n- run: scrut test tests/\n```\n\n### set-up-actionlint\n\nInstall actionlint binary with a pinned version.\n\n#### Inputs\n\n| Name      | Description                   | Required | Default  |\n| --------- | ----------------------------- | -------- | -------- |\n| `version` | actionlint version to install | No       | `1.7.12` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/set-up-actionlint@v3.0.0\n- run: actionlint\n```\n\n### set-up-shfmt\n\nInstall shfmt binary with a pinned version.\n\n#### Inputs\n\n| Name      | Description              | Required | Default  |\n| --------- | ------------------------ | -------- | -------- |\n| `version` | shfmt version to install | No       | `3.13.1` |\n\nOnly the pinned version is supported; overriding `version` requires updating\nthe hardcoded SHA-256 checksums in `actions/set-up-shfmt/action.yml` first.\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/set-up-shfmt@v3.0.0\n- run: shfmt -d .\n```\n\n### run-gitleaks\n\nInstall gitleaks binary and run a scan.\n\n#### Inputs\n\n| Name      | Description                   | Required | Default             |\n| --------- | ----------------------------- | -------- | ------------------- |\n| `version` | gitleaks version to install   | No       | `8.30.1`            |\n| `args`    | Arguments to pass to gitleaks | No       | `detect --source .` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/run-gitleaks@v3.0.0\n```\n\n### run-trufflehog\n\nInstall trufflehog binary and run a scan.\n\n#### Inputs\n\n| Name      | Description                     | Required | Default                    |\n| --------- | ------------------------------- | -------- | -------------------------- |\n| `version` | trufflehog version to install   | No       | `3.95.2`                   |\n| `args`    | Arguments to pass to trufflehog | No       | `filesystem --directory .` |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/run-trufflehog@v3.0.0\n```\n\n### run-markscribe\n\nInstall markscribe binary and generate a file from a Go template. Replaces\n`charmbracelet/readme-scribe` with a direct binary download and SHA-256\nchecksum verification.\n\nCallers must set `GITHUB_TOKEN` in the step's `env:` for GitHub API access in\ntemplates.\n\n#### Inputs\n\n| Name       | Description                           | Required | Default         |\n| ---------- | ------------------------------------- | -------- | --------------- |\n| `version`  | markscribe version to install         | No       | `0.8.1`         |\n| `template` | Path to the Go template file          | No       | `README.md.tpl` |\n| `write-to` | Output file path (empty for stdout)   | No       | `README.md`     |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/run-markscribe@v3.0.0\n  env:\n    GITHUB_TOKEN: ${{ secrets.PERSONAL_GITHUB_TOKEN }}\n  with:\n    template: \"templates/README.md.tpl\"\n    write-to: \"README.md\"\n```\n\n### run-cspell\n\nInstall cspell and run it with inline pull-request annotations. Thin\nalternative to\n[`streetsidesoftware/cspell-action`](https://github.com/streetsidesoftware/cspell-action).\nInstalls cspell from this repo's sha512-pinned `package-lock.json`\n(same trust path as the [lint-text](#lint-text) reusable workflow) and\nregisters a problem matcher so cspell's default\n`path:line:col - Unknown word` output surfaces as PR annotations.\n\nNode.js must be available on the runner; pair with `actions/setup-node`\nif it is not already installed. For most projects, the\n[lint-text](#lint-text) reusable workflow with `run-cspell: true` is a\nbetter fit; reach for this action when you need cspell standalone in a\nlarger custom workflow.\n\n#### Inputs\n\n| Name     | Description                                                          | Required | Default |\n| -------- | -------------------------------------------------------------------- | -------- | ------- |\n| `files`  | Newline-delimited globs passed to cspell                             | No       | `.`     |\n| `config` | Path to a cspell config file (auto-discovered when empty)            | No       | `\"\"`    |\n| `args`   | Extra arguments to pass to cspell, one per line                      | No       | `\"\"`    |\n\n#### Usage\n\n```yaml\n- uses: actions/setup-node@v4\n  with:\n    node-version: \"24.15.0\"\n- uses: cboone/gh-actions/actions/run-cspell@v3.0.0\n```\n\n### run-reuse\n\nInstall [reuse](https://reuse.software/) and run it (default:\n`reuse lint`) for SPDX/REUSE compliance. Thin alternative to\n[`fsfe/reuse-action`](https://github.com/fsfe/reuse-action). Installs\nreuse from this repo's hash-pinned `requirements/reuse.txt` (every\ntransitive dependency is sha256-pinned via\n`uv pip compile --generate-hashes`).\n\n#### Inputs\n\n| Name         | Description                                              | Required | Default    |\n| ------------ | -------------------------------------------------------- | -------- | ---------- |\n| `uv-version` | uv version to install for the reuse install step        | No       | `0.11.8`   |\n| `args`       | Arguments to pass to `reuse`, one per line              | No       | `lint`     |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/run-reuse@v3.0.0\n```\n\n### create-pull-request\n\nSHA-pinned wrapper around\n[peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request).\nCentralizes version management so downstream repos do not pin the upstream action\nindividually.\n\n#### Inputs\n\n| Name             | Description                                        | Required | Default                                |\n| ---------------- | -------------------------------------------------- | -------- | -------------------------------------- |\n| `token`          | GITHUB_TOKEN or a personal access token            | No       | `${{ github.token }}`                  |\n| `branch`         | The pull request branch name                       | No       | `create-pull-request/patch`            |\n| `delete-branch`  | Delete the branch when the PR is merged or closed  | No       | `false`                                |\n| `base`           | Pull request base branch                           | No       | Branch checked out in the workflow     |\n| `commit-message` | The commit message for the changes                 | No       | `[create-pull-request] automated ...`  |\n| `title`          | The title of the pull request                      | No       | `Changes by create-pull-request ...`   |\n| `body`           | The body of the pull request                       | No       | `\"\"`                                   |\n| `labels`         | Comma or newline-separated labels                  | No       | `\"\"`                                   |\n| `assignees`      | Comma or newline-separated assignees               | No       | `\"\"`                                   |\n| `draft`          | Create the pull request as a draft                 | No       | `false`                                |\n\n#### Outputs\n\n| Name                      | Description                                          |\n| ------------------------- | ---------------------------------------------------- |\n| `pull-request-number`     | The pull request number                              |\n| `pull-request-url`        | The URL of the pull request                          |\n| `pull-request-operation`  | Operation performed: created, updated, closed, none  |\n| `pull-request-head-sha`   | The commit SHA of the pull request branch            |\n| `pull-request-branch`     | The branch name of the pull request                  |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/create-pull-request@v3.0.0\n  with:\n    branch: chore/update-data\n    commit-message: \"chore: update generated data\"\n    title: \"chore: update generated data\"\n    body: \"Automated update.\"\n    labels: automation\n    delete-branch: true\n```\n\n### create-gh-release\n\nCreate a GitHub Release with `gh release create`. Thin alternative to\n[`softprops/action-gh-release`](https://github.com/softprops/action-gh-release)\nfor callers that need asset uploads, auto-generated release notes, and\ndraft/prerelease flags. The `gh` CLI ships preinstalled on\nGitHub-hosted runners, so no binary download or checksum table is needed.\n\nFor changelog-driven releases, prefer the [create-gh-release-from-changelog](#create-gh-release-from-changelog)\nreusable workflow. Reach for `create-gh-release` when you need to attach files\nor auto-generate notes from merged PRs.\n\n#### Inputs\n\n| Name                     | Description                                                     | Required | Default                |\n| ------------------------ | --------------------------------------------------------------- | -------- | ---------------------- |\n| `tag-name`               | Git tag for the release                                         | No       | `${{ github.ref_name }}` |\n| `name`                   | Release title (defaults to the tag name when empty)             | No       | `\"\"`                   |\n| `body`                   | Inline release notes                                            | No       | `\"\"`                   |\n| `body-path`              | Path to a file containing release notes                         | No       | `\"\"`                   |\n| `generate-release-notes` | Auto-generate release notes from merged pull requests           | No       | `false`                |\n| `files`                  | Newline-delimited file paths to attach (globs are expanded)     | No       | `\"\"`                   |\n| `draft`                  | Create the release as a draft                                   | No       | `false`                |\n| `prerelease`             | Mark the release as a prerelease                                | No       | `false`                |\n| `target-commitish`       | Commit SHA, branch, or tag to point the release at              | No       | `\"\"`                   |\n| `token`                  | GitHub token (must have `contents: write`)                      | No       | `${{ github.token }}`  |\n\n`body`, `body-path`, and `generate-release-notes` are mutually exclusive.\n\n#### Outputs\n\n| Name  | Description                |\n| ----- | -------------------------- |\n| `url` | URL of the created release |\n\n#### Usage\n\n```yaml\n- uses: cboone/gh-actions/actions/create-gh-release@v3.0.0\n  with:\n    files: |\n      dist/*.tar.gz\n      dist/*.zip\n    generate-release-notes: true\n```\n\n## Reusable Workflows\n\n### create-gh-release-from-changelog\n\nCreate a GitHub Release from a version tag, extracting release notes from a\nchangelog file in Keep a Changelog format.\n\n**Permissions:** `contents: write`\n\n#### Inputs\n\n| Name              | Type    | Default          | Description                          |\n| ----------------- | ------- | ---------------- | ------------------------------------ |\n| `changelog-file`  | string  | `CHANGELOG.md`   | Path to the changelog file           |\n| `draft`           | boolean | `false`          | Create the release as a draft        |\n| `prerelease`      | boolean | `false`          | Mark the release as a prerelease     |\n| `runs-on`         | string  | `ubuntu-latest`  | Runner label (Windows not supported) |\n| `timeout-minutes` | number  | `10`             | Job timeout in minutes               |\n\n#### Usage\n\n```yaml\njobs:\n  release:\n    uses: cboone/gh-actions/.github/workflows/create-gh-release-from-changelog.yml@v3.0.0\n```\n\n### run-go-ci\n\nRun Go tests, linting, build verification, scrut CLI tests, and format checking.\nEach check runs as a separate job that can be toggled on or off.\n\nConsuming repos must provide a Makefile with targets matching each enabled job:\n`vet`, `test`, `lint`, `build`, `fmt`. The `fmt` target must be a format check\n(exit non-zero when files need formatting), not a write operation.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name                    | Type    | Default          | Description                                                |\n| ----------------------- | ------- | ---------------- | ---------------------------------------------------------- |\n| `go-version`            | string  | `\"\"`             | Go version to install. When set, overrides go-version-file |\n| `go-version-file`       | string  | `go.mod`         | File to read the Go version from                           |\n| `runs-on`               | string  | `ubuntu-latest`  | Runner label (Windows is not supported)                    |\n| `run-lint`              | boolean | `true`           | Run `make lint`                                            |\n| `golangci-lint-version` | string  | `\"2.11.4\"`       | golangci-lint version to install                           |\n| `run-scrut`             | boolean | `false`          | Run scrut CLI tests                                        |\n| `scrut-build-cmd`       | string  | `go build ./...` | Command to build the binary for scrut tests                |\n| `scrut-env`             | string  | `\"\"`             | Newline-delimited KEY=VALUE env vars for scrut tests       |\n| `scrut-test-dir`        | string  | `tests/`         | Directory containing scrut test files                      |\n| `scrut-setup-cmd`       | string  | `\"\"`             | Optional shell command to run before scrut tests           |\n| `run-format-check`      | boolean | `false`          | Run `make fmt` format check                                |\n| `run-build`             | boolean | `false`          | Run `make build`                                           |\n| `test-flags`            | string  | `\"-race\"`        | Flags for go test (only used when coverage is enabled)     |\n| `coverage`              | boolean | `false`          | Generate coverage and upload to Codecov                    |\n| `codecov-cli-version`   | string  | `\"11.2.8\"`       | Codecov CLI version to install                             |\n| `codecov-files`         | string  | `coverage.out`   | Coverage file path for Codecov upload                      |\n| `timeout-minutes`       | number  | `15`             | Job timeout in minutes                                     |\n\n#### Secrets\n\n| Name            | Required | Description          |\n| --------------- | -------- | -------------------- |\n| `CODECOV_TOKEN` | No       | Codecov upload token |\n\n#### Usage\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-go-ci.yml@v3.0.0\n    with:\n      run-lint: true\n      run-format-check: true\n      coverage: true\n    secrets:\n      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n```\n\n### release-go-binaries\n\nRun GoReleaser to build and publish a Go release.\n\n**Permissions:** `contents: write`\n\n#### Inputs\n\n| Name                 | Type   | Default           | Description                          |\n| -------------------- | ------ | ----------------- | ------------------------------------ |\n| `go-version-file`    | string | `go.mod`          | File to read the Go version from     |\n| `runs-on`            | string | `ubuntu-latest`   | Runner label (Windows not supported) |\n| `goreleaser-version` | string | `\"2.15.4\"`        | GoReleaser version to install        |\n| `goreleaser-args`    | string | `release --clean` | Arguments to pass to goreleaser      |\n| `timeout-minutes`    | number | `30`              | Job timeout in minutes               |\n\n#### Secrets\n\n| Name                 | Required | Description                    |\n| -------------------- | -------- | ------------------------------ |\n| `HOMEBREW_TAP_TOKEN` | No       | Token for Homebrew tap updates |\n\n#### Usage\n\n```yaml\njobs:\n  release:\n    uses: cboone/gh-actions/.github/workflows/release-go-binaries.yml@v3.0.0\n    with:\n      goreleaser-version: \"2.15.4\"\n    secrets:\n      HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}\n```\n\n### run-rust-ci\n\nRun Rust tests, clippy linting, format checking, dependency auditing, and spell\nchecking. Each check runs as a separate job that can be toggled on or off.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name                 | Type    | Default          | Description                                              |\n| -------------------- | ------- | ---------------- | -------------------------------------------------------- |\n| `rust-version`       | string  | `\"stable\"`       | Rust toolchain version to install                        |\n| `runs-on`            | string  | `ubuntu-latest`  | Runner label (Windows is not supported)                  |\n| `run-test`           | boolean | `true`           | Run cargo test                                           |\n| `use-nextest`        | boolean | `false`          | Use cargo-nextest instead of cargo test                  |\n| `nextest-version`    | string  | `\"0.9.133\"`      | cargo-nextest version to install                         |\n| `test-args`          | string  | `\"\"`             | Additional arguments for cargo test or nextest           |\n| `run-lint`           | boolean | `true`           | Run cargo clippy                                         |\n| `clippy-args`        | string  | `\"-D warnings\"`  | Arguments passed to clippy after `--`                    |\n| `run-format-check`   | boolean | `true`           | Run cargo fmt --check                                    |\n| `run-deny`           | boolean | `false`          | Run cargo deny check (requires deny.toml)                |\n| `deny-version`       | string  | `\"0.19.4\"`       | cargo-deny version to install                            |\n| `run-audit`          | boolean | `false`          | Run cargo audit                                          |\n| `audit-version`      | string  | `\"0.22.1\"`       | cargo-audit version to install                           |\n| `run-typos`          | boolean | `false`          | Run typos spell checking                                 |\n| `cargo-features`     | string  | `\"\"`             | Cargo features passed via --features                     |\n| `extra-components`   | string  | `\"\"`             | Extra rustup components to install                       |\n| `coverage`           | boolean | `false`          | Generate coverage and upload to Codecov                  |\n| `codecov-cli-version`| string  | `\"11.2.8\"`       | Codecov CLI version to install                           |\n| `codecov-files`      | string  | `lcov.info`      | Coverage file path                                       |\n| `timeout-minutes`    | number  | `15`             | Job timeout in minutes                                   |\n\n#### Secrets\n\n| Name            | Required | Description          |\n| --------------- | -------- | -------------------- |\n| `CODECOV_TOKEN` | No       | Codecov upload token |\n\n#### Usage\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-rust-ci.yml@v3.0.0\n    with:\n      run-deny: true\n      run-audit: true\n      run-typos: true\n```\n\nWith cargo-nextest and coverage:\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-rust-ci.yml@v3.0.0\n    with:\n      use-nextest: true\n      coverage: true\n    secrets:\n      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}\n```\n\n### release-rust-binaries\n\nBuild Rust binaries for multiple targets and publish them as a GitHub Release.\nSupports matrix builds across different runners and optional Homebrew formula\nupdates.\n\n**Permissions:** `contents: write`\n\n#### Inputs\n\n| Name                    | Type    | Default    | Description                                                       |\n| ----------------------- | ------- | ---------- | ----------------------------------------------------------------- |\n| `targets`               | string  |            | JSON array of `{\"target\",\"runner\"}` objects (required)            |\n| `binary-name`           | string  | `\"\"`       | Binary name (extracted from Cargo.toml if empty)                  |\n| `rust-version`          | string  | `\"stable\"` | Rust toolchain version to install                                 |\n| `build-args`            | string  | `\"\"`       | Additional arguments for cargo build                              |\n| `archive-prefix`        | string  | `\"\"`       | Override archive prefix (default: {binary}-{version})             |\n| `update-homebrew`       | boolean | `false`    | Update a Homebrew formula after releasing                         |\n| `homebrew-tap`          | string  | `\"\"`       | Homebrew tap repository (e.g. user/homebrew-tap)                  |\n| `homebrew-formula-path` | string  | `\"\"`       | Path to the formula in the tap repo (e.g. Formula/mytool.rb)      |\n| `homebrew-license`      | string  | `\"MIT\"`    | SPDX license identifier for the Homebrew formula                  |\n| `timeout-minutes`       | number  | `30`       | Job timeout in minutes                                            |\n\n#### Secrets\n\n| Name                 | Required | Description                    |\n| -------------------- | -------- | ------------------------------ |\n| `HOMEBREW_TAP_TOKEN` | No       | Token for Homebrew tap updates |\n\n#### Usage\n\n```yaml\njobs:\n  release:\n    uses: cboone/gh-actions/.github/workflows/release-rust-binaries.yml@v3.0.0\n    with:\n      targets: \u003e-\n        [\n          {\"target\": \"aarch64-apple-darwin\", \"runner\": \"macos-latest\"},\n          {\"target\": \"x86_64-apple-darwin\", \"runner\": \"macos-latest\"},\n          {\"target\": \"x86_64-unknown-linux-gnu\", \"runner\": \"ubuntu-latest\"}\n        ]\n```\n\nWith Homebrew formula updates:\n\n```yaml\njobs:\n  release:\n    uses: cboone/gh-actions/.github/workflows/release-rust-binaries.yml@v3.0.0\n    with:\n      targets: \u003e-\n        [\n          {\"target\": \"aarch64-apple-darwin\", \"runner\": \"macos-latest\"},\n          {\"target\": \"x86_64-unknown-linux-gnu\", \"runner\": \"ubuntu-latest\"}\n        ]\n      update-homebrew: true\n      homebrew-tap: myuser/homebrew-tap\n      homebrew-formula-path: Formula/mytool.rb\n    secrets:\n      HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}\n```\n\n### scan-for-secrets\n\nRun gitleaks, trufflehog, or both to scan for leaked secrets. Supports\nfull-history and working-tree scan scopes.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name                 | Type   | Default        | Description                                      |\n| -------------------- | ------ | -------------- | ------------------------------------------------ |\n| `tool`               | string | `gitleaks`     | Which tool to run: gitleaks, trufflehog, or both |\n| `scan-scope`         | string | `full-history` | Scan scope: full-history or working-tree         |\n| `gitleaks-version`   | string | `\"8.30.1\"`     | gitleaks version to install                      |\n| `trufflehog-version` | string | `\"3.95.2\"`     | trufflehog version to install                    |\n| `fetch-depth`        | number | `0`            | Git fetch depth (0 for full history)             |\n| `allowlist-config`   | string | `\"\"`           | Path to a gitleaks allowlist config file         |\n| `timeout-minutes`    | number | `15`           | Job timeout in minutes                           |\n\n#### Usage\n\n```yaml\njobs:\n  scan:\n    uses: cboone/gh-actions/.github/workflows/scan-for-secrets.yml@v3.0.0\n    with:\n      tool: both\n```\n\n### lint-text\n\nRun Markdown linting, Prettier formatting checks, cspell spelling checks,\nand yamllint YAML validation. Each tool can be toggled independently.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name               | Type    | Default | Description                |\n| ------------------ | ------- | ------- | -------------------------- |\n| `node-version`     | string  | `\"24.15.0\"`  | Node.js version to install |\n| `run-markdownlint` | boolean | `true`  | Run markdownlint-cli2      |\n| `run-prettier`     | boolean | `true`  | Run Prettier format check  |\n| `run-cspell`       | boolean | `false` | Run cspell spell checker   |\n| `run-yamllint`     | boolean | `false` | Run yamllint               |\n| `timeout-minutes`  | number  | `10`    | Job timeout in minutes     |\n\n#### Usage\n\n```yaml\njobs:\n  text:\n    uses: cboone/gh-actions/.github/workflows/lint-text.yml@v3.0.0\n    with:\n      run-cspell: true\n```\n\n### lint-shell\n\nRun ShellCheck and shfmt on shell scripts. Automatically discovers scripts\nby file extension and MIME type.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name              | Type    | Default    | Description              |\n| ----------------- | ------- | ---------- | ------------------------ |\n| `run-shellcheck`  | boolean | `true`     | Run ShellCheck           |\n| `run-shfmt`       | boolean | `true`     | Run shfmt format check   |\n| `shfmt-version`   | string  | `\"3.13.1\"` | shfmt version to install |\n| `timeout-minutes` | number  | `10`       | Job timeout in minutes   |\n\nOnly the pinned `shfmt-version` is supported; overriding it requires updating\nthe hardcoded SHA-256 checksums in `.github/workflows/lint-shell.yml` first.\n\n#### Usage\n\n```yaml\njobs:\n  shell:\n    uses: cboone/gh-actions/.github/workflows/lint-shell.yml@v3.0.0\n```\n\n### lint-github-actions\n\nRun actionlint to validate GitHub Actions workflow files.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name                 | Type   | Default    | Description                   |\n| -------------------- | ------ | ---------- | ----------------------------- |\n| `actionlint-version` | string | `\"1.7.12\"` | actionlint version to install |\n| `timeout-minutes`    | number | `10`       | Job timeout in minutes        |\n\n#### Usage\n\n```yaml\njobs:\n  github:\n    uses: cboone/gh-actions/.github/workflows/lint-github-actions.yml@v3.0.0\n```\n\n### deploy-to-pages\n\nBuild a static site and deploy it to GitHub Pages. Optionally sets up Go\nand/or Node.js before running the build command.\n\n**Permissions:** `contents: read`, `pages: write`, `id-token: write`\n\n#### Inputs\n\n| Name              | Type    | Default         | Description                          |\n| ----------------- | ------- | --------------- | ------------------------------------ |\n| `build-command`   | string  |                 | Command to build the site (required) |\n| `artifact-path`   | string  | `./_site`       | Path to the built site directory     |\n| `runs-on`         | string  | `ubuntu-latest` | Runner label                         |\n| `setup-go`        | boolean | `false`         | Set up Go before building            |\n| `go-version-file` | string  | `go.mod`        | File to read the Go version from     |\n| `setup-node`      | boolean | `false`         | Set up Node.js before building       |\n| `node-version`    | string  | `\"24.15.0\"`          | Node.js version to install           |\n| `timeout-minutes` | number  | `15`            | Job timeout in minutes               |\n\n#### Usage\n\n```yaml\njobs:\n  pages:\n    uses: cboone/gh-actions/.github/workflows/deploy-to-pages.yml@v3.0.0\n    with:\n      build-command: \"npm run build\"\n      artifact-path: ./dist\n      setup-node: true\n```\n\n### analyze-with-codeql\n\nRun GitHub CodeQL security analysis. SHA-pins all `github/codeql-action`\nsub-actions internally and conditionally sets up Go when the language list\nincludes it.\n\n**Permissions:** `contents: read`, `security-events: write`\n\n#### Inputs\n\n| Name              | Type   | Default                  | Description                                                |\n| ----------------- | ------ | ------------------------ | ---------------------------------------------------------- |\n| `languages`       | string | `go`                     | Comma-separated CodeQL languages to analyze                |\n| `queries`         | string | `security-and-quality`   | CodeQL query suite to run                                  |\n| `go-version`      | string | `\"\"`                     | Go version to install. When set, overrides go-version-file |\n| `go-version-file` | string | `go.mod`                 | File to read the Go version from                           |\n| `category-prefix` | string | `/language:`             | Prefix for the CodeQL analysis category                    |\n| `runs-on`         | string | `macos-latest`           | Runner label                                               |\n| `timeout-minutes` | number | `30`                     | Job timeout in minutes                                     |\n\n#### Usage\n\n```yaml\njobs:\n  codeql:\n    uses: cboone/gh-actions/.github/workflows/analyze-with-codeql.yml@v3.0.0\n    with:\n      languages: go\n      go-version: \"1.25\"\n    permissions:\n      contents: read\n      security-events: write\n```\n\n### run-scrut-tests\n\nRun scrut CLI snapshot tests. Designed for non-Go projects (e.g., shell plugins)\nthat need scrut testing without Go setup or build steps. Installs scrut with\nSHA-256 checksum verification and runs tests against the specified directory.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name              | Type   | Default         | Description                                          |\n| ----------------- | ------ | --------------- | ---------------------------------------------------- |\n| `scrut-version`   | string | `\"0.4.3\"`       | scrut version to install (checksums pinned to this)  |\n| `scrut-shell`     | string | `\"\"`            | Shell for `--shell` flag (e.g., \"zsh\", \"bash\")       |\n| `scrut-test-dir`  | string | `\"tests/\"`      | Directory containing scrut test files                |\n| `scrut-env`       | string | `\"\"`            | Newline-delimited KEY=VALUE env vars for scrut tests |\n| `scrut-setup-cmd` | string | `\"\"`            | Shell command to run before scrut tests              |\n| `runs-on`         | string | `ubuntu-latest` | Runner label (Windows is not supported)              |\n| `timeout-minutes` | number | `10`            | Job timeout in minutes                               |\n\n#### Usage\n\n```yaml\njobs:\n  scrut:\n    uses: cboone/gh-actions/.github/workflows/run-scrut-tests.yml@v3.0.0\n```\n\nWith a custom shell and environment variables:\n\n```yaml\njobs:\n  scrut:\n    uses: cboone/gh-actions/.github/workflows/run-scrut-tests.yml@v3.0.0\n    with:\n      scrut-shell: zsh\n      scrut-env: |\n        MY_PLUGIN_DIR=./src\n      scrut-setup-cmd: \"make build\"\n```\n\n### publish-to-npm\n\nPublish an npm package to a registry. Detects lockfile presence to choose\nbetween `npm ci` and `npm install`.\n\n**Permissions:** `contents: read`, `packages: write`\n\n#### Inputs\n\n| Name              | Type   | Default                      | Description                |\n| ----------------- | ------ | ---------------------------- | -------------------------- |\n| `node-version`    | string | `\"24.15.0\"`                       | Node.js version to install |\n| `registry-url`    | string | `https://npm.pkg.github.com` | npm registry URL           |\n| `timeout-minutes` | number | `10`                         | Job timeout in minutes     |\n\n#### Secrets\n\n| Name              | Required | Description                               |\n| ----------------- | -------- | ----------------------------------------- |\n| `NODE_AUTH_TOKEN` | Yes      | Authentication token for the npm registry |\n\n#### Usage\n\n```yaml\njobs:\n  publish:\n    uses: cboone/gh-actions/.github/workflows/publish-to-npm.yml@v3.0.0\n    secrets:\n      NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n```\n\n### run-zig-ci\n\nRun Zig tests, format checking, build verification, cross-compilation checks,\nand scrut CLI tests. Each check runs as a separate job that can be toggled on or\noff.\n\nUnlike run-go-ci.yml, this workflow runs Zig commands directly (not via Makefile\ntargets) since Zig projects idiomatically use `build.zig` as their build system.\n\n**Permissions:** `contents: read`\n\n#### Inputs\n\n| Name                | Type    | Default         | Description                                          |\n| ------------------- | ------- | --------------- | ---------------------------------------------------- |\n| `zig-version`       | string  | `\"\"`            | Zig version to install (e.g., `\"0.15.2\"`)            |\n| `zig-version-file`  | string  | `\"\"`            | Path to a `.zon` file with `.minimum_zig_version`    |\n| `runs-on`           | string  | `ubuntu-latest` | Runner label (Windows is not supported)              |\n| `run-test`          | boolean | `true`          | Run `zig build test`                                 |\n| `run-fmt`           | boolean | `true`          | Run `zig fmt --check src/ build.zig`                 |\n| `run-build`         | boolean | `true`          | Run `zig build`                                      |\n| `run-cross-compile` | boolean | `false`         | Build all cross-compilation targets                  |\n| `cross-targets`     | string  | (see below)     | Space-separated Zig target triples                   |\n| `run-scrut`         | boolean | `false`         | Run scrut CLI tests                                  |\n| `scrut-build-cmd`   | string  | `zig build`     | Command to build the binary for scrut tests          |\n| `scrut-env`         | string  | `\"\"`            | Newline-delimited KEY=VALUE env vars for scrut tests |\n| `scrut-test-dir`    | string  | `tests/`        | Directory containing scrut test files                |\n| `scrut-setup-cmd`   | string  | `\"\"`            | Optional shell command to run before scrut tests     |\n| `timeout-minutes`   | number  | `20`            | Job timeout in minutes                               |\n\nDefault `cross-targets`:\n\n```text\nx86_64-linux-gnu aarch64-linux-gnu x86_64-macos aarch64-macos x86_64-windows-gnu\n```\n\nSpecify at most one of `zig-version` or `zig-version-file`. If both are\nset, `zig-version` takes precedence. If neither is set, `mlugg/setup-zig`\nfalls back to its own auto-detection (reads `minimum_zig_version` from\n`build.zig.zon`, or installs `latest` if no `build.zig.zon` is present).\n\n#### Usage\n\nWith an explicit version:\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-zig-ci.yml@v3.0.0\n    with:\n      zig-version: \"0.14.1\"\n      run-cross-compile: true\n```\n\nReading the version from `build.zig.zon`:\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-zig-ci.yml@v3.0.0\n    with:\n      zig-version-file: build.zig.zon\n      run-cross-compile: true\n```\n\nWith scrut CLI tests:\n\n```yaml\njobs:\n  ci:\n    uses: cboone/gh-actions/.github/workflows/run-zig-ci.yml@v3.0.0\n    with:\n      zig-version-file: build.zig.zon\n      run-scrut: true\n      scrut-build-cmd: \"zig build\"\n      scrut-env: |\n        MY_BIN=./zig-out/bin/my-tool\n```\n\n### release-zig-binaries\n\nBuild a Zig binary for multiple targets and create a GitHub Release with\npackaged artifacts and SHA-256 checksums. Leverages Zig's native\ncross-compilation from a single runner (no matrix, no macOS runners).\n\n**Permissions:** `contents: write`\n\n#### Inputs\n\n| Name               | Type   | Default         | Description                                       |\n| ------------------ | ------ | --------------- | ------------------------------------------------- |\n| `zig-version`      | string | `\"\"`            | Zig version to install (e.g., `\"0.15.2\"`)         |\n| `zig-version-file` | string | `\"\"`            | Path to a `.zon` file with `.minimum_zig_version` |\n| `binary-name`      | string |                 | Name of the binary (required)                     |\n| `targets`          | string | (see below)     | Space-separated Zig target triples                |\n| `optimize`         | string | `ReleaseSafe`   | Zig optimization level                            |\n| `runs-on`          | string | `ubuntu-latest` | Runner label (Windows not supported)              |\n| `timeout-minutes`  | number | `30`            | Job timeout in minutes                            |\n\nDefault `targets`:\n\n```text\nx86_64-linux-gnu aarch64-linux-gnu x86_64-macos aarch64-macos x86_64-windows-gnu\n```\n\n`zig-version` and `zig-version-file` follow the same precedence rules as\nin `run-zig-ci.yml`: `zig-version` wins if both are set, and if neither is\nset `mlugg/setup-zig` falls back to its own auto-detection.\n\n#### Usage\n\n```yaml\njobs:\n  release:\n    uses: cboone/gh-actions/.github/workflows/release-zig-binaries.yml@v3.0.0\n    with:\n      zig-version-file: build.zig.zon\n      binary-name: \"my-tool\"\n```\n\n## Migration\n\nThe first release that includes these path renames is a breaking release.\nConsumers moving to that release must update action paths and reusable workflow\nfilenames in their `uses:` strings. Old paths remain available only on older\nrelease tags that predate the rename.\n\n### Composite Action Paths\n\n| Old path | New path |\n| --- | --- |\n| `cboone/gh-actions/actions/gh-release@\u003ctag\u003e` | `cboone/gh-actions/actions/create-gh-release@\u003ctag\u003e` |\n| `cboone/gh-actions/actions/setup-actionlint@\u003ctag\u003e` | `cboone/gh-actions/actions/set-up-actionlint@\u003ctag\u003e` |\n| `cboone/gh-actions/actions/setup-golangci-lint@\u003ctag\u003e` | `cboone/gh-actions/actions/set-up-golangci-lint@\u003ctag\u003e` |\n| `cboone/gh-actions/actions/setup-goreleaser@\u003ctag\u003e` | `cboone/gh-actions/actions/set-up-goreleaser@\u003ctag\u003e` |\n| `cboone/gh-actions/actions/setup-scrut@\u003ctag\u003e` | `cboone/gh-actions/actions/set-up-scrut@\u003ctag\u003e` |\n| `cboone/gh-actions/actions/setup-shfmt@\u003ctag\u003e` | `cboone/gh-actions/actions/set-up-shfmt@\u003ctag\u003e` |\n\n### Reusable Workflow Paths\n\n| Old path | New path |\n| --- | --- |\n| `cboone/gh-actions/.github/workflows/create-release.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/create-gh-release-from-changelog.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/go-ci.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/run-go-ci.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/go-release.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/release-go-binaries.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/rust-ci.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/run-rust-ci.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/rust-release.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/release-rust-binaries.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/secret-scan.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/scan-for-secrets.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/text-lint.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/lint-text.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/shell-lint.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/lint-shell.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/github-lint.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/lint-github-actions.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/pages-deploy.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/deploy-to-pages.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/codeql.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/analyze-with-codeql.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/scrut.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/run-scrut-tests.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/npm-publish.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/publish-to-npm.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/zig-ci.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/run-zig-ci.yml@\u003ctag\u003e` |\n| `cboone/gh-actions/.github/workflows/zig-release.yml@\u003ctag\u003e` | `cboone/gh-actions/.github/workflows/release-zig-binaries.yml@\u003ctag\u003e` |\n\nDo not change external GitHub Actions such as `actions/setup-go` or\n`actions/setup-node` as part of this migration. If branch protection rules\nrequire specific workflow status check names, update those settings after the\nworkflow rename lands.\n\n## Versioning\n\nThis project uses [Semantic Versioning](https://semver.org/) with exact version\ntags. Pin to a specific version (e.g., `@v3.0.0`) for production use.\n\n### Version bumps\n\n- **Patch** (e.g., v2.1.3 to v2.1.4): bug fixes, tool version bumps that do not\n  change behavior, documentation updates.\n- **Minor** (e.g., v2.1.1 to v2.2.0): new optional inputs, new actions or\n  workflows, additive changes that do not affect existing callers.\n- **Major** (e.g., v2.2.0 to v3.0.0): breaking changes. A **breaking change** is any\n  modification that requires callers to update their workflow files: renaming or\n  removing an input, changing a default in a way that alters behavior, or\n  removing an action or workflow.\n\n### Release process\n\nReleases are created with the `/release` skill, which analyzes conventional\ncommits, recommends a version bump, updates CHANGELOG.md, creates a release\ncommit, and tags it. The recommended outcome for each release is a single\nexact version tag (e.g., `v3.0.0`) pointing to the release commit.\n\nAfter tagging locally, push:\n\n```bash\ngit push origin main v3.0.0\n```\n\n### Pinning for callers\n\nAlways pin to an exact release tag (e.g. `@v3.0.0`). Branch refs like\n`@main` are not supported: they float, they bypass our SHA-pin and\nchecksum contract, and the supply-chain risk is not worth the\nconvenience.\n\n## License\n\n[MIT License](./LICENSE). TL;DR: Do whatever you want with this software, just\nkeep the copyright notice included. The authors aren't liable if something goes\nwrong.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcboone%2Fgh-actions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcboone%2Fgh-actions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcboone%2Fgh-actions/lists"}