Miscellaneous improvements and updates #386
Workflow file for this run
This file contains hidden or 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
| # Build showcase images (tag pr-<number>), Helm install/upgrade per PR, register PR webhook with Traction, optional URL comment. | |
| # | |
| # Shared Docker steps live under `.github/actions/showcase-build-*` (also used by deploy-showcase-dev). | |
| # | |
| # Configure on bcgov/BC-Wallet-Demo (repository Actions secrets): | |
| # Secrets: OPENSHIFT_SERVER, OPENSHIFT_TOKEN, OPENSHIFT_DEV_NAMESPACE | |
| # Pre-create OpenShift Secret `showcase-traction` in OPENSHIFT_DEV_NAMESPACE (shared with dev deploy). | |
| # Optional variable: SHOWCASE_PR_HOST_SUFFIX — hostname without scheme (overrides workflow default). | |
| # Default is Silver dev ingress (see env.SHOWCASE_PR_HOST_SUFFIX). Public URL: | |
| # https://pr-<N>-<suffix>/digital-trust/showcase | |
| # Optional build-args (same as build_packages): REACT_APP_* via repo Variables or Secrets. | |
| # | |
| # Helm 3 stores release metadata in the target namespace (default: Secrets; optional: ConfigMaps). | |
| # The OpenShift token must be allowed to list (and create/update/delete/get) that resource type there. | |
| # | |
| # Skips when not bcgov, on draft PRs (no deploy), or when OpenShift secrets are missing at deploy time. | |
| # Expect PR branches on bcgov/BC-Wallet-Demo (same-repo PRs) so Actions secrets/vars apply; fork PRs lack secrets. | |
| name: Showcase PR — build and deploy | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'charts/showcase/**' | |
| - 'deploy/showcase/**' | |
| - 'frontend/**' | |
| - 'server/**' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - '.github/workflows/deploy-showcase-pr.yaml' | |
| - '.github/actions/showcase-build-server/**' | |
| - '.github/actions/showcase-build-frontend/**' | |
| - '.github/actions/showcase-setup-oc-helm/**' | |
| - '.github/actions/showcase-helm-lint/**' | |
| - '.github/scripts/showcase-traction-webhook.sh' | |
| types: [opened, synchronize, reopened, ready_for_review] | |
| draft: false | |
| concurrency: | |
| group: showcase-pr-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| # GHCR push needs packages:write; orgs may also require Actions "Read and write" workflow permissions | |
| # and linking the repo to the package. ghcr login uses repository_owner + GITHUB_TOKEN (see showcase-build-* actions). | |
| permissions: | |
| contents: read | |
| packages: write | |
| pull-requests: write | |
| env: | |
| HUSKY: '0' | |
| REGISTRY: ghcr.io | |
| SHOWCASE_SERVER_IMAGE: ghcr.io/${{ github.repository_owner }}/digital-trust-showcase-server | |
| SHOWCASE_FRONTEND_IMAGE: ghcr.io/${{ github.repository_owner }}/digital-trust-showcase-frontend | |
| # PR Route host fragment (no scheme): https://pr-<N>-<SHOWCASE_PR_HOST_SUFFIX>/… | |
| # Override per-repo with Actions variable SHOWCASE_PR_HOST_SUFFIX if your cluster DNS differs. | |
| SHOWCASE_PR_HOST_SUFFIX: ${{ vars.SHOWCASE_PR_HOST_SUFFIX != '' && vars.SHOWCASE_PR_HOST_SUFFIX || 'digital-trust-showcase-dev.apps.silver.devops.gov.bc.ca' }} | |
| # Traction tenant proxy for PR webhook registration (matches deploy/showcase/values-pr.yaml). | |
| TRACTION_URL: 'https://traction-tenant-proxy-dev.apps.silver.devops.gov.bc.ca' | |
| jobs: | |
| ready: | |
| name: Ready gates | |
| runs-on: ubuntu-latest | |
| outputs: | |
| deploy: ${{ github.repository_owner == 'bcgov' && github.event.pull_request.draft != true }} | |
| build: ${{ github.repository_owner == 'bcgov' }} | |
| steps: | |
| - name: Compute gate outputs | |
| run: 'true' | |
| build_server: | |
| name: Build and push server image | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| needs: [ready] | |
| if: needs.ready.outputs.build == 'true' | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: ./.github/actions/showcase-build-server | |
| with: | |
| image: ${{ env.SHOWCASE_SERVER_IMAGE }} | |
| tag: pr-${{ github.event.pull_request.number }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| build_frontend: | |
| name: Build and push frontend image | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| needs: [ready] | |
| if: needs.ready.outputs.build == 'true' | |
| permissions: | |
| contents: read | |
| packages: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: ./.github/actions/showcase-build-frontend | |
| with: | |
| image: ${{ env.SHOWCASE_FRONTEND_IMAGE }} | |
| tag: pr-${{ github.event.pull_request.number }} | |
| react_app_host_backend: https://pr-${{ github.event.pull_request.number }}-${{ env.SHOWCASE_PR_HOST_SUFFIX }} | |
| react_app_insights_project_id: ${{ vars.REACT_APP_INSIGHTS_PROJECT_ID || secrets.REACT_APP_INSIGHTS_PROJECT_ID }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| deploy: | |
| name: Helm upgrade (PR instance) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: [ready, build_server, build_frontend] | |
| # Job-level `if` cannot use `secrets` (GitHub restriction). Verify OpenShift secrets in-step. | |
| if: ${{ always() && needs.ready.outputs.deploy == 'true' && needs.build_server.result == 'success' && needs.build_frontend.result == 'success' }} | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - name: Verify OpenShift secrets for deploy | |
| env: | |
| OPENSHIFT_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }} | |
| OPENSHIFT_SERVER: ${{ secrets.OPENSHIFT_SERVER }} | |
| OPENSHIFT_DEV_NAMESPACE: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| run: | | |
| if [[ -z "${OPENSHIFT_TOKEN}" || -z "${OPENSHIFT_SERVER}" || -z "${OPENSHIFT_DEV_NAMESPACE}" ]]; then | |
| echo '::error::Missing OPENSHIFT_SERVER, OPENSHIFT_TOKEN, or OPENSHIFT_DEV_NAMESPACE for showcase PR deploy.' | |
| exit 1 | |
| fi | |
| - uses: ./.github/actions/showcase-setup-oc-helm | |
| - uses: redhat-actions/oc-login@5eb45e848b168b6bf6b8fe7f1561003c12e3c99d # v1.3 | |
| with: | |
| openshift_server_url: ${{ secrets.OPENSHIFT_SERVER }} | |
| openshift_token: ${{ secrets.OPENSHIFT_TOKEN }} | |
| namespace: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| - name: Helm release storage RBAC | |
| env: | |
| OPENSHIFT_DEV_NAMESPACE: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| run: | | |
| set -euo pipefail | |
| # Do not use `oc project -q`: some CI tokens cannot *view* the Project but can still act in the namespace. | |
| ns="${OPENSHIFT_DEV_NAMESPACE}" | |
| if [[ -z "${ns}" ]]; then | |
| echo '::error::OPENSHIFT_DEV_NAMESPACE is empty.' | |
| exit 1 | |
| fi | |
| if oc auth can-i list secrets -n "${ns}" --quiet >/dev/null 2>&1; then | |
| echo "Helm will use default Secret release storage in namespace ${ns}." | |
| elif oc auth can-i list configmaps -n "${ns}" --quiet >/dev/null 2>&1; then | |
| echo "HELM_DRIVER=configmap" >> "${GITHUB_ENV}" | |
| echo "Helm will use ConfigMap release storage (list secrets denied in ${ns})." | |
| else | |
| echo '::notice::oc whoami: '"$(oc whoami 2>&1 || true)" | |
| echo '::notice::SubjectAccessReview list secrets:' | |
| oc auth can-i list secrets -n "${ns}" 2>&1 || true | |
| echo '::notice::SubjectAccessReview list configmaps:' | |
| oc auth can-i list configmaps -n "${ns}" 2>&1 || true | |
| echo '::error::Helm cannot run: this token must be allowed to list Secrets or ConfigMaps in namespace '"${ns}"' for Helm 3 release history (https://helm.sh/docs/topics/advanced/). Grant the CI service account get,list,create,update,patch,delete on secrets or on configmaps in that namespace (same pattern as bcgov/traction PR deploy).' | |
| exit 1 | |
| fi | |
| - uses: ./.github/actions/showcase-helm-lint | |
| with: | |
| skip_checkout: 'true' | |
| skip_helm_install: 'true' | |
| - name: Helm upgrade --install | |
| working-directory: charts/showcase | |
| env: | |
| PR_NUM: ${{ github.event.pull_request.number }} | |
| HOST_SUFFIX: ${{ env.SHOWCASE_PR_HOST_SUFFIX }} | |
| OWNER_LOWER: ${{ github.repository_owner }} | |
| OPENSHIFT_DEV_NAMESPACE: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| run: | | |
| set -euo pipefail | |
| origin="https://pr-${PR_NUM}-${HOST_SUFFIX}" | |
| owner_lc="$(echo "${OWNER_LOWER}" | tr '[:upper:]' '[:lower:]')" | |
| ns="${OPENSHIFT_DEV_NAMESPACE}" | |
| if ! oc get secret showcase-traction -n "${ns}" >/dev/null 2>&1; then | |
| echo '::warning::Secret showcase-traction not found in '"${ns}"' — create it before deploy (see deploy/showcase/values-pr.yaml).' | |
| fi | |
| helm dependency update | |
| helm_args=( | |
| -f ../../deploy/showcase/values-pr.yaml | |
| --namespace "${ns}" | |
| --set-string "showcase.publicOrigin=${origin}" | |
| --set "showcase.server.image.repository=${owner_lc}/digital-trust-showcase-server" | |
| --set "showcase.server.image.tag=pr-${PR_NUM}" | |
| --set "showcase.frontend.image.repository=${owner_lc}/digital-trust-showcase-frontend" | |
| --set "showcase.frontend.image.tag=pr-${PR_NUM}" | |
| --wait | |
| --timeout 10m | |
| ) | |
| if ! helm upgrade --install "pr-${PR_NUM}-showcase" . "${helm_args[@]}"; then | |
| echo '::error::helm upgrade failed; status and recent events follow.' | |
| helm status "pr-${PR_NUM}-showcase" -n "${OPENSHIFT_DEV_NAMESPACE}" 2>/dev/null || true | |
| oc get events -n "${OPENSHIFT_DEV_NAMESPACE}" --sort-by='.lastTimestamp' 2>/dev/null | tail -40 || true | |
| inst="pr-${PR_NUM}-showcase" | |
| p="$( | |
| oc get pods -n "${OPENSHIFT_DEV_NAMESPACE}" \ | |
| -l "app.kubernetes.io/component=server,app.kubernetes.io/instance=${inst}" \ | |
| -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true | |
| )" | |
| if [[ -n "${p}" ]]; then | |
| echo '::notice::--- oc describe pod '"${p}"' (tail) ---' | |
| oc describe pod "${p}" -n "${OPENSHIFT_DEV_NAMESPACE}" 2>/dev/null | tail -80 || true | |
| echo '::notice::--- oc logs '"${p}"' -c wait-for-mongo-tcp (tail) ---' | |
| oc logs "${p}" -n "${OPENSHIFT_DEV_NAMESPACE}" -c wait-for-mongo-tcp --tail=60 2>/dev/null || true | |
| echo '::notice::--- oc logs '"${p}"' -c server (tail) ---' | |
| oc logs "${p}" -n "${OPENSHIFT_DEV_NAMESPACE}" -c server --tail=80 2>/dev/null || true | |
| fi | |
| exit 1 | |
| fi | |
| # Same image tag (:pr-N) may point at a new digest; restart pulls new layers. Wait so the job does not succeed before pods are ready. | |
| - name: Restart deployments and wait for rollouts | |
| env: | |
| PR_NUM: ${{ github.event.pull_request.number }} | |
| OPENSHIFT_DEV_NAMESPACE: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| run: | | |
| set -euo pipefail | |
| ns="${OPENSHIFT_DEV_NAMESPACE}" | |
| oc rollout restart "deployment/pr-${PR_NUM}-showcase-server" -n "${ns}" | |
| oc rollout status "deployment/pr-${PR_NUM}-showcase-server" -n "${ns}" --timeout=10m | |
| oc rollout restart "deployment/pr-${PR_NUM}-showcase-frontend" -n "${ns}" | |
| oc rollout status "deployment/pr-${PR_NUM}-showcase-frontend" -n "${ns}" --timeout=10m | |
| # Append this PR's webhook to the shared Traction tenant; other registered URLs are preserved. | |
| - name: Register PR webhook with Traction | |
| env: | |
| PR_NUM: ${{ github.event.pull_request.number }} | |
| SHOWCASE_PR_HOST_SUFFIX: ${{ env.SHOWCASE_PR_HOST_SUFFIX }} | |
| TRACTION_URL: ${{ env.TRACTION_URL }} | |
| OPENSHIFT_DEV_NAMESPACE: ${{ secrets.OPENSHIFT_DEV_NAMESPACE }} | |
| run: .github/scripts/showcase-traction-webhook.sh add | |
| pr_urls_comment: | |
| name: PR deployment comment | |
| runs-on: ubuntu-latest | |
| needs: [ready, deploy] | |
| if: ${{ always() && needs.ready.outputs.deploy == 'true' && needs.deploy.result == 'success' }} | |
| steps: | |
| - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 | |
| - uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0 | |
| id: fc | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| comment-author: 'github-actions[bot]' | |
| body-includes: <!-- showcase-pr-url --> | |
| - name: Create PR deployment comment | |
| if: steps.fc.outputs.comment-id == '' | |
| uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| body: | | |
| <!-- showcase-pr-url --> | |
| | Showcase PR | | | |
| | --- | --- | | |
| | UI (same host as API) | <a href="https://pr-${{ github.event.pull_request.number }}-${{ env.SHOWCASE_PR_HOST_SUFFIX }}/digital-trust/showcase" target="_blank" rel="noopener noreferrer">https://pr-${{ github.event.pull_request.number }}-${{ env.SHOWCASE_PR_HOST_SUFFIX }}/digital-trust/showcase</a> | | |
| Showcase PR deployment URL (Helm release `pr-${{ github.event.pull_request.number }}-showcase`). | |
| - name: Update PR deployment comment | |
| if: steps.fc.outputs.comment-id != '' | |
| uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0 | |
| with: | |
| issue-number: ${{ github.event.pull_request.number }} | |
| comment-id: ${{ steps.fc.outputs.comment-id }} | |
| edit-mode: replace | |
| body: | | |
| <!-- showcase-pr-url --> | |
| | Showcase PR | | | |
| | --- | --- | | |
| | UI (same host as API) | <a href="https://pr-${{ github.event.pull_request.number }}-${{ env.SHOWCASE_PR_HOST_SUFFIX }}/digital-trust/showcase" target="_blank" rel="noopener noreferrer">https://pr-${{ github.event.pull_request.number }}-${{ env.SHOWCASE_PR_HOST_SUFFIX }}/digital-trust/showcase</a> | | |
| Showcase PR deployment URL (Helm release `pr-${{ github.event.pull_request.number }}-showcase`). |