Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Coverage

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: read

jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- workflow ---'
cat -n .github/workflows/coverage.yml
printf '%s\n' '--- checkout references ---'
rg -n -C 3 'actions/checkout|persist-credentials|pull_request|permissions|run:' .github/workflows
printf '%s\n' '--- pinned action metadata ---'
curl -fsSL 'https://raw.githubusercontent.com/actions/checkout/3d3c42e5aac5ba805825da76410c181273ba90b1/action.yml' | sed -n '1,180p'

Repository: commit-check/commit-check-action

Length of output: 15131


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import re
from pathlib import Path
from urllib.request import urlopen

workflow = Path(".github/workflows/coverage.yml").read_text()
metadata_url = (
    "https://raw.githubusercontent.com/actions/checkout/"
    "3d3c42e5aac5ba805825da76410c181273ba90b1/action.yml"
)
metadata = urlopen(metadata_url, timeout=10).read().decode()

assert re.search(r"^\s*pull_request:\s*$", workflow, re.M)
assert re.search(r"^\s*permissions:\s*$", workflow, re.M)
assert re.search(r"^\s+contents:\s+read\s*$", workflow, re.M)
checkout = workflow.index("actions/checkout@")
first_run = workflow.index("run:", checkout)
assert first_run > checkout
assert re.search(
    r"persist-credentials:\s*[\r\n ]",
    metadata,
)
assert re.search(
    r"persist-credentials:\s*\n(?:\s+.*\n)*?\s+default:\s*true\b",
    metadata,
)

print("pull_request trigger: present")
print("job token permission: contents: read")
print("repository-controlled run step after checkout: present")
print("pinned actions/checkout persist-credentials default: true")
print("pinned actions/checkout token input default: github.token")
PY

Repository: commit-check/commit-check-action

Length of output: 2457


🏁 Script executed:

#!/bin/bash
set -e
python3 - <<'PY'
import re
from pathlib import Path
from urllib.request import urlopen

workflow = Path(".github/workflows/coverage.yml").read_text()
metadata = urlopen(
    "https://raw.githubusercontent.com/actions/checkout/"
    "3d3c42e5aac5ba805825da76410c181273ba90b1/action.yml",
    timeout=10,
).read().decode()

assert re.search(r"^\s*pull_request:\s*$", workflow, re.M)
assert re.search(r"^\s*contents:\s+read\s*$", workflow, re.M)
checkout = workflow.index("actions/checkout@")
assert workflow.index("run:", checkout) > checkout
assert re.search(
    r"persist-credentials:\s*\n(?:\s+.*\n)*?\s+default:\s*true\b",
    metadata,
)
assert re.search(r"default:\s*\$\{\{\s*github\.token\s*\}\}", metadata)

print("pull_request trigger: present")
print("job token permission: contents: read")
print("post-checkout run step: present")
print("persist-credentials default: true")
print("token default: github.token")
PY

Repository: commit-check/commit-check-action

Length of output: 2456


🏁 Script executed:

#!/bin/bash
set -e
curl -fsSL \
  'https://raw.githubusercontent.com/actions/checkout/3d3c42e5aac5ba805825da76410c181273ba90b1/action.yml' |
python3 -c '
import re
import sys
from pathlib import Path

workflow = Path(".github/workflows/coverage.yml").read_text()
metadata = sys.stdin.read()

assert re.search(r"^\s*pull_request:\s*$", workflow, re.M)
assert re.search(r"^\s*contents:\s+read\s*$", workflow, re.M)
checkout = workflow.index("actions/checkout@")
assert workflow.index("run:", checkout) > checkout
assert re.search(
    r"persist-credentials:\s*\n(?:\s+.*\n)*?\s+default:\s*true\b",
    metadata,
)
assert re.search(r"default:\s*\$\{\{\s*github\.token\s*\}\}", metadata)

print("pull_request trigger: present")
print("job token permission: contents: read")
print("post-checkout run step: present")
print("persist-credentials default: true")
print("token default: github.token")
'

Repository: commit-check/commit-check-action

Length of output: 331


Disable checkout credential persistence.

Because this pull_request job runs repository-controlled code after checkout, the default persist-credentials: true exposes the contents: read token through local Git configuration. Set persist-credentials: false.

Proposed fix
       - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+        with:
+          persist-credentials: false
📝 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.

Suggested change
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
🧰 Tools
🪛 zizmor (1.29.0)

[warning] 16-16: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 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/coverage.yml at line 16, Update the actions/checkout step
in the coverage workflow to set persist-credentials to false, preventing the
checkout token from remaining in local Git configuration while preserving the
existing pinned action reference.

Source: Linters/SAST tools

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
# 3.10 is the real floor, see test.yml
python-version: "3.10"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests with coverage
run: |
pytest --cov=main --cov-report=xml --cov-report=term-missing main_test.py
- name: Upload coverage to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
# Hard-fail on push to main so a broken upload is visible; on PRs the
# report is informational and a flaky upload should not block review.
fail_ci_if_error: ${{ github.event_name == 'push' }}
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ venv/
.venv/
__pycache__/
result.txt

# pytest-cov
.coverage
.coverage.*
coverage.xml
htmlcov/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[![GitHub marketplace](https://img.shields.io/badge/Marketplace-commit--check--action-blue)](https://github.com/marketplace/actions/commit-check-action)
[![commit-check](https://img.shields.io/badge/commit--check-enabled-brightgreen?logo=Git&logoColor=white&color=%232c9ccd)](https://github.com/commit-check/commit-check)
[![slsa-badge](https://slsa.dev/images/gh-badge-level3.svg?color=blue)](https://github.com/commit-check/commit-check-action/blob/a2873ca0482dd505c93fb51861c953e82fd0a186/action.yml#L59-L69)
[![codecov](https://codecov.io/gh/commit-check/commit-check-action/graph/badge.svg?token=QHUDSMJGS7)](https://codecov.io/gh/commit-check/commit-check-action)

A GitHub Action for checking commit message formatting, branch naming, committer name, email, commit signoff, and more.

Expand Down