Skip to content

chore(deps,actions)(deps): bump actions/setup-node from 6 to 7 #88

chore(deps,actions)(deps): bump actions/setup-node from 6 to 7

chore(deps,actions)(deps): bump actions/setup-node from 6 to 7 #88

Workflow file for this run

name: Dogfood
# Runs OWASP.WTF against this repo on every PR and push to main.
# Two jobs:
# - self-scan-cli : exercises the CLI built from PR source.
# - self-scan-action : exercises the composite action in action.yml.
# Tracked by: https://github.com/DecOperations/OWASP.WTF/issues/28
on:
push:
branches: [main]
pull_request:
branches: [main]
concurrency:
group: dogfood-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
security-events: write
pull-requests: write
actions: read
jobs:
self-scan-cli:
name: Self-scan (CLI from source)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
- uses: actions/setup-node@v7
with:
node-version: '22'
cache: 'pnpm'
registry-url: 'https://npm.pkg.github.com'
scope: '@decoperations'
- name: Install dependencies
run: pnpm install --frozen-lockfile
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build CLI
run: pnpm build
- name: Install OSS scanners (semgrep, gitleaks, trivy)
run: |
set -euo pipefail
python3 -m pip install --user semgrep
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
case "$(uname -m)" in
x86_64|amd64) arch="x64" ;;
arm64|aarch64) arch="arm64" ;;
*) echo "::error::Unsupported arch: $(uname -m)"; exit 1 ;;
esac
gl_tag="$(curl -sSfL -H 'Accept: application/vnd.github+json' \
https://api.github.com/repos/gitleaks/gitleaks/releases/latest \
| grep -oE '"tag_name":\s*"[^"]+"' | head -n1 \
| sed -E 's/.*"tag_name":\s*"([^"]+)".*/\1/')"
gl_version="${gl_tag#v}"
tmp="$(mktemp -d)"
curl -sSfL \
"https://github.com/gitleaks/gitleaks/releases/download/${gl_tag}/gitleaks_${gl_version}_${os}_${arch}.tar.gz" \
-o "$tmp/gitleaks.tar.gz"
tar -xzf "$tmp/gitleaks.tar.gz" -C "$tmp" gitleaks
sudo install -m 0755 "$tmp/gitleaks" /usr/local/bin/gitleaks
rm -rf "$tmp"
curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
| sh -s -- -b /usr/local/bin
- name: Doctor
run: node packages/cli/dist/index.js doctor || true
# Pass 1 — SARIF + binding gate (fail-on: high).
# If a baseline file exists at the repo root, findings recorded in it
# are suppressed from --fail-on grading (see #34). Today the repo is
# clean post-#36 Phase 1 so the file is absent and the gate fires on
# any new high+ finding.
- name: Scan (SARIF, binding gate)
id: scan-sarif
run: |
baseline_args=()
if [ -f owasp-baseline.json ]; then
baseline_args+=(--baseline owasp-baseline.json)
fi
node packages/cli/dist/index.js scan . \
--no-banner \
--ignore "$IGNORE_GLOBS" \
--format sarif \
--output owasp-wtf.sarif \
--fail-on high \
"${baseline_args[@]}"
env:
IGNORE_GLOBS: '**/.next/**,**/dist/**,**/out/**,**/node_modules/**,**/.turbo/**,**/coverage/**,**/.pnpm-store/**,pnpm-lock.yaml,**/test/fixtures/**'
# Pass 2 — JSON for the sticky PR comment. Observe-only so the comment
# always lands even when the gate above fired.
- name: Scan (JSON for summary)
if: always()
run: |
baseline_args=()
if [ -f owasp-baseline.json ]; then
baseline_args+=(--baseline owasp-baseline.json)
fi
node packages/cli/dist/index.js scan . \
--no-banner \
--ignore "$IGNORE_GLOBS" \
--format json \
--output owasp-wtf.json \
"${baseline_args[@]}"
env:
IGNORE_GLOBS: '**/.next/**,**/dist/**,**/out/**,**/node_modules/**,**/.turbo/**,**/coverage/**,**/.pnpm-store/**,pnpm-lock.yaml,**/test/fixtures/**'
continue-on-error: true
# Schema-validate the emitted SARIF BEFORE upload. Malformed SARIF
# is silently dropped by GitHub code scanning (shows 0 findings, no
# error) — exactly the failure mode this gate exists to prevent.
# Tracked by #17.
- name: Validate SARIF schema
if: ${{ always() && hashFiles('owasp-wtf.sarif') != '' }}
run: node packages/cli/scripts/validate-sarif.mjs owasp-wtf.sarif
- name: Upload SARIF to GitHub code scanning
if: ${{ always() && hashFiles('owasp-wtf.sarif') != '' }}
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: owasp-wtf.sarif
category: owasp-wtf-cli
- name: Upload reports
if: always()
uses: actions/upload-artifact@v7
with:
name: owasp-wtf-self-scan
path: |
owasp-wtf.sarif
owasp-wtf.json
- name: Build PR comment body
id: summary
if: ${{ github.event_name == 'pull_request' && hashFiles('owasp-wtf.json') != '' }}
env:
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
SECURITY_URL: ${{ github.server_url }}/${{ github.repository }}/security/code-scanning?query=is%3Aopen+tool%3AOWASP.WTF
run: |
node <<'NODE' > comment.md
const fs = require('fs');
const r = JSON.parse(fs.readFileSync('owasp-wtf.json', 'utf8'));
const findings = r.findings || [];
const counts = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };
for (const f of findings) {
const sev = String(f.severity || 'info').toLowerCase();
if (counts[sev] !== undefined) counts[sev]++;
}
const total = findings.length;
const score = r.score ?? 'n/a';
const top = [...findings]
.sort((a, b) => {
const order = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
return (order[a.severity] ?? 9) - (order[b.severity] ?? 9);
})
.slice(0, 5);
let out = '<!-- owasp-wtf:self-scan -->\n';
out += '## 🛡️ OWASP.WTF self-scan\n\n';
out += `**Total findings:** ${total} • **Risk score:** ${score}\n\n`;
out += '| Severity | Count |\n|---|---|\n';
for (const sev of ['critical', 'high', 'medium', 'low', 'info']) {
out += `| ${sev} | ${counts[sev]} |\n`;
}
if (top.length) {
out += '\n<details><summary>Top findings</summary>\n\n';
for (const f of top) {
const loc = f.file ? `\`${f.file}${f.line ? ':' + f.line : ''}\`` : '';
out += `- **${(f.severity || 'info').toUpperCase()}** — ${f.title || f.ruleId || 'finding'} ${loc}\n`;
}
out += '\n</details>\n';
}
out += `\n[Workflow run](${process.env.RUN_URL}) · [Code scanning results](${process.env.SECURITY_URL})\n`;
process.stdout.write(out);
NODE
- name: Upsert sticky PR comment
if: ${{ github.event_name == 'pull_request' && hashFiles('comment.md') != '' }}
uses: marocchino/sticky-pull-request-comment@v3
with:
header: owasp-wtf-self-scan
path: comment.md
self-scan-action:
name: Self-scan (composite action)
runs-on: ubuntu-latest
# Disabled until cli-v0.2.3+ is published. The action installs the CLI
# from a release tarball asset (added in PR #26); releases predating that
# rollout (≤ cli-v0.2.2) don't carry the asset and the install step fails
# by design. Re-enable by removing this `if:` once the next release ships
# from main — tracked in issue #28.
if: false
steps:
- uses: actions/checkout@v6
- name: Run OWASP.WTF action against this repo
uses: ./
with:
mode: scan
format: sarif
output: owasp-wtf-action.sarif
fail-on: ''
ignore: '**/.next/**,**/dist/**,**/out/**,**/node_modules/**,**/.turbo/**,**/coverage/**,**/.pnpm-store/**,pnpm-lock.yaml,**/test/fixtures/**'
install-tools: 'semgrep,gitleaks,trivy'
upload-sarif: 'true'
artifact-name: owasp-wtf-action-report
env:
# The local action installs the CLI from a release asset.
# Provide the workflow token so private-repo scenarios work too.
GH_TOKEN: ${{ github.token }}