Skip to content

Java CI with Maven

Java CI with Maven #59

Workflow file for this run

# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
#push:
#branches: [ main ]
#pull_request:
#branches: [ main ]
workflow_dispatch:
jobs:
build:
permissions:
security-events: write
id-token: write
contents: read
attestations: write
packages: write
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '17' ]
# outputs:
# my_output: ${{ steps.generate_sbom.outputs.result }}
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'adopt'
cache: maven
- name: Build with Maven Wrapper
run: |
pwd
./mvnw -B package > app.jar
# - uses: actions/checkout@v4
# with:
# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
- name: Generate artifact attestation
uses: actions/attest-build-provenance@v1
# outputs:
# Attestation:
with:
subject-path: ./app.jar
- name: verify jar attesttion
env:
GH_TOKEN: ${{secrets.GH_TOKEN}}
run: |
# gh attestation download app.jar -o github
# wget https://github.com/saurav631/spring-petclinic/attestations/1598170/download -o sigstore.json
# gh attestation verify github --owner saurav631 --bundle sigstore.json
# gh attestation verify app.jar --owner saurav631 --bundle ./saurav631-spring-petclinic-attestation-1598170.sigstore.json --format=json
gh attestation verify app.jar --owner saurav631 --format=json
# gh attestation verify app.jar --owner saurv631 --bundle application/vnd.dev.sigstore.bundle.v0.3+json --format=json
# gh attestation verify sigstore.json --owner saurav631 --format=json
# - name: Set up JDK 17
# uses: actions/setup-java@v1
# with:
# java-version: 17
# - name: Cache SonarQube packages
# uses: actions/cache@v1
# with:
# path: ~/.sonar/cache
# key: ${{ runner.os }}-sonar
# restore-keys: ${{ runner.os }}-sonar
# - name: Cache Maven packages
# uses: actions/cache@v1
# with:
# path: ~/.m2
# key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
# restore-keys: ${{ runner.os }}-m2
# - name: Build and analyze
# env:
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# SONAR_HOST_URL: http://20.235.200.36:9000/
# run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=PetClinic -Dsonar.projectName='PetClinic'
# - name: Check SonarQube Quality Gate
# run: |
# sleep 10
# STATUS=$(curl -s -u ${{ secrets.SONAR_TOKEN }} "http://20.235.200.36:9000/api/qualitygates/project_status?projectKey=PetClinic" | jq -r '.projectStatus.status')
# echo "Quality Gate Status: $STATUS"
# if [ "$STATUS" != "OK" ]; then
# echo "SonarQube Quality Gate failed"
# exit 1
# fi
# - name: Install & Running TruffleHog
# run: |
# pip install truffleHog
# trufflehog git_url https://github.com/saurav631/spring-petclinic/ --repo_path .
- name: Install Syft
run: |
curl -sSL https://github.com/anchore/syft/releases/download/v0.66.0/syft_0.66.0_linux_amd64.tar.gz | tar xz -C /usr/local/bin syft
- name: Generate SBOM with Syft
# id: generate_sbom
run: |
# echo "result=`syft dir:. -o cyclonedx-json > sbom.json`" >> $GITHUB_ENV
syft dir:. -o cyclonedx-json > sbom.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
- name: Generate SBOM attestation
uses: actions/attest-sbom@v1
with:
subject-path: ./sbom.json
sbom-path: ./sbom.json
- name: verify SBOM attesttion
env:
GH_TOKEN: ${{secrets.GH_TOKEN}}
run: |
# gh attestation verify sbom.json --owner saurav631 --bundle ./sbom.json
gh attestation verify ./sbom.json --owner saurav631 --format=json
# gh attestation verify app.jar --owner saurav631 --format=json
# gh attestation verify sbom.json --owner saurav631 --bundle ./saurav631-spring-petclinic-attestation-1599265.sigstore.json
# - name: Dependency Scanning with OWASP Dependency-Check
# run: |
# /opt/dependency-check/bin/dependency-check.sh --project my_project --out dependency-check-report --scan .
# - name: Upload Dependency Check Report
# uses: actions/upload-artifact@v3
# with:
# name: dependency-check-report
# path: dependency-check-report
# - name: Scan Docker Images for Vulnerabilities
# run: |
# sudo apt-get update
# sudo apt-get install -y docker.io
# sudo systemctl start docker
# sudo systemctl enable docker
# curl -sSL https://github.com/aquasecurity/trivy/releases/download/v0.36.0/trivy_0.36.0_Linux-64bit.deb -o trivy.deb
# sudo dpkg -i trivy.deb
# trivy image my_microservice:latest
# - name: Deploy Microservices
# run: |
# kubectl apply -f k8s/deployment.yaml
- name: Build Docker Image
run: ./mvnw spring-boot:build-image
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
# username: ${{ secrets.CR_Username }}
username: ${{ github.actor }}
# password: ${{ secrets.CR_Password }}
password: ${{secrets.GH_TOKEN}}
registry: ghcr.io
- name: Tag Docker Image
run: |
docker tag docker.io/library/spring-petclinic:3.3.0-SNAPSHOT ghcr.io/saurav631/spring-petclinic:latest
- name: Push Docker Image
run: |
docker push ghcr.io/saurav631/spring-petclinic:latest
- name: Run Trivy Vulnerability Scanner
uses: aquasecurity/trivy-action@7b7aa264d83dc58691451798b4d117d53d21edfe
with:
image-ref: 'ghcr.io/saurav631/spring-petclinic:latest'
format: 'template'
template: '@/contrib/sarif.tpl'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload Trivy Scan Results to GitHub Security Tab
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'
sign:
name: Sign Container Image
runs-on: ubuntu-latest
needs: build
steps:
- name: Check Out Source Code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Download file artifact
uses: actions/download-artifact@v4
with:
name: sbom
- name: Log in to GitHub Container Registry
uses: docker/login-action@v2
with:
# username: ${{ secrets.CR_Username }}
username: ${{github.actor}}
# password: ${{ secrets.CR_Password }}
password: ${{secrets.GH_TOKEN}}
registry: ghcr.io
# - name: Install Cosign CLI
# run: |
# curl -sSL -o /usr/local/bin/cosign https://github.com/sigstore/cosign/releases/download/v2.1.1/cosign-linux-amd64
# chmod +x /usr/local/bin/cosign
# cosign version
- name: Install Cosign CLI
run: |
curl -sSL -o /usr/local/bin/cosign https://github.com/sigstore/cosign/releases/download/v2.2.3/cosign-linux-amd64
chmod +x /usr/local/bin/cosign
cosign version
# - name: Create Decrypted Signing Key File
# run: |
# echo "${{ secrets.COSIGN_KEY }}" > cosign.key
# - name: Sign Docker Image with Cosign
# run: |
# cosign sign --key cosign.key ghcr.io/saurav631/spring-petclinic:latest
- name: sign container image
run: |
cosign sign --key env://COSIGN_KEY ghcr.io/saurav631/spring-petclinic:latest --yes
shell: bash
env:
COSIGN_KEY: ${{secrets.Cosign_Key}}
COSIGN_PASSWORD: ${{secrets.Cosign_Key_Password}}
# - name: Create Public Key File_
# run: echo "${{ secrets.Cosign_Pub }}" > cosign.pub
- name: Public Key Creation
run: |
cosign public-key --key env://COSIGN_KEY > cosign.pub
shell: bash
env:
COSIGN_KEY: ${{secrets.Cosign_Key}}
COSIGN_PASSWORD: ${{secrets.Cosign_Key_Password}}
- name: Verify Docker Image Signature
run: |
cosign verify --key cosign.pub ghcr.io/saurav631/spring-petclinic:latest #--insecure-ignore-tlog #--check-claims=false
- name: Attach SBOM
id: attach-sbom
run: |
set -e # Exit on error
# Run the cosign attach sbom command and capture its output
# echo "sbom: ${{ needs.build.outputs.my_output }}"
# output=$(cosign attach sbom --sbom ${{ needs.build.outputs.my_output }} ghcr.io/saurav631/spring-petclinic:latest) || { echo "Failed to run cosign attach sbom"; exit 1; }
# output=$(cosign attach sbom --sbom sbom.json ghcr.io/saurav631/spring-petclinic:latest) || { echo "Failed to run cosign attach sbom"; exit 1; }
output=$(cosign attach sbom --sbom sbom.json ghcr.io/saurav631/spring-petclinic:latest 2>&1) || { echo "Failed to run cosign attach sbom"; exit 1; }
# output=$(cosign attach sbom --sbom sbom.json ghcr.io/saurav631/spring-petclinic:latest) || { echo "Failed to run cosign attach sbom"; exit 1; }
# cosign attest --predicate <FILE> --type <TYPE> --key cosign.key <IMAGE>
echo "cat output --> showing output below"
echo "$output"
# Extract the SHA from the output
sbom_filename=$(echo "$output" | grep -oP 'sha256-[\w\d]+\.sbom') || { echo "Failed to extract SBOM filename"; exit 1; }
echo "$sbom_filename"
# Check if the extraction was successful
if [ -z "$sbom_filename" ]; then
echo "Error: No SBOM filename found in the output"
exit 1
fi
# Set the extracted SHA as an environment variable
echo "SBOM_FILENAME=$sbom_filename" >> $GITHUB_ENV
- name: Sign the SBOM attached with the Image
run: |
set -e # Exit on error
# Use the environment variable to construct the command
if [ -z "$SBOM_FILENAME" ]; then
echo "Error: SBOM_FILENAME environment variable is not set"
exit 1
fi
echo "Signing SBOM with filename: $SBOM_FILENAME"
cosign sign --key env://COSIGN_KEY ghcr.io/saurav631/spring-petclinic:$SBOM_FILENAME --yes || { echo "Failed to sign with SBOM"; exit 1; }
shell: bash
env:
COSIGN_KEY: ${{secrets.Cosign_Key}}
COSIGN_PASSWORD: ${{secrets.Cosign_Key_Password}}
- name: Verify Sign of SBOM attached with the Image
run: |
set -e # Exit on error
cosign verify --key cosign.pub ghcr.io/saurav631/spring-petclinic:$SBOM_FILENAME || { echo "Failed to verify SBOM Sign"; exit 1; }
- name: Directly attest SBOM with the Image
run: |
set -e # Exit on error
output=$(cosign attest --key env://COSIGN_KEY --type cyclonedx --predicate sbom.json ghcr.io/saurav631/spring-petclinic:latest --yes 2>&1) || { echo "Failed to attest sbom with the image"; exit 1; }
echo "$output"
shell: bash
env:
COSIGN_KEY: ${{secrets.Cosign_Key}}
COSIGN_PASSWORD: ${{secrets.Cosign_Key_Password}}
- name: Verfiy the attested Image
run: |
set -e # Exit on error
output1=$(cosign verify-attestation --key cosign.pub ghcr.io/saurav631/spring-petclinic:latest | jq -r .payload | base64 -D | jq . 2>&1) || { echo "Failed to verify the attested image"; exit 1; }
echo "output: $output1"