diff --git a/.github/actions/nx-app-build/action.yaml b/.github/actions/nx-app-build/action.yaml new file mode 100644 index 0000000000..54ca843c49 --- /dev/null +++ b/.github/actions/nx-app-build/action.yaml @@ -0,0 +1,72 @@ +name: "Build and push Docker image for Nx frontend app in /bciers directory" +description: "Reusable action to build and push a Docker image for an Nx app in the /bciers directory" + +inputs: + project: + description: "Nx project name" + required: true + image_url: + description: "Docker image URL" + required: true + github_token: + description: "GitHub token" + required: true + +runs: + using: composite + steps: + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ inputs.image_url }} + tags: | + type=sha,format=long,prefix= + latest + type=ref,event=pr + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ inputs.github_token }} + - name: Install dependencies + shell: bash + run: | + corepack enable + yarn install --immutable + cd bciers && yarn install --immutable + - uses: actions/setup-node@v4 + - name: Derive appropriate SHAs for base and head for `nx affected` commands + uses: nrwl/nx-set-shas@v4 + with: + main-branch-name: "develop" + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-bciers-${{ inputs.project }}${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-bciers-${{ inputs.project }} + - name: Build images + shell: bash + env: + INPUT_GITHUB_TOKEN: ${{ inputs.github_token }} + INPUT_PUSH: true + INPUT_TAGS: ${{ steps.meta.outputs.tags }} + INPUT_LABELS: ${{ steps.meta.output.labels }} + INPUT_CACHE_FROM: type=local,src=/tmp/.buildx-cache + INPUT_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new + run: | + npx nx container ${{ inputs.project }} --skip-nx-cache + working-directory: ./bciers + # Temp fix + # https://github.com/docker/build-push-action/issues/252 + # https://github.com/moby/buildkit/issues/1896 + - name: Move cache + shell: bash + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/actions/run-backend/action.yml b/.github/actions/run-backend/action.yml new file mode 100644 index 0000000000..e2efaa4843 --- /dev/null +++ b/.github/actions/run-backend/action.yml @@ -0,0 +1,14 @@ +name: "Run Django backend" +description: "Runs the Django backend locally" + +inputs: + django_secret_key: + description: "Django secret key" + required: true + +runs: + using: composite + steps: + - name: start backend + shell: bash + run: docker run -d --network=host -e "DB_USER=postgres" -e "DB_NAME=registration" -e "DB_PORT=5432" -e "DB_HOST=localhost" -e "DJANGO_SECRET_KEY=${{ inputs.django_secret_key }}" -e "ALLOWED_HOSTS=localhost,0.0.0.0,127.0.0.1" -e "ENVIRONMENT=develop" -e "CI=true" ghcr.io/bcgov/cas-reg-backend:${{ github.sha }} diff --git a/.github/actions/local-app-run/action.yml b/.github/actions/run-registration1-app/action.yml similarity index 68% rename from .github/actions/local-app-run/action.yml rename to .github/actions/run-registration1-app/action.yml index 0bf61ea075..f034d895ba 100644 --- a/.github/actions/local-app-run/action.yml +++ b/.github/actions/run-registration1-app/action.yml @@ -19,8 +19,9 @@ runs: using: composite steps: - name: start backend - shell: bash - run: docker run -d --network=host -e "DB_USER=postgres" -e "DB_NAME=registration" -e "DB_PORT=5432" -e "DB_HOST=localhost" -e "DJANGO_SECRET_KEY=${{ inputs.django_secret_key }}" -e "ALLOWED_HOSTS=localhost,0.0.0.0,127.0.0.1" -e "ENVIRONMENT=develop" -e "CI=true" ghcr.io/bcgov/cas-reg-backend:${{ github.sha }} + uses: ./.github/actions/run-backend + with: + django_secret_key: ${{ inputs.django_secret_key }} - name: start frontend shell: bash - run: docker run -d --network=host -e "NEXTAUTH_URL_INTERNAL=http://localhost:3000/" -e "NEXTAUTH_URL=http://localhost:3000/" -e "NEXTAUTH_SECRET=${{ inputs.nextauth_secret }}" -e "API_URL=http://127.0.0.1:8000/api/" -e "KEYCLOAK_LOGIN_URL=https://dev.loginproxy.gov.bc.ca/auth/realms/standard" -e "KEYCLOAK_CLIENT_SECRET=${{ inputs.keycloak_client_secret }}" -e "KEYCLOAK_CLIENT_ID=${{ inputs.keycloak_client_id }}" ghcr.io/bcgov/cas-reg-frontend:${{ github.sha }} + run: docker run -d --network=host -e "NEXTAUTH_URL_INTERNAL=http://localhost:3000/" -e "NEXTAUTH_URL=http://localhost:3000/" -e "NEXTAUTH_SECRET=${{ inputs.nextauth_secret }}" -e "API_URL=http://127.0.0.1:8000/api/" -e "KEYCLOAK_LOGIN_URL=https://dev.loginproxy.gov.bc.ca/auth/realms/standard" -e "KEYCLOAK_CLIENT_SECRET=${{ inputs.keycloak_client_secret }}" -e "KEYCLOAK_CLIENT_ID=${{ inputs.keycloak_client_id }}" ghcr.io/bcgov/cas-reg1-frontend:${{ github.sha }} diff --git a/.github/workflows/build-backend.yaml b/.github/workflows/build-backend.yaml new file mode 100644 index 0000000000..11008e5eb5 --- /dev/null +++ b/.github/workflows/build-backend.yaml @@ -0,0 +1,55 @@ +name: Build BCIERS backend Docker container + +on: + workflow_call: + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/bcgov/cas-reg-backend + tags: | + type=sha,format=long,prefix= + latest + type=ref,event=pr + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Cache Docker layers + uses: actions/cache@v4 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-bc_obps-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx-bc_obps + - name: Build image + uses: docker/build-push-action@v5 + with: + context: bc_obps + builder: ${{ steps.buildx.outputs.name }} + push: true + file: bc_obps/Dockerfile + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + # Temp fix + # https://github.com/docker/build-push-action/issues/252 + # https://github.com/moby/buildkit/issues/1896 + - name: Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/workflows/build-registration.yaml b/.github/workflows/build-registration.yaml new file mode 100644 index 0000000000..10c670a955 --- /dev/null +++ b/.github/workflows/build-registration.yaml @@ -0,0 +1,19 @@ +name: Build Registration Docker container + +on: + workflow_call: + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Build registration container + uses: ./.github/actions/nx-app-build + with: + project: registration + image_url: ghcr.io/bcgov/cas-reg-frontend + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-registration1.yaml b/.github/workflows/build-registration1.yaml new file mode 100644 index 0000000000..e2db710e58 --- /dev/null +++ b/.github/workflows/build-registration1.yaml @@ -0,0 +1,19 @@ +name: Build Registration1 Docker container + +on: + workflow_call: + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Build registration1 container + uses: ./.github/actions/nx-app-build + with: + project: registration1 + image_url: ghcr.io/bcgov/cas-reg1-frontend + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/build-reporting.yaml b/.github/workflows/build-reporting.yaml new file mode 100644 index 0000000000..84161df05c --- /dev/null +++ b/.github/workflows/build-reporting.yaml @@ -0,0 +1,19 @@ +name: Build Reporting Docker container + +on: + workflow_call: + +jobs: + docker-build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Build reporting container + uses: ./.github/actions/nx-app-build + with: + project: reporting + image_url: ghcr.io/bcgov/cas-rep-frontend + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codeql.yaml b/.github/workflows/codeql.yaml index 1060f24690..abe32b986e 100644 --- a/.github/workflows/codeql.yaml +++ b/.github/workflows/codeql.yaml @@ -12,21 +12,12 @@ name: "CodeQL" on: - push: - branches: [main, develop] - tags: - - frontend - - backend - - configs - pull_request: - # The branches below must be a subset of the branches above - branches: [main, develop] + workflow_call: schedule: - cron: "19 23 * * 5" jobs: analyze: - name: Analyze runs-on: ubuntu-latest permissions: actions: read diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml new file mode 100644 index 0000000000..93a6159cc3 --- /dev/null +++ b/.github/workflows/main.yaml @@ -0,0 +1,54 @@ +# This is the main workflow which will orchestrate the other workflows: + +name: main + +on: + push: + branches: [develop, main] + pull_request: + branches: [develop, main] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + PGUSER: postgres + +jobs: + install-dev-tools: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - run: yarn install --immutable + working-directory: ./bciers + build-backend: + uses: ./.github/workflows/build-backend.yaml + build-registration: + uses: ./.github/workflows/build-registration.yaml + build-registration1: + uses: ./.github/workflows/build-registration1.yaml + build-reporting: + uses: ./.github/workflows/build-reporting.yaml + test-code: + needs: [install-dev-tools] + uses: ./.github/workflows/test-code.yaml + test-backend: + needs: [build-backend, install-dev-tools] + uses: ./.github/workflows/test-backend.yaml + secrets: inherit + test-e2e: + needs: [build-registration1, install-dev-tools] + uses: ./.github/workflows/test-e2e.yaml + secrets: inherit + zap-owasp: + # We will need to set up registration part 2 and reporting to get zap scanned + needs: [build-backend, build-registration1, install-dev-tools] + uses: ./.github/workflows/zap-owasp.yaml + trivy: + uses: ./.github/workflows/trivy.yaml + codeql: + uses: ./.github/workflows/codeql.yaml diff --git a/.github/workflows/test-backend.yaml b/.github/workflows/test-backend.yaml new file mode 100644 index 0000000000..e4ca80e22e --- /dev/null +++ b/.github/workflows/test-backend.yaml @@ -0,0 +1,26 @@ +# This file is used for tests that use the backend container +# For tests that don't require containers to be built first, see test-code.yaml + +name: Test BCIERS backend container + +on: + workflow_call: + +env: + PGUSER: postgres + DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} + +jobs: + pythontests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - name: start backend + uses: ./.github/actions/run-backend + with: + django_secret_key: ${{ env.DJANGO_SECRET_KEY }} + - name: Run pytest + working-directory: ./bc_obps + run: make pythontests diff --git a/.github/workflows/test-code.yaml b/.github/workflows/test-code.yaml new file mode 100644 index 0000000000..7b3a270fdb --- /dev/null +++ b/.github/workflows/test-code.yaml @@ -0,0 +1,76 @@ +# This workflow is to run all tests that don't require containers to be built + +name: Test BCIERS code + +on: + workflow_call: + +env: + PGUSER: postgres + DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} + KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }} + KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} + NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} + +jobs: + nx-tests: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./bciers + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - name: Run Nx Affected Tests with Remote Caching + id: nx-tests + run: | + yarn nx affected --base=origin/develop --target=test --parallel + shell: bash + + yarn-audit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - run: yarn npm audit + working-directory: ./bciers + + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - name: set pre-commit cache directory + run: | + echo "PRE_COMMIT_HOME=$GITHUB_WORKSPACE/.pre-commit-cache" >> $GITHUB_ENV + - name: set PY + run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV + - name: create commitlint COMMIT_EDITMSG if not exists + run: | + if test -f ".git/COMMIT_EDITMSG"; then + echo "COMMIT_EDITMSG EXISTS, skipping" + else + touch .git/COMMIT_EDITMSG + fi + - uses: actions/cache@v4 + with: + path: | + ./.pre-commit-cache + key: pre-commit-${{ env.PY }}-${{ hashFiles('.pre-commit-config.yaml') }}-v4 + - run: pip install -r requirements.txt + - uses: pre-commit/action@v3.0.1 + + check-migrations: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - run: poetry run python manage.py makemigrations --check --dry-run + working-directory: ./bc_obps diff --git a/.github/workflows/test-e2e.yaml b/.github/workflows/test-e2e.yaml new file mode 100644 index 0000000000..3f0c2b3ba7 --- /dev/null +++ b/.github/workflows/test-e2e.yaml @@ -0,0 +1,154 @@ +# This file is used for tests that use Nx app containers. +# For tests that don't require containers to be built first, see test-code.yaml + +name: Test BCIERS Nx App containers + +on: + workflow_call: + +env: + PGUSER: postgres + DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} + KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }} + KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} + NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} + +jobs: + e2e-tests: + name: ๐Ÿงช e2e tests ${{ matrix.project }} + runs-on: ubuntu-latest + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - project: chromium + os: ubuntu-latest + cache_dir: ~/.cache/ms-playwright + - project: firefox + os: ubuntu-latest + cache_dir: ~/.cache/ms-playwright + # Commented out because of flakey issues with webkit in CI + # - project: webkit + # os: macos-latest + # cache_dir: ~/Library/Caches/ms-playwright + steps: + - uses: actions/checkout@v4 + + - name: ๐ŸŽ setup dev env + uses: ./.github/actions/dev-env-setup + + - name: ๐ŸŽ setup local app + uses: ./.github/actions/run-registration1-app + with: + django_secret_key: ${{ env.DJANGO_SECRET_KEY }} + keycloak_client_id: ${{ env.KEYCLOAK_CLIENT_ID }} + keycloak_client_secret: ${{ env.KEYCLOAK_CLIENT_SECRET }} + nextauth_secret: ${{ env.NEXTAUTH_SECRET }} + - name: โšก๏ธ cache Playwright binaries + uses: actions/cache@v4 + id: playwright-cache + with: + path: ${{ matrix.cache_dir }} + key: ${{ runner.os }}-${{ matrix.project }}-ms-playwright-registration + + - name: ๐Ÿ“ฅ install Playwright ${{ matrix.project }} + if: steps.playwright-cache.outputs.cache-hit != 'true' + run: npx playwright install --with-deps ${{ matrix.project }} + working-directory: ./bciers/apps/registration1 + + - name: ๐ŸŽญ Run Playwright Tests + run: | + npx happo-e2e -- npx playwright test --project=${{ matrix.project }} bciers/apps/registration1/e2e/* + env: + XDEBUG: pw:api,pw:browser* + API_URL: http://127.0.0.1:8000/api/ + DB_USER: postgres + DB_NAME: registration + DB_PORT: 5432 + DB_HOST: localhost + E2E_BASEURL: http://localhost:3000/ + E2E_CAS_USER: ${{ secrets.E2E_CAS_USER }} + E2E_CAS_USER_GUID: ${{ secrets.E2E_CAS_USER_GUID }} + E2E_CAS_USER_PASSWORD: ${{ secrets.E2E_CAS_USER_PASSWORD}} + E2E_CAS_ADMIN_STORAGE_STATE: ${{ secrets.E2E_CAS_ADMIN_STORAGE_STATE}} + E2E_CAS_ANALYST_STORAGE_STATE: ${{ secrets.E2E_CAS_ANALYST_STORAGE_STATE}} + E2E_CAS_PENDING_STORAGE_STATE: ${{ secrets.E2E_CAS_PENDING_STORAGE_STATE}} + E2E_INDUSTRY_USER_ADMIN: bc-cas-dev + E2E_INDUSTRY_USER_ADMIN_GUID: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_GUID }} + E2E_INDUSTRY_USER_ADMIN_PASSWORD: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_PASSWORD }} + E2E_INDUSTRY_USER_ADMIN_STORAGE_STATE: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_STORAGE_STATE}} + E2E_INDUSTRY_USER: bc-cas-dev-secondary + E2E_INDUSTRY_USER_GUID: ${{ secrets.E2E_INDUSTRY_USER_GUID }} + E2E_INDUSTRY_USER_PASSWORD: ${{ secrets.E2E_INDUSTRY_USER_PASSWORD }} + E2E_INDUSTRY_USER_STORAGE_STATE: ${{ secrets.E2E_INDUSTRY_USER_STORAGE_STATE}} + E2E_NEW_USER: bc-cas-dev-three + E2E_NEW_USER_GUID: ${{ secrets.E2E_NEW_USER_GUID }} + E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }} + E2E_NEW_USER_STORAGE_STATE: ${{ secrets.E2E_NEW_USER_STORAGE_STATE}} + HAPPO_API_KEY: ${{ secrets.HAPPO_API_KEY }} + HAPPO_API_SECRET: ${{ secrets.HAPPO_API_SECRET }} + HAPPO_NONCE: ${{ github.sha }} + SMTP_CONNECTION_STRING: smtp://@localhost:1025 + working-directory: ./bciers/apps/registration1 + - name: ๐Ÿ’พ save ${{ matrix.project }} report artifact + # prefer to upload the report only in case of test failure + if: failure() + uses: actions/upload-artifact@v4 + with: + # Store all of the reports separately by reconfiguring the report name + name: blob-report-${{ matrix.project }} + path: bciers/blob-report + retention-days: 1 + # Merge the e2e blob reports to one HTML report + e2e-report: + name: ๐Ÿ“Š e2e report artifact + runs-on: ubuntu-latest + needs: [e2e-tests] + if: ${{ always() && contains(needs.*.result, 'failure') }} + steps: + - name: Download blob reports from GitHub Actions Artifacts + uses: actions/download-artifact@v4 + with: + path: all-blob-reports + # To minimize the report file size only download Chromium reports + # If you want to debug other reports, add the * pattern back in temporarily + pattern: blob-report-chromium #blob-report-* + merge-multiple: true + + - name: Merge into HTML Report + run: npx playwright merge-reports --reporter html ./all-blob-reports + - name: Upload HTML report + uses: actions/upload-artifact@v4 + with: + name: playwright-report + path: playwright-report + retention-days: 14 + # Ensure the e2e tests and e2e report completed successfully + e2e: + if: ${{ always() }} + runs-on: ubuntu-latest + needs: [e2e-tests] + steps: + - run: exit 1 + if: >- + ${{ + contains(needs.*.result, 'failure') + || contains(needs.*.result, 'cancelled') + || contains(needs.*.result, 'skipped') + }} + + happo-finalize: + runs-on: ubuntu-latest + needs: [e2e-tests] + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - name: finalize happo e2e tests + env: + HAPPO_API_KEY: ${{ secrets.HAPPO_API_KEY }} + HAPPO_API_SECRET: ${{ secrets.HAPPO_API_SECRET }} + HAPPO_NONCE: ${{ github.sha }} + run: npx happo-e2e finalize + working-directory: ./bciers/apps/registration1 diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml deleted file mode 100644 index 38825d30c4..0000000000 --- a/.github/workflows/test.yaml +++ /dev/null @@ -1,475 +0,0 @@ -name: Test Registration App - -on: - push: - branches: [develop, main, dylan/nx-3] - tags: - - frontend - - backend - - components - pull_request: - branches: [develop, main] - workflow_dispatch: - -env: - PGUSER: postgres - DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} - KEYCLOAK_CLIENT_ID: ${{ secrets.KEYCLOAK_CLIENT_ID }} - KEYCLOAK_CLIENT_SECRET: ${{ secrets.KEYCLOAK_CLIENT_SECRET }} - NEXTAUTH_SECRET: ${{ secrets.NEXTAUTH_SECRET }} - -# Cancel current job when pushing new commit into the PR -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - install-dev-tools: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - run: yarn install --immutable - working-directory: ./bciers - - nx-tests: - needs: install-dev-tools - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./bciers - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - name: Run Nx Affected Tests with Remote Caching - id: nx-tests - run: | - yarn nx affected --base=origin/develop --target=test --parallel - shell: bash - - yarn-audit: - needs: install-dev-tools - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - run: yarn npm audit - working-directory: ./bciers - - pre-commit: - needs: install-dev-tools - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - name: set pre-commit cache directory - run: | - echo "PRE_COMMIT_HOME=$GITHUB_WORKSPACE/.pre-commit-cache" >> $GITHUB_ENV - - name: set PY - run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - name: create commitlint COMMIT_EDITMSG if not exists - run: | - if test -f ".git/COMMIT_EDITMSG"; then - echo "COMMIT_EDITMSG EXISTS, skipping" - else - touch .git/COMMIT_EDITMSG - fi - - uses: actions/cache@v4 - with: - path: | - ./.pre-commit-cache - key: pre-commit-${{ env.PY }}-${{ hashFiles('.pre-commit-config.yaml') }}-v4 - - run: pip install -r requirements.txt - - uses: pre-commit/action@v3.0.1 - - backend-docker-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - install: true - - name: Docker meta - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/bcgov/cas-reg-backend - tags: | - type=sha,format=long,prefix= - latest - type=ref,event=pr - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Cache Docker layers - uses: actions/cache@v4 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-bc_obps-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx-bc_obps - - name: Build image - uses: docker/build-push-action@v5 - with: - context: bc_obps - builder: ${{ steps.buildx.outputs.name }} - push: true - file: bc_obps/Dockerfile - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache - - nx-docker-build-registration: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./bciers - needs: backend-docker-build - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/bcgov/cas-reg-frontend - tags: | - type=sha,format=long,prefix= - latest - type=ref,event=pr - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Install dependencies - run: | - corepack enable - yarn install --immutable - cd ../bciers && yarn install --immutable - - uses: actions/setup-node@v4 - - name: Derive appropriate SHAs for base and head for `nx affected` commands - uses: nrwl/nx-set-shas@v4 - with: - main-branch-name: "develop" - - name: Cache Docker layers - uses: actions/cache@v4 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-bciers-registration${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx-bciers-registration - - name: Build images - env: - INPUT_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - INPUT_PUSH: true - INPUT_TAGS: ${{ steps.meta.outputs.tags }} - INPUT_LABELS: ${{ steps.meta.output.labels }} - INPUT_CACHE_FROM: type=local,src=/tmp/.buildx-cache - INPUT_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new - run: | - npx nx container registration1 --skip-nx-cache - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache - - nx-docker-build-reporting: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ./bciers - needs: backend-docker-build - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Docker metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/bcgov/cas-rep-frontend - tags: | - type=sha,format=long,prefix= - latest - type=ref,event=pr - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Install dependencies - run: | - corepack enable - yarn install --immutable - cd ../bciers && yarn install --immutable - - uses: actions/setup-node@v4 - - name: Derive appropriate SHAs for base and head for `nx affected` commands - uses: nrwl/nx-set-shas@v4 - with: - main-branch-name: "develop" - - name: Cache Docker layers - uses: actions/cache@v4 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-bciers-reporting${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx-bciers-reporting - - name: Build images - env: - INPUT_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - INPUT_PUSH: true - INPUT_TAGS: ${{ steps.meta.outputs.tags }} - INPUT_LABELS: ${{ steps.meta.output.labels }} - INPUT_CACHE_FROM: type=local,src=/tmp/.buildx-cache - INPUT_CACHE_TO: type=local,dest=/tmp/.buildx-cache-new - run: | - npx nx container reporting --skip-nx-cache - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache - - zap-owasp: - needs: - [ - "backend-docker-build", - "nx-docker-build-registration", - "install-dev-tools", - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - name: run app locally - uses: ./.github/actions/local-app-run - with: - django_secret_key: ${{ env.DJANGO_SECRET_KEY }} - - name: ZAP Frontend Scan - uses: zaproxy/action-baseline@v0.12.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - docker_name: "ghcr.io/zaproxy/zaproxy:stable" - target: "http://localhost:3000/" - rules_file_name: ".zap/rules-frontend.tsv" - cmd_options: "-a -d -T 5 -m 2" - issue_title: OWASP Baseline - Frontend - fail_action: false - - name: ZAP Backend Scan - uses: zaproxy/action-baseline@v0.12.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - docker_name: "ghcr.io/zaproxy/zaproxy:stable" - target: "http://0.0.0.0:8000/" - rules_file_name: ".zap/rules-backend.tsv" - cmd_options: "-a -d -T 5 -m 2" - issue_title: OWASP Baseline - Backend - fail_action: false - - e2e-tests: - name: ๐Ÿงช e2e tests ${{ matrix.project }} - needs: - - backend-docker-build - - nx-docker-build-registration - - install-dev-tools - runs-on: ubuntu-latest - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - include: - - project: chromium - os: ubuntu-latest - cache_dir: ~/.cache/ms-playwright - - project: firefox - os: ubuntu-latest - cache_dir: ~/.cache/ms-playwright - # Commented out because of flakey issues with webkit in CI - # - project: webkit - # os: macos-latest - # cache_dir: ~/Library/Caches/ms-playwright - steps: - - uses: actions/checkout@v4 - - - name: ๐ŸŽ setup dev env - uses: ./.github/actions/dev-env-setup - - - name: ๐ŸŽ setup local app - uses: ./.github/actions/local-app-run - with: - django_secret_key: ${{ env.DJANGO_SECRET_KEY }} - keycloak_client_id: ${{ env.KEYCLOAK_CLIENT_ID }} - keycloak_client_secret: ${{ env.KEYCLOAK_CLIENT_SECRET }} - nextauth_secret: ${{ env.NEXTAUTH_SECRET }} - - name: โšก๏ธ cache Playwright binaries - uses: actions/cache@v4 - id: playwright-cache - with: - path: ${{ matrix.cache_dir }} - key: ${{ runner.os }}-${{ matrix.project }}-ms-playwright-registration - - - name: ๐Ÿ“ฅ install Playwright ${{ matrix.project }} - if: steps.playwright-cache.outputs.cache-hit != 'true' - run: npx playwright install --with-deps ${{ matrix.project }} - working-directory: ./bciers/apps/registration1 - - - name: ๐ŸŽญ Run Playwright Tests - run: | - npx happo-e2e -- npx playwright test --project=${{ matrix.project }} bciers/apps/registration1/e2e/* - env: - XDEBUG: pw:api,pw:browser* - API_URL: http://127.0.0.1:8000/api/ - DB_USER: postgres - DB_NAME: registration - DB_PORT: 5432 - DB_HOST: localhost - E2E_BASEURL: http://localhost:3000/ - E2E_CAS_USER: ${{ secrets.E2E_CAS_USER }} - E2E_CAS_USER_GUID: ${{ secrets.E2E_CAS_USER_GUID }} - E2E_CAS_USER_PASSWORD: ${{ secrets.E2E_CAS_USER_PASSWORD}} - E2E_CAS_ADMIN_STORAGE_STATE: ${{ secrets.E2E_CAS_ADMIN_STORAGE_STATE}} - E2E_CAS_ANALYST_STORAGE_STATE: ${{ secrets.E2E_CAS_ANALYST_STORAGE_STATE}} - E2E_CAS_PENDING_STORAGE_STATE: ${{ secrets.E2E_CAS_PENDING_STORAGE_STATE}} - E2E_INDUSTRY_USER_ADMIN: bc-cas-dev - E2E_INDUSTRY_USER_ADMIN_GUID: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_GUID }} - E2E_INDUSTRY_USER_ADMIN_PASSWORD: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_PASSWORD }} - E2E_INDUSTRY_USER_ADMIN_STORAGE_STATE: ${{ secrets.E2E_INDUSTRY_USER_ADMIN_STORAGE_STATE}} - E2E_INDUSTRY_USER: bc-cas-dev-secondary - E2E_INDUSTRY_USER_GUID: ${{ secrets.E2E_INDUSTRY_USER_GUID }} - E2E_INDUSTRY_USER_PASSWORD: ${{ secrets.E2E_INDUSTRY_USER_PASSWORD }} - E2E_INDUSTRY_USER_STORAGE_STATE: ${{ secrets.E2E_INDUSTRY_USER_STORAGE_STATE}} - E2E_NEW_USER: bc-cas-dev-three - E2E_NEW_USER_GUID: ${{ secrets.E2E_NEW_USER_GUID }} - E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }} - E2E_NEW_USER_STORAGE_STATE: ${{ secrets.E2E_NEW_USER_STORAGE_STATE}} - HAPPO_API_KEY: ${{ secrets.HAPPO_API_KEY }} - HAPPO_API_SECRET: ${{ secrets.HAPPO_API_SECRET }} - HAPPO_NONCE: ${{ github.sha }} - SMTP_CONNECTION_STRING: smtp://@localhost:1025 - working-directory: ./bciers/apps/registration1 - - name: ๐Ÿ’พ save ${{ matrix.project }} report artifact - # prefer to upload the report only in case of test failure - if: failure() - uses: actions/upload-artifact@v4 - with: - # Store all of the reports separately by reconfiguring the report name - name: blob-report-${{ matrix.project }} - path: bciers/blob-report - retention-days: 1 - # Merge the e2e blob reports to one HTML report - e2e-report: - name: ๐Ÿ“Š e2e report artifact - runs-on: ubuntu-latest - needs: [e2e-tests] - if: ${{ always() && contains(needs.*.result, 'failure') }} - steps: - - name: Download blob reports from GitHub Actions Artifacts - uses: actions/download-artifact@v4 - with: - path: all-blob-reports - # To minimize the report file size only download Chromium reports - # If you want to debug other reports, add the * pattern back in temporarily - pattern: blob-report-chromium #blob-report-* - merge-multiple: true - - - name: Merge into HTML Report - run: npx playwright merge-reports --reporter html ./all-blob-reports - - name: Upload HTML report - uses: actions/upload-artifact@v4 - with: - name: playwright-report - path: playwright-report - retention-days: 14 - # Ensure the e2e tests and e2e report completed successfully - e2e: - if: ${{ always() }} - runs-on: ubuntu-latest - needs: [e2e-tests] - steps: - - run: exit 1 - if: >- - ${{ - contains(needs.*.result, 'failure') - || contains(needs.*.result, 'cancelled') - || contains(needs.*.result, 'skipped') - }} - - happo-finalize: - runs-on: ubuntu-latest - needs: [e2e-tests] - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - name: finalize happo e2e tests - env: - HAPPO_API_KEY: ${{ secrets.HAPPO_API_KEY }} - HAPPO_API_SECRET: ${{ secrets.HAPPO_API_SECRET }} - HAPPO_NONCE: ${{ github.sha }} - run: npx happo-e2e finalize - working-directory: ./bciers/apps/registration1 - - backend-tests: - needs: - [ - "backend-docker-build", - "nx-docker-build-registration", - "install-dev-tools", - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - name: run app locally - uses: ./.github/actions/local-app-run - with: - django_secret_key: ${{ env.DJANGO_SECRET_KEY }} - - name: Run pytest - working-directory: ./bc_obps - run: make pythontests - check-migrations: - needs: install-dev-tools - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: dev env setup - uses: ./.github/actions/dev-env-setup - - run: poetry run python manage.py makemigrations --check --dry-run - working-directory: ./bc_obps diff --git a/.github/workflows/scan-code-trivy.yaml b/.github/workflows/trivy.yaml similarity index 73% rename from .github/workflows/scan-code-trivy.yaml rename to .github/workflows/trivy.yaml index 0f33494e55..abc4cc3011 100644 --- a/.github/workflows/scan-code-trivy.yaml +++ b/.github/workflows/trivy.yaml @@ -1,21 +1,10 @@ name: Trivy Scan Code on: - push: - branches: [main, develop] - tags: - - frontend - - backend - pull_request: - # The branches below must be a subset of the branches above - branches: [main, develop] - -concurrency: - group: callee-trivy-${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true + workflow_call: jobs: - trivy-scan-code: + analyze: runs-on: ubuntu-latest timeout-minutes: 60 steps: diff --git a/.github/workflows/zap-owasp.yaml b/.github/workflows/zap-owasp.yaml new file mode 100644 index 0000000000..819442da53 --- /dev/null +++ b/.github/workflows/zap-owasp.yaml @@ -0,0 +1,40 @@ +name: ZAP OWASP Scan Code + +on: + workflow_call: + +env: + PGUSER: postgres + DJANGO_SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }} + +jobs: + zap-scan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: dev env setup + uses: ./.github/actions/dev-env-setup + - name: run app locally + uses: ./.github/actions/run-registration1-app + with: + django_secret_key: ${{ env.DJANGO_SECRET_KEY }} + - name: ZAP Frontend Scan + uses: zaproxy/action-baseline@v0.12.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + docker_name: "ghcr.io/zaproxy/zaproxy:stable" + target: "http://localhost:3000/" + rules_file_name: ".zap/rules-frontend.tsv" + cmd_options: "-a -d -T 5 -m 2" + issue_title: OWASP Baseline - Frontend + fail_action: false + - name: ZAP Backend Scan + uses: zaproxy/action-baseline@v0.12.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + docker_name: "ghcr.io/zaproxy/zaproxy:stable" + target: "http://0.0.0.0:8000/" + rules_file_name: ".zap/rules-backend.tsv" + cmd_options: "-a -d -T 5 -m 2" + issue_title: OWASP Baseline - Backend + fail_action: false diff --git a/bciers/apps/registration/Dockerfile b/bciers/apps/registration/Dockerfile new file mode 100644 index 0000000000..557cae4314 --- /dev/null +++ b/bciers/apps/registration/Dockerfile @@ -0,0 +1,34 @@ +# Install dependencies only when needed +FROM docker.io/node:20.11 as deps +WORKDIR /usr/src/app +COPY ./package*.json ./ +RUN corepack enable +RUN corepack enable +RUN yarn set version 4.2.0 +# Force Yarn to use standard node-modules folder +RUN echo 'nodeLinker: "node-modules"' >> ./.yarnrc.yml +RUN yarn install + +# Production image, copy all the files and run next +FROM docker.io/node:20.11 as runner + +ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64 /usr/local/bin/dumb-init +RUN chmod +x /usr/local/bin/dumb-init +ENTRYPOINT ["dumb-init", "--"] + +ENV NODE_ENV production +ENV PORT 3000 +WORKDIR /usr/src/app +COPY --from=deps --chown=node:node /usr/src/app/node_modules node_modules +COPY --from=deps --chown=node:node /usr/src/app/package.json package.json +COPY --chown=node:node ./public ./public +COPY --chown=node:node ./.next ./.next +USER node +EXPOSE 3000 +# COPY --chown=node:node ./tools/scripts/entrypoints/api.sh /usr/local/bin/docker-entrypoint.sh +# ENTRYPOINT [ "docker-entrypoint.sh" ] +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry. +ENV NEXT_TELEMETRY_DISABLED 1 +CMD ["node_modules/.bin/next", "start"] diff --git a/bciers/apps/registration/project.json b/bciers/apps/registration/project.json index bc8ed55001..01f50af1c3 100644 --- a/bciers/apps/registration/project.json +++ b/bciers/apps/registration/project.json @@ -16,7 +16,9 @@ "outputs": ["{options.outputPath}"], "defaultConfiguration": "dev", "options": { - "outputPath": "dist/registration" + "outputPath": "dist/registration", + "experimentalAppOnly": true, + "generateLockfile": true } }, "start": { diff --git a/bciers/apps/registration1/project.json b/bciers/apps/registration1/project.json index ff9b1faf5a..00f47a061e 100644 --- a/bciers/apps/registration1/project.json +++ b/bciers/apps/registration1/project.json @@ -29,7 +29,7 @@ "engine": "docker", "context": "dist/registration1", "file": "apps/registration1/Dockerfile", - "tags": ["cas-registration:latest"] + "tags": ["cas-registration1:latest"] } }, "lint": { diff --git a/helm/cas-registration/templates/frontend/deployment.yaml b/helm/cas-registration/templates/frontend/deployment.yaml deleted file mode 100644 index a40201813c..0000000000 --- a/helm/cas-registration/templates/frontend/deployment.yaml +++ /dev/null @@ -1,80 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "cas-registration.fullname" . }}-frontend - labels: - component: frontend -{{- include "cas-registration.labels" . | nindent 4 }} -spec: -{{- if not .Values.frontend.autoscaling.enabled }} - replicas: {{ .Values.frontend.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "cas-registration.selectorLabels" . | nindent 6 }} - component: frontend - strategy: - type: RollingUpdate - template: - metadata: - labels: -{{- include "cas-registration.selectorLabels" . | nindent 8 }} - component: frontend - spec: - containers: - - name: {{ template "cas-registration.fullname" . }}-frontend - env: - - name: API_URL - value: http://{{ include "cas-registration.fullname" . }}-backend.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.service.port }}/api/ - - name: KEYCLOAK_CLIENT_SECRET - valueFrom: - secretKeyRef: - name: keycloak-gold-client-secret - key: kcClientSecret - - name: KEYCLOAK_AUTH_URL - value: {{ .Values.frontend.auth.keycloakAuthUrl}} - - name: KEYCLOAK_REALMS - value: {{ .Values.frontend.auth.keycloakRealms}} - - name: KEYCLOAK_OIDC - value: {{ .Values.frontend.auth.keycloakOidc}} - - name: KEYCLOAK_LOGIN_URL - value: {{ .Values.frontend.auth.keycloakAuthUrl}}{{ .Values.frontend.auth.keycloakRealms }} - - name: KEYCLOAK_LOGOUT_URL - value: {{ .Values.frontend.auth.keycloakAuthUrl}}{{ .Values.frontend.auth.keycloakRealms }}{{ .Values.frontend.auth.keycloakOidc}}/logout - - name: KEYCLOAK_TOKEN_URL - value: {{ .Values.frontend.auth.keycloakAuthUrl}}{{ .Values.frontend.auth.keycloakRealms }}{{ .Values.frontend.auth.keycloakOidc}}/token - - name: NEXTAUTH_URL - value: https://{{ .Values.frontend.route.host }} - - name: SITEMINDER_AUTH_URL - value: {{ .Values.frontend.auth.siteminderAuthUrl }} - - name: SITEMINDER_LOGOUT_URL - value: {{ .Values.frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi - - name: NEXT_PUBLIC_KEYCLOAK_LOGOUT_URL - value: {{ .Values.frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.frontend.auth.keycloakAuthUrl}}{{ .Values.frontend.auth.keycloakRealms }}{{ .Values.frontend.auth.keycloakOidc}}/logout - - name: KEYCLOAK_CLIENT_ID - value: {{ .Values.frontend.auth.keycloakClientId }} - - name: SITEMINDER_KEYCLOAK_LOGOUT_URL - value: {{ .Values.frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.frontend.auth.keycloakAuthUrl}}{{ .Values.frontend.auth.keycloakRealms }}{{ .Values.frontend.auth.keycloakOidc}}/logout - - name: NEXTAUTH_SECRET - valueFrom: - secretKeyRef: - name: {{ template "cas-registration.fullname" . }}-nextauth - key: nextauth-secret - - name: NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY - value: {{ .Values.growthbook.clientKey }} - {{- if hasSuffix "-prod" .Release.Namespace }} - - name: SENTRY_ENVIRONMENT - value: {{ include "cas-registration.namespaceSuffix" . }} - - name: SENTRY_RELEASE - value: {{ .Values.frontend.image.tag }} - - name: SENTRY_TRACE_SAMPLE_RATE - value: {{ .Values.frontend.sentry.traceSampleRate | quote }} - {{- end }} - image: "{{ .Values.frontend.image.repository }}:{{ .Values.defaultImageTag | default .Values.frontend.image.tag }}" - imagePullPolicy: {{ .Values.frontend.image.pullPolicy }} - ports: - - containerPort: {{ .Values.frontend.service.port }} - protocol: TCP - resources: - {{- toYaml .Values.frontend.resources | nindent 12 }} - restartPolicy: Always diff --git a/helm/cas-registration/templates/frontend/hpa.yaml b/helm/cas-registration/templates/frontend/hpa.yaml deleted file mode 100644 index 2c807e03e0..0000000000 --- a/helm/cas-registration/templates/frontend/hpa.yaml +++ /dev/null @@ -1,28 +0,0 @@ -{{- if .Values.frontend.autoscaling.enabled }} -apiVersion: autoscaling/v2beta1 -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "cas-registration.fullname" . }}-frontend - labels: - {{- include "cas-registration.labels" . | nindent 4 }} -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ include "cas-registration.fullname" . }}-frontend - minReplicas: {{ .Values.frontend.autoscaling.minReplicas }} - maxReplicas: {{ .Values.frontend.autoscaling.maxReplicas }} - metrics: - {{- if .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - targetAverageUtilization: {{ .Values.frontend.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - targetAverageUtilization: {{ .Values.frontend.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} -{{- end }} diff --git a/helm/cas-registration/templates/frontend/service.yaml b/helm/cas-registration/templates/frontend/service.yaml deleted file mode 100644 index f63c618049..0000000000 --- a/helm/cas-registration/templates/frontend/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: {{ include "cas-registration.fullname" . }}-frontend - labels: - {{- include "cas-registration.labels" . | nindent 4 }} -spec: - type: {{ .Values.frontend.service.type }} - ports: - - port: {{ .Values.frontend.service.port }} - targetPort: 3000 - protocol: TCP - name: {{ include "cas-registration.fullname" . }}-frontend - selector: - {{- include "cas-registration.selectorLabels" . | nindent 4 }} - component: frontend diff --git a/helm/cas-registration/templates/registration/deployment.yaml b/helm/cas-registration/templates/registration/deployment.yaml new file mode 100644 index 0000000000..cf42d20824 --- /dev/null +++ b/helm/cas-registration/templates/registration/deployment.yaml @@ -0,0 +1,82 @@ +{{- if (.Values.registrationFrontend.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cas-registration.fullname" . }}-registration-frontend + labels: + component: registration-frontend +{{- include "cas-registration.labels" . | nindent 4 }} +spec: +{{- if not .Values.registrationFrontend.autoscaling.enabled }} + replicas: {{ .Values.registrationFrontend.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "cas-registration.selectorLabels" . | nindent 6 }} + component: registration-frontend + strategy: + type: RollingUpdate + template: + metadata: + labels: +{{- include "cas-registration.selectorLabels" . | nindent 8 }} + component: registration-frontend + spec: + containers: + - name: {{ template "cas-registration.fullname" . }}-registration-frontend + env: + - name: API_URL + value: http://{{ include "cas-registration.fullname" . }}-backend.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.service.port }}/api/ + - name: KEYCLOAK_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: keycloak-gold-client-secret + key: kcClientSecret + - name: KEYCLOAK_AUTH_URL + value: {{ .Values.registrationFrontend.auth.keycloakAuthUrl}} + - name: KEYCLOAK_REALMS + value: {{ .Values.registrationFrontend.auth.keycloakRealms}} + - name: KEYCLOAK_OIDC + value: {{ .Values.registrationFrontend.auth.keycloakOidc}} + - name: KEYCLOAK_LOGIN_URL + value: {{ .Values.registrationFrontend.auth.keycloakAuthUrl}}{{ .Values.registrationFrontend.auth.keycloakRealms }} + - name: KEYCLOAK_LOGOUT_URL + value: {{ .Values.registrationFrontend.auth.keycloakAuthUrl}}{{ .Values.registrationFrontend.auth.keycloakRealms }}{{ .Values.registrationFrontend.auth.keycloakOidc}}/logout + - name: KEYCLOAK_TOKEN_URL + value: {{ .Values.registrationFrontend.auth.keycloakAuthUrl}}{{ .Values.registrationFrontend.auth.keycloakRealms }}{{ .Values.registrationFrontend.auth.keycloakOidc}}/token + - name: NEXTAUTH_URL + value: https://{{ .Values.registrationFrontend.route.host }} + - name: SITEMINDER_AUTH_URL + value: {{ .Values.registrationFrontend.auth.siteminderAuthUrl }} + - name: SITEMINDER_LOGOUT_URL + value: {{ .Values.registrationFrontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi + - name: NEXT_PUBLIC_KEYCLOAK_LOGOUT_URL + value: {{ .Values.registrationFrontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.registrationFrontend.auth.keycloakAuthUrl}}{{ .Values.registrationFrontend.auth.keycloakRealms }}{{ .Values.registrationFrontend.auth.keycloakOidc}}/logout + - name: KEYCLOAK_CLIENT_ID + value: {{ .Values.registrationFrontend.auth.keycloakClientId }} + - name: SITEMINDER_KEYCLOAK_LOGOUT_URL + value: {{ .Values.registrationFrontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.registrationFrontend.auth.keycloakAuthUrl}}{{ .Values.registrationFrontend.auth.keycloakRealms }}{{ .Values.registrationFrontend.auth.keycloakOidc}}/logout + - name: NEXTAUTH_SECRET + valueFrom: + secretKeyRef: + name: {{ template "cas-registration.fullname" . }}-nextauth + key: nextauth-secret + - name: NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY + value: {{ .Values.growthbook.clientKey }} + {{- if hasSuffix "-prod" .Release.Namespace }} + - name: SENTRY_ENVIRONMENT + value: {{ include "cas-registration.namespaceSuffix" . }} + - name: SENTRY_RELEASE + value: {{ .Values.registrationFrontend.image.tag }} + - name: SENTRY_TRACE_SAMPLE_RATE + value: {{ .Values.registrationFrontend.sentry.traceSampleRate | quote }} + {{- end }} + image: "{{ .Values.registrationFrontend.image.repository }}:{{ .Values.defaultImageTag | default .Values.registrationFrontend.image.tag }}" + imagePullPolicy: {{ .Values.registrationFrontend.image.pullPolicy }} + ports: + - containerPort: {{ .Values.registrationFrontend.service.port }} + protocol: TCP + resources: + {{- toYaml .Values.registrationFrontend.resources | nindent 12 }} + restartPolicy: Always +{{- end }} diff --git a/helm/cas-registration/templates/registration/hpa.yaml b/helm/cas-registration/templates/registration/hpa.yaml new file mode 100644 index 0000000000..07fe2d639f --- /dev/null +++ b/helm/cas-registration/templates/registration/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.registration1Frontend.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "cas-registration.fullname" . }}-registration-frontend + labels: + {{- include "cas-registration.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "cas-registration.fullname" . }}-registration-frontend + minReplicas: {{ .Values.registrationFrontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.registrationFrontend.autoscaling.maxReplicas }} + metrics: + {{- if .Values.registrationFrontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.registrationFrontend.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.registrationFrontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.registrationFrontend.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/cas-registration/templates/registration/route.yaml b/helm/cas-registration/templates/registration/route.yaml new file mode 100644 index 0000000000..b881e9377f --- /dev/null +++ b/helm/cas-registration/templates/registration/route.yaml @@ -0,0 +1,24 @@ +{{- if (.Values.registrationFrontend.enabled) }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ template "cas-registration.fullname" . }}-registration-frontend + labels: +{{ include "cas-registration.labels" . | indent 4 }} + annotations: + haproxy.router.openshift.io/balance: roundrobin + haproxy.router.openshift.io/rewrite-target: / + +spec: + host: {{ .Values.registrationFrontend.route.host }} + path: {{ .Values.registrationFrontend.route.path }} + port: + targetPort: {{ template "cas-registration.fullname" . }}-registration-frontend + tls: + insecureEdgeTerminationPolicy: Redirect + termination: edge + to: + kind: Service + name: {{ template "cas-registration.fullname" . }}-registration-frontend + weight: 100 +{{- end }} diff --git a/helm/cas-registration/templates/registration/service.yaml b/helm/cas-registration/templates/registration/service.yaml new file mode 100644 index 0000000000..935f851327 --- /dev/null +++ b/helm/cas-registration/templates/registration/service.yaml @@ -0,0 +1,18 @@ +{{- if (.Values.registrationFrontend.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "cas-registration.fullname" . }}-registration-frontend + labels: + {{- include "cas-registration.labels" . | nindent 4 }} +spec: + type: {{ .Values.registrationFrontend.service.type }} + ports: + - port: {{ .Values.registrationFrontend.service.port }} + targetPort: 3000 + protocol: TCP + name: {{ include "cas-registration.fullname" . }}-registration-frontend + selector: + {{- include "cas-registration.selectorLabels" . | nindent 4 }} + component: frontend +{{- end }} diff --git a/helm/cas-registration/templates/registration1/deployment.yaml b/helm/cas-registration/templates/registration1/deployment.yaml new file mode 100644 index 0000000000..85d2045dee --- /dev/null +++ b/helm/cas-registration/templates/registration1/deployment.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "cas-registration.fullname" . }}-registration1-frontend + labels: + component: registration1-frontend +{{- include "cas-registration.labels" . | nindent 4 }} +spec: +{{- if not .Values.registration1Frontend.autoscaling.enabled }} + replicas: {{ .Values.registration1Frontend.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "cas-registration.selectorLabels" . | nindent 6 }} + component: registration1-frontend + strategy: + type: RollingUpdate + template: + metadata: + labels: +{{- include "cas-registration.selectorLabels" . | nindent 8 }} + component: registration1-frontend + spec: + containers: + - name: {{ template "cas-registration.fullname" . }}-registration1-frontend + env: + - name: API_URL + value: http://{{ include "cas-registration.fullname" . }}-backend.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.backend.service.port }}/api/ + - name: KEYCLOAK_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: keycloak-gold-client-secret + key: kcClientSecret + - name: KEYCLOAK_AUTH_URL + value: {{ .Values.registration1Frontend.auth.keycloakAuthUrl}} + - name: KEYCLOAK_REALMS + value: {{ .Values.registration1Frontend.auth.keycloakRealms}} + - name: KEYCLOAK_OIDC + value: {{ .Values.registration1Frontend.auth.keycloakOidc}} + - name: KEYCLOAK_LOGIN_URL + value: {{ .Values.registration1Frontend.auth.keycloakAuthUrl}}{{ .Values.registration1Frontend.auth.keycloakRealms }} + - name: KEYCLOAK_LOGOUT_URL + value: {{ .Values.registration1Frontend.auth.keycloakAuthUrl}}{{ .Values.registration1Frontend.auth.keycloakRealms }}{{ .Values.registration1Frontend.auth.keycloakOidc}}/logout + - name: KEYCLOAK_TOKEN_URL + value: {{ .Values.registration1Frontend.auth.keycloakAuthUrl}}{{ .Values.registration1Frontend.auth.keycloakRealms }}{{ .Values.registration1Frontend.auth.keycloakOidc}}/token + - name: NEXTAUTH_URL + value: https://{{ .Values.registration1Frontend.route.host }} + - name: SITEMINDER_AUTH_URL + value: {{ .Values.registration1Frontend.auth.siteminderAuthUrl }} + - name: SITEMINDER_LOGOUT_URL + value: {{ .Values.registration1Frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi + - name: NEXT_PUBLIC_KEYCLOAK_LOGOUT_URL + value: {{ .Values.registration1Frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.registration1Frontend.auth.keycloakAuthUrl}}{{ .Values.registration1Frontend.auth.keycloakRealms }}{{ .Values.registration1Frontend.auth.keycloakOidc}}/logout + - name: KEYCLOAK_CLIENT_ID + value: {{ .Values.registration1Frontend.auth.keycloakClientId }} + - name: SITEMINDER_KEYCLOAK_LOGOUT_URL + value: {{ .Values.registration1Frontend.auth.siteminderAuthUrl }}/clp-cgi/logoff.cgi?retnow=1&returl={{ .Values.registration1Frontend.auth.keycloakAuthUrl}}{{ .Values.registration1Frontend.auth.keycloakRealms }}{{ .Values.registration1Frontend.auth.keycloakOidc}}/logout + - name: NEXTAUTH_SECRET + valueFrom: + secretKeyRef: + name: {{ template "cas-registration.fullname" . }}-nextauth + key: nextauth-secret + - name: NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY + value: {{ .Values.growthbook.clientKey }} + {{- if hasSuffix "-prod" .Release.Namespace }} + - name: SENTRY_ENVIRONMENT + value: {{ include "cas-registration.namespaceSuffix" . }} + - name: SENTRY_RELEASE + value: {{ .Values.registration1Frontend.image.tag }} + - name: SENTRY_TRACE_SAMPLE_RATE + value: {{ .Values.registration1Frontend.sentry.traceSampleRate | quote }} + {{- end }} + image: "{{ .Values.registration1Frontend.image.repository }}:{{ .Values.defaultImageTag | default .Values.registration1Frontend.image.tag }}" + imagePullPolicy: {{ .Values.registration1Frontend.image.pullPolicy }} + ports: + - containerPort: {{ .Values.registration1Frontend.service.port }} + protocol: TCP + resources: + {{- toYaml .Values.registration1Frontend.resources | nindent 12 }} + restartPolicy: Always diff --git a/helm/cas-registration/templates/registration1/hpa.yaml b/helm/cas-registration/templates/registration1/hpa.yaml new file mode 100644 index 0000000000..7013d55d7e --- /dev/null +++ b/helm/cas-registration/templates/registration1/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.registration1Frontend.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "cas-registration.fullname" . }}-registration1-frontend + labels: + {{- include "cas-registration.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "cas-registration.fullname" . }}-registration1-frontend + minReplicas: {{ .Values.registration1Frontend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.registration1Frontend.autoscaling.maxReplicas }} + metrics: + {{- if .Values.registration1Frontend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.registration1Frontend.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.registration1Frontend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.registration1Frontend.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/cas-registration/templates/frontend/route.yaml b/helm/cas-registration/templates/registration1/route.yaml similarity index 76% rename from helm/cas-registration/templates/frontend/route.yaml rename to helm/cas-registration/templates/registration1/route.yaml index 9a6e49775c..fa7a16a83c 100644 --- a/helm/cas-registration/templates/frontend/route.yaml +++ b/helm/cas-registration/templates/registration1/route.yaml @@ -13,16 +13,16 @@ apiVersion: route.openshift.io/v1 kind: Route metadata: - name: {{ template "cas-registration.fullname" . }}-frontend + name: {{ template "cas-registration.fullname" . }}-registration1-frontend labels: {{ include "cas-registration.labels" . | indent 4 }} annotations: haproxy.router.openshift.io/balance: roundrobin spec: - host: {{ .Values.frontend.route.host }} + host: {{ .Values.registration1Frontend.route.host }} port: - targetPort: {{ template "cas-registration.fullname" . }}-frontend + targetPort: {{ template "cas-registration.fullname" . }}-registration1-frontend tls: insecureEdgeTerminationPolicy: Redirect termination: edge @@ -33,5 +33,5 @@ spec: {{- end }} to: kind: Service - name: {{ template "cas-registration.fullname" . }}-frontend + name: {{ template "cas-registration.fullname" . }}-registration1-frontend weight: 100 diff --git a/helm/cas-registration/templates/frontend/secret.yaml b/helm/cas-registration/templates/registration1/secret.yaml similarity index 100% rename from helm/cas-registration/templates/frontend/secret.yaml rename to helm/cas-registration/templates/registration1/secret.yaml diff --git a/helm/cas-registration/templates/registration1/service.yaml b/helm/cas-registration/templates/registration1/service.yaml new file mode 100644 index 0000000000..874b7918bc --- /dev/null +++ b/helm/cas-registration/templates/registration1/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "cas-registration.fullname" . }}-registration1-frontend + labels: + {{- include "cas-registration.labels" . | nindent 4 }} +spec: + type: {{ .Values.registration1Frontend.service.type }} + ports: + - port: {{ .Values.registration1Frontend.service.port }} + targetPort: 3000 + protocol: TCP + name: {{ include "cas-registration.fullname" . }}-registration1-frontend + selector: + {{- include "cas-registration.selectorLabels" . | nindent 4 }} + component: frontend diff --git a/helm/cas-registration/values-dev.yaml b/helm/cas-registration/values-dev.yaml index 0b66a6b6fd..ed83d91654 100644 --- a/helm/cas-registration/values-dev.yaml +++ b/helm/cas-registration/values-dev.yaml @@ -20,7 +20,22 @@ backend: cpu: 60m memory: 256Mi -frontend: +registrationFrontend: + replicaCount: 1 + + route: + host: cas-reg-frontend-dev.apps.silver.devops.gov.bc.ca + path: "/registration2" + + environment: develop + + auth: + keycloakAuthUrl: https://dev.loginproxy.gov.bc.ca/auth + siteminderAuthUrl: https://logontest7.gov.bc.ca + + + +registration1Frontend: replicaCount: 2 image: diff --git a/helm/cas-registration/values-prod.yaml b/helm/cas-registration/values-prod.yaml index 9ebf763345..0a59cdc336 100644 --- a/helm/cas-registration/values-prod.yaml +++ b/helm/cas-registration/values-prod.yaml @@ -18,7 +18,7 @@ backend: cpu: 300m memory: 300Mi -frontend: +registration1Frontend: replicaCount: 2 image: diff --git a/helm/cas-registration/values-test.yaml b/helm/cas-registration/values-test.yaml index edcfaee575..374e26cd60 100644 --- a/helm/cas-registration/values-test.yaml +++ b/helm/cas-registration/values-test.yaml @@ -18,7 +18,7 @@ backend: cpu: 60m memory: 256Mi -frontend: +registration1Frontend: replicaCount: 2 image: diff --git a/helm/cas-registration/values.yaml b/helm/cas-registration/values.yaml index b14c1b5028..5b44d4b3a3 100644 --- a/helm/cas-registration/values.yaml +++ b/helm/cas-registration/values.yaml @@ -37,15 +37,55 @@ backend: targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80 -frontend: +registrationFrontend: + image: + repository: ghcr.io/bcgov/cas-reg-frontend + pullPolicy: Always + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + replicaCount: 1 + environment: ~ + + auth: + keycloakAuthUrl: ~ + keycloakRealms: /realms/standard + keycloakOidc: /protocol/openid-connect + keycloakClientId: obps-4953 + + service: + type: ClusterIP + port: 3000 + + route: + host: ~ + + resources: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 60m + memory: 192Mi + + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Registration Part I frontend +registration1Frontend: image: - repository: ghcr.io/bcgov/cas-reg-frontend + repository: ghcr.io/bcgov/cas-reg1-frontend pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. tag: "latest" + replicaCount: 1 + environment: ~ auth: @@ -60,6 +100,7 @@ frontend: route: host: ~ + path: ~ resources: limits: