labels: location: manager clone: git: image: woodpeckerci/plugin-git settings: partial: false depth: 1 steps: # Run Tests test: name: test image: node:22-alpine commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apk add --no-cache curl - npm --version | cat - node --version | cat - rm -rf node_modules - if [ -f package-lock.json ]; then npm ci; else npm install; fi - npm test when: branch: main event: [push, pull_request, cron] # Check if package-lock.json needs refresh (PRs) or refresh it (cron) lockfile-check: name: lockfile-check image: node:22-alpine commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - sh scripts/refresh-lockfile.sh --check when: branch: main event: [push, pull_request] # Scan for unused code and dependencies scan-unused: name: scan-unused image: node:22-alpine depends_on: [ "test" ] commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - rm -rf node_modules - npm ci - echo "=== Scanning for unused files/exports/dependencies (knip) ===" - npx --yes knip || echo "knip found issues (non-blocking)" - echo "=== Scanning for unused npm dependencies (depcheck) ===" - npx --yes depcheck || echo "depcheck found issues (non-blocking)" when: branch: main event: [push, pull_request, cron] # SBOM for source code sbom-source: name: sbom-source image: alpine:3.20 commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apk add --no-cache curl tar - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin - syft version | cat - syft dir:. -o table | tee sbom.txt - syft dir:. -o spdx-json > sbom.spdx.json - echo "SBOM generated successfully" - ls -lh sbom.* | cat when: branch: main event: [push, pull_request, cron] # Trivy filesystem scan trivy-fs: name: trivy-fs image: aquasec/trivy:latest commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - echo "=== DEBUG: Git commit ===" - git rev-parse HEAD | cat - echo "=== DEBUG: package-lock.json exists? ===" - ls -la package-lock.json - echo "=== DEBUG: package-lock.json hash ===" - sha256sum package-lock.json | cat - echo "=== DEBUG: glob version in lockfile ===" - grep -A3 '"node_modules/glob"' package-lock.json | head -5 || echo "glob not found" - echo "=== DEBUG: mime version in lockfile ===" - grep -A3 '"node_modules/mime"' package-lock.json | head -5 || echo "mime not found" - echo "=== DEBUG: tar version in lockfile ===" - grep -A3 '"node_modules/tar"' package-lock.json | head -5 || echo "tar not found" - echo "=== DEBUG: Check for vulnerable versions ===" - grep -E '10\.4\.5|6\.2\.1|7\.4\.3|1\.2\.7' package-lock.json || echo "No vulnerable versions found" - echo "=== DEBUG: Trivy version ===" - trivy --version | cat - echo "=== Running Trivy scan with debug ===" - trivy fs --debug --scanners vuln,misconfig --severity HIGH,CRITICAL --exit-code 0 . - trivy fs --scanners vuln,misconfig --severity HIGH,CRITICAL --exit-code 0 Dockerfile when: branch: main event: [push, pull_request, cron] # Build Docker image for scanning build-image: name: build-image image: woodpeckerci/plugin-docker-buildx depends_on: [ "test" ] environment: REGISTRY_USER: from_secret: REGISTRY_USER REGISTRY_PASSWORD: from_secret: REGISTRY_PASSWORD DOCKER_REGISTRY_USER: from_secret: DOCKER_REGISTRY_USER DOCKER_REGISTRY_PASSWORD: from_secret: DOCKER_REGISTRY_PASSWORD volumes: - /var/run/docker.sock:/var/run/docker.sock commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - HOSTNAME=$(docker info --format "{{.Name}}") - echo "Building on $HOSTNAME" - echo "$${DOCKER_REGISTRY_PASSWORD}" | docker login -u "$${DOCKER_REGISTRY_USER}" --password-stdin - echo "$${REGISTRY_PASSWORD}" | docker login -u "$${REGISTRY_USER}" --password-stdin git.nixc.us - docker build -t git.nixc.us/nixius/hastebin:latest --no-cache . - docker push git.nixc.us/nixius/hastebin:latest when: branch: main event: [push, cron] # Scan Docker image with Trivy trivy-image: name: trivy-image image: aquasec/trivy:latest depends_on: [ "build-image" ] volumes: - /var/run/docker.sock:/var/run/docker.sock commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - trivy --version | cat - trivy image --timeout 10m --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 git.nixc.us/nixius/hastebin:latest when: branch: main event: [push, cron] # Generate SBOM for Docker image sbom-image: name: sbom-image image: alpine:3.20 depends_on: [ "build-image" ] volumes: - /var/run/docker.sock:/var/run/docker.sock commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apk add --no-cache curl docker-cli - curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin - syft version | cat - syft docker:git.nixc.us/nixius/hastebin:latest -o table | tee sbom-image.txt - syft docker:git.nixc.us/nixius/hastebin:latest -o spdx-json > sbom-image.spdx.json - echo "Image SBOM generated successfully" - ls -lh sbom-image.* | cat when: branch: main event: [push, cron]