Skip to content
Merged

Dev #2653

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/cypress-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Cypress E2E — Dev

# Auto-triggers after a successful dev deployment.
# Can also be run manually — supply base_url to target a feature branch deployment
# instead of the default dev environment URL.
#
# Runs Cypress inside OpenShift (d18498-tools) rather than on the GitHub-hosted
# runner, since the app's Route is IP-allowlisted to the BC Gov network.
# Test credentials come from Vault (GH_UGM_CYPRESS_CONFIG) via External Secrets,
# not GitHub Actions secrets — see cypress-e2e-runner.yml.

on:
workflow_run:
workflows: ["Dev - Build & Push docker images"]
types: [completed]
workflow_dispatch:
inputs:
base_url:
description: "Override baseUrl (e.g. https://feature-branch.apps.silver.devops.gov.bc.ca/)"
required: false
type: string

permissions:
contents: read

jobs:
cypress:
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/cypress-e2e-runner.yml
with:
env_name: dev
cypress_config_key: CYPRESS_CONFIG_DEV
base_url: ${{ inputs.base_url || '' }}
secrets: inherit
130 changes: 130 additions & 0 deletions .github/workflows/cypress-e2e-runner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: Cypress E2E (runner)

# Shared job called by cypress-dev/test/uat/prod.yml.
#
# Unlike Grants, this doesn't run Cypress on the GitHub-hosted runner directly —
# the Unity Grant Manager Route is IP-allowlisted to the BC Gov network, which
# GitHub-hosted runners can't reach. Instead this job launches an OpenShift Job
# (from the unity-cypress-job Template in d18498-tools) that runs the existing
# Unity.AutoUI Cypress suite from inside the cluster, waits for it to finish,
# and pulls the logs/screenshots back into this Actions run.
#
# Test credentials are NOT GitHub secrets — the Job pulls them from the
# unity-cypress-config Secret in d18498-tools, synced from Vault
# (GH_UGM_CYPRESS_CONFIG) via External Secrets.
#
# OpenShift auth reuses the same oc-login pattern already used by
# docker-build-dev.yml/docker-build-test.yml/docker-build-main.yml.

on:
workflow_call:
inputs:
env_name:
description: "Cypress environment name: dev | test | uat | prod"
required: true
type: string
cypress_config_key:
description: "Key in the unity-cypress-config Secret for this env (e.g. CYPRESS_CONFIG_DEV)"
required: true
type: string
base_url:
description: "Optional baseUrl override — use to target a feature branch deployment instead of the default env URL"
required: false
type: string
default: ""
gh_environment:
description: "GitHub Environment to source OpenShift credentials from (defaults to env_name — dev/test have their own; uat/prod reuse 'main')"
required: false
type: string
default: ""

permissions:
contents: read

env:
TOOLS_NAMESPACE: d18498-tools
JOB_TIMEOUT: 20m

jobs:
cypress:
name: Cypress E2E — ${{ inputs.env_name }}
runs-on: ubuntu-latest
environment: ${{ inputs.gh_environment || inputs.env_name }}
env:
OC_CLUSTER: ${{ vars.OPENSHIFT_CLUSTER }}
OC_AUTH_TOKEN: ${{ secrets.OPENSHIFT_TOKEN }}
GH_TOKEN: ${{ secrets.GH_API_TOKEN }}

steps:
- name: Install OpenShift CLI
run: |
curl -LO https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest/linux/oc.tar.gz
tar -xvf oc.tar.gz
sudo mv oc /usr/local/bin

- name: Connect to OpenShift API
run: oc login --token=$OC_AUTH_TOKEN --server=$OC_CLUSTER

- name: Launch Cypress Job
id: launch
run: |
# The unity-cypress-job Template lives in the tenant-gitops-d18498 repo
# and is synced into the cluster by ArgoCD — process it by name directly
# from d18498-tools rather than checking out that repo here.
JOB_REF=$(oc process unity-cypress-job \
-p ENV=${{ inputs.env_name }} \
-p CYPRESS_CONFIG_KEY=${{ inputs.cypress_config_key }} \
-p GIT_REF=$GITHUB_SHA \
-p GIT_TOKEN=$GH_TOKEN \
-p BASE_URL="${{ inputs.base_url }}" \
-n $TOOLS_NAMESPACE \
| oc create -f - -o name -n $TOOLS_NAMESPACE)
echo "Created $JOB_REF"
echo "job_ref=$JOB_REF" >> "$GITHUB_OUTPUT"

- name: Wait for Cypress Job to finish
id: wait
run: |
JOB_REF="${{ steps.launch.outputs.job_ref }}"
oc wait --for=condition=complete --timeout=$JOB_TIMEOUT "$JOB_REF" -n $TOOLS_NAMESPACE &
COMPLETE_PID=$!
oc wait --for=condition=failed --timeout=$JOB_TIMEOUT "$JOB_REF" -n $TOOLS_NAMESPACE &
FAILED_PID=$!
wait -n $COMPLETE_PID $FAILED_PID || true
kill $COMPLETE_PID $FAILED_PID 2>/dev/null || true

SUCCEEDED=$(oc get "$JOB_REF" -n $TOOLS_NAMESPACE -o jsonpath='{.status.succeeded}')
echo "succeeded=${SUCCEEDED:-0}" >> "$GITHUB_OUTPUT"

- name: Show Cypress logs
if: always()
run: |
JOB_REF="${{ steps.launch.outputs.job_ref }}"
oc logs "$JOB_REF" -n $TOOLS_NAMESPACE -c cypress --tail=-1 || true

- name: Collect screenshots on failure
if: steps.wait.outputs.succeeded != '1'
run: |
JOB_NAME="${{ steps.launch.outputs.job_ref }}"
JOB_NAME="${JOB_NAME#job.batch/}"
POD=$(oc get pods -n $TOOLS_NAMESPACE -l job-name="$JOB_NAME" -o jsonpath='{.items[0].metadata.name}')
mkdir -p cypress-screenshots
oc cp "$TOOLS_NAMESPACE/$POD:/workspace/applications/Unity.AutoUI/cypress/screenshots" ./cypress-screenshots -c cypress || true

- name: Upload screenshots on failure
if: steps.wait.outputs.succeeded != '1'
uses: actions/upload-artifact@v5
with:
name: cypress-screenshots-${{ inputs.env_name }}-${{ github.run_number }}
path: cypress-screenshots
if-no-files-found: ignore

- name: Clean up Cypress Job
if: always()
run: |
JOB_REF="${{ steps.launch.outputs.job_ref }}"
oc delete "$JOB_REF" -n $TOOLS_NAMESPACE --ignore-not-found

- name: Fail workflow if Cypress did not succeed
if: steps.wait.outputs.succeeded != '1'
run: exit 1
20 changes: 20 additions & 0 deletions .github/workflows/cypress-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Cypress E2E — Prod

# Manual-only — triggered after UAT sign-off, not automatically after deployment.
#
# Runs Cypress inside OpenShift (d18498-tools) — see cypress-e2e-runner.yml.

on:
workflow_dispatch:

permissions:
contents: read

jobs:
cypress:
uses: ./.github/workflows/cypress-e2e-runner.yml
with:
env_name: prod
cypress_config_key: CYPRESS_CONFIG_PROD
gh_environment: main
secrets: inherit
24 changes: 24 additions & 0 deletions .github/workflows/cypress-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Cypress E2E — Test

# Runs against the test environment after a successful test deployment,
# or manually via workflow_dispatch.
#
# Runs Cypress inside OpenShift (d18498-tools) — see cypress-e2e-runner.yml.

on:
workflow_run:
workflows: ["Test - Build & Push docker images"]
types: [completed]
workflow_dispatch:

permissions:
contents: read

jobs:
cypress:
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/cypress-e2e-runner.yml
with:
env_name: test
cypress_config_key: CYPRESS_CONFIG_TEST
secrets: inherit
30 changes: 30 additions & 0 deletions .github/workflows/cypress-uat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Cypress E2E — UAT

# Runs against the UAT environment after a successful main deployment,
# or manually via workflow_dispatch.
#
# Unity has no separate UAT build workflow — UAT deploys off the main build,
# so this triggers off the same workflow_run as prod's build pipeline.
# There's also no "uat" GitHub Environment today, so oc-login reuses the
# "main" Environment's OpenShift credentials (same cluster-wide access).
#
# Runs Cypress inside OpenShift (d18498-tools) — see cypress-e2e-runner.yml.

on:
workflow_run:
workflows: ["Main - Build & Push docker images"]
types: [completed]
workflow_dispatch:

permissions:
contents: read

jobs:
cypress:
if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/cypress-e2e-runner.yml
with:
env_name: uat
cypress_config_key: CYPRESS_CONFIG_UAT
gh_environment: main
secrets: inherit
8 changes: 7 additions & 1 deletion applications/Unity.AutoUI/.gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Cypress TypeScript project gitignore

# Comment cypress.env.json to update build pipeline settings
# Comment cypress.env.json to update build pipeline settings
cypress.env.json

# Local environment config files — create from the .example files in cypress/config/
cypress/config/dev.json
cypress/config/test.json
cypress/config/uat.json
cypress/config/prod.json

# Dependency directories
node_modules/
jspm_packages/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Cypress Environment Config Files

The `*.json` config files in this folder are **excluded from git** (via `.gitignore`) because they contain credentials.
Each developer must create their own local copies from the `.example` files provided.

In CI, `dev.json`/`test.json`/`uat.json`/`prod.json` are written at runtime from the `unity-cypress-config` Secret
(synced from Vault key `GH_UGM_CYPRESS_CONFIG`) by the Cypress Job — see `cypress-job-template.yaml` in
`tenant-gitops-d18498`.

## Setup

Copy the example file(s) for the environment(s) you need and fill in your credentials:

```bash
Copy-Item cypress/config/dev.json.example cypress/config/dev.json
Copy-Item cypress/config/test.json.example cypress/config/test.json
Copy-Item cypress/config/uat.json.example cypress/config/uat.json
Copy-Item cypress/config/prod.json.example cypress/config/prod.json
```
11 changes: 11 additions & 0 deletions applications/Unity.AutoUI/cypress/config/dev.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"webapp.url": "https://dev-unity.apps.silver.devops.gov.bc.ca/",
"environment": "DEV",
"test1username": "",
"test1password": "",
"test2username": "",
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
}
11 changes: 11 additions & 0 deletions applications/Unity.AutoUI/cypress/config/dev2.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"webapp.url": "https://dev2-unity.apps.silver.devops.gov.bc.ca/",
"environment": "DEV2",
"test1username": "",
"test1password": "",
"test2username": "",
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
}
11 changes: 11 additions & 0 deletions applications/Unity.AutoUI/cypress/config/prod.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"webapp.url": "https://prod-unity.apps.silver.devops.gov.bc.ca/",
"environment": "PROD",
"test1username": "",
"test1password": "",
"test2username": "",
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
}
11 changes: 11 additions & 0 deletions applications/Unity.AutoUI/cypress/config/test.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"webapp.url": "https://test-unity.apps.silver.devops.gov.bc.ca/",
"environment": "TEST",
"test1username": "",
"test1password": "",
"test2username": "",
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
}
11 changes: 11 additions & 0 deletions applications/Unity.AutoUI/cypress/config/uat.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"webapp.url": "https://uat-unity.apps.silver.devops.gov.bc.ca/",
"environment": "UAT",
"test1username": "",
"test1password": "",
"test2username": "",
"test2password": "",
"TEST_EMAIL_TO": "",
"TEST_EMAIL_CC": "",
"TEST_EMAIL_BCC": ""
}
Loading