From 9430a6a0f72d254a2bb5f590107181bdb52ec789 Mon Sep 17 00:00:00 2001 From: Derek Roberts Date: Tue, 5 Dec 2023 15:51:42 -0800 Subject: [PATCH] ci: workflow updates (#834) --- .github/workflows/.deploy.yml | 94 ++++++++++++++++++++++++-------- .github/workflows/analysis.yml | 3 +- .github/workflows/merge.yml | 99 +++++++++++++++++++--------------- .github/workflows/pr-close.yml | 97 ++++----------------------------- .github/workflows/pr-open.yml | 49 +++++++++++------ charts/onroutebc/Chart.yaml | 2 +- 6 files changed, 173 insertions(+), 171 deletions(-) diff --git a/.github/workflows/.deploy.yml b/.github/workflows/.deploy.yml index 29c7116b1..387bacbfb 100644 --- a/.github/workflows/.deploy.yml +++ b/.github/workflows/.deploy.yml @@ -4,7 +4,7 @@ on: workflow_call: inputs: ### Required - target: + release: description: 'PR number, test or prod.' required: true type: string @@ -15,26 +15,30 @@ on: required: false type: boolean default: true + environment: + description: "Deployment environment - dev/test/prod" + required: true + type: string + default: "dev" tag: description: 'Docker tag; e.g. PR number, tag, test or prod' required: false type: string default: ${{ github.event.number }} - license: + namespace: description: 'BC Gov LICENSE_PLATE of deployment env' - required: true + required: false type: string - default: "DEFINE_ME" + default: "c28f0c" vault_role: description: "nonprod/prod" required: true type: string default: "nonprod" - zone: - description: "Deployment zone - dev/test/prod" - required: true + triggers: + description: Paths to trigger a deploy; omit=always; e.g. ('backend/' 'frontend/') + required: false type: string - default: "dev" ### Usually a bad idea / not recommended directory: @@ -52,45 +56,89 @@ on: default: 'values.yaml' required: false type: string + params: + description: 'Extra parameters to pass to helm upgrade' + default: '' + required: false + type: string + +env: + repo_release: ${{ github.event.repository.name }}-${{ inputs.release }} + package_tag: ${{ inputs.tag }} jobs: # https://github.com/bcgov-nr/action-deployer-openshift deploys: name: Helm - environment: ${{ inputs.zone}} + environment: ${{ inputs.environment }} runs-on: ubuntu-22.04 timeout-minutes: ${{ inputs.timeout-minutes }} steps: - uses: actions/checkout@v4 - - name: Deploy + - name: Check Deployment Triggers + id: triggers + run: | + # Expand for trigger processing + + # Always deploy if no triggers are provided + if [ -z "${{ inputs.triggers }}" ]; then + echo "Always deploy when no triggers are provided" + echo "triggered=true" >> $GITHUB_OUTPUT + exit 0 + fi + + # Deploy if changed files (git diff) match triggers + TRIGGERS=${{ inputs.triggers }} + git fetch origin ${{ github.event.repository.default_branch }} + while read -r check; do + for t in "${TRIGGERS[@]}"; do + if [[ "${check}" =~ "${t}" ]]; then + echo "Build triggered based on git diff" + echo -e "${t}\n --> ${check}" + echo "triggered=true" >> $GITHUB_OUTPUT + exit 0 + fi + done + done < <(git diff origin/${{ github.event.repository.default_branch }} --name-only) + + # If here skip deployment + echo "No triggers have fired, deployment skipped" + + - name: Deploy if Triggers Fired + if: ${{ steps.triggers.outputs.triggered == 'true' }} working-directory: ${{ inputs.directory }} shell: bash run: | - # Login to OpenShift (NOTE: project command is a safeguard) oc login --token=${{ secrets.oc_token }} --server=${{ vars.oc_server }} - oc project ${{ vars.oc_namespace }} + oc project ${{ vars.OC_NAMESPACE }} # Safeguard! # Interrupt any previous jobs (status = pending-upgrade) - PREVIOUS=$(helm status ${{ github.event.repository.name }}-${{ inputs.tag }} -o json | jq .info.status || true) + PREVIOUS=$(helm status ${{ env.repo_release }} -o json | jq .info.status || true) if [[ ${PREVIOUS} =~ pending ]]; then echo "Rollback triggered" - helm rollback ${{ github.event.repository.name }}-${{ inputs.tag }} || \ - helm uninstall ${{ github.event.repository.name }}-${{ inputs.tag }} + helm rollback ${{ env.repo_release }} || \ + helm uninstall ${{ env.repo_release }} fi - # Deploy Helm Chart + # Package Helm release helm dependency update + helm package --app-version="${{ env.package_tag }}" --version=${{ inputs.tag }} . + + # Deploy Helm release helm upgrade \ --set global.autoscaling=${{ inputs.autoscaling }} \ --set-string global.repository=${{ github.repository }} \ - --set-string global.tag=${{ inputs.target }} \ - --set-string global.license=${{inputs.license}} \ - --set-string global.zone=${{inputs.zone}} \ - --set-string global.vault.role=${{inputs.vault_role}} \ + --set-string global.tag=${{ inputs.release }} \ + --set-string global.license=${{ inputs.namespace }} \ + --set-string global.zone=${{ inputs.environment }} \ + --set-string global.vault.role=${{ inputs.vault_role }} \ --install --wait --atomic ${{ github.event.repository.name }}-${{ inputs.tag }} \ - --timeout ${{ inputs.timeout-minutes }}m \ - --force \ - --values ${{ inputs.values }} . + --timeout ${{ inputs.timeout-minutes }}m --force \ + --values ${{ inputs.values }} ${{ inputs.params }} \ + ./${{ github.event.repository.name }}-${{ inputs.tag }}.tgz + # print history + helm history ${{ env.repo_release }} + # Remove old build runs, build pods and deployment pods oc delete po --field-selector=status.phase==Succeeded diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index b7fc3ded7..dee09165c 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -3,6 +3,7 @@ name: Analysis on: push: branches: [main] + merge_group: pull_request: types: [opened, reopened, synchronize, ready_for_review] schedule: @@ -43,7 +44,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Run Trivy vulnerability scanner in repo mode - uses: aquasecurity/trivy-action@0.14.0 + uses: aquasecurity/trivy-action@0.15.0 with: format: "sarif" output: "trivy-results.sarif" diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index c892b86fc..804c520f7 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -1,69 +1,84 @@ name: Merge on: - workflow_run: - workflows: [PR Closed] - types: [completed] + push: + branches: [main] + paths-ignore: + - '*.md' + - '.github/**' + - 'common/graphics/**' + - '!.github/workflows/.deploy.yml' + - '!.github/workflows/merge.yml' + workflow_dispatch: + inputs: + pr_no: + description: "PR-numbered container set to deploy" + type: number + required: true concurrency: group: ${{ github.workflow }} cancel-in-progress: true jobs: + vars: + name: Set Variables + outputs: + tag: ${{ steps.tag.outputs.tag }} + runs-on: ubuntu-22.04 + timeout-minutes: 1 + steps: + # Get last merged (or current) PR number + - uses: actions/checkout@v4 + - name: Get PR Number + id: tag + run: | + # Accept a provided PR as input or use the API + if [ ! -z "${{ inputs.pr_no }}" ]; then + PR_NO="${{ inputs.pr_no }}" + else + HEAD=$(git log main --oneline | head -n1 | awk '{print $1}') + PR_NO=$(\ + curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ github.token }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/bcgov/quickstart-openshift/commits/${HEAD}/pulls \ + | jq .[0].number + ) + fi + echo -e "Last PR: ${PR_NO}" + + # Validate PR number and send to output + if [ ! "${PR_NO}" =~ ^[0-9]+$ ]; then + echo "PR number not found" + exit 1 + fi + echo "tag=${PR_NO}" >> $GITHUB_OUTPUT + deploys-test: name: Deploys (test) + needs: [vars] uses: ./.github/workflows/.deploy.yml secrets: inherit with: - tag: test - target: latest - values: values.yaml - license: c28f0c + environment: test + release: test + tag: ${{ needs.vars.outputs.tag }} vault_role: nonprod - zone: test -# integration-e2e: -# name: Integration and E2E Tests -# needs: [deploys-test] -# uses: ./.github/workflows/.tests.yml -# with: -# target: test - - promote-images-test: - name: Promote Images - Test - #needs: [deploys-test, integration-e2e] - needs: [deploys-test] - runs-on: ubuntu-22.04 - permissions: - packages: write - strategy: - matrix: - package: [dops, vehicles, frontend] - timeout-minutes: 2 - steps: - - uses: shrink/actions-docker-registry-tag@v3 - with: - registry: ghcr.io - repository: ${{ github.repository }}/${{ matrix.package }} - target: latest - tags: test - deploys-prod: name: Deploys (prod) - needs: [promote-images-test] + needs: [deploys-test, vars] uses: ./.github/workflows/.deploy.yml secrets: inherit with: - tag: prod - target: test - values: values.yaml - license: c28f0c + environment: prod + tag: ${{ needs.vars.outputs.tag }} + release: test vault_role: prod - zone: prod promote-images-prod: name: Promote Images - Prod - needs: [deploys-prod] + needs: [deploys-prod, vars] runs-on: ubuntu-22.04 permissions: packages: write @@ -76,5 +91,5 @@ jobs: with: registry: ghcr.io repository: ${{ github.repository }}/${{ matrix.package }} - target: test + target: ${{ needs.vars.outputs.tag }} tags: prod #Promote images AFTER successful deploy diff --git a/.github/workflows/pr-close.yml b/.github/workflows/pr-close.yml index 77b78dac1..8452dd9d7 100644 --- a/.github/workflows/pr-close.yml +++ b/.github/workflows/pr-close.yml @@ -2,7 +2,6 @@ name: PR Closed on: pull_request: - branches: [main] types: [closed] concurrency: @@ -15,109 +14,33 @@ jobs: cleanup-openshift: name: Cleanup OpenShift env: - name: ${{ github.event.repository.name }}-${{ github.event.number }} + release: ${{ github.event.repository.name }}-${{ github.event.number }} runs-on: ubuntu-22.04 timeout-minutes: 10 steps: - name: Remove OpenShift artifacts run: | oc login --token=${{ secrets.OC_TOKEN }} --server=${{ vars.OC_SERVER }} - oc project ${{ vars.OC_NAMESPACE }} + oc project ${{ vars.OC_NAMESPACE }} # Safeguard! # If found, then remove - helm status ${{ env.name }} && helm uninstall --no-hooks ${{ env.name }} || \ - echo "Not found: ${{ env.name }}" + helm status ${{ env.release }} && helm uninstall --no-hooks ${{ env.release }} || \ + echo "Not found: ${{ env.release }}" # Remove Bitnami Crunchy PVCs - oc delete pvc data-${{ github.event.repository.name }}-${{ github.event.number }}-bitnami-pg-0 || \ - echo "$@" - GitVersion: - name: Mainline Versioning - GitVersion - if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' - runs-on: ubuntu-22.04 - steps: - - name: Checkout Code - uses: actions/checkout@v4 - with: - fetch-depth: 0 # fetch the whole repo history - - - name: Setup GitVersion - uses: gittools/actions/gitversion/setup@v0.10.2 - with: - versionSpec: "5.x" - - - name: Determine SemVersion - id: gitversion - uses: gittools/actions/gitversion/execute@v0.10.2 - with: - useConfigFile: true - configFilePath: GitVersion.yaml - - - name: Display GitVersion outputs - run: | - echo "Major: ${{ steps.gitversion.outputs.major }}" - echo "Minor: ${{ steps.gitversion.outputs.minor }}" - echo "Patch: ${{ steps.gitversion.outputs.patch }}" - echo "PreReleaseTag: ${{ steps.gitversion.outputs.preReleaseTag }}" - echo "PreReleaseTagWithDash: ${{ steps.gitversion.outputs.preReleaseTagWithDash }}" - echo "PreReleaseLabel: ${{ steps.gitversion.outputs.preReleaseLabel }}" - echo "PreReleaseNumber: ${{ steps.gitversion.outputs.preReleaseNumber }}" - echo "WeightedPreReleaseNumber: ${{ steps.gitversion.outputs.weightedPreReleaseNumber }}" - echo "BuildMetaData: ${{ steps.gitversion.outputs.buildMetaData }}" - echo "BuildMetaDataPadded: ${{ steps.gitversion.outputs.buildMetaDataPadded }}" - echo "FullBuildMetaData: ${{ steps.gitversion.outputs.fullBuildMetaData }}" - echo "MajorMinorPatch: ${{ steps.gitversion.outputs.majorMinorPatch }}" - echo "SemVer: ${{ steps.gitversion.outputs.semVer }}" - echo "LegacySemVer: ${{ steps.gitversion.outputs.legacySemVer }}" - echo "LegacySemVerPadded: ${{ steps.gitversion.outputs.legacySemVerPadded }}" - echo "AssemblySemVer: ${{ steps.gitversion.outputs.assemblySemVer }}" - echo "AssemblySemFileVer: ${{ steps.gitversion.outputs.assemblySemFileVer }}" - echo "FullSemVer: ${{ steps.gitversion.outputs.fullSemVer }}" - echo "InformationalVersion: ${{ steps.gitversion.outputs.informationalVersion }}" - echo "BranchName: ${{ steps.gitversion.outputs.branchName }}" - echo "EscapedBranchName: ${{ steps.gitversion.outputs.escapedBranchName }}" - echo "Sha: ${{ steps.gitversion.outputs.sha }}" - echo "ShortSha: ${{ steps.gitversion.outputs.shortSha }}" - echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}" - echo "NuGetVersion: ${{ steps.gitversion.outputs.nuGetVersion }}" - echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.nuGetPreReleaseTagV2 }}" - echo "NuGetPreReleaseTag: ${{ steps.gitversion.outputs.nuGetPreReleaseTag }}" - echo "VersionSourceSha: ${{ steps.gitversion.outputs.versionSourceSha }}" - echo "CommitsSinceVersionSource: ${{ steps.gitversion.outputs.commitsSinceVersionSource }}" - echo "CommitsSinceVersionSourcePadded: ${{ steps.gitversion.outputs.commitsSinceVersionSourcePadded }}" - echo "UncommittedChanges: ${{ steps.gitversion.outputs.uncommittedChanges }}" - echo "CommitDate: ${{ steps.gitversion.outputs.commitDate }}" - outputs: - fullSemVer: ${{ steps.gitversion.outputs.fullSemVer}} - - create-release: - name: Create release - runs-on: ubuntu-22.04 - needs: - - GitVersion - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - steps: - - name: Create Release - run: | - gh release create "${{ needs.GitVersion.outputs.fullSemVer }}" \ - --repo=${{ github.repository }} \ - --title="${{ github.repository }}-${{ needs.GitVersion.outputs.fullSemVer }}" \ - --generate-notes - + oc delete pvc data-${{ env.release }}-bitnami-pg-0 || \ + echo "Not found: pvc data-${{ env.release }}-bitnami-pg-0" - # If merged into main, then handle any image promotions - tag-images: - name: Tag Images - needs: [GitVersion] - if: ${{ needs.GitVersion.outputs.fullSemVer != '' }} + # Add tags to PR image + retags: + name: Promote Images runs-on: ubuntu-22.04 permissions: packages: write strategy: matrix: package: [dops, vehicles, frontend] - timeout-minutes: 2 + timeout-minutes: 1 steps: - uses: shrink/actions-docker-registry-tag@v3 with: diff --git a/.github/workflows/pr-open.yml b/.github/workflows/pr-open.yml index 096c061df..7780f3b57 100644 --- a/.github/workflows/pr-open.yml +++ b/.github/workflows/pr-open.yml @@ -2,8 +2,7 @@ name: PR on: pull_request: - branches: [main] - workflow_dispatch: + merge_group: concurrency: # PR open and close use the same group, allowing only one at a time @@ -11,16 +10,9 @@ concurrency: cancel-in-progress: true jobs: - conventional-commits: - name: Conventional Commits - runs-on: ubuntu-22.04 - steps: - - uses: amannn/action-semantic-pull-request@v5.4.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - pr-description-add: name: PR Description Add + if: github.event_name == 'pull_request' env: DOMAIN: apps.silver.devops.gov.bc.ca PREFIX: ${{ github.event.repository.name }}-${{ github.event.number }} @@ -48,9 +40,32 @@ jobs: After merge, new images are promoted to: - [Merge Workflow](https://github.com/${{ github.repository }}/actions/workflows/merge.yml) + # Find initial PR number (for merge queues) + vars: + name: Build and Deploy Vars + outputs: + tag: ${{ steps.deploys.outputs.tag }} + runs-on: ubuntu-22.04 + steps: + - name: Set Variables + id: deploys + run: | + # Get PR number (different process for merge queue) + if [ ${{ github.event_name }} == 'pull_request' ] + then + tag=${{ github.event.number }} + else + tag=$(echo ${{ github.event.merge_group.head_ref }} | grep -Eo "queue/main/pr-[0-9]+" | cut -d '-' -f2) + fi + + echo "Summary ---" + echo -e "\tTag (PR no): ${tag}" + echo "tag=${tag}" >> $GITHUB_OUTPUT + # https://github.com/bcgov-nr/action-builder-ghcr builds: name: Builds + needs: [vars] runs-on: ubuntu-22.04 permissions: packages: write @@ -63,20 +78,20 @@ jobs: with: keep_versions: 50 package: ${{ matrix.package }} - tag: ${{ github.event.number }} - tag_fallback: test + tag: ${{ needs.vars.outputs.tag }} + tag_fallback: latest triggers: ('${{ matrix.package }}/') # https://github.com/bcgov-nr/action-deployer-openshift deploys: name: Deploys - needs: [builds] + needs: [builds, vars] uses: ./.github/workflows/.deploy.yml secrets: inherit with: autoscaling: false - target: ${{ github.event.number }} - values: values.yaml - license: c28f0c + environment: dev + release: ${{ needs.vars.outputs.tag }} + tag: ${{ needs.vars.outputs.tag }} + # triggers: ('database/' 'dops/' 'frontend/' 'vehicles/') vault_role: nonprod - zone: dev diff --git a/charts/onroutebc/Chart.yaml b/charts/onroutebc/Chart.yaml index 3f53be459..84a427b2e 100644 --- a/charts/onroutebc/Chart.yaml +++ b/charts/onroutebc/Chart.yaml @@ -1,6 +1,6 @@ --- apiVersion: v2 -name: onRouteBC +name: onroutebc description: Helm chart for onRouteBC type: application version: 1.0.1