Merge pull request #111 from bcgov/grazing-lease-update #70
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: Merge to Main | |
on: | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- ".github/ISSUE_TEMPLATE/*" | |
- "**.md" | |
workflow_dispatch: | |
env: | |
REGISTRY: ghcr.io | |
NAME: nr-ticdi | |
concurrency: | |
group: ${{ github.workflow }} | |
cancel-in-progress: true | |
jobs: | |
# https://github.com/marketplace/actions/ghcr-io-container-cleanup | |
cleanup-ghcr: | |
name: Cleanup Container Registry | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Delete old packages | |
uses: davahome/[email protected] | |
with: | |
delete_untagged: 1 | |
keep_versions: 10 | |
keep_versions_untagged: 0 | |
minimum_days: 14 | |
owner: orgs/bcgov | |
package: ${{ github.event.repository.name }} | |
skip_tags: prod-frontend,prod-backend | |
token: ${{ secrets.GHCR_TOKEN }} | |
codeql: | |
name: Semantic Code Analysis | |
runs-on: ubuntu-22.04 | |
permissions: | |
actions: read | |
contents: read | |
security-events: write | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Initialize | |
uses: github/codeql-action/init@v2 | |
with: | |
languages: javascript | |
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java). | |
# If this step fails, then you should remove it and run the build manually (see below) | |
- name: Autobuild | |
uses: github/codeql-action/autobuild@v2 | |
- name: Perform CodeQL Analysis | |
uses: github/codeql-action/analyze@v2 | |
# SonarCloud runs in the main branch are needed to compare against PRs | |
# sonarcloud: | |
# name: Static Analysis | |
# runs-on: ubuntu-22.04 | |
# steps: | |
# - uses: actions/checkout@v3 | |
# # Disable shallow clone for SonarCloud analysis | |
# with: | |
# fetch-depth: 0 | |
# - name: Backend Tests | |
# run: | | |
# cd frontend | |
# npm ci | |
# npm run test:cov | |
# - name: Frontend Tests | |
# run: | | |
# cd frontend | |
# npm ci | |
# npm run test:cov | |
# - name: SonarCloud Scan | |
# uses: SonarSource/sonarcloud-github-action@master | |
# env: | |
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any | |
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
# with: | |
# args: > | |
# -Dsonar.exclusions=**/test/**,.github/**/* | |
# -Dsonar.organization=bcgov-sonarcloud | |
# -Dsonar.javascript.lcov.reportPaths=backend/coverage/lcov.info,frontend/coverage/lcov.info | |
# -Dsonar.cobertura.reportPaths=backend/coverage/cobertura-coverage.xml,frontend/coverage/cobertura-coverage.xml | |
# -Dsonar.project.monorepo.enabled=true | |
# -Dsonar.projectKey=${{ github.event.repository.name }} | |
# -Dsonar.sources=backend,frontend | |
# -Dsonar.tests=backend/test,frontend/test | |
deploy-test: | |
name: TEST Deployment | |
needs: | |
- cleanup-ghcr | |
- codeql | |
# - sonarcloud | |
runs-on: ubuntu-22.04 | |
environment: | |
name: test | |
env: | |
ZONE: test | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Deploy | |
run: | | |
# Login to OpenShift and select project | |
oc login --token=${{ secrets.OC_TOKEN }} --server=${{ secrets.OC_SERVER }} | |
oc project ${{ secrets.OC_NAMESPACE }} | |
# Do not replace database; 'oc create' kicks up an error if objects already exist | |
oc process -f .github/openshift/deploy.database.yml -p ZONE=${{ env.ZONE }} | oc create -f - || true | |
# Process and apply deployment templates | |
oc process -f .github/openshift/deploy.backend.yml -p ZONE=${{ env.ZONE }} \ | |
-p PROMOTE=${{ github.repository }}:${{ env.ZONE }}-backend | oc apply -f - | |
oc process -f .github/openshift/deploy.frontend.yml -p ZONE=${{ env.ZONE }} \ | |
-p PROMOTE=${{ github.repository }}:${{ env.ZONE }}-frontend | oc apply -f - | |
# Follow any active rollouts (see deploymentconfigs) | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-database -w | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-backend -w | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-frontend -w | |
# Remove completed build runs, build pods and deployment pods | |
for p in $(oc get po | grep "Completed" | awk '{print $1}') | |
do | |
oc delete po ${p} | |
done | |
zap-backend: | |
name: Backend Pen Tests | |
needs: | |
- deploy-test | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v3 | |
- name: ZAP Scan | |
uses: zaproxy/[email protected] | |
with: | |
target: https://${{ env.NAME }}-test-backend.apps.silver.devops.gov.bc.ca/ | |
cmd_options: "-a" | |
allow_issue_writing: false | |
fail_action: false | |
zap-frontend: | |
name: Frontend Pen Tests | |
needs: | |
- deploy-test | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v3 | |
- name: ZAP Scan | |
uses: zaproxy/[email protected] | |
with: | |
target: https://${{ env.NAME }}-test-frontend.apps.silver.devops.gov.bc.ca/ | |
cmd_options: "-a" | |
allow_issue_writing: false | |
fail_action: false | |
# https://github.com/snyk/cli, https://github.com/snyk/actions | |
# Note: using free tier - called late in pipeline to limit runs | |
# snyk: | |
# name: Vulnerability Report | |
# needs: | |
# - zap-backend | |
# - zap-frontend | |
# runs-on: ubuntu-22.04 | |
# steps: | |
# - uses: actions/checkout@v3 | |
# | |
# - name: Run Snyk to check for vulnerabilities | |
# uses: snyk/actions/node@master | |
# continue-on-error: true # To make sure that SARIF upload gets called | |
# env: | |
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | |
# with: | |
# args: --all-projects --severity-threshold=high --sarif-file-output=snyk.sarif | |
# - name: Upload result to GitHub Code Scanning | |
# uses: github/codeql-action/upload-sarif@v2 | |
# with: | |
# sarif_file: snyk.sarif | |
# https://github.com/marketplace/actions/aqua-security-trivy | |
trivy-repo: | |
name: Repository Report | |
needs: | |
- zap-backend | |
- zap-frontend | |
runs-on: ubuntu-22.04 | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Run Trivy vulnerability scanner in repo mode | |
uses: aquasecurity/[email protected] | |
with: | |
scan-type: "fs" | |
format: "sarif" | |
output: "trivy-results.sarif" | |
ignore-unfixed: true | |
severity: "CRITICAL,HIGH" | |
security-checks: "vuln,secret,config" | |
- name: Upload Trivy scan results to GitHub Security tab | |
uses: github/codeql-action/upload-sarif@v2 | |
with: | |
sarif_file: "trivy-results.sarif" | |
image-backend: | |
name: Backend Image Handling | |
needs: | |
- zap-backend | |
- zap-frontend | |
outputs: | |
build: ${{ steps.check.outputs.build }} | |
env: | |
COMPONENT: backend | |
PREV: test | |
ZONE: prod | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Check for image changes | |
id: check | |
run: | | |
# Vars | |
IMG_PREV="${{ env.REGISTRY }}/${{ github.repository }}:${{ env.PREV }}-${{ env.COMPONENT }}" | |
IMG_ZONE="${{ env.REGISTRY }}/${{ github.repository }}:${{ env.ZONE }}-${{ env.COMPONENT }}" | |
# Pull previous image; grab SHA | |
docker pull "${IMG_PREV}" | |
SHA_PREV=$(docker inspect -f '{{.Id}}' "${IMG_PREV}") | |
# Use blank SHA for promoted image, unless a real one exists instead | |
docker pull "${IMG_ZONE}" && \ | |
SHA_ZONE=$(docker inspect -f '{{.Id}}' "${IMG_ZONE}") || | |
SHA_ZONE="" | |
# Output SHAs | |
echo -e "\n${IMG_PREV}: ${SHA_PREV}" | |
echo -e "${IMG_ZONE}: ${SHA_ZONE}\n" | |
# If different, then trigger updates | |
if [[ "${SHA_PREV}" != "${SHA_ZONE}" ]]; then | |
echo "::set-output name=build::true" | |
echo "Image has changed" | |
exit 0 | |
fi | |
echo "Image promotion not required" | |
image-frontend: | |
name: Frontend Image Handling | |
needs: | |
- zap-backend | |
- zap-frontend | |
outputs: | |
build: ${{ steps.check.outputs.build }} | |
env: | |
COMPONENT: frontend | |
PREV: test | |
ZONE: prod | |
runs-on: ubuntu-22.04 | |
steps: | |
- name: Check for image changes | |
id: check | |
run: | | |
# Vars | |
IMG_PREV="${{ env.REGISTRY }}/${{ github.repository }}:${{ env.PREV }}-${{ env.COMPONENT }}" | |
IMG_ZONE="${{ env.REGISTRY }}/${{ github.repository }}:${{ env.ZONE }}-${{ env.COMPONENT }}" | |
# Pull previous image; grab SHA | |
docker pull "${IMG_PREV}" | |
SHA_PREV=$(docker inspect -f '{{.Id}}' "${IMG_PREV}") | |
# Use blank SHA for promoted image, unless a real one exists instead | |
docker pull "${IMG_ZONE}" && \ | |
SHA_ZONE=$(docker inspect -f '{{.Id}}' "${IMG_ZONE}") || | |
SHA_ZONE="" | |
# Output SHAs | |
echo -e "\n${IMG_PREV}: ${SHA_PREV}" | |
echo -e "${IMG_ZONE}: ${SHA_ZONE}\n" | |
# If different, then trigger updates | |
if [[ "${SHA_PREV}" != "${SHA_ZONE}" ]]; then | |
echo "::set-output name=build::true" | |
echo "Image has changed" | |
exit 0 | |
fi | |
echo "Image promotion not required" | |
deploy-prod: | |
name: PROD Deployment | |
needs: | |
- image-backend | |
- image-frontend | |
# - snyk | |
- trivy-repo | |
runs-on: ubuntu-22.04 | |
environment: | |
name: prod | |
env: | |
ZONE: prod | |
PREV: test | |
steps: | |
- name: Remove any stale backend images | |
if: needs.image-backend.outputs.build == 'true' | |
env: | |
COMPONENT: backend | |
run: | | |
# Login to OpenShift and select project | |
oc login --token=${{ secrets.OC_TOKEN }} --server=${{ secrets.OC_SERVER }} | |
oc project ${{ secrets.OC_NAMESPACE }} | |
oc delete is/${{ env.NAME }}-${{ env.ZONE}}-${{ env.COMPONENT }} || true | |
- name: Remove any stale frontend images | |
if: needs.image-frontend.outputs.build == 'true' | |
env: | |
COMPONENT: frontend | |
run: | | |
# Login to OpenShift and select project | |
oc login --token=${{ secrets.OC_TOKEN }} --server=${{ secrets.OC_SERVER }} | |
oc project ${{ secrets.OC_NAMESPACE }} | |
oc delete is/${{ env.NAME }}-${{ env.ZONE}}-${{ env.COMPONENT }} || true | |
- uses: actions/checkout@v3 | |
- name: Deploy | |
run: | | |
# Login to OpenShift and select project | |
oc login --token=${{ secrets.OC_TOKEN }} --server=${{ secrets.OC_SERVER }} | |
oc project ${{ secrets.OC_NAMESPACE }} | |
# Do not replace database; 'oc create' kicks up an error if objects already exist | |
oc process -f .github/openshift/deploy.database.yml -p ZONE=${{ env.ZONE }} | oc create -f - || true | |
# Process and apply deployment templates | |
oc process -f .github/openshift/deploy.backend.yml -p ZONE=${{ env.ZONE }} \ | |
-p PROMOTE=${{ github.repository }}:${{ env.PREV }}-backend | oc apply -f - | |
oc process -f .github/openshift/deploy.frontend.yml -p ZONE=${{ env.ZONE }} \ | |
-p PROMOTE=${{ github.repository }}:${{ env.PREV }}-frontend | oc apply -f - | |
# Follow any active rollouts (see deploymentconfigs) | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-database -w | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-backend -w | |
oc rollout status dc/${{ env.NAME }}-${{ env.ZONE }}-frontend -w | |
# Remove completed build runs, build pods and deployment pods | |
for p in $(oc get po | grep "Completed" | awk '{print $1}') | |
do | |
oc delete po ${p} | |
done | |
- name: Promote Backend Image to PROD | |
uses: shrink/actions-docker-registry-tag@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
repository: ${{ github.repository }} | |
target: ${{ env.PREV }}-backend | |
tags: | | |
prod-backend | |
- name: Promote Frontend Image to PROD | |
uses: shrink/actions-docker-registry-tag@v3 | |
with: | |
registry: ${{ env.REGISTRY }} | |
repository: ${{ github.repository }} | |
target: ${{ env.PREV }}-frontend | |
tags: | | |
prod-frontend | |
# # Uncomment to for development and troubleshooting | |
# # https://docs.github.com/en/actions/learn-github-actions/contexts | |
# view-context: | |
# name: View GitHub Context | |
# runs-on: ubuntu-22.04 | |
# steps: | |
# - name: Echo GitHub context | |
# uses: satackey/[email protected] | |
# with: | |
# script: | | |
# const github = require('@actions/github'); | |
# console.log(JSON.stringify(github, null, 2)); |