Skip to content
Open
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
41 changes: 41 additions & 0 deletions .github/workflows/mutation-testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Mutation Testing

# Non-blocking: this runs on a schedule and on demand, never gates merges.
# It reports how effective the test suite is at catching real bugs (mutation
# score), scoped to util/ for now. See issue #760.
on:
schedule:
- cron: '0 6 * * 1' # Weekly on Monday 06:00 UTC
workflow_dispatch:

jobs:
mutation-test:
runs-on: ubuntu-latest
container:
# Official Node 20 image (Debian bookworm) — Node baked in, no third-party
# repo, same base used by the integration workflow.
image: 'node:20-bookworm'
steps:
- name: Install canvas build dependencies
run: |
apt-get update --yes
apt-get install --yes --no-install-recommends \
build-essential pkg-config libcairo2-dev libpango1.0-dev \
libjpeg-dev libgif-dev librsvg2-dev

- uses: actions/checkout@v4

- run: npm ci

- name: Run mutation testing on util/
run: npm run mutation-test:util
env:
NODE_ENV: test

- name: Upload mutation report
if: always()
uses: actions/upload-artifact@v4
with:
name: mutation-report
path: reports/mutation/
Comment on lines +26 to +40

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major

Pin both GitHub Actions to full SHAs.

actions/checkout@v4 and actions/upload-artifact@v4 use mutable tags. Pin them to their full 40-character commit SHAs to prevent supply-chain attacks where tags are retargeted to malicious code. Include the tag as a comment for readability.

- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
...
- uses: actions/upload-artifact@66337390251171e342b772552734d18b63d645f9 # v4

Use Dependabot or Renovate to automate SHA updates when new releases are available.

🧰 Tools
🪛 zizmor (1.26.1)

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

(artipacked)


[error] 26-26: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 37-37: 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/mutation-testing.yaml around lines 26 - 40, The workflow
still uses mutable GitHub Action tags in the mutation-testing job, so update the
actions referenced by actions/checkout and actions/upload-artifact to their full
40-character commit SHAs and keep the original version as an inline comment for
readability. Make this change in the mutation-testing workflow alongside the
existing run steps, preserving the same behavior while removing tag-based
supply-chain risk.

if-no-files-found: ignore
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ admin.macaroon
tls.cert
dist/
.history/
commands.log
commands.log
# StrykerJS mutation testing
.stryker-tmp/
reports/
Loading
Loading