Motivation | Install | How to use | GitHub Actions | Configuration | LICENSE
pinact is a CLI to edit GitHub Workflow and Composite action files and pin versions of Actions and Reusable Workflows. pinact can also update their versions and verify version annotations.
pinact run
$ git diff
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 84bd67a..5d92e44 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -113,17 +113,17 @@ jobs:
needs: path-filter
permissions: {}
steps:
- - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3
- - uses: actions/setup-go@v4
+ - uses: actions/checkout@83b7061638ee4956cf7545a6f7efe594e5ad0247 # v3.5.1
+ - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0
- name: Cache Primes
id: cache-primes
- uses: actions/cache@v3.3.1
+ uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1
with:
path: prime-numbers
key: ${{ runner.os }}-primes
actionlint:
- 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
with:
aqua_version: v2.3.4
permissions:
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@v3
uses: actions/cache@v3.3.1
The Renovate preset helpers:pinGitHubActionDigestsToSemver is useful, but pinact is still useful:
- 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
pinact calls GitHub REST API to get commit hashes and tags.
You can pass GitHub Access token via environment variable GITHUB_TOKEN
.
If no GitHub Access token is passed, pinact calls GitHub REST API without access token.
Please run pinact run
on a Git repository root directory, then target files are fixed.
pinact run
Default target files are:
.github/workflows/*.yml
.github/workflows/*.yaml
action.yml
action.yaml
*/action.yml
*/action.yaml
*/*/action.yml
*/*/action.yaml
*/*/*/action.yml
*/*/*/action.yaml
You can change target files by command line arguments or configuration files.
e.g.
pinact run example.yaml
#663 pinact >= v1.1.0
You can update actions using the -update (-u)
option:
pinact run -u
pinact can fix example codes in documents too.
pinact run README.md
A configuration file is optional.
You can create a configuration file .pinact.yaml
by pinact init
.
pinact init
You can change the output path.
pinact init '.github/pinact.yaml'
About the configuration, please see Configuration.
pinact >= v1.6.0
#816
Instead of fixing files, you can validate if actions are pinned by --check
option:
pinact run --check
Using this option, pinact doesn't fix files. If actions aren't pinned, the command fails.
$ pinact run --check
ERRO[0000] parse a line action=actions/checkout@v2 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
ERRO[0000] parse a line action=actions/cache@v3.3.1 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
ERRO[0000] parse a line action=rharkor/caching-for-turbo@v1.6 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
ERRO[0000] parse a line action=actions/checkout@v3 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
ERRO[0000] parse a line action=actions/checkout@v3 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
ERRO[0000] parse a line action=suzuki-shunsuke/actionlint-workflow/.github/workflows/actionlint.yaml@v0.5.0 error="action isn't pinned" pinact_version= program=pinact workflow_file=testdata/foo.yaml
$ echo $?
1
Please see the document.
https://github.com/suzuki-shunsuke/pinact-action
We develop GitHub Actions to pin GitHub Actions and reusable workflows by pinact.
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
.
As of pinact v2.2.0, pinact configuration file has a schema version.
version: 3
In general, you should use the latest schema version.
pinact v2.2.0 or later supports this version.
.pinact.yaml
e.g.
version: 3
files:
- pattern: .github/workflows/*.yml
- pattern: .github/workflows/*.yaml
- pattern: .github/actions/*/action.yml
- pattern: .github/actions/*/action.yaml
ignore_actions:
# slsa-framework/slsa-github-generator doesn't support pinning version
# > Invalid ref: 68bad40844440577b33778c9f29077a3388838e9. Expected ref of the form refs/tags/vX.Y.Z
# https://github.com/slsa-framework/slsa-github-generator/issues/722
- name: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml
ref: "v\\d+\\.\\d+\\.\\d+"
- name: suzuki-shunsuke/.*
ref: main
This is optional. A list of target files.
This is required. A glob pattern of target files. Go's path/filepath#Glob is used. A relative path from pinact's configuration file. If files are passed via positional command line arguments, the configuration is ignored.
e.g.
files:
- pattern: .github/workflows/*.yml
- pattern: .github/workflows/*.yaml
- pattern: README.md
This is optional. A list of ignored actions and reusable workflows.
This is required. A regular expression of ignored actions and reusable workflows.
ignored_actions:
- name: actions/.*
ref: main
Warning
Regular expressions must match with action names exactly.
For instance, name: actions/
doesn't match with actions/checkout
Regarding regular expressions, Go's regexp package is used.
This is required. A regular expression of ignored action versions (branch, tag, or commit hash).
Warning
Regular expressions must match with action names exactly.
For instance, ref: main
doesn't match with malicious-main
Please see here.
- pinact.json
- https://raw.githubusercontent.com/suzuki-shunsuke/pinact/refs/heads/main/json-schema/pinact.json
If you look for a CLI tool to validate configuration with JSON Schema, ajv-cli is useful.
ajv --spec=draft2020 -s json-schema/pinact.json -d pinact.yaml
Version: main
# yaml-language-server: $schema=https://raw.githubusercontent.com/suzuki-shunsuke/pinact/main/json-schema/pinact.json
Or pinning version:
# yaml-language-server: $schema=https://raw.githubusercontent.com/suzuki-shunsuke/pinact/v1.1.2/json-schema/pinact.json
- Renovate github-actions Manager - Additional Information
- sethvargo/ratchet is a great tool, but there are known issues.