GitHub Actions (package-scanner-ci)
Use package-scanner-ci to send lockfiles and package.json to the hosted PackageScanner service on pull requests and pushes.
Repository (source and docs)It reads supported lockfiles and/or package.json from the workspace and forwards them to the PackageScanner CI API. It does not analyze dependencies locally—it is a thin CI client.
- Fail the job on malware by default, and on High/Critical vulnerabilities by default
- Auto-detect lockfiles so you can start with a minimal workflow
- Expose analysis-id, malware counts, and severity-specific vulnerability counts as outputs
Step 1: Reference the action
Pin the published GitHub Action like this.
uses: Kazuki-tam/package-scanner-ci@v1Minimal workflow
After setting permissions and checking out the repo, run the scan step.
permissions:
contents: read
jobs:
package-scanner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- id: scan
uses: Kazuki-tam/package-scanner-ci@v1
- run: |
echo "analysis=${{ steps.scan.outputs.analysis-id }}"
echo "malware=${{ steps.scan.outputs.malware-count }}"
echo "vulns=${{ steps.scan.outputs.vulnerability-count }}"
echo "low=${{ steps.scan.outputs.vulnerability-low-count }}"
echo "moderate=${{ steps.scan.outputs.vulnerability-moderate-count }}"
echo "high=${{ steps.scan.outputs.vulnerability-high-count }}"
echo "critical=${{ steps.scan.outputs.vulnerability-critical-count }}"Step 2: Example with triggers
Run only when dependency manifests change (adjust paths for your repo).
name: PackageScanner
on:
pull_request:
paths:
- "package.json"
- "package-lock.json"
- "pnpm-lock.yaml"
- "yarn.lock"
- "bun.lock"
push:
branches:
- main
permissions:
contents: read
jobs:
package-scanner:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- id: scan
uses: Kazuki-tam/package-scanner-ci@v1
- run: |
echo "analysis=${{ steps.scan.outputs.analysis-id }}"
echo "malware=${{ steps.scan.outputs.malware-count }}"Step 3: Understand failures
By default the step fails when malware is found, and when High/Critical vulnerabilities are present (tune with fail-on-vulnerability-severity).
- Malware findings are present (when fail-on-malware is true)
- At least one vulnerability is High or Critical (default fail-on-vulnerability-severity is high)
You can change the vulnerability threshold with fail-on-vulnerability-severity.
- off: never fail because of vulnerabilities
- low: fail on any vulnerability
- moderate: fail on moderate, high, or critical
- high: fail on high or critical (default)
- critical: fail only on critical
Scan a monorepo subdirectory
Set working-directory when manifests live under apps/*.
- id: scan
uses: Kazuki-tam/package-scanner-ci@v1
with:
working-directory: "apps/web"Read outputs without failing the job
Set fail-on-malware to false and fail-on-vulnerability-severity to off to keep the job green while reading outputs.
- id: scan
uses: Kazuki-tam/package-scanner-ci@v1
with:
fail-on-malware: "false"
fail-on-vulnerability-severity: "off"
- run: echo "analysis=${{ steps.scan.outputs.analysis-id }} malware=${{ steps.scan.outputs.malware-count }} vulns=${{ steps.scan.outputs.vulnerability-count }}"Post a PR comment
Example using actions/github-script to format outputs and post a comment.
- uses: actions/github-script@v7
if: github.event_name == 'pull_request'
with:
script: |
const body = [
"## PackageScanner",
`- Malware: ${{ steps.scan.outputs.malware-count }}`,
`- Low: ${{ steps.scan.outputs.vulnerability-low-count }}`,
`- Moderate: ${{ steps.scan.outputs.vulnerability-moderate-count }}`,
`- High: ${{ steps.scan.outputs.vulnerability-high-count }}`,
`- Critical: ${{ steps.scan.outputs.vulnerability-critical-count }}`,
].join("\n");
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});- Run actions/checkout before this action so files exist in the workspace
- Self-hosted runners must have node on PATH
- Node 18.17+
- Allow outbound HTTPS to https://www.package-scanner.dev
- working-directory: Base directory for resolving lockfile and package-json paths. Default: .
- lockfile: Optional explicit path; otherwise auto-detects common lockfile names.
- package-json: Optional path; defaults to package.json when present.
- package-manager: npm, pnpm, yarn, or bun when it cannot be inferred from the lockfile name.
- fail-on-malware: Exit with failure when malware is reported. Default: true.
- fail-on-vulnerability-severity: off, low, moderate, high, or critical. Default: high.
- enable-metadata-check: Enable npm registry metadata checks (requires package.json). Default: false.
- Outputs — analysis-id, malware-count, vulnerability-count, and per-severity vulnerability counts. A Markdown summary may be written to the job summary when available.
- Transmitted data can include raw lockfile/package.json contents, inferred package manager, and the enable-metadata-check flag.
- Paths must resolve inside the checked-out workspace; traversal outside the workspace is rejected.
- If your policy forbids sending private dependency contents to a third-party host, decide whether this hosted API is appropriate for your organization.
- See the repository docs (CONSUMER-GUIDE, API-SPEC) and examples/consumer-workflow.yml for more detail.