Skip to content

docs: update badge

docs: update badge #79

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
name: Test & Lint
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
statuses: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Node.js
uses: actions/setup-node@b789df37d6b7526a863bf51b65df64f3f56ffe4f # v7
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Run lint
run: npm run lint
- name: Run tests
run: npm run test:ci
- name: Run tests with coverage
run: npm run test:coverage
- name: Run build
run: npm run build
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f
with:
token: ${{ secrets.CODECOV_TOKEN }}
semgrep:
name: Semrep (SAST)
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
statuses: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Get week number for cache key
id: week
run: echo "week=$(date +%V)" >> $GITHUB_OUTPUT
- name: Cache Semgrep
id: cache-semgrep
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v7
with:
path: |
~/.cache/pip
~/.semgrep/
# Expires weekly — matches Dependabot cadence
key: semgrep-${{ runner.os }}-${{ steps.week.outputs.week }}
- name: Install Semgrep
# Always runs — ~/.cache/pip only caches downloads, not the binary itself.
# On cache hit, pip uses cached .whl files (~1 sec); on miss, downloads fresh.
run: python3 -m pip install semgrep
- name: Semgrep SAST
# Skip .github/ — CI workflow YAML is not application code
run: semgrep scan --config auto --error --exclude .github
trivy:
name: Trivy (SCA)
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
statuses: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@c07df6fec6fa692e6fd1200d50aaa1fdd66f03c8 # v0.36.0
with:
scan-type: "fs"
scan-ref: "."
scanners: "vuln"
format: "table"
severity: "CRITICAL,HIGH"
exit-code: 1
# dependency-review:
#name: Dependency Review
#if: github.event_name == 'pull_request'
#runs-on: ubuntu-latest
#permissions:
#contents: read
#pull-requests: write
#
#steps:
#- name: Checkout
#uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
#
#- name: Dependency Review
#uses: actions/dependency-review-action@1e966ba708e4b64bb0c9bfb7abb5a232840be16a # v5.0
#with:
# Fail on critical & high — warn on everything else
#fail-on-severity: high
# Allow these licenses for Angular ecosystem
#allow-licenses: >-
#MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD,
#CC0-1.0, Unlicense, Python-2.0, Zlib
gitleaks:
name: Gitleaks (Secrets)
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
statuses: write
steps:
- name: Checkout
uses: actions/checkout@f548e57e544e1ff5a4c46bf1e1b8685f8e4a348a # v7.0.1
with:
fetch-depth: 0 # Gitleaks needs full git history
- name: Gitleaks secret scan
uses: gitleaks/gitleaks-action@bcfb9cce635345aac9996cedc19b2de8e01b894f
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
sonarcloud:
name: SonarCloud (Deep SAST)
# The SonarCloud action handles missing tokens gracefully
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # SonarCloud needs full git history
- name: Setup Node.js
uses: actions/setup-node@b789df37d6b7526a863bf51b65df64f3f56ffe4f # v7
with:
node-version: 24
cache: npm
cache-dependency-path: package-lock.json
- name: Install dependencies
run: npm ci --legacy-peer-deps
- name: Generate coverage report
run: npm run test:coverage
- name: SonarCloud Scan
uses: sonarsource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1 nosemgrep:generic.secrets.security.detected-sonarqube-docs-api-key
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Vercel:
name: Notify Vercel
if: always()
needs: [test, semgrep, trivy, sonarcloud, gitleaks]
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
statuses: write
steps:
- name: Notify Vercel
uses: vercel/repository-dispatch/actions/status@30f760c6640485cd92f8c785ef361382555fb712 # v1
with:
# Must match the check name configured in Vercel Deployment Checks
name: "Vercel - stephulz-portfolio: coverage"
github_token: ${{ secrets.GITHUB_TOKEN }}
# Fail the job if any upstream dependency failed — this makes the
# vercel/repository-dispatch post-action report failure to Vercel.
- name: Propagate upstream failure
if: >-
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: |
echo "❌ Some checks failed — notifying Vercel of failure"
echo "test: ${{ needs.test.result }}"
echo "semgrep: ${{ needs.semgrep.result }}"
echo "trivy: ${{ needs.trivy.result }}"
echo "gitleaks: ${{ needs.gitleaks.result }}"
exit 1