Pinner ๐งช
A high-performance Rust CLI utility to hash-pin GitHub Actions in your workflow files. Secure your CI/CD supply chain by converting volatile, mutable tags (like @v2) into immutable, cryptographic commit SHAs (like @df4cb1c...).
Documentation ๐
The full documentation for the project is available at: https://ffalcinelli.github.io/pinner/
Why Pin? ๐
Using mutable tags like @v2 or @main in GitHub Actions introduces a security risk. If an attacker gains access to an action's repository, they can move the tag to a malicious commit, leading to a supply chain attack on your infrastructure.
Hash-pinning ensures that you run the exact code you've audited, every single time.
Name Origin โ๏ธ
The name Pinner is inspired by the Pinner reaction in organic chemistry. Discovered by Adolf Pinner, this reaction involves the acid-catalyzed conversion of a reactive nitrile into a highly stable Pinner salt.
Just as the Pinner reaction acts as a catalyst to transform a volatile compound into a stable, fixed salt, this CLI acts as a catalyst for your CI/CD, transforming "floating" action tags into secure, immutable, and fixed commit SHAs.
Features โจ
- Safe Replacement: Uses Regex-based parsing to preserve your YAML comments and formatting perfectly.
- Tag Preservation: Automatically appends the original tag as a comment for readability (e.g.,
@<hash> # v2). - GitHub API Integration: Automatically fetches the correct commit SHA for any tag or branch.
- Batch Processing: Scans your entire
.github/workflows/directory by default. - Targeted Updates: Specify exactly which workflow files or directories to process with the
--workflowflag.
Installation ๐ ๏ธ
# Install via cargo (recommended)
# Alternatively, install via cargo-git
Alternatively, from source:
Usage ๐
1. Pin all actions
Scans .github/workflows/ and converts all tags to pinned hashes.
Input: - uses: actions/checkout@v3
Output: - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
2. Specify specific workflows
You can target specific files or directories using the --workflow (or -w) flag.
# Pin actions in a single file
# Pin actions in multiple specific files
# Pin actions in a custom directory
3. Set a specific action hash
Forcibly updates a specific action across all workflows.
4. Upgrade to latest
Re-pins all actions to the latest commit on their main branch (or the latest release tag if available).
Common Flags
--yes(-y): Automatically confirm all replacements.--dry-run: Print diff without modifying files.--quiet(-q): Suppress all console output.--workflow(-w): Workflow files or directories to process.
Rate Limiting & Authentication ๐
Pinner uses the GitHub API to fetch commit SHAs. To avoid hitting rate limits (especially in CI or large projects), you should provide a GitHub token via the GITHUB_TOKEN environment variable.
The token only needs read-only access to public repositories (or repo scope for private ones).
Development ๐ฉโ๐ป
This project is built with Rust and follows clean code principles.
- Tests:
cargo test - Lints:
cargo clippy - Formatting:
cargo fmt - Coverage:
cargo tarpaulin
Contributing ๐ค
Contributions are welcome! Please feel free to submit a Pull Request or open an issue for any bugs or feature requests.
License ๐
MIT License. See LICENSE for details.