# Woodpecker CI configuration for camera-trng # Builds binaries for Linux (x86_64, aarch64) and pushes Docker image # Image: git.nixc.us/colin/camera-trng:latest labels: location: manager clone: git: image: woodpeckerci/plugin-git settings: partial: false depth: 1 steps: # ============================================ # Build and Test # ============================================ test: name: test image: rust:1.75-bookworm commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apt-get update && apt-get install -y --no-install-recommends libv4l-dev libudev-dev pkg-config - rustc --version | cat - cargo --version | cat - cargo check --locked - cargo test --locked - cargo build --release --locked - ls -lh target/release/camera-trng | cat || true when: branch: master event: [push, pull_request, cron] # ============================================ # Build Linux x86_64 release binary # ============================================ build-linux-x86_64: name: build-linux-x86_64 image: rust:1.75-bookworm depends_on: [test] commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apt-get update && apt-get install -y --no-install-recommends libv4l-dev libudev-dev pkg-config - rustup target add x86_64-unknown-linux-gnu - cargo build --release --locked --target x86_64-unknown-linux-gnu - mkdir -p dist - cp target/x86_64-unknown-linux-gnu/release/camera-trng dist/camera-trng-linux-x86_64 - chmod +x dist/camera-trng-linux-x86_64 - ls -lh dist/ | cat - sha256sum dist/* | tee dist/checksums-x86_64.txt when: branch: master event: [push, tag] # ============================================ # Build Linux aarch64 release binary (cross-compile) # ============================================ build-linux-aarch64: name: build-linux-aarch64 image: rust:1.75-bookworm depends_on: [test] failure: ignore commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apt-get update && apt-get install -y --no-install-recommends gcc-aarch64-linux-gnu libc6-dev-arm64-cross pkg-config - rustup target add aarch64-unknown-linux-gnu - | mkdir -p ~/.cargo cat > ~/.cargo/config.toml << 'EOF' [target.aarch64-unknown-linux-gnu] linker = "aarch64-linux-gnu-gcc" EOF - export PKG_CONFIG_ALLOW_CROSS=1 - export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc # Note: Cross-compiling with native camera deps is complex; this may fail - cargo build --release --locked --target aarch64-unknown-linux-gnu || echo "aarch64 cross-compile failed (expected due to native deps)" - mkdir -p dist - cp target/aarch64-unknown-linux-gnu/release/camera-trng dist/camera-trng-linux-aarch64 2>/dev/null || echo "aarch64 binary not available" - ls -lh dist/ | cat || true when: branch: master event: [push, tag] # ============================================ # Cargo audit for known vulnerabilities # ============================================ cargo-audit: name: cargo-audit image: rust:1.75-bookworm commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - cargo install cargo-audit - cargo audit --json | tee cargo-audit.json - cargo audit || true when: branch: master event: [push, pull_request, cron] # ============================================ # SBOM for source code (Rust/Cargo) # ============================================ 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 - echo "=== Scanning Cargo.lock for dependencies ===" - syft dir:. -o table | tee sbom.txt - syft dir:. -o spdx-json > sbom.spdx.json - syft dir:. -o cyclonedx-json > sbom.cyclonedx.json - echo "SBOM generated successfully" - ls -lh sbom.* | cat when: branch: master 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 - trivy --version | cat - echo "=== Scanning filesystem for vulnerabilities ===" - trivy fs --scanners vuln,misconfig,secret --severity HIGH,CRITICAL --exit-code 0 . - echo "=== Scanning Cargo.lock for dependency vulnerabilities ===" - trivy fs --scanners vuln --severity HIGH,CRITICAL --exit-code 0 Cargo.lock when: branch: master event: [push, pull_request, cron] # ============================================ # Clippy linting # ============================================ clippy: name: clippy image: rust:1.75-bookworm commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - apt-get update && apt-get install -y --no-install-recommends libv4l-dev libudev-dev pkg-config - rustup component add clippy - cargo clippy --locked -- -D warnings || true when: branch: master event: [push, pull_request, cron] # ============================================ # Format check # ============================================ fmt-check: name: fmt-check image: rust:1.75-bookworm commands: - echo "nameserver 1.1.1.1" > /etc/resolv.conf - echo "nameserver 1.0.0.1" >> /etc/resolv.conf - rustup component add rustfmt - cargo fmt --check when: branch: master event: [push, pull_request, cron] # ============================================ # Build and push Docker image to git.nixc.us/colin/camera-trng # ============================================ 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 # Build with cache and tag with commit SHA - docker build -t git.nixc.us/colin/camera-trng:latest -t git.nixc.us/colin/camera-trng:${CI_COMMIT_SHA:0:8} . - docker push git.nixc.us/colin/camera-trng:latest - docker push git.nixc.us/colin/camera-trng:${CI_COMMIT_SHA:0:8} - echo "Pushed git.nixc.us/colin/camera-trng:latest" - echo "Pushed git.nixc.us/colin/camera-trng:${CI_COMMIT_SHA:0:8}" when: branch: master event: [push, cron] # ============================================ # Build and push tagged release image # ============================================ build-image-tag: name: build-image-tag 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 - 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/colin/camera-trng:${CI_COMMIT_TAG} -t git.nixc.us/colin/camera-trng:latest . - docker push git.nixc.us/colin/camera-trng:${CI_COMMIT_TAG} - docker push git.nixc.us/colin/camera-trng:latest - echo "Pushed git.nixc.us/colin/camera-trng:${CI_COMMIT_TAG}" when: event: tag # ============================================ # 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/colin/camera-trng:latest when: branch: master 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/colin/camera-trng:latest -o table | tee sbom-image.txt - syft docker:git.nixc.us/colin/camera-trng:latest -o spdx-json > sbom-image.spdx.json - echo "Image SBOM generated successfully" - ls -lh sbom-image.* | cat when: branch: master event: [push, cron]