GitHub Action
Official SCAL-P GitHub Action — composite action that installs the CLI and runs scalp ci with SARIF support, SHA-pinned for supply chain security.
The SCAL-P GitHub Action is the recommended way to run SCAL-P in GitHub Actions workflows. It downloads the correct binary for your runner platform, runs scalp ci, and produces structured reports — all in a single step.
Usage
- uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
version: latest
sarif: .scalp/report.sarifAlways pin the action to a specific commit SHA instead of a tag. Tags are mutable — a tag could be moved to a different commit. SHAs are immutable and guarantee you're running the exact code you reviewed.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
version | no | latest | SCAL-P version (e.g. v0.3.0). Use latest for the newest release. |
pm | no | auto-detect | Package manager: npm, pnpm, yarn, bun. |
policy | no | .scalp/policy.json | Path to policy file, relative to working-directory. |
output | no | .scalp/ci-report.json | Path for the CI report, relative to working-directory. |
pr-context | no | fork | PR context: fork (blocks scripts, forces hashes) or internal (respects policy). |
allow-scripts | no | false | Allow install scripts (only applies to internal PRs). |
sarif | no | (empty) | Path for SARIF 2.1.0 report, relative to working-directory. Leave empty to skip. |
working-directory | no | . | Working directory relative to repo root (useful for monorepos). |
Outputs
| Output | Description | Example |
|---|---|---|
status | CI run result | pass or fail |
report-path | Absolute path to the JSON report | /home/runner/work/repo/.scalp/ci-report.json |
sarif-path | Absolute path to the SARIF report | /home/runner/work/repo/.scalp/report.sarif |
Examples
Minimal — quick CI check
name: SCAL-P
on: [pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- name: SCAL-P CI
uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
version: latestWith SARIF and Code Scanning
name: SCAL-P with Code Scanning
on: [pull_request]
jobs:
security:
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- name: Run SCAL-P CI
uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
version: latest
sarif: .scalp/report.sarif
continue-on-error: true
- name: Upload SARIF to GitHub
if: success() || failure()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: .scalp/report.sarifCustom version and policy
- uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
version: v0.2.0
policy: config/scalp-policy.json
output: reports/scalp-report.jsonMonorepo with working directory
- uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
version: latest
working-directory: packages/my-app
sarif: ../../.scalp/report.sarifUsing outputs in subsequent steps
- name: Run SCAL-P CI
uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
id: scalp
- name: Check result
run: |
if [[ "${{ steps.scalp.outputs.status }}" == "pass" ]]; then
echo "SCAL-P checks passed!"
else
echo "SCAL-P checks failed — check the report at ${{ steps.scalp.outputs.report-path }}"
exit 1
fiMatrix across package managers
name: SCAL-P Multi-PM
on: [pull_request]
jobs:
security:
runs-on: ubuntu-latest
strategy:
matrix:
pm: [npm, pnpm, yarn, bun]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- name: Install ${{ matrix.pm }}
run: npm install -g ${{ matrix.pm }}
- name: SCAL-P with ${{ matrix.pm }}
uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
with:
pm: ${{ matrix.pm }}
sarif: .scalp/${{ matrix.pm }}-report.sarifHow it works
Under the hood, the action runs two shell steps:
Install SCAL-P — runs scripts/install-scalp.sh which detects the runner OS and
architecture (linux/darwin/windows × amd64/arm64), resolves the latest version if needed,
downloads the correct release archive, verifies its SHA-512 checksum against the release's
checksums.txt, and installs the binary to $HOME/.local/bin/scalp.
Run scalp ci — executes scalp ci with all the inputs mapped to CLI flags. Converts
relative paths to absolute paths for the outputs. Writes status, report-path, and
sarif-path to $GITHUB_OUTPUT. If the CLI exits non-zero, sets status=fail and propagates
the failure.
Security in the install script
| Measure | What it does |
|---|---|
| SHA-512 verification | Downloads checksums.txt from the release and verifies the binary's hash via openssl dgst -sha512 |
| Magic byte check | Rejects downloaded files that aren't actual gzip or zip archives (catches GitHub HTML error pages) |
| Binary-only install | Extracts only the scalp binary, discarding READMEs, licenses, and other files |
| Temp directory cleanup | Creates a temporary directory on start, removes it on exit (even on failure) |
GITHUB_PATH registration | Appends the install directory to $GITHUB_PATH so scalp is available in subsequent steps |
Platform support
| OS | Architectures |
|---|---|
| Linux | amd64, arm64 |
| macOS | amd64, arm64 |
| Windows | amd64 |
Why SHA pinning matters
# Good — immutable SHA
uses: scal-p-labs/scalp-action@0b29e6acb5c358a7c6b6d470c6ab8cb6e86fc217
# Risky — tag could be moved
uses: scal-p-labs/scalp-action@v0.3.0Tags are human-friendly references that maintainers can move. A compromised or careless maintainer could force-push a new commit to the same tag. SHA pinning guarantees you're running the exact code you reviewed.
When you want to update, change the SHA — not the tag.