Install | How to use | Configuration
pinact is a CLI to pin GitHub Actions and Reusable Workflows. pinact can also update their versions and verify version comments.
$ pinact run
.github/workflows/test.yaml:8
- - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3
+ - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3.5.1
.github/workflows/test.yaml:9
- - uses: actions/setup-go@v4
+ - uses: actions/setup-go@7b8cf10d4e4a01d4992d18a89f4d7dc5a3e6d6f4 # v4.3.0
.github/workflows/test.yaml:10
- - uses: actions/cache@v3.3.1
+ - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
.github/workflows/test.yaml:16
- uses: suzuki-shunsuke/actionlint-workflow/.github/workflows/actionlint.yaml@v0.5.0
+ uses: suzuki-shunsuke/actionlint-workflow/.github/workflows/actionlint.yaml@b6a5f966d4504893b2aeb60cf2b0de8946e48504 # v0.5.0- Pin GitHub Actions and Reusable Workflows
- Check if actions are pinned without editing files
- Offline check without GitHub API
- Update actions with a minimum release age
- Verify version comments (
-verify-comment) - Require a version comment on SHA-pinned actions
- Verify if actions meet the minimum release age
- Pin branches
- Include and exclude specific actions
- Generate SARIF. This is useful to create reviews using reviewdog
- Read GitHub access token via keyrings or ghtkn
- Pin only changed lines
- Support GitHub Enterprise Server
- GitHub Action
pinact run [<workflow file>...]If no file is specified, the following files are pinned:
.github/workflows/*.yml
.github/workflows/*.yaml
action.yml
action.yaml
*/action.yml
*/action.yaml
*/*/action.yml
*/*/action.yaml
*/*/*/action.yml
*/*/*/action.yaml
Not only workflow files, but also text files of any formats are supported.
This is useful to pin actions in text files such as README.md.
pinact run README.mdBy default, pinact edit files.
If -check or -fix=false is specified, pinact just checks if actions are pinned without editing files.
pinact run -checkFor an offline check (no GitHub API call, only the 40-character SHA syntactic check), add -no-api:
pinact run -fix=false -no-apiWith -no-api, pinact can't fetch action versions and SHA, so pinact can't pin actions.
So it only checks if actions are pinned with full-length commit SHA.
Update actions to latest versions:
pinact run -updatepinact supports two kinds of minimum release age checks:
- Verify current versions: Verify if current action versions meet the minimum release age requirement
- Verify new versions: Exclude versions that don't meet the minimum release age requirement when updating actions (
-update)- If no release meeting the given minimum age is found, pinact will exit with an error.
This helps reduce supply chain security risks.
By default, no minimum release age is set. You can set the minimum release age by some methods:
-min-age <minimum release age>: Set the minimum release age in days
pinact run -min-age 7- Environment variable
PINACT_MIN_AGE - Configuration file
.pinact.yml.rules[].min_age: A rule specific minimum release age in days.min_age.value: The default minimum release age in days
min_age:
value: 7
rules:
- min_age: 0
conditions:
- expr: |
ActionRepoOwner == "suzuki-shunsuke"It may be wasteful to verify all current versions against the minimum release age every time pinact runs.
Therefore, current versions are verified using the min_age setting in .pinact.yml and PINACT_MIN_AGE only when --verify-min-age is set or .min_age.always is true.
pinact run -verify-min-ageOr
min_age:
value: 7
always: true # default is falseOn the other hand, when updating actions min_age setting is always used to filter new versions.
- For GitHub Releases, the
PublishedAtdate is checked - For tags, the commit's
Committer.Dateis checked (requires additional API call)
Please see Verify version comments.
pinact run -verify-commentpinact >= v3.10.0, #1529
By default, pinact doesn't pin branches such as main or master.
If you want to pin specific branches, you can use the --branch-to-tag option.
pinact run --branch-to-tag '<regular expression matching branch name>'The value is evaluated as a regular expression with partial match, just like --include / --exclude.
Anchor with ^...$ for an exact match - for short branch names like main this is recommended to avoid matching mainline etc.
Versions that don't match any of the supplied regexps continue to error out as before.
The branch is converted to the latest stable tag of the action. Pre-releases are used only when no stable tag exists.
--min-age is honored: when set, tags released within the cooldown window are skipped.
--branch-to-tag can be specified multiple times.
e.g.
pinact run --branch-to-tag '^main$' --branch-to-tag '^release/.*$'#1082 pinact >= v3.4.0
You can fix only specific actions using the -include (-i) <regular expression> option.
You can also exclude only specific actions using the -exclude (-e) <regular expression> option.
e.g.
pinact run -i "actions/.*" -i "^aquaproj/aqua-installer$"pinact run -e "actions/.*" -e "^aquaproj/aqua-installer$"pinact >= v3.7.0 #1294
pinact can output the result in the SARIF format.
pinact run --format sarifThis format is useful to integration tools like reviewdog and GitHub SARIF Code Scanning.
-format sarif implies -fix=false, so files are not modified.
If you want to fix files, use -fix.
pinact run --format sarif -fixpinact run -format sarif |
reviewdog -f sarif -name pinact -reporter github-pr-review- run: pinact run -format sarif > sarif.json || true
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9
with:
sarif_file: sarif.json
category: pinactpinact >= v4.0.0
pinact supports pinning only changed lines using the -diff-file option.
This is useful to introduce pinact gradually.
pinact run -diff-file diff.txt diff.txt must be the unified diff format.
diff --git a/testdata/diff-file/action.yaml b/testdata/diff-file/action.yaml
index 0000001..0000002 100644
--- a/testdata/diff-file/action.yaml
+++ b/testdata/diff-file/action.yaml
@@ -7,5 +7,5 @@ jobs:
permissions: {}
steps:
- uses: actions/checkout@v3.6.0
- - uses: actions/setup-go@v3.5.0
+ - uses: actions/setup-go@v4.0.0
- uses: actions/cache@v3.3.1-diff-file - means reading from stdin:
cat diff.txt | pinact run -diff-file -You can generate a diff file via GitHub Actions using pr-unified-diff-action.
- uses: suzuki-shunsuke/pr-unified-diff-action@c932c1df5f577028d8ca05d2d3c0c059072d8821 # v0.0.1
id: diff
- run: pinact run -diff-file "$DIFF_FILE"
env:
DIFF_FILE: ${{ steps.diff.outputs.diff_path }}pinact calls GitHub REST API to get commit hashes and tags.
You can pass GitHub Access token via environment variable PINACT_GITHUB_TOKEN or GITHUB_TOKEN.
If no GitHub Access token is passed, pinact calls GitHub REST API without access token.
About GitHub Enterprise Server, see also GitHub Access Token for GHES.
pinact >= v3.8.0
You can create a GitHub App User Access Token by ghtkn integration. About ghtkn, please see the document of ghtkn. You need to set up ghtkn first.
export PINACT_GHTKN=truepinact >= v3.1.0
You can manage a GitHub Access token using secret store such as Windows Credential Manager, macOS Keychain, and GNOME Keyring.
- Configure a GitHub Access token by
pinact token setcommand:
$ pinact token set
Enter a GitHub access token: # Input GitHub Access tokenor you can also pass a GitHub Access token via standard input:
echo "<github access token>" | pinact token set -stdin- Enable the feature by setting the environment variable
PINACT_KEYRING_ENABLED:
export PINACT_KEYRING_ENABLED=trueNote that if the environment variable GITHUB_TOKEN is set, this feature gets disabled.
You can remove a GitHub Access token from keyring by pinact token rm command:
pinact token rm- Command line options
- Environment variables
- Local configuration file
- Global configuration file
A configuration file is optional.
pinact supports a configuration file .pinact.yaml, .github/pinact.yaml, .pinact.yml or .github/pinact.yml.
You can also specify the configuration file path by the environment variable PINACT_CONFIG or command line option -c.
You can generate a configuration file by pinact init.
pinact init [<configuration file path>]Furthermore, pinact supports a global configuration file for user-wide defaults.
For more details, see Configuration File.
| Code | Meaning |
|---|---|
| 0 | Everything is pinned, or pinact fixed it |
| 1 | -fix=false was set and something needs pinning |
| 2 | An action cannot be auto-fixed (branch reference, missing version comment on a SHA pin, -verify-comment mismatch, or -min-age violation) |
| 3 | GitHub API error, invalid CLI flag combination, or other unexpected error |
https://github.com/suzuki-shunsuke/pinact-action
We develop GitHub Actions to pin GitHub Actions and reusable workflows by pinact.
Tip
Since v3.10.0, the --branch-to-tag option lets you opt-in to pinning specific branches to the latest stable tag of an action.
In some cases pinact doesn't pin versions intentionally, which may confuse you.
For instance, pinact doesn't pin branches like main and master by default.
For more details, please see here?.
It is a good manner to pin GitHub Actions versions by commit hash. GitHub tags are mutable so they have a substantial security and reliability risk.
See also Security hardening for GitHub Actions - GitHub Docs
Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload
👍
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1👎
uses: actions/cache@v3uses: actions/cache@v3.3.1The Renovate preset helpers:pinGitHubActionDigestsToSemver is useful, but pinact is still useful: You can use both the preset and pinact together.
- Renovate can't pin actions in pull requests before merging them. If you use linters such as ghalint in CI, you need to pin actions before merging pull requests (ref. ghalint policy to enforce actions to be pinned)
- Even if you use Renovate, sometimes you would want to update actions manually
- pinact is useful for non Renovate users
- pinact supports verifying version annotations
- Renovate github-actions Manager - Additional Information
- sethvargo/ratchet is a great tool, but there are known issues.