Debug sbom upload and security tag
This commit is contained in:
@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user