Debug sbom upload and security tag

This commit is contained in:
2025-07-03 09:32:35 -06:00
parent 86eba16061
commit 08bcc0eecb

View File

@ -14,180 +14,218 @@ env:
jobs: jobs:
# Job 1: Lint and Test # Job 1: Lint and Test
# test: test:
# name: 🧪 Test & Lint name: 🧪 Test & Lint
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - name: Checkout code - name: Checkout code
# uses: actions/checkout@v4 uses: actions/checkout@v4
# - name: Setup Node.js - name: Setup Node.js
# uses: actions/setup-node@v4 uses: actions/setup-node@v4
# with: with:
# node-version: ${{ env.NODE_VERSION }} node-version: ${{ env.NODE_VERSION }}
# cache: 'npm' cache: 'npm'
# - name: Install dependencies - name: Install dependencies
# run: npm ci run: npm ci
# - name: Run linting - name: Run linting
# run: npm run lint run: npm run lint
# - name: Run tests - name: Run tests
# run: npm run test:coverage run: npm run test:coverage
# - name: Upload test results - name: Upload test results
# uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
# if: always() if: always()
# with: with:
# name: test-results name: test-results
# path: | path: |
# coverage/ coverage/
# test-results.xml test-results.xml
# # Job 2: Security Scan # Job 2: Security Scan
# security: security:
# name: 🔒 Security Scan name: 🔒 Security Scan
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - name: Checkout code - name: Checkout code
# uses: actions/checkout@v4 uses: actions/checkout@v4
# - name: Setup Node.js - name: Setup Node.js
# uses: actions/setup-node@v4 uses: actions/setup-node@v4
# with: with:
# node-version: ${{ env.NODE_VERSION }} node-version: ${{ env.NODE_VERSION }}
# cache: 'npm' cache: 'npm'
# - name: Install dependencies - name: Install dependencies
# run: npm ci run: npm ci
# - name: Run security audit - name: Run security audit
# run: npm audit --audit-level=high run: npm audit --audit-level=high
# - name: Check for vulnerabilities - name: Check for vulnerabilities
# run: | run: |
# if npm audit --audit-level=moderate --json | jq '.vulnerabilities | length' | grep -v '^0$'; then if npm audit --audit-level=moderate --json | jq '.vulnerabilities | length' | grep -v '^0$'; then
# echo "Vulnerabilities found!" echo "Vulnerabilities found!"
# npm audit --audit-level=moderate npm audit --audit-level=moderate
# exit 1 exit 1
# fi fi
# Job 3: Build and Push Docker Image # Job 3: Build and Push Docker Image
build: build:
name: 🏗️ Build & Push Image name: 🏗️ Build & Push Image
runs-on: ubuntu-latest runs-on: ubuntu-latest
# needs: [test, security] outputs:
digest: ${{ steps.build.outputs.digest }}
needs: [test, security]
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
# outputs: outputs:
# image-tag: ${{ steps.meta.outputs.tags }} image-tag: ${{ steps.meta.outputs.tags }}
# image-digest: ${{ steps.build.outputs.digest }} image-digest: ${{ steps.build.outputs.digest }}
steps: steps:
# - name: Checkout code - name: Checkout code
# uses: actions/checkout@v4 uses: actions/checkout@v4
# - name: Set up Docker Buildx - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
# - name: Login to Harbor Registry - name: Login to Harbor Registry
# uses: docker/login-action@v3 uses: docker/login-action@v3
# with: with:
# registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
# username: ${{ secrets.HARBOR_USERNAME }} username: ${{ secrets.HARBOR_USERNAME }}
# password: ${{ secrets.HARBOR_TOKEN }} password: ${{ secrets.HARBOR_TOKEN }}
# - name: Extract metadata - name: Extract metadata
# id: meta id: meta
# uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
# with: with:
# images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# tags: | tags: |
# type=ref,event=branch type=ref,event=branch
# type=ref,event=pr type=ref,event=pr
# type=sha,prefix={{branch}}- type=sha,prefix={{branch}}-
# type=raw,value=latest,enable={{is_default_branch}} type=raw,value=latest,enable={{is_default_branch}}
# type=raw,value={{date 'YYYYMMDD-HHmmss'}} type=raw,value={{date 'YYYYMMDD-HHmmss'}}
# - name: Build and push Docker image - name: Build and push Docker image
# id: build id: build
# uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
# with: with:
# context: . context: .
# platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
# push: true push: true
# tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
# labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
# cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
# cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Generate SBOM - name: Generate SBOM
run: | run: |
# Install syft # Install syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
echo "${{ secrets.HARBOR_TOKEN }}"
echo "${{ env.REGISTRY }}"
echo "${{ secrets.HARBOR_USERNAME }}"
echo "${{ env.IMAGE_NAME }}"
# Login to registry - use the REGISTRY variable for the URL # Login to registry - use the REGISTRY variable for the URL
echo "${{ secrets.HARBOR_TOKEN }}" | docker login ${{ env.REGISTRY }} -u '${{ secrets.HARBOR_USERNAME }}' --password-stdin echo "${{ secrets.HARBOR_TOKEN }}" | docker login ${{ env.REGISTRY }} -u '${{ secrets.HARBOR_USERNAME }}' --password-stdin
# Generate SBOM using latest tag # Generate SBOM using latest tag
syft ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest -o spdx-json > sbom.spdx.json syft ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest -o spdx-json > sbom.spdx.json
# Verify SBOM was created # Verify SBOM was created
if [ ! -f sbom.spdx.json ]; then if [ ! -f sbom.spdx.json ]; then
echo "Failed to generate SBOM" echo "Failed to generate SBOM"
exit 1 exit 1
fi fi
echo "SBOM generated successfully" echo "SBOM generated successfully"
- name: Upload SBOM to Harbor - name: Attach SBOM to Docker image
run: | run: |
# Install ORAS # Install ORAS
curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz
tar -xzf oras_1.1.0_linux_amd64.tar.gz tar -xzf oras_1.1.0_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/ sudo mv oras /usr/local/bin/
# Push SBOM as an artifact to Harbor # Get the image digest from the build step
oras push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-sbom \ IMAGE_DIGEST="${{ steps.build.outputs.digest }}"
# Attach SBOM to the specific image digest
oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \
--artifact-type application/spdx+json \ --artifact-type application/spdx+json \
sbom.spdx.json:application/spdx+json sbom.spdx.json:application/spdx+json
echo "SBOM uploaded successfully to Harbor" echo "SBOM attached successfully to image digest: ${IMAGE_DIGEST}"
# Job 4: Image Security Scan # Job 4: Image Security Scan
# scan: scan:
# name: 🛡️ Image Security Scan name: 🛡️ Image Security Scan
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# needs: build needs: build
# if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
# steps: steps:
# - name: Login to Harbor Registry - name: Login to Harbor Registry
# uses: docker/login-action@v3 uses: docker/login-action@v3
# with: with:
# registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
# username: ${{ secrets.HARBOR_USERNAME }} username: ${{ secrets.HARBOR_USERNAME }}
# password: ${{ secrets.HARBOR_TOKEN }} password: ${{ secrets.HARBOR_TOKEN }}
# - name: Run Trivy vulnerability scanner - name: Run Trivy vulnerability scanner
# uses: aquasecurity/trivy-action@master uses: aquasecurity/trivy-action@master
# with: with:
# image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# format: 'sarif' format: 'sarif'
# output: 'trivy-results.sarif' output: 'trivy-results.sarif'
# - name: Upload Trivy scan results - name: Generate JSON scan results
# uses: actions/upload-artifact@v3 uses: aquasecurity/trivy-action@master
# with: with:
# name: trivy-scan-results image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# path: trivy-results.sarif format: 'json'
output: 'trivy-results.json'
# - name: Check for HIGH/CRITICAL vulnerabilities - name: Upload scan results artifacts
# uses: aquasecurity/trivy-action@master uses: actions/upload-artifact@v3
# with: with:
# image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} name: trivy-scan-results
# format: 'json' path: |
# output: 'trivy-results.json' trivy-results.sarif
# exit-code: '1' trivy-results.json
# severity: 'HIGH,CRITICAL'
- name: Attach scan results to Harbor image
run: |
# Install ORAS
curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz
tar -xzf oras_1.1.0_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/
# Get the image digest from the build job
IMAGE_DIGEST="${{ needs.build.outputs.digest }}"
# Attach SARIF scan results
oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \
--artifact-type application/sarif+json \
trivy-results.sarif:application/sarif+json
# Attach JSON scan results
oras attach ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${IMAGE_DIGEST} \
--artifact-type application/json \
trivy-results.json:application/json \
--annotation "scan.type=vulnerability" \
--annotation "scan.tool=trivy"
echo "Scan results attached successfully to image digest: ${IMAGE_DIGEST}"
- name: Check for HIGH/CRITICAL vulnerabilities
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
format: 'json'
output: 'trivy-critical.json'
exit-code: '1'
severity: 'HIGH,CRITICAL'
# # Job 5: Deploy to Development # # Job 5: Deploy to Development
# deploy-dev: # deploy-dev: