chore(ci): use reusable github actions workflows#31
Conversation
📝 WalkthroughWalkthroughBoth GitHub Actions workflow jobs ( ChangesCI Workflow Delegation and Composer-Unused Config
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~4 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 PHPStan (2.2.2)PHPStan was skipped because the config uses disallowed Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/cgl.yml:
- Around line 9-11: The reusable workflow reference in both
`.github/workflows/cgl.yml` and `.github/workflows/release.yml` uses `@main`
which is mutable and poses a supply-chain security risk. Replace `@main` with a
full 40-character commit SHA in the
konradmichalik/reusable-github-actions/.github/workflows/cgl.yml reference on
line 9 of cgl.yml and in the analogous reference on line 10 of release.yml to
pin the workflow to an immutable commit.
In @.github/workflows/release.yml:
- Line 10: The reusable GitHub Actions workflow reference in the release.yml
file uses `@main`, which is mutable and vulnerable to supply chain attacks. In the
uses statement referencing
konradmichalik/reusable-github-actions/.github/workflows/release.yml, replace
`@main` with a full-length commit SHA (40 character hash) to pin the workflow to a
specific immutable commit. This ensures that only the reviewed version of the
upstream workflow can be executed.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 660ddee0-7a9d-43b8-9745-9fe0ba243d46
📒 Files selected for processing (3)
.github/workflows/cgl.yml.github/workflows/release.ymlcomposer-unused.php
| uses: konradmichalik/reusable-github-actions/.github/workflows/cgl.yml@main | ||
| with: | ||
| php-version: '8.3' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Verify workflow `uses:` references are pinned to full commit SHAs.
# Expected: no output. Any output indicates unpinned references.
rg -nP --iglob '*.yml' '^\s*uses:\s*[^@]+@(?![0-9a-fA-F]{40}\b)\S+'Repository: move-elevator/deployer-tools
Length of output: 221
🏁 Script executed:
# First, verify the target file exists and show its content
if [ -f ".github/workflows/cgl.yml" ]; then
echo "=== File exists: .github/workflows/cgl.yml ==="
cat -n ".github/workflows/cgl.yml" | head -20
else
echo "File not found: .github/workflows/cgl.yml"
fi
# List all YAML files in .github/workflows
echo -e "\n=== YAML files in .github/workflows ==="
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -20
# Search for unpinned workflow uses with corrected pattern
echo -e "\n=== Searching for unpinned 'uses:' references ==="
rg 'uses:.*@(?!([0-9a-fA-F]{40})($|[^0-9a-fA-F]))' --type yaml -n 2>/dev/null || echo "rg search completed"Repository: move-elevator/deployer-tools
Length of output: 542
🏁 Script executed:
# Check the other workflow file for context on pinning practices
echo "=== Content of release.yml ==="
cat -n ".github/workflows/release.yml"
# Search for any policy documentation about pinning or security
echo -e "\n=== Searching for policy/documentation files ==="
find . -maxdepth 2 -type f \( -iname "SECURITY*" -o -iname "POLICY*" -o -iname "CONTRIBUTING*" -o -iname "README*" \) -not -path "./.git/*" | head -20
# Check for any comments or docs about action pinning in workflow files
echo -e "\n=== Checking for pinning-related comments in workflows ==="
rg -l 'pin|sha|commit|hash' --type yaml .github/workflows/ 2>/dev/null || trueRepository: move-elevator/deployer-tools
Length of output: 465
🏁 Script executed:
# Check SECURITY.md for pinning policy
echo "=== Content of docs/SECURITY.md ==="
cat ./docs/SECURITY.md
echo -e "\n=== Checking README.md for CI/CD or pinning policies ==="
head -100 ./README.mdRepository: move-elevator/deployer-tools
Length of output: 4116
🏁 Script executed:
# Search for zizmor or other security linting configs
echo "=== Searching for security/linting configs ==="
find . -maxdepth 2 -type f \( -name ".zizmor*" -o -name "*zizmor*" -o -name ".github-security*" \) 2>/dev/null
# Check all .github root files
echo -e "\n=== Files in .github root ==="
ls -la .github/ | grep -v workflows
# Check if there's a dependabot or similar security config
echo -e "\n=== Checking for dependabot/security configs ==="
ls -la .github/
# Search for any mentions of "zizmor" in the repo
echo -e "\n=== Searching for zizmor mentions ==="
rg -r 'zizmor' --type yaml --type json 2>/dev/null || echo "No zizmor references found"Repository: move-elevator/deployer-tools
Length of output: 542
🌐 Web query:
zizmor github actions security linter
💡 Result:
zizmor is a security-focused static analysis tool designed specifically for GitHub Actions [1][2]. Written in Rust, it aims to identify and help remediate potential vulnerabilities within CI/CD configurations [2][3]. Key features of zizmor include: Security Auditing: It detects common security issues such as template injection vulnerabilities, accidental credential exposure, excessive runner permissions, and the use of known vulnerable actions [2][4]. Integration Options: zizmor-action: The official GitHub Action for automated integration. It supports uploading results to GitHub Advanced Security (where available) or printing them directly to the console [5][6]. Manual Integration: Users can run zizmor directly in their workflows using various output formats, including SARIF (for code scanning integration), JSON, or plain text [6]. Developer-Friendly: It is designed with a high signal-to-noise ratio and supports multiple "personas" (like pedantic or auditor) to adjust sensitivity [1]. Offline Capability: zizmor functions as an offline-native tool, though it can optionally utilize a GitHub API token to fetch remote workflows or interact with GitHub's ecosystem [1][7]. Compatibility: It can be integrated into broader linter frameworks such as Super-Linter and MegaLinter [6]. Official documentation and resources are available at https://zizmor.sh/ and the source code can be found in the zizmorcore/zizmor repository on GitHub [1][2].
Citations:
- 1: https://zizmor.sh/
- 2: https://github.com/zizmorcore/zizmor
- 3: https://github.com/zizmorcore/zizmor/blob/main/docs/index.md
- 4: https://docs.zizmor.sh/audits/
- 5: https://github.com/zizmorcore/zizmor-action?tab=readme-ov-file
- 6: https://docs.zizmor.sh/integrations/
- 7: https://docs.zizmor.sh/quickstart/
🌐 Web query:
github reusable workflows pinning commit sha best practice
💡 Result:
The best practice for referencing reusable workflows in GitHub Actions is to pin them to a full-length commit SHA [1][2][3]. Using mutable references like branch names or tags is a significant security risk, as a compromised upstream repository could allow an attacker to inject malicious code that your workflows would automatically execute [1][2][4]. Key recommendations and best practices include: Pin to full SHA: Always reference reusable workflows using a 40-character commit SHA [2][4]. This ensures immutability and guarantees that the exact code you audited is the code that runs, protecting against supply chain attacks such as malicious tag re-pointing [1][4]. Maintain readability with comments: While the reference must be a SHA, it is a common best practice to append the intended version tag as a comment for readability and easier maintenance, for example: uses: owner/repo/.github/workflows/workflow.yml@a1b2c3d4e5f6g7h8i9j0k1l2 # v1.0.0 [4][5]. Use organization policies: If using GitHub Enterprise, configure the organization-level policy to Require actions to be pinned to a full-length commit SHA [1][3]. This enforcement mechanism prevents accidental use of mutable references and ensures consistent security standards across your organization [3]. Implement drift audits: Because organization policies may not recursively verify nested reusable workflows, implement periodic audits or CI checks to walk the dependency tree of your workflows [1]. Tools or custom scripts can be used to parse YAML files, resolve the references, and fail builds that contain unpinned refs [1]. Leverage automation: Use tools like Dependabot or specialized CI utilities (e.g., pinact) to help manage and update these pinned references, ensuring that you can receive security patches and feature updates while maintaining control over when upgrades occur [3][5]. Note on same-repo workflows: Reusable workflows located within the same repository (e.g.,./.github/workflows/my-workflow.yml) are implicitly pinned to the commit SHA of the caller, so they do not require explicit SHA pinning [4]. Cross-repository references, however, must always be explicitly pinned [4].
Citations:
- 1: https://www.systemshardening.com/articles/cicd/github-actions-reusable-workflow-pinning-audit/
- 2: https://adaptive-enforcement-lab.com/secure/github-actions-security/workflows/reusable/caller-validation-pinning/
- 3: https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/
- 4: https://github.com/ActionsCI/reusable-workflows
- 5: chore(ci): pin all GitHub Actions and reusable workflows by SHA huggingface/transformers#45955
Pin reusable workflow to an immutable commit SHA.
Line 9 uses @main, which is mutable and creates a supply-chain security risk. GitHub's recommended best practice is to pin reusable workflows to a full 40-character commit SHA to prevent supply-chain attacks. The same issue also exists in .github/workflows/release.yml at line 10.
Suggested fix for cgl.yml
- uses: konradmichalik/reusable-github-actions/.github/workflows/cgl.yml@main
+ uses: konradmichalik/reusable-github-actions/.github/workflows/cgl.yml@<FULL_40_CHAR_COMMIT_SHA>Apply the same fix to .github/workflows/release.yml line 10.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| uses: konradmichalik/reusable-github-actions/.github/workflows/cgl.yml@main | |
| with: | |
| php-version: '8.3' | |
| uses: konradmichalik/reusable-github-actions/.github/workflows/cgl.yml@abc123def456789012345678901234567890abcd | |
| with: | |
| php-version: '8.3' |
🧰 Tools
🪛 zizmor (1.25.2)
[error] 9-9: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/cgl.yml around lines 9 - 11, The reusable workflow
reference in both `.github/workflows/cgl.yml` and
`.github/workflows/release.yml` uses `@main` which is mutable and poses a
supply-chain security risk. Replace `@main` with a full 40-character commit SHA
in the konradmichalik/reusable-github-actions/.github/workflows/cgl.yml
reference on line 9 of cgl.yml and in the analogous reference on line 10 of
release.yml to pin the workflow to an immutable commit.
Source: Linters/SAST tools
| uses: softprops/action-gh-release@v3 | ||
| with: | ||
| generate_release_notes: true | ||
| uses: konradmichalik/reusable-github-actions/.github/workflows/release.yml@main |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/release.yml | head -20Repository: move-elevator/deployer-tools
Length of output: 293
🌐 Web query:
GitHub Actions reusable workflow pinning commit hash best practices security
💡 Result:
The security best practice for GitHub Actions reusable workflows is to pin all references to a full-length commit SHA [1][2][3]. Using a tag or branch (e.g., @v1) as a reference is inherently mutable, meaning the underlying code can change without the workflow file being updated [4][5][6]. If an attacker compromises the repository containing the reusable workflow, they can force-push a malicious update to a tag, which your pipelines would automatically execute [1][3][7]. Pinning to a full-length commit SHA ensures immutability; it binds your workflow to a specific, cryptographically verified snapshot of the code, preventing such supply chain attacks [1][7][8]. To maintain the benefits of versioning while ensuring security, follow these conventions: 1. Use full-length commit SHAs: Always use the 40-character commit hash for references [9][1][10]. 2. Add descriptive comments: Append the original version tag as a comment to preserve readability and aid automated tooling (e.g., uses: owner/repo/.github/workflows/main.yml@a1b2c3d4... # v1.2.3) [7][5][8]. 3. Automate updates: Configure automated dependency managers like Dependabot or Renovate to monitor for new tags and generate pull requests that update the SHA and the associated comment [7][6][8]. 4. Enforce via policy: If you are using GitHub Enterprise or an organization account, enable the policy "Require actions to be pinned to a full-length commit SHA" in your organization settings to prevent unpinned references across all repositories [9][1][10][3]. Note that while some organizational policies may explicitly target "actions," you should manually audit and pin reusable workflows with the same level of rigor, as they share similar security risks [9][3]. Beyond pinning, remember that reusable workflows operate with the caller's permissions and secrets [9][11]. Therefore, you should also: - Limit secret inheritance: Prefer explicit secret passing (secrets:...) over secrets: inherit to minimize exposure [11]. - Validate inputs: Treat all workflow inputs as untrusted and validate them before use to prevent command injection [11].
Citations:
- 1: https://docs.github.com/en/actions/reference/security/secure-use
- 2: https://github.com/github/docs/blob/962a1c8dccb8c0f66548b324e5b921b5e4fbc3d6/content/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions.md
- 3: https://mikael.barbero.tech/blog/post/2026-03-24-stop-trusting-mutable-references/
- 4: https://samsond.github.io/posts/why-tags-fail/
- 5: https://kollitsch.dev/blog/2026/pinning-github-actions-to-commit-hashes/
- 6: https://nearform.com/insights/why-you-should-pin-your-github-actions-by-commit-hash/
- 7: https://safeguard.sh/resources/blog/github-actions-pinning-sha-vs-tag
- 8: https://tenthirtyam.org/dispatches/2026/03/27/why-you-should-pin-github-actions-to-commit-hashes/
- 9: https://www.systemshardening.com/articles/cicd/github-actions-reusable-workflow-pinning-audit/
- 10: https://github.blog/changelog/2025-08-15-github-actions-policy-now-supports-blocking-and-sha-pinning-actions/
- 11: https://adaptive-enforcement-lab.com/secure/github-actions-security/workflows/reusable/
🌐 Web query:
zizmor GitHub Actions security checker unpinned-uses
💡 Result:
The unpinned-uses audit is a security check provided by zizmor, a static analysis tool for GitHub Actions [1][2]. Its primary purpose is to identify and flag GitHub Actions or reusable workflows that are not pinned to a specific, immutable SHA reference [1][3]. Key details of the unpinned-uses audit include: Functionality and Configuration: The rule ensures that actions are pinned by SHA hash, which protects against supply chain attacks where a tagged or branch-based reference (like v1 or main) is updated with malicious code [1][4]. As of zizmor v1.20.0, the default policy requires hash-pinning for all actions, including official GitHub actions [1][5]. Users can customize this behavior via a zizmor.yml configuration file, where they can define granular policies (e.g., allowing ref-pinning for trusted organizations) using pattern matching [1]. Audit Policies: The audit supports three primary policies for matched patterns: - hash-pin: Requires the action to be pinned by a full SHA reference [1]. - ref-pin: Allows pinning by symbolic reference (e.g., tags or branches) or SHA reference [1]. - any: Requires no specific pinning [1]. Execution Requirements: The audit does not require online access to perform the initial detection of unpinned uses [6]. However, if you wish to use the tool's auto-fix feature to automatically resolve findings by pinning them to the latest SHA, online access and a GitHub token are required to fetch the commit hashes [6]. If you wish to revert to a more permissive policy for first-party actions (like those under actions/) after the v1.20.0 change, you can add the following to your zizmor.yml file [1][5]: rules: unpinned-uses: config: policies: actions/: ref-pin github/: ref-pin dependabot/: ref-pin
Citations:
- 1: https://docs.zizmor.sh/audits/
- 2: https://github.com/zizmorcore/zizmor/
- 3: https://docs.zizmor.sh/release-notes/
- 4: Reconsider the default inclusion of official GitHub actions in unpinned-uses zizmorcore/zizmor#1434
- 5: https://github.com/zizmorcore/zizmor/releases/tag/v1.20.0
- 6: https://github.com/zizmorcore/zizmor/blob/main/docs/usage.md
Pin the release reusable workflow reference to a commit hash.
Line 10 references @main, which is mutable and allows unreviewed upstream changes in the release path. Pinning to a full-length commit SHA prevents supply chain attacks where an attacker could compromise the upstream repository and force-push malicious code to the branch.
Suggested fix
- uses: konradmichalik/reusable-github-actions/.github/workflows/release.yml@main
+ uses: konradmichalik/reusable-github-actions/.github/workflows/release.yml@<FULL_40_CHAR_COMMIT_SHA>🧰 Tools
🪛 zizmor (1.25.2)
[error] 10-10: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yml at line 10, The reusable GitHub Actions
workflow reference in the release.yml file uses `@main`, which is mutable and
vulnerable to supply chain attacks. In the uses statement referencing
konradmichalik/reusable-github-actions/.github/workflows/release.yml, replace
`@main` with a full-length commit SHA (40 character hash) to pin the workflow to a
specific immutable commit. This ensures that only the reviewed version of the
upstream workflow can be executed.
Source: Linters/SAST tools
Summary
konradmichalik/reusable-github-actionscomposer-unusedpackage exclusions out of the workflow into a repo-local config file, so the generic reusable CGL workflow works unchangedChanges
.github/workflows/cgl.yml— call reusablecgl.yml@mainwithphp-version: '8.3'.github/workflows/release.yml— call reusablerelease.yml@maincomposer-unused.php— ignoredeployer/deployerandsourcebroker/deployer-extendedviaNamedFilter(these are consumed through Deployer's recipe loader, not PHP autoload)Notes
composer-unused.phplints clean, and a barecomposer-unusedrun (phar 0.9.6, the version CI installs) reports0 unused, 2 ignoredwith exit 0 — the config replaces the former--excludePackageflags exactly.composer update --lockstep is intentionally dropped (not present in the reusable workflow; not required by composer-normalize / PHP-CS-Fixer).Summary by CodeRabbit