chore: enforce incremental code coverage at 80% for PR gating#60
chore: enforce incremental code coverage at 80% for PR gating#60sungjujin wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| go test -race -v -coverprofile=coverage.out ./... | ||
| working-directory: './src/github.com/segmentio/nsq-go' | ||
| - name: Upload coverage to Codecov | ||
| uses: codecov/codecov-action@v5 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
The codecov/codecov-action is pinned to a mutable version tag (v5) instead of an immutable commit SHA, allowing potential supply chain attacks if the repository is compromised.
More details about this
The codecov/codecov-action is referenced by a version tag (v5) instead of being pinned to a specific commit SHA. This means the action can change without your knowledge—if a malicious actor gains control of the codecov/codecov-action repository, they could push a backdoored version to the v5 tag, and your workflow would automatically use it on the next run.
Exploit scenario:
- An attacker compromises the codecov/codecov-action repository on GitHub or tricks the maintainers into merging malicious code
- They update the
v5tag to point to their backdoored commit - Your GitHub Actions workflow runs and pulls
codecov/codecov-action@v5, which now executes the attacker's code - The malicious action runs with your workflow's credentials and can exfiltrate your
coverage.outfile, environment variables likeGITHUB_TOKEN, or access to your repository
By using a version tag like v5, you're trusting that the tag won't be moved. A full commit SHA (40 hexadecimal characters) is immutable—even if the repository is compromised, the specific code you specified cannot be changed.
To resolve this comment:
✨ Commit fix suggestion
| uses: codecov/codecov-action@v5 | |
| uses: codecov/codecov-action@b0c41b0cdf2050f1b3a81c9f70294c7c3a0c68f7 # v5.0.0 |
View step-by-step instructions
- Go to the Codecov action repository and find the full commit SHA for the desired release version (e.g., v5): https://github.com/codecov/codecov-action/releases.
- Replace
uses: codecov/codecov-action@v5withuses: codecov/codecov-action@<commit-sha>using the full 40-character SHA for the v5 release you want to use.
For example:uses: codecov/codecov-action@b0c41b0cdf2050f1b3a81c9f70294c7c3a0c68f7 - Optionally, add a comment showing the version tag this SHA refers to, like
# v5.0.0for easier maintenance in the future.
Pinning by commit SHA ensures the action version can't change unexpectedly, reducing supply chain risk.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by third-party-action-not-pinned-to-commit-sha.
Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.
You can view more details about this finding in the Semgrep AppSec Platform.
| go test -race -v -coverprofile=coverage.out ./... | ||
| working-directory: './src/github.com/segmentio/nsq-go' | ||
| - name: Upload coverage to Codecov | ||
| uses: codecov/codecov-action@v5 |
There was a problem hiding this comment.
Semgrep identified an issue in your code:
The codecov-action step uses a mutable tag (@v5) instead of a pinned commit SHA, allowing the action owner to silently change what code executes in your CI/CD pipeline.
More details about this
The step uses codecov/codecov-action@v5, which references a mutable tag rather than a pinned commit SHA. This means the action owner can change what code runs under this tag without your knowledge.
Attack scenario:
- An attacker compromises the Codecov GitHub Actions repository or gains access to the
v5tag - They update the
v5tag to point to malicious code - On your next workflow run, the GitHub Actions runner downloads and executes the compromised code with access to your repository's secrets (like
GITHUB_TOKEN) - The attacker exfiltrates your repository secrets, coverage reports, or injects code into your build artifacts
This is exactly how the trivy-action and kics-github-action compromises happened. The v5 tag can be silently repointed, making it impossible to detect the compromise until damage is done.
To resolve this comment:
✨ Commit fix suggestion
| uses: codecov/codecov-action@v5 | |
| uses: codecov/codecov-action@d94fb1c7b16d28912cacee80f0657e33b57cb74e # v5.0.0 |
View step-by-step instructions
- Find the line with
uses: codecov/codecov-action@v5. - Visit https://github.com/codecov/codecov-action/releases and identify the preferred stable release for
v5. - Copy the full 40-character commit SHA associated with that version.
- Change the
usesline to use the full commit SHA, for example:uses: codecov/codecov-action@d94fb1c7b16d28912cacee80f0657e33b57cb74e # v5.0.0(replace with the correct SHA for the version you want). - Optionally add a comment with the original tag name for clarity.
Pinning actions to a commit SHA ensures the workflow always uses the same trusted code and prevents silent upstream changes.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by github-actions-mutable-action-tag.
Need help with this issue? Consult our Semgrep Findings Documentation or ask in #help-appsec on Slack.
You can view more details about this finding in the Semgrep AppSec Platform.
Summary
Changes
codecov.yml(new)patch.default.informational: false— PRs with <80% incremental coverage will be blockedproject.default.informational: true— project-level coverage is advisory only.github/workflows/ci.yml-coverprofile=coverage.outflag togo testto generate coverage reportcodecov/codecov-action@v5step to uploadcoverage.outto CodecovWhy Patch Coverage (Not Project Coverage)?
Incremental (patch) coverage is more actionable:
Notes
Reference Implementation
See table-scanner for the canonical setup.
🤖 Generated with Claude Code