feat: add github job summary #10
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: 1. Non-production deployment | |
env: | |
IMAGE_NAME: ghcr.io/opsta/opsta-linebot | |
on: | |
push: | |
paths-ignore: | |
- 'README.md' | |
- 'Makefile' | |
- 'docker-compose.yml' | |
- '.gitignore' | |
- 'requirements-orig-*.txt' | |
- '.devcontainer/**' | |
- 'iac/**' | |
branches: | |
- 'main' | |
jobs: | |
setup: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Set DEPLOY_ENV | |
run: | | |
if [[ ${{ github.ref_name }} == 'main' || ${{ github.ref_name }} == 'master' ]]; then | |
# You can change this to uat for main/master branch in case of you have more than dev and production environment | |
echo "DEPLOY_ENV=dev" >> "$GITHUB_ENV" | |
else | |
echo "DEPLOY_ENV=${{ github.ref_name }}" >> "$GITHUB_ENV" | |
fi | |
- name: Docker meta | |
id: meta | |
uses: docker/metadata-action@v5 | |
with: | |
# list of Docker images to use as base name for tags | |
images: ${{ env.IMAGE_NAME }} | |
# generate Docker tags based on the following events/attributes | |
tags: | | |
# branch event | |
type=ref,event=branch | |
# tag edge on default branch | |
type=edge | |
# dynamically set the branch name as a prefix | |
type=sha,prefix=${{ env.DEPLOY_ENV }}-,priority=750 | |
# For use in other jobs | |
outputs: | |
tags: "${{ steps.meta.outputs.tags }}" | |
labels: "${{ steps.meta.outputs.labels }}" | |
version: "${{ steps.meta.outputs.version }}" | |
deploy_env: "${{ env.DEPLOY_ENV }}" | |
sonarqube: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
# Disabling shallow clones is recommended for improving the relevancy of reporting | |
fetch-depth: 0 | |
- name: SonarQube Scan | |
uses: sonarsource/sonarqube-scan-action@v3 | |
with: | |
args: > | |
-D sonar.organization=${{ secrets.SONARQUBE_ORG }} | |
-D sonar.projectKey=${{ github.event.repository.name }} | |
-D sonar.sources=. | |
-D sonar.qualitygate.wait=true | |
-D sonar.python.version=3.12 | |
env: | |
SONAR_TOKEN: ${{ secrets.SONARQUBE_TOKEN }} | |
SONAR_HOST_URL: ${{ secrets.SONARQUBE_HOST }} | |
- name: Create SonarQube Report for DefectDojo | |
if: always() | |
run: | | |
# Install Sonar Report | |
mkdir -p ~/.local/bin | |
npm config set prefix '~/.local/' | |
npm install --global [email protected] | |
# Always run SAST Report from SonarQube | |
export PATH=~/.local/bin/:$PATH | |
# On SonarQube Community edition, you only can use main branch | |
sonar-report \ | |
--sonarorganization="${{ secrets.SONARQUBE_ORG }}" \ | |
--sonarurl="${{ secrets.SONARQUBE_HOST }}" \ | |
--sonartoken="${{ secrets.SONARQUBE_TOKEN }}" \ | |
--sonarcomponent="${{ github.event.repository.name }}" \ | |
--project="${{ github.event.repository.name }}" \ | |
--application="${{ github.event.repository.name }}" \ | |
--release="${{ needs.setup.outputs.version }}" \ | |
--output="sonar-report.html" \ | |
--branch="main" | |
- name: Upload Sonar Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: sonar-report | |
path: sonar-report.html | |
retention-days: 1 | |
trivy-sca-report: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Generate Trivy SCA Vulnerability Report | |
uses: aquasecurity/[email protected] | |
with: | |
scan-type: "fs" | |
scan-ref: . | |
scanners: 'vuln,license' | |
format: json | |
output: trivy-sca-report.json | |
- name: Upload Trivy SCA Report | |
uses: actions/upload-artifact@v4 | |
with: | |
name: trivy-sca-report | |
path: trivy-sca-report.json | |
retention-days: 1 | |
trivy-sca-security-gate: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Trivy SCA Vulnerability Fail Gate | |
uses: aquasecurity/[email protected] | |
with: | |
scan-type: "fs" | |
scan-ref: . | |
scanners: 'vuln,license' | |
severity: 'MEDIUM,HIGH,CRITICAL' | |
format: table | |
exit-code: 1 | |
trivy-iac-report: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install Helm | |
uses: azure/setup-helm@v4 | |
- name: Generate Kubernetes Manifest files with Helm Template | |
run: | | |
helm template -f iac/helm-values/${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }}.yaml \ | |
${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }} oci://ghcr.io/gimlet-io/onechart --version 0.73.0 \ | |
> iac/${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }}-manifest.yaml | |
- name: Generate Trivy IaC Vulnerability Report | |
uses: aquasecurity/[email protected] | |
with: | |
scan-type: "fs" | |
scan-ref: . | |
scanners: 'misconfig,secret' | |
format: json | |
output: trivy-iac-report.json | |
- name: Upload Trivy IaC Report | |
uses: actions/upload-artifact@v4 | |
with: | |
name: trivy-iac-report | |
path: trivy-iac-report.json | |
retention-days: 1 | |
trivy-iac-security-gate: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Install Helm | |
uses: azure/setup-helm@v4 | |
- name: Generate Kubernetes Manifest files with Helm Template | |
run: | | |
helm template -f iac/helm-values/${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }}.yaml \ | |
${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }} oci://ghcr.io/gimlet-io/onechart --version 0.73.0 \ | |
> iac/${{ github.event.repository.name }}-${{ needs.setup.outputs.deploy_env }}-manifest.yaml | |
- name: Trivy IaC Vulnerability Fail Gate | |
uses: aquasecurity/[email protected] | |
with: | |
scan-type: "fs" | |
scan-ref: . | |
scanners: 'misconfig,secret' | |
severity: 'MEDIUM,HIGH,CRITICAL' | |
format: table | |
exit-code: 1 | |
build-push: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Login to Docker Hub | |
if: github.event_name != 'pull_request' | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build and push | |
uses: docker/build-push-action@v6 | |
with: | |
context: . | |
push: ${{ github.event_name != 'pull_request' }} | |
tags: ${{ needs.setup.outputs.tags }} | |
labels: ${{ needs.setup.outputs.labels }} | |
cache-to: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache,mode=max | |
cache-from: type=registry,ref=${{ env.IMAGE_NAME }}:buildcache | |
env: | |
DOCKER_BUILD_RECORD_UPLOAD: false | |
trivy-image-report: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
- build-push | |
steps: | |
- name: Generate Trivy Image Vulnerability Report | |
uses: aquasecurity/[email protected] | |
with: | |
image-ref: "${{ env.IMAGE_NAME }}:${{ needs.setup.outputs.version }}" | |
scanners: 'vuln,misconfig,secret' | |
format: json | |
output: trivy-image-report.json | |
env: | |
TRIVY_USERNAME: ${{ github.actor }} | |
TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} | |
- name: Upload Trivy Image Report | |
uses: actions/upload-artifact@v4 | |
with: | |
name: trivy-image-report | |
path: trivy-image-report.json | |
retention-days: 1 | |
trivy-image-security-gate: | |
runs-on: ubuntu-latest | |
needs: | |
- setup | |
- build-push | |
steps: | |
- name: Trivy Image Vulnerability Fail Gate | |
uses: aquasecurity/[email protected] | |
with: | |
image-ref: "${{ env.IMAGE_NAME }}:${{ needs.setup.outputs.version }}" | |
scanners: 'vuln,misconfig,secret' | |
severity: 'HIGH,CRITICAL' | |
format: table | |
exit-code: 1 | |
# Commit to Git for ArgoCD | |
gitops-commit: | |
runs-on: ubuntu-latest | |
# run after all of needs are complete (whether skipped or success) | |
if: ${{ !cancelled() && !failure() }} | |
needs: | |
- setup | |
- build-push | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Update Image Version in Helm Value file | |
uses: fjogeleit/yaml-update-action@main | |
with: | |
valueFile: "iac/helm-values/opsta-line-bot-${{ needs.setup.outputs.deploy_env }}.yaml" | |
propertyPath: image.tag | |
value: ${{ needs.setup.outputs.version }} | |
branch: main | |
message: "Update Image Version to ${{ needs.setup.outputs.version }}" | |
# ArgoCD Sync | |
gitops-sync: | |
runs-on: ubuntu-latest | |
container: | |
image: quay.io/argoproj/argocd:v2.12.4 | |
env: | |
ARGOCD_SERVER: ${{ secrets.ARGOCD_SERVER }} | |
ARGOCD_AUTH_TOKEN: ${{ secrets.ARGOCD_AUTH_TOKEN }} | |
# run after all of needs are complete (whether skipped or success) | |
if: ${{ !cancelled() && !failure() }} | |
needs: | |
- setup | |
- gitops-commit | |
steps: | |
- name: Sync ArgoCD | |
run: | | |
argocd app sync demo-opsta-line-bot-${{ needs.setup.outputs.deploy_env }}/opsta-line-bot-${{ needs.setup.outputs.deploy_env }} --project demo | |
argocd app wait demo-opsta-line-bot-${{ needs.setup.outputs.deploy_env }}/opsta-line-bot-${{ needs.setup.outputs.deploy_env }} --health | |
zap-baseline: | |
runs-on: ubuntu-latest | |
if: ${{ !cancelled() && !failure() }} | |
needs: | |
- setup | |
- gitops-sync | |
steps: | |
- name: ZAP Baseline Scan | |
uses: zaproxy/[email protected] | |
with: | |
target: "https://demo-linebot.${{ needs.setup.outputs.deploy_env }}.opsta.dev" | |
allow_issue_writing: false | |
artifact_name: zap-baseline-scan | |
cmd_options: "-x zap-baseline-report.xml" | |
- name: Upload ZAP Baseline Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: zap-baseline-report | |
path: zap-baseline-report.xml | |
retention-days: 1 | |
zap-api: | |
runs-on: ubuntu-latest | |
if: ${{ !cancelled() && !failure() }} | |
needs: | |
- setup | |
- gitops-sync | |
steps: | |
- name: ZAP API Scan | |
uses: zaproxy/[email protected] | |
with: | |
target: "https://demo-linebot.${{ needs.setup.outputs.deploy_env }}.opsta.dev" | |
allow_issue_writing: false | |
artifact_name: zap-api-scan | |
cmd_options: "-x zap-api-report.xml" | |
- name: Upload ZAP API Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: zap-api-report | |
path: zap-api-report.xml | |
retention-days: 1 | |
zap-full: | |
runs-on: ubuntu-latest | |
if: ${{ !cancelled() && !failure() }} | |
needs: | |
- setup | |
- gitops-sync | |
steps: | |
- name: ZAP Full Scan | |
uses: zaproxy/[email protected] | |
with: | |
target: "https://demo-linebot.${{ needs.setup.outputs.deploy_env }}.opsta.dev" | |
allow_issue_writing: false | |
artifact_name: zap-full-scan | |
cmd_options: "-x zap-full-report.xml" | |
- name: Upload ZAP Full Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: zap-full-report | |
path: zap-full-report.xml | |
retention-days: 1 | |
defectdojo-import: | |
runs-on: ubuntu-latest | |
if: always() | |
needs: | |
- setup | |
- sonarqube | |
- trivy-sca-report | |
- trivy-iac-report | |
- trivy-image-report | |
- zap-baseline | |
- zap-api | |
- zap-full | |
steps: | |
- name: Download all workflow run artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
merge-multiple: true | |
- name: Import Security Test Report into DefectDojo | |
uses: portswigger-cloud/defectdojo-import-scan@v1 | |
with: | |
defectdojo-url: ${{ secrets.DEFECTDOJO_HOST }} | |
defectdojo-username: ${{ secrets.DEFECTDOJO_USERNAME }} | |
defectdojo-password: ${{ secrets.DEFECTDOJO_PASSWORD }} | |
defectdojo-product-type: Research and Development | |
defectdojo-product: ${{ github.event.repository.name }} | |
defectdojo-environment-type: ${{ needs.setup.outputs.deploy_env }} | |
defectdojo-scan-type: ${{ matrix.defectdojo_scan_type }} | |
defectdojo-engagement-name: ${{ needs.setup.outputs.deploy_env }}-${{ github.run_id }} | |
scan-results-file-name: ${{ matrix.defectdojo_report_file }} | |
strategy: | |
matrix: | |
include: | |
- defectdojo_report_file: sonar-report.html | |
defectdojo_scan_type: SonarQube Scan | |
defectdojo_test_title: SonarQube Scan | |
- defectdojo_report_file: trivy-sca-report.json | |
defectdojo_scan_type: Trivy Scan | |
defectdojo_test_title: Trivy SCA Scan | |
- defectdojo_report_file: trivy-iac-report.json | |
defectdojo_scan_type: Trivy Scan | |
defectdojo_test_title: Trivy IaC Scan | |
- defectdojo_report_file: trivy-image-report.json | |
defectdojo_scan_type: Trivy Scan | |
defectdojo_test_title: Trivy Image Scan | |
- defectdojo_report_file: zap-baseline-report.xml | |
defectdojo_scan_type: ZAP Scan | |
defectdojo_test_title: ZAP Scan Baseline | |
- defectdojo_report_file: zap-api-report.xml | |
defectdojo_scan_type: ZAP Scan | |
defectdojo_test_title: ZAP Scan API | |
- defectdojo_report_file: zap-full-report.xml | |
defectdojo_scan_type: ZAP Scan | |
defectdojo_test_title: ZAP Scan Full | |
defectdojo-findings: | |
runs-on: ubuntu-latest | |
if: always() | |
needs: | |
- defectdojo-import | |
steps: | |
- name: DefectDojo Query Findings | |
uses: portswigger-cloud/defectdojo-active-findings@v1 | |
with: | |
defectdojo-url: ${{ secrets.DEFECTDOJO_HOST }} | |
defectdojo-username: ${{ secrets.DEFECTDOJO_USERNAME }} | |
defectdojo-password: ${{ secrets.DEFECTDOJO_PASSWORD }} | |
defectdojo-product: ${{ github.event.repository.name }} | |
defectdojo-security-gate: | |
runs-on: ubuntu-latest | |
if: always() | |
needs: | |
- defectdojo-import | |
steps: | |
- name: DefectDojo Security Gate Thresholds | |
uses: portswigger-cloud/defectdojo-findings-thresholds@v1 | |
with: | |
defectdojo-url: ${{ secrets.DEFECTDOJO_HOST }} | |
defectdojo-username: ${{ secrets.DEFECTDOJO_USERNAME }} | |
defectdojo-password: ${{ secrets.DEFECTDOJO_PASSWORD }} | |
defectdojo-product: ${{ github.event.repository.name }} | |
# Need to put every thresholds to make it working | |
total-threshold: 1000000 | |
critical-threshold: 0 | |
high-threshold: 0 | |
medium-threshold: 1000000 | |
low-threshold: 1000000 | |
info-threshold: 1000000 |