diff --git a/.github/actions/post-deploy-smoke-test/action.yml b/.github/actions/post-deploy-smoke-test/action.yml new file mode 100644 index 0000000000..c4f27ba6c7 --- /dev/null +++ b/.github/actions/post-deploy-smoke-test/action.yml @@ -0,0 +1,19 @@ +name: Smoke test post deploy +description: Invoke a script that visits a deploy smoke check page that displays whether the backend / db are healthy. +inputs: + base_domain_name: + description: The domain where the application is deployed (e.g. "simplereport.gov" or "test.simplereport.gov") + required: true +runs: + using: composite + steps: + - name: create env file + shell: bash + working-directory: frontend + run: | + touch .env + echo REACT_APP_BASE_URL=${{ inputs.base_domain_name }}>> .env.production.local + - name: Run smoke test script + shell: bash + working-directory: frontend + run: yarn smoke:deploy:ci diff --git a/.github/workflows/checkForChanges.yml b/.github/workflows/checkForChanges.yml index badc700b5c..1ca0621035 100644 --- a/.github/workflows/checkForChanges.yml +++ b/.github/workflows/checkForChanges.yml @@ -1,33 +1,33 @@ -name: Check for Changes -# Reusable workflow, compatible with push and pull_request events -on: - workflow_call: - inputs: - # can be a file or a folder - what_to_check: - required: true - type: string - outputs: - has_changes: - description: true or false string - value: ${{ jobs.check_for_changes.outputs.has_changes }} -jobs: - check_for_changes: - runs-on: ubuntu-latest - outputs: - has_changes: ${{ steps.check_for_changes.outputs.has_changes }} - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - shell: bash - id: check_for_changes - run: | - echo "::group::Set has_changes output" - diff=$(git diff-tree --no-commit-id --name-only -r "origin/main" HEAD -- "${{ inputs.what_to_check }}") - echo "Diff: $diff" - diff_length=$(echo ${#diff}) - has_diff=$([ $diff_length -gt 0 ] && echo "true" || echo "false") - echo "The Changes: ${has_diff}" - echo "has_changes=${has_diff}" >> "$GITHUB_OUTPUT" - echo "::endgroup::" +#name: Check for Changes +## Reusable workflow, compatible with push and pull_request events +#on: +# workflow_call: +# inputs: +# # can be a file or a folder +# what_to_check: +# required: true +# type: string +# outputs: +# has_changes: +# description: true or false string +# value: ${{ jobs.check_for_changes.outputs.has_changes }} +#jobs: +# check_for_changes: +# runs-on: ubuntu-latest +# outputs: +# has_changes: ${{ steps.check_for_changes.outputs.has_changes }} +# steps: +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 +# - shell: bash +# id: check_for_changes +# run: | +# echo "::group::Set has_changes output" +# diff=$(git diff-tree --no-commit-id --name-only -r "origin/main" HEAD -- "${{ inputs.what_to_check }}") +# echo "Diff: $diff" +# diff_length=$(echo ${#diff}) +# has_diff=$([ $diff_length -gt 0 ] && echo "true" || echo "false") +# echo "The Changes: ${has_diff}" +# echo "has_changes=${has_diff}" >> "$GITHUB_OUTPUT" +# echo "::endgroup::" diff --git a/.github/workflows/checkGraphql.yml b/.github/workflows/checkGraphql.yml index 597ec82fd0..5d3237c9a2 100644 --- a/.github/workflows/checkGraphql.yml +++ b/.github/workflows/checkGraphql.yml @@ -1,59 +1,59 @@ -name: Check Graphql - -on: - workflow_dispatch: - pull_request: - branches: - - "**" - merge_group: - types: - - checks_requested - push: - branches: - - main - -env: - NODE_VERSION: 18 - -defaults: - run: - working-directory: frontend - -jobs: - check-graphql-types: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{env.NODE_VERSION}} - uses: actions/setup-node@v4.0.1 - with: - node-version: ${{env.NODE_VERSION}} - - name: Cache yarn - uses: actions/cache@v3.3.2 - with: - path: ~/.cache/yarn - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Node setup - run: yarn install --prefer-offline - - name: Generate grahpql types - run: yarn codegen - - name: Lint generated files - run: yarn lint:write - - name: Check for changes - run: | - if [[ -z "$(git status --porcelain)" ]]; then - exit 0 - else - echo "Current generated code does not match code in latest commit. try running cd frontend/ && yarn codegen" - git diff >> diff.txt - exit 1 - fi - - name: Archive git diff - uses: actions/upload-artifact@v4 - if: failure() - with: - name: files changed - path: frontend/diff.txt - retention-days: 7 +#name: Check Graphql +# +#on: +# workflow_dispatch: +# pull_request: +# branches: +# - "**" +# merge_group: +# types: +# - checks_requested +# push: +# branches: +# - main +# +#env: +# NODE_VERSION: 18 +# +#defaults: +# run: +# working-directory: frontend +# +#jobs: +# check-graphql-types: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - name: Use Node.js ${{env.NODE_VERSION}} +# uses: actions/setup-node@v4.0.0 +# with: +# node-version: ${{env.NODE_VERSION}} +# - name: Cache yarn +# uses: actions/cache@v3.3.2 +# with: +# path: ~/.cache/yarn +# key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} +# restore-keys: | +# ${{ runner.os }}-yarn- +# - name: Node setup +# run: yarn install --prefer-offline +# - name: Generate grahpql types +# run: yarn codegen +# - name: Lint generated files +# run: yarn lint:write +# - name: Check for changes +# run: | +# if [[ -z "$(git status --porcelain)" ]]; then +# exit 0 +# else +# echo "Current generated code does not match code in latest commit. try running cd frontend/ && yarn codegen" +# git diff >> diff.txt +# exit 1 +# fi +# - name: Archive git diff +# uses: actions/upload-artifact@v3 +# if: failure() +# with: +# name: files changed +# path: frontend/diff.txt +# retention-days: 7 diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 2a4017cd38..6786b235be 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -1,64 +1,64 @@ -name: Chromatic - -on: - workflow_dispatch: - pull_request: - branches: - - "**" - paths: - - "frontend/**" - push: - branches: - - main - paths: - - "frontend/**" - -env: - NODE_VERSION: 18 - -jobs: - chromatic-deployment: - runs-on: ubuntu-latest - steps: - - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Chromatic wants the history - - - uses: actions/setup-node@v4.0.1 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install dependencies - run: yarn - working-directory: frontend - - - name: Publish to Chromatic - if: github.ref != 'refs/heads/main' - uses: chromaui/action@v10 - with: - workingDir: frontend - token: ${{ secrets.GITHUB_TOKEN }} - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - ignoreLastBuildOnBranch: "**" # Better comparisons after rebasing - exitZeroOnChanges: true - exitOnceUploaded: true - - - name: Publish to Chromatic (auto-accept changes on merge main) - if: github.ref == 'refs/heads/main' - uses: chromaui/action@v10 - with: - workingDir: frontend - token: ${{ secrets.GITHUB_TOKEN }} - projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} - ignoreLastBuildOnBranch: "**" - exitZeroOnChanges: true - exitOnceUploaded: true - autoAcceptChanges: true # handle squash-on-merge - - - name: Artifact Chromatic logs - if: failure() - uses: actions/upload-artifact@v4 - with: - name: logs - path: frontend/*.log +#name: Chromatic +# +#on: +# workflow_dispatch: +# pull_request: +# branches: +# - "**" +# paths: +# - "frontend/**" +# push: +# branches: +# - main +# paths: +# - "frontend/**" +# +#env: +# NODE_VERSION: 18 +# +#jobs: +# chromatic-deployment: +# runs-on: ubuntu-latest +# steps: +# +# - uses: actions/checkout@v4 +# with: +# fetch-depth: 0 # Chromatic wants the history +# +# - uses: actions/setup-node@v4.0.0 +# with: +# node-version: ${{ env.NODE_VERSION }} +# +# - name: Install dependencies +# run: yarn +# working-directory: frontend +# +# - name: Publish to Chromatic +# if: github.ref != 'refs/heads/main' +# uses: chromaui/action@v10 +# with: +# workingDir: frontend +# token: ${{ secrets.GITHUB_TOKEN }} +# projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} +# ignoreLastBuildOnBranch: "**" # Better comparisons after rebasing +# exitZeroOnChanges: true +# exitOnceUploaded: true +# +# - name: Publish to Chromatic (auto-accept changes on merge main) +# if: github.ref == 'refs/heads/main' +# uses: chromaui/action@v10 +# with: +# workingDir: frontend +# token: ${{ secrets.GITHUB_TOKEN }} +# projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} +# ignoreLastBuildOnBranch: "**" +# exitZeroOnChanges: true +# exitOnceUploaded: true +# autoAcceptChanges: true # handle squash-on-merge +# +# - name: Artifact Chromatic logs +# if: failure() +# uses: actions/upload-artifact@v3 +# with: +# name: logs +# path: frontend/*.log diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 43eaf7ed75..9ac5a61b4b 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,3 +1,60 @@ +<<<<<<< HEAD +#name: "CodeQL" +# +#on: +# push: +# branches: [ "main" ] +# pull_request: +# branches: [ "main" ] +# schedule: +# - cron: "45 4 * * 3" +# +#concurrency: +# group: ${{ github.workflow }}-${{ github.ref }} +# cancel-in-progress: true +# +#env: +# JAVA_VERSION: 17 +# JAVA_DISTRIBUTION: 'zulu' +# +#jobs: +# analyze: +# name: Analyze +# runs-on: ubuntu-latest +# permissions: +# actions: read +# contents: read +# security-events: write +# +# strategy: +# fail-fast: false +# matrix: +# language: [ javascript, java ] +# +# steps: +# - name: Checkout +# uses: actions/checkout@v4 +# +# - name: Initialize CodeQL +# uses: github/codeql-action/init@v2 +# with: +# languages: ${{ matrix.language }} +# queries: +security-and-quality +# +# - name: Set up JDK +# uses: actions/setup-java@v4 +# with: +# java-version: ${{env.JAVA_VERSION}} +# distribution: ${{env.JAVA_DISTRIBUTION}} +# +# - name: Autobuild +# uses: github/codeql-action/autobuild@v2 +# +# - name: Perform CodeQL Analysis +# uses: github/codeql-action/analyze@v2 +# with: +# category: "/language:${{ matrix.language }}" +======= name: "CodeQL" on: @@ -52,4 +109,5 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 with: - category: "/language:${{ matrix.language }}" \ No newline at end of file + category: "/language:${{ matrix.language }}" +>>>>>>> bob/7019-prod-e2e-health-check diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 71d929184b..42ba3b3ab1 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -1,74 +1,74 @@ -name: coverity-scan -on: - workflow_dispatch: # because sometimes you just want to force a branch to have tests run - push: - branches: - - main - paths: - - .github/workflows/coverity_scan.yml - pull_request: - branches: - - "**" - paths: - - .github/workflows/coverity_scan.yml - schedule: - - cron: '0 18 * * *' # Daily at 18:00 UTC - -env: - JAVA_VERSION: 17 - JAVA_DISTRIBUTION: 'zulu' - NODE_VERSION: 18 - -defaults: - run: - working-directory: ./backend - -jobs: - scan: - runs-on: ubuntu-latest - if: ${{ github.actor != 'dependabot[bot]' }} - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4.0.1 - with: - node-version: ${{env.NODE_VERSION}} - - name: Cache npm local files - uses: actions/cache@v3.3.2 - with: - path: | - ./frontend/node_modules - key: npm-${{env.NODE_VERSION}}-${{ hashFiles('frontend/yarn.lock', 'frontend/package.json') }} - - name: Install dependencies - run: yarn install - working-directory: ./frontend - - name: Set up JDK - uses: actions/setup-java@v4 - with: - java-version: ${{env.JAVA_VERSION}} - distribution: ${{env.JAVA_DISTRIBUTION}} - - name: Cache Java Dependencies - uses: actions/cache@v3.3.2 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-build-${{ hashFiles('*.gradle', 'gradle/dependency-locks/*') }} - - name: Download Coverity Build Tool - run: | - wget -q https://scan.coverity.com/download/java/linux64 --post-data "token=${{ secrets.COVERITY_TOKEN }}&project=CDCgov/prime-simplereport" -O cov-analysis-linux64.tar.gz - mkdir cov-analysis-linux64 - tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64 - - name: Build with cov-build - run: | - export PATH=`pwd`/cov-analysis-linux64/bin:$PATH - cov-build --dir cov-int --fs-capture-search ../frontend ./gradlew clean assemble - - name: Submit the result to Coverity Scan - run: | - tar czvf sr.tgz cov-int - curl \ - --form token=${{ secrets.COVERITY_TOKEN }} \ - --form email=nicholas.a.robison@omb.eop.gov \ - --form file=@sr.tgz \ - --form version=${{ env.GITHUB_REF }} \ - --form description="`git rev-parse --short HEAD`" \ - https://scan.coverity.com/builds?project=CDCgov%2Fprime-simplereport +#name: coverity-scan +#on: +# workflow_dispatch: # because sometimes you just want to force a branch to have tests run +# push: +# branches: +# - main +# paths: +# - .github/workflows/coverity_scan.yml +# pull_request: +# branches: +# - "**" +# paths: +# - .github/workflows/coverity_scan.yml +# schedule: +# - cron: '0 18 * * *' # Daily at 18:00 UTC +# +#env: +# JAVA_VERSION: 17 +# JAVA_DISTRIBUTION: 'zulu' +# NODE_VERSION: 18 +# +#defaults: +# run: +# working-directory: ./backend +# +#jobs: +# scan: +# runs-on: ubuntu-latest +# if: ${{ github.actor != 'dependabot[bot]' }} +# steps: +# - uses: actions/checkout@v4 +# - uses: actions/setup-node@v4.0.0 +# with: +# node-version: ${{env.NODE_VERSION}} +# - name: Cache npm local files +# uses: actions/cache@v3.3.2 +# with: +# path: | +# ./frontend/node_modules +# key: npm-${{env.NODE_VERSION}}-${{ hashFiles('frontend/yarn.lock', 'frontend/package.json') }} +# - name: Install dependencies +# run: yarn install +# working-directory: ./frontend +# - name: Set up JDK +# uses: actions/setup-java@v4 +# with: +# java-version: ${{env.JAVA_VERSION}} +# distribution: ${{env.JAVA_DISTRIBUTION}} +# - name: Cache Java Dependencies +# uses: actions/cache@v3.3.2 +# with: +# path: | +# ~/.gradle/caches +# ~/.gradle/wrapper +# key: gradle-build-${{ hashFiles('*.gradle', 'gradle/dependency-locks/*') }} +# - name: Download Coverity Build Tool +# run: | +# wget -q https://scan.coverity.com/download/java/linux64 --post-data "token=${{ secrets.COVERITY_TOKEN }}&project=CDCgov/prime-simplereport" -O cov-analysis-linux64.tar.gz +# mkdir cov-analysis-linux64 +# tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64 +# - name: Build with cov-build +# run: | +# export PATH=`pwd`/cov-analysis-linux64/bin:$PATH +# cov-build --dir cov-int --fs-capture-search ../frontend ./gradlew clean assemble +# - name: Submit the result to Coverity Scan +# run: | +# tar czvf sr.tgz cov-int +# curl \ +# --form token=${{ secrets.COVERITY_TOKEN }} \ +# --form email=nicholas.a.robison@omb.eop.gov \ +# --form file=@sr.tgz \ +# --form version=${{ env.GITHUB_REF }} \ +# --form description="`git rev-parse --short HEAD`" \ +# https://scan.coverity.com/builds?project=CDCgov%2Fprime-simplereport diff --git a/.github/workflows/deployProd.yml b/.github/workflows/deployProd.yml index 53249ea09a..2b5f99b51a 100644 --- a/.github/workflows/deployProd.yml +++ b/.github/workflows/deployProd.yml @@ -98,3 +98,5 @@ jobs: :siren-gif: Deploy to ${{ env.DEPLOY_ENV }} failed. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} :siren-gif: webhook_url: ${{ secrets.SR_ALERTS_SLACK_WEBHOOK_URL }} user_map: $${{ secrets.SR_ALERTS_GITHUB_SLACK_MAP }} + +# a post-prod health check workflow is defined in smokeTestDeployProd. See the Alert response wiki page for more details \ No newline at end of file diff --git a/.github/workflows/e2eLocal.yml b/.github/workflows/e2eLocal.yml index 9d738e6042..8acee0cc6d 100644 --- a/.github/workflows/e2eLocal.yml +++ b/.github/workflows/e2eLocal.yml @@ -1,148 +1,148 @@ -name: Run end-to-end tests - -on: - workflow_call: - secrets: - OKTA_API_KEY: - required: true - SMARTY_AUTH_ID: - required: true - SMARTY_AUTH_TOKEN: - required: true - CYPRESS_OKTA_USERNAME: - required: true - CYPRESS_OKTA_PASSWORD: - required: true - CYPRESS_OKTA_SECRET: - required: true - inputs: - DOCKER_BACKEND_IMAGE_VERSION: - required: false - type: string - DOCKER_CYPRESS_IMAGE_VERSION: - required: false - type: string - DOCKER_DATABASE_IMAGE_VERSION: - required: false - type: string - DOCKER_FRONTEND_IMAGE_VERSION: - required: false - type: string - DOCKER_NGINX_IMAGE_VERSION: - required: false - type: string - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }}-e2e-local - cancel-in-progress: true - -jobs: - - cypress-local-env: - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Set Swap Space - uses: ./.github/actions/set-swap-space - with: - swap-size-gb: 10 - - - name: Update files permissions - # Even though we don't use it, we need the .env file created here due to an issue similar to this one: https://github.com/mutagen-io/mutagen/issues/265 - run: | - echo "::group::Update permissions" - echo FAKE_ENV="true" >> .env - sudo chmod -R 777 backend - sudo chmod -R 777 frontend - echo "::endgroup::" - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Run Cypress - timeout-minutes: 30 - env: - # CI settings - CI: 1 - # docker settings - DOCKER_CLIENT_TIMEOUT: 180 - DOCKER_BACKEND_IMAGE_VERSION: ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }} - DOCKER_CYPRESS_IMAGE_VERSION: ${{ inputs.DOCKER_CYPRESS_IMAGE_VERSION }} - DOCKER_DATABASE_IMAGE_VERSION: ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }} - DOCKER_FRONTEND_IMAGE_VERSION: ${{ inputs.DOCKER_FRONTEND_IMAGE_VERSION }} - DOCKER_NGINX_IMAGE_VERSION: ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }} - COMPOSE_HTTP_TIMEOUT: 180 - # backend settings - SPRING_PROFILES_ACTIVE: e2e,db-dockerized - OKTA_TESTING_DISABLEHTTPSCHECK: "true" - OKTA_API_KEY: ${{ secrets.OKTA_API_KEY }} - OKTA_OAUTH2_CLIENT_ID: 0oa1k0163nAwfVxNW1d7 - SMARTY_AUTH_ID: ${{ secrets.SMARTY_AUTH_ID }} - SMARTY_AUTH_TOKEN: ${{ secrets.SMARTY_AUTH_TOKEN }} - SPRING_LIQUIBASE_ENABLED: "true" - GIT_DISCOVERY_ACROSS_FILESYSTEM: 1 - WIREMOCK_URL: "http://wiremock:8088" - # cypress settings - CYPRESS_OKTA_REDIRECT_URI: "https%3A%2F%2Flocalhost.simplereport.gov%2Fapp" - CYPRESS_OKTA_USERNAME: ${{ secrets.CYPRESS_OKTA_USERNAME }} - CYPRESS_OKTA_PASSWORD: ${{ secrets.CYPRESS_OKTA_PASSWORD }} - CYPRESS_OKTA_SECRET: ${{ secrets.CYPRESS_OKTA_SECRET }} - CYPRESS_BACKEND_URL: "https://localhost.simplereport.gov/api" - SPEC_PATH: "cypress/e2e/**" - TEST_ENV: "https://localhost.simplereport.gov" - # frontend settings - REACT_APP_OKTA_URL: "http://wiremock:8088" - REACT_APP_OKTA_CLIENT_ID: 0oa1k0163nAwfVxNW1d7 - REACT_APP_BASE_URL: https://localhost.simplereport.gov - REACT_APP_BACKEND_URL: https://localhost.simplereport.gov/api - PUBLIC_URL: /app/ - REACT_APP_OKTA_ENABLED: "true" - REACT_APP_DISABLE_MAINTENANCE_BANNER: "true" - shell: bash - run: | - echo "::group::Run Cypress locally" - echo "Backend branch tag (or latest): ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }}" - echo "Cypress branch tag (or latest): ${{ inputs.DOCKER_CYPRESS_IMAGE_VERSION }}" - echo "Database branch tag (or latest): ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }}" - echo "Frontend branch tag (or latest): ${{ inputs.DOCKER_FRONTEND_IMAGE_VERSION }}" - echo "Nginx branch tag (or latest): ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }}" - docker compose -f docker-compose.yml -f docker-compose.cypress.yml up --abort-on-container-exit --attach cypress --exit-code-from cypress --quiet-pull - echo "::endgroup::" - - - name: Get docker logs - if: always() - shell: bash - run: | - echo "Saving $container logs" - docker compose -f docker-compose.yml -f docker-compose.cypress.yml logs --timestamps >& cypress-run.log - - - name: Stop containers - if: always() - shell: bash - run: | - echo "::group::Stop Docker containers" - docker compose -f docker-compose.yml -f docker-compose.cypress.yml down - echo "::endgroup::" - - - name: Archive cypress failures - if: always() - uses: actions/upload-artifact@v4 - with: - name: cypress-results - path: | - cypress/videos/* - cypress/screenshots/* - - - name: Archive docker logs - if: always() - uses: actions/upload-artifact@v4 - with: - name: logs - path: cypress-run.log +#name: Run end-to-end tests +# +#on: +# workflow_call: +# secrets: +# OKTA_API_KEY: +# required: true +# SMARTY_AUTH_ID: +# required: true +# SMARTY_AUTH_TOKEN: +# required: true +# CYPRESS_OKTA_USERNAME: +# required: true +# CYPRESS_OKTA_PASSWORD: +# required: true +# CYPRESS_OKTA_SECRET: +# required: true +# inputs: +# DOCKER_BACKEND_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_CYPRESS_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_DATABASE_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_FRONTEND_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_NGINX_IMAGE_VERSION: +# required: false +# type: string +# +#concurrency: +# group: ${{ github.workflow }}-${{ github.ref }}-e2e-local +# cancel-in-progress: true +# +#jobs: +# +# cypress-local-env: +# runs-on: ubuntu-latest +# steps: +# +# - name: Checkout +# uses: actions/checkout@v4 +# +# - name: Set Swap Space +# uses: ./.github/actions/set-swap-space +# with: +# swap-size-gb: 10 +# +# - name: Update files permissions +# # Even though we don't use it, we need the .env file created here due to an issue similar to this one: https://github.com/mutagen-io/mutagen/issues/265 +# run: | +# echo "::group::Update permissions" +# echo FAKE_ENV="true" >> .env +# sudo chmod -R 777 backend +# sudo chmod -R 777 frontend +# echo "::endgroup::" +# +# - name: Log in to the Container registry +# uses: docker/login-action@v3 +# with: +# registry: ghcr.io +# username: ${{ github.actor }} +# password: ${{ secrets.GITHUB_TOKEN }} +# +# - name: Run Cypress +# timeout-minutes: 30 +# env: +# # CI settings +# CI: 1 +# # docker settings +# DOCKER_CLIENT_TIMEOUT: 180 +# DOCKER_BACKEND_IMAGE_VERSION: ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }} +# DOCKER_CYPRESS_IMAGE_VERSION: ${{ inputs.DOCKER_CYPRESS_IMAGE_VERSION }} +# DOCKER_DATABASE_IMAGE_VERSION: ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }} +# DOCKER_FRONTEND_IMAGE_VERSION: ${{ inputs.DOCKER_FRONTEND_IMAGE_VERSION }} +# DOCKER_NGINX_IMAGE_VERSION: ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }} +# COMPOSE_HTTP_TIMEOUT: 180 +# # backend settings +# SPRING_PROFILES_ACTIVE: e2e,db-dockerized +# OKTA_TESTING_DISABLEHTTPSCHECK: "true" +# OKTA_API_KEY: ${{ secrets.OKTA_API_KEY }} +# OKTA_OAUTH2_CLIENT_ID: 0oa1k0163nAwfVxNW1d7 +# SMARTY_AUTH_ID: ${{ secrets.SMARTY_AUTH_ID }} +# SMARTY_AUTH_TOKEN: ${{ secrets.SMARTY_AUTH_TOKEN }} +# SPRING_LIQUIBASE_ENABLED: "true" +# GIT_DISCOVERY_ACROSS_FILESYSTEM: 1 +# WIREMOCK_URL: "http://wiremock:8088" +# # cypress settings +# CYPRESS_OKTA_REDIRECT_URI: "https%3A%2F%2Flocalhost.simplereport.gov%2Fapp" +# CYPRESS_OKTA_USERNAME: ${{ secrets.CYPRESS_OKTA_USERNAME }} +# CYPRESS_OKTA_PASSWORD: ${{ secrets.CYPRESS_OKTA_PASSWORD }} +# CYPRESS_OKTA_SECRET: ${{ secrets.CYPRESS_OKTA_SECRET }} +# CYPRESS_BACKEND_URL: "https://localhost.simplereport.gov/api" +# SPEC_PATH: "cypress/e2e/**" +# TEST_ENV: "https://localhost.simplereport.gov" +# # frontend settings +# REACT_APP_OKTA_URL: "http://wiremock:8088" +# REACT_APP_OKTA_CLIENT_ID: 0oa1k0163nAwfVxNW1d7 +# REACT_APP_BASE_URL: https://localhost.simplereport.gov +# REACT_APP_BACKEND_URL: https://localhost.simplereport.gov/api +# PUBLIC_URL: /app/ +# REACT_APP_OKTA_ENABLED: "true" +# REACT_APP_DISABLE_MAINTENANCE_BANNER: "true" +# shell: bash +# run: | +# echo "::group::Run Cypress locally" +# echo "Backend branch tag (or latest): ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }}" +# echo "Cypress branch tag (or latest): ${{ inputs.DOCKER_CYPRESS_IMAGE_VERSION }}" +# echo "Database branch tag (or latest): ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }}" +# echo "Frontend branch tag (or latest): ${{ inputs.DOCKER_FRONTEND_IMAGE_VERSION }}" +# echo "Nginx branch tag (or latest): ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }}" +# docker compose -f docker-compose.yml -f docker-compose.cypress.yml up --abort-on-container-exit --attach cypress --exit-code-from cypress --quiet-pull +# echo "::endgroup::" +# +# - name: Get docker logs +# if: always() +# shell: bash +# run: | +# echo "Saving $container logs" +# docker compose -f docker-compose.yml -f docker-compose.cypress.yml logs --timestamps >& cypress-run.log +# +# - name: Stop containers +# if: always() +# shell: bash +# run: | +# echo "::group::Stop Docker containers" +# docker compose -f docker-compose.yml -f docker-compose.cypress.yml down +# echo "::endgroup::" +# +# - name: Archive cypress failures +# if: always() +# uses: actions/upload-artifact@v3 +# with: +# name: cypress-results +# path: | +# cypress/videos/* +# cypress/screenshots/* +# +# - name: Archive docker logs +# if: always() +# uses: actions/upload-artifact@v3 +# with: +# name: logs +# path: cypress-run.log diff --git a/.github/workflows/lighthouse.yml b/.github/workflows/lighthouse.yml index 87cfac1038..4c8b4f179b 100644 --- a/.github/workflows/lighthouse.yml +++ b/.github/workflows/lighthouse.yml @@ -1,85 +1,85 @@ -name: Run Lighthouse Audit -on: - workflow_call: - inputs: - DOCKER_BACKEND_IMAGE_VERSION: - required: false - type: string - DOCKER_DATABASE_IMAGE_VERSION: - required: false - type: string - DOCKER_NGINX_IMAGE_VERSION: - required: false - type: string - DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: - required: false - type: string - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - lhci: - name: Lighthouse - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Set Swap Space - uses: ./.github/actions/set-swap-space - with: - swap-size-gb: 10 - - - name: Add hosts to /etc/hosts - run: | - sudo echo "127.0.0.1 localhost.simplereport.gov" | sudo tee -a /etc/hosts - - - name: Update files permissions - # Even though we don't use it, we need the .env file created here due to an issue similar to this one: https://github.com/mutagen-io/mutagen/issues/265 - run: | - echo "::group::Update permissions" - echo FAKE_ENV="true" >> .env - sudo chmod -R 777 backend - sudo chmod -R 777 frontend - echo "::endgroup::" - - - name: Log in to the Container registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup and Run Lighthouse - env: - # CI settings - CI: 1 - # docker settings - DOCKER_CLIENT_TIMEOUT: 180 - COMPOSE_HTTP_TIMEOUT: 180 - DOCKER_BACKEND_IMAGE_VERSION: ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }} - DOCKER_DATABASE_IMAGE_VERSION: ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }} - DOCKER_NGINX_IMAGE_VERSION: ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }} - DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: ${{ inputs.DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION }} - shell: bash - run: | - echo "::group::Running containers" - echo "Backend branch tag (or latest): ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }}" - echo "Database branch tag (or latest): ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }}" - echo "Nginx branch tag (or latest): ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }}" - echo "Frontend branch tag (or latest): ${{ inputs.DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION }}" - echo "::endgroup::" - - echo "::group::Run Lighthouse locally" - bash lighthouse.sh - echo "::endgroup::" - - - name: Archive Lighthouse results - uses: actions/upload-artifact@v4 - if: always() - with: - name: lighthouse-results - path: lighthouse/* \ No newline at end of file +#name: Run Lighthouse Audit +#on: +# workflow_call: +# inputs: +# DOCKER_BACKEND_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_DATABASE_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_NGINX_IMAGE_VERSION: +# required: false +# type: string +# DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: +# required: false +# type: string +# +#concurrency: +# group: ${{ github.workflow }}-${{ github.ref }} +# cancel-in-progress: true +# +#jobs: +# lhci: +# name: Lighthouse +# runs-on: ubuntu-latest +# steps: +# +# - name: Checkout +# uses: actions/checkout@v4 +# +# - name: Set Swap Space +# uses: ./.github/actions/set-swap-space +# with: +# swap-size-gb: 10 +# +# - name: Add hosts to /etc/hosts +# run: | +# sudo echo "127.0.0.1 localhost.simplereport.gov" | sudo tee -a /etc/hosts +# +# - name: Update files permissions +# # Even though we don't use it, we need the .env file created here due to an issue similar to this one: https://github.com/mutagen-io/mutagen/issues/265 +# run: | +# echo "::group::Update permissions" +# echo FAKE_ENV="true" >> .env +# sudo chmod -R 777 backend +# sudo chmod -R 777 frontend +# echo "::endgroup::" +# +# - name: Log in to the Container registry +# uses: docker/login-action@v3 +# with: +# registry: ghcr.io +# username: ${{ github.actor }} +# password: ${{ secrets.GITHUB_TOKEN }} +# +# - name: Setup and Run Lighthouse +# env: +# # CI settings +# CI: 1 +# # docker settings +# DOCKER_CLIENT_TIMEOUT: 180 +# COMPOSE_HTTP_TIMEOUT: 180 +# DOCKER_BACKEND_IMAGE_VERSION: ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }} +# DOCKER_DATABASE_IMAGE_VERSION: ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }} +# DOCKER_NGINX_IMAGE_VERSION: ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }} +# DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: ${{ inputs.DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION }} +# shell: bash +# run: | +# echo "::group::Running containers" +# echo "Backend branch tag (or latest): ${{ inputs.DOCKER_BACKEND_IMAGE_VERSION }}" +# echo "Database branch tag (or latest): ${{ inputs.DOCKER_DATABASE_IMAGE_VERSION }}" +# echo "Nginx branch tag (or latest): ${{ inputs.DOCKER_NGINX_IMAGE_VERSION }}" +# echo "Frontend branch tag (or latest): ${{ inputs.DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION }}" +# echo "::endgroup::" +# +# echo "::group::Run Lighthouse locally" +# bash lighthouse.sh +# echo "::endgroup::" +# +# - name: Archive Lighthouse results +# uses: actions/upload-artifact@v3 +# if: always() +# with: +# name: lighthouse-results +# path: lighthouse/* diff --git a/.github/workflows/liquibaseRollback.yml b/.github/workflows/liquibaseRollback.yml index a4ca30f422..97a975e6e7 100644 --- a/.github/workflows/liquibaseRollback.yml +++ b/.github/workflows/liquibaseRollback.yml @@ -1,47 +1,47 @@ -name: Liquibase Rollback - -concurrency: - group: db-actions - cancel-in-progress: false - -on: - workflow_dispatch: - inputs: - deploy_env: - description: The environment of the database. - required: true - type: choice - options: [demo, dev, dev2, dev3, dev4, dev5, dev6, dev7, pentest, test, training, stg, prod] - default: dev - action: - description: The liquibase action to run. - required: true - type: choice - options: [rollback] - default: rollback - liquibase_rollback_tag: - description: The Liquibase tag to roll back to - required: true - type: string - default: "" - -jobs: - - db_rollback_action: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: DB Liquibase Rollback - uses: ./.github/actions/db-actions - with: - deploy_env: ${{ github.event.inputs.deploy_env }} - action: ${{ github.event.inputs.action }} - liquibase_rollback_tag: ${{ github.event.inputs.liquibase_rollback_tag }} - azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} - acr_repo_url: ${{ secrets.ACR_REPO_URL }} - acr_admin_username: ${{ secrets.ACR_ADMIN_USERNAME }} - acr_admin_pasword: ${{ secrets.ACR_ADMIN_PASWORD }} - terraform_arm_client_id: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} - terraform_arm_client_secret: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} - terraform_arm_subscription_id: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} - terraform_arm_tenant_id: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} +#name: Liquibase Rollback +# +#concurrency: +# group: db-actions +# cancel-in-progress: false +# +#on: +# workflow_dispatch: +# inputs: +# deploy_env: +# description: The environment of the database. +# required: true +# type: choice +# options: [demo, dev, dev2, dev3, dev4, dev5, dev6, dev7, pentest, test, training, stg, prod] +# default: dev +# action: +# description: The liquibase action to run. +# required: true +# type: choice +# options: [rollback] +# default: rollback +# liquibase_rollback_tag: +# description: The Liquibase tag to roll back to +# required: true +# type: string +# default: "" +# +#jobs: +# +# db_rollback_action: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - name: DB Liquibase Rollback +# uses: ./.github/actions/db-actions +# with: +# deploy_env: ${{ github.event.inputs.deploy_env }} +# action: ${{ github.event.inputs.action }} +# liquibase_rollback_tag: ${{ github.event.inputs.liquibase_rollback_tag }} +# azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} +# acr_repo_url: ${{ secrets.ACR_REPO_URL }} +# acr_admin_username: ${{ secrets.ACR_ADMIN_USERNAME }} +# acr_admin_pasword: ${{ secrets.ACR_ADMIN_PASWORD }} +# terraform_arm_client_id: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} +# terraform_arm_client_secret: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} +# terraform_arm_subscription_id: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} +# terraform_arm_tenant_id: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} diff --git a/.github/workflows/liquibaseValidate.yml b/.github/workflows/liquibaseValidate.yml index 11ff68d8b0..7ee285bf87 100644 --- a/.github/workflows/liquibaseValidate.yml +++ b/.github/workflows/liquibaseValidate.yml @@ -1,41 +1,41 @@ -name: Liquibase Validate - -concurrency: - group: db-actions - cancel-in-progress: false - -on: - workflow_dispatch: - inputs: - deploy_env: - description: The environment of the database. - required: true - type: choice - options: [demo, dev, dev2, dev3, dev4, dev5, dev6, dev7, pentest, test, training, stg, prod] - default: dev - action: - description: The liquibase action to run. - required: true - type: choice - options: [validate] - default: validate - -jobs: - - db_validate_action: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: DB Liquibase Rollback - uses: ./.github/actions/db-actions - with: - deploy_env: ${{ github.event.inputs.deploy_env }} - action: ${{ github.event.inputs.action }} - azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} - acr_repo_url: ${{ secrets.ACR_REPO_URL }} - acr_admin_username: ${{ secrets.ACR_ADMIN_USERNAME }} - acr_admin_pasword: ${{ secrets.ACR_ADMIN_PASWORD }} - terraform_arm_client_id: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} - terraform_arm_client_secret: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} - terraform_arm_subscription_id: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} - terraform_arm_tenant_id: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} +#name: Liquibase Validate +# +#concurrency: +# group: db-actions +# cancel-in-progress: false +# +#on: +# workflow_dispatch: +# inputs: +# deploy_env: +# description: The environment of the database. +# required: true +# type: choice +# options: [demo, dev, dev2, dev3, dev4, dev5, dev6, dev7, pentest, test, training, stg, prod] +# default: dev +# action: +# description: The liquibase action to run. +# required: true +# type: choice +# options: [validate] +# default: validate +# +#jobs: +# +# db_validate_action: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - name: DB Liquibase Rollback +# uses: ./.github/actions/db-actions +# with: +# deploy_env: ${{ github.event.inputs.deploy_env }} +# action: ${{ github.event.inputs.action }} +# azure_credentials: ${{ secrets.AZURE_CREDENTIALS }} +# acr_repo_url: ${{ secrets.ACR_REPO_URL }} +# acr_admin_username: ${{ secrets.ACR_ADMIN_USERNAME }} +# acr_admin_pasword: ${{ secrets.ACR_ADMIN_PASWORD }} +# terraform_arm_client_id: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} +# terraform_arm_client_secret: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} +# terraform_arm_subscription_id: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} +# terraform_arm_tenant_id: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} diff --git a/.github/workflows/smokeTestDeployProd.yml b/.github/workflows/smokeTestDeployProd.yml new file mode 100644 index 0000000000..3d2dec111e --- /dev/null +++ b/.github/workflows/smokeTestDeployProd.yml @@ -0,0 +1,48 @@ +name: Smoke test deploy Prod +run-name: Smoke test the deploy for prod by @${{ github.actor }} + +on: + push: + # workflow_run: + # workflows: ["Deploy Prod"] + # types: + # - completed + +env: + BASE_DOMAIN_NAME: https://dev6.simplereport.gov + +jobs: + smoke-test-front-and-back-end: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + - name: Cache yarn + uses: actions/cache@v3.3.2 + with: + path: ~/.cache/yarn + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + - name: Set up dependencies + working-directory: frontend + run: yarn install --prefer-offline + - name: Smoke test the env + uses: ./.github/actions/post-deploy-smoke-test + with: + base_domain_name: ${{ env.BASE_DOMAIN_NAME }} + slack_alert: + runs-on: ubuntu-latest + if: failure() + needs: [ smoke-test-front-and-back-end ] + steps: + - uses: actions/checkout@v4 + - name: Send alert to Slack + uses: ./.github/actions/slack-message + with: + username: ${{ github.actor }} + description: | + :siren-gif: Post-deploy smoke test couldn't verify that the frontend is talking to the backend. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} :siren-gif: + webhook_url: ${{ secrets.SR_ALERTS_SLACK_WEBHOOK_URL }} + user_map: $${{ secrets.SR_ALERTS_GITHUB_SLACK_MAP }} diff --git a/.github/workflows/terraformChecks.yml b/.github/workflows/terraformChecks.yml index 09d341fbe4..87f54826b7 100644 --- a/.github/workflows/terraformChecks.yml +++ b/.github/workflows/terraformChecks.yml @@ -1,101 +1,101 @@ -name: Terraform Checks - -on: - workflow_dispatch: # because sometimes you just want to force a branch to have tests run - pull_request: - branches: - - "**" - merge_group: - types: - - checks_requested - -defaults: - run: - working-directory: ./ops - -jobs: - check-terraform-formatting: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: hashicorp/setup-terraform@v3.0.0 - with: - terraform_version: 1.3.3 - - name: Terraform fmt - run: terraform fmt -check -recursive - - check-terraform-validity: - runs-on: ubuntu-latest - env: - TERRAFORM_DIRS: | - dev dev/persistent dev2 dev2/persistent dev3 dev3/persistent dev4 dev4/persistent - dev5 dev5/persistent dev6 dev6/persistent dev7 dev7/persistent - test test/persistent demo demo/persistent training training/persistent - stg stg/persistent pentest pentest/persistent prod prod/persistent - global - steps: - - uses: actions/checkout@v4 - - uses: hashicorp/setup-terraform@v3.0.0 - with: - terraform_version: 1.3.3 - - name: Terraform Init - run: | - for d in $TERRAFORM_DIRS - do - echo "Initializing $d"; - (cd $d && terraform init -backend=false) - done - - name: Terraform Validate - run: | - for d in $TERRAFORM_DIRS - do - echo "Validating $d"; - (cd $d && terraform validate) - done - - terraform-plan: - runs-on: ubuntu-latest - needs: [check-terraform-validity] - env: # all Azure interaction is through terraform - ARM_CLIENT_ID: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} - ARM_CLIENT_SECRET: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} - ARM_SUBSCRIPTION_ID: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} - ARM_TENANT_ID: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} - OKTA_API_TOKEN: ${{ secrets.OKTA_API_TOKEN }} - steps: - - uses: actions/checkout@v4 - - name: Dependabot bypass - if: ${{ github.actor == 'dependabot[bot]' }} - run: | - true - - uses: azure/login@v1 - if: ${{ github.actor != 'dependabot[bot]' }} - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - - uses: hashicorp/setup-terraform@v3.0.0 - if: ${{ github.actor != 'dependabot[bot]' }} - with: - terraform_version: 1.3.3 - - name: Terraform Init Prod - if: ${{ github.actor != 'dependabot[bot]' }} - run: make init-prod - - name: Build ReportStream function app Prod - if: ${{ github.actor != 'dependabot[bot]' }} - uses: ./.github/actions/build-reportstream-functions - with: - deploy-env: ${{env.DEPLOY_ENV}} - - name: Terraform Plan Prod - if: ${{ github.actor != 'dependabot[bot]' }} - run: make plan-prod - - - name: Terraform Init Stg - if: ${{ github.actor != 'dependabot[bot]' }} - run: make init-stg - - name: Build ReportStream function app Stg - if: ${{ github.actor != 'dependabot[bot]' }} - uses: ./.github/actions/build-reportstream-functions - with: - deploy-env: stg - - name: Terraform plan Stg - if: ${{ github.actor != 'dependabot[bot]' }} - run: make plan-stg +#name: Terraform Checks +# +#on: +# workflow_dispatch: # because sometimes you just want to force a branch to have tests run +# pull_request: +# branches: +# - "**" +# merge_group: +# types: +# - checks_requested +# +#defaults: +# run: +# working-directory: ./ops +# +#jobs: +# check-terraform-formatting: +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# - uses: hashicorp/setup-terraform@v3.0.0 +# with: +# terraform_version: 1.3.3 +# - name: Terraform fmt +# run: terraform fmt -check -recursive +# +# check-terraform-validity: +# runs-on: ubuntu-latest +# env: +# TERRAFORM_DIRS: | +# dev dev/persistent dev2 dev2/persistent dev3 dev3/persistent dev4 dev4/persistent +# dev5 dev5/persistent dev6 dev6/persistent dev7 dev7/persistent +# test test/persistent demo demo/persistent training training/persistent +# stg stg/persistent pentest pentest/persistent prod prod/persistent +# global +# steps: +# - uses: actions/checkout@v4 +# - uses: hashicorp/setup-terraform@v3.0.0 +# with: +# terraform_version: 1.3.3 +# - name: Terraform Init +# run: | +# for d in $TERRAFORM_DIRS +# do +# echo "Initializing $d"; +# (cd $d && terraform init -backend=false) +# done +# - name: Terraform Validate +# run: | +# for d in $TERRAFORM_DIRS +# do +# echo "Validating $d"; +# (cd $d && terraform validate) +# done +# +# terraform-plan: +# runs-on: ubuntu-latest +# needs: [check-terraform-validity] +# env: # all Azure interaction is through terraform +# ARM_CLIENT_ID: ${{ secrets.TERRAFORM_ARM_CLIENT_ID }} +# ARM_CLIENT_SECRET: ${{ secrets.TERRAFORM_ARM_CLIENT_SECRET }} +# ARM_SUBSCRIPTION_ID: ${{ secrets.TERRAFORM_ARM_SUBSCRIPTION_ID }} +# ARM_TENANT_ID: ${{ secrets.TERRAFORM_ARM_TENANT_ID }} +# OKTA_API_TOKEN: ${{ secrets.OKTA_API_TOKEN }} +# steps: +# - uses: actions/checkout@v4 +# - name: Dependabot bypass +# if: ${{ github.actor == 'dependabot[bot]' }} +# run: | +# true +# - uses: azure/login@v1 +# if: ${{ github.actor != 'dependabot[bot]' }} +# with: +# creds: ${{ secrets.AZURE_CREDENTIALS }} +# - uses: hashicorp/setup-terraform@v3.0.0 +# if: ${{ github.actor != 'dependabot[bot]' }} +# with: +# terraform_version: 1.3.3 +# - name: Terraform Init Prod +# if: ${{ github.actor != 'dependabot[bot]' }} +# run: make init-prod +# - name: Build ReportStream function app Prod +# if: ${{ github.actor != 'dependabot[bot]' }} +# uses: ./.github/actions/build-reportstream-functions +# with: +# deploy-env: ${{env.DEPLOY_ENV}} +# - name: Terraform Plan Prod +# if: ${{ github.actor != 'dependabot[bot]' }} +# run: make plan-prod +# +# - name: Terraform Init Stg +# if: ${{ github.actor != 'dependabot[bot]' }} +# run: make init-stg +# - name: Build ReportStream function app Stg +# if: ${{ github.actor != 'dependabot[bot]' }} +# uses: ./.github/actions/build-reportstream-functions +# with: +# deploy-env: stg +# - name: Terraform plan Stg +# if: ${{ github.actor != 'dependabot[bot]' }} +# run: make plan-stg diff --git a/.github/workflows/testingWorkflow.yml b/.github/workflows/testingWorkflow.yml index 4ac88d0558..ad0bc136cb 100644 --- a/.github/workflows/testingWorkflow.yml +++ b/.github/workflows/testingWorkflow.yml @@ -1,284 +1,284 @@ -name: Testing Workflow - -on: - workflow_dispatch: - inputs: - platforms: - description: "Build additional architectures (linux/arm64). linux/amd64 is built by default." - required: false - force_build: - description: "Force build the docker images" - required: true - default: true - pull_request: - branches: - - "**" - merge_group: - types: - - checks_requested - push: - branches: - - main - -permissions: - contents: read - packages: write - -jobs: -# Check for changes in the backend, cypress, database, frontend, and nginx directories - workflow_changes: - with: - what_to_check: ./.github - uses: ./.github/workflows/checkForChanges.yml - - backend_changes: - with: - what_to_check: ./backend - uses: ./.github/workflows/checkForChanges.yml - - cypress_changes: - with: - what_to_check: ./cypress - uses: ./.github/workflows/checkForChanges.yml - - database_changes: - with: - what_to_check: ./backend/db-setup - uses: ./.github/workflows/checkForChanges.yml - - frontend_changes: - with: - what_to_check: ./frontend - uses: ./.github/workflows/checkForChanges.yml - - nginx_changes: - with: - what_to_check: ./nginx - uses: ./.github/workflows/checkForChanges.yml - -# Build Docker Images for the backend, cypress, database, frontend, and nginx - build_backend_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.backend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - backend_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_backend_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Backend Image - id: set_backend_version - uses: ./.github/actions/docker-buildx - with: - file: ./backend/Dockerfile - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: backend - platform: ${{ matrix.platform }} - - build_cypress_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.cypress_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - cypress_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_cypress_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Cypress Image - id: set_cypress_version - uses: ./.github/actions/docker-buildx - with: - file: ./cypress/Dockerfile - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: cypress - platform: ${{ matrix.platform }} - - build_database_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.database_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - database_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_database_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Database Image - id: set_database_version - uses: ./.github/actions/docker-buildx - with: - context: ./backend/db-setup - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: database - platform: ${{ matrix.platform }} - - build_frontend_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.frontend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - frontend_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_frontend_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Frontend Image - id: set_frontend_version - uses: ./.github/actions/docker-buildx - with: - file: ./frontend/Dockerfile - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: frontend - platform: ${{ matrix.platform }} - build_args: | - "REACT_APP_OKTA_URL=http://wiremock:8088" - "REACT_APP_OKTA_CLIENT_ID=0oa1k0163nAwfVxNW1d7" - "REACT_APP_BASE_URL=https://localhost.simplereport.gov" - "REACT_APP_BACKEND_URL=https://localhost.simplereport.gov/api" - "PUBLIC_URL=/app/" - "REACT_APP_OKTA_ENABLED=true" - "REACT_APP_DISABLE_MAINTENANCE_BANNER=true" - - build_frontend_lighthouse_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.frontend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - frontend_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_frontend_lighthouse_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Frontend Lighthouse Image - id: set_frontend_lighthouse_version - uses: ./.github/actions/docker-buildx - with: - file: ./frontend/Dockerfile - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: frontend-lighthouse - platform: ${{ matrix.platform }} - build_args: | - "REACT_APP_BASE_URL=https://localhost.simplereport.gov" - "REACT_APP_BACKEND_URL=https://localhost.simplereport.gov/api" - "PUBLIC_URL=/app/" - "REACT_APP_OKTA_ENABLED=false" - "REACT_APP_DISABLE_MAINTENANCE_BANNER=true" - - build_nginx_image: - if: needs.workflow_changes.outputs.has_changes == 'true' || needs.nginx_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' - needs: - - nginx_changes - - workflow_changes - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - platform: ${{ inputs.platform }} - outputs: - version: ${{ steps.set_nginx_version.outputs.version }} - steps: - - uses: actions/checkout@v4 - - name: Build Nginx Image - id: set_nginx_version - uses: ./.github/actions/docker-buildx - with: - context: ./nginx - gh_username: ${{ github.actor }} - gh_token: ${{ secrets.GITHUB_TOKEN }} - image_name: nginx - platform: ${{ matrix.platform }} - -# Automated tests - e2e_local: - if: | - always() && !failure() && !cancelled() - needs: - - build_backend_image - - build_cypress_image - - build_database_image - - build_frontend_image - - build_nginx_image - uses: ./.github/workflows/e2eLocal.yml - secrets: - CYPRESS_OKTA_USERNAME: ${{ secrets.CYPRESS_OKTA_USERNAME }} - CYPRESS_OKTA_PASSWORD: ${{ secrets.CYPRESS_OKTA_PASSWORD }} - CYPRESS_OKTA_SECRET: ${{ secrets.CYPRESS_OKTA_SECRET }} - OKTA_API_KEY: ${{ secrets.OKTA_API_KEY }} - SMARTY_AUTH_ID: ${{ secrets.SMARTY_AUTH_ID }} - SMARTY_AUTH_TOKEN: ${{ secrets.SMARTY_AUTH_TOKEN }} - with: - DOCKER_BACKEND_IMAGE_VERSION: ${{ needs.build_backend_image.outputs.version }} - DOCKER_CYPRESS_IMAGE_VERSION: ${{ needs.build_cypress_image.outputs.version }} - DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} - DOCKER_FRONTEND_IMAGE_VERSION: ${{ needs.build_frontend_image.outputs.version }} - DOCKER_NGINX_IMAGE_VERSION: ${{ needs.build_nginx_image.outputs.version }} - - lighthouse: - if: | - always() && !failure() && !cancelled() - needs: - - build_backend_image - - build_database_image - - build_frontend_lighthouse_image - - build_nginx_image - uses: ./.github/workflows/lighthouse.yml - with: - DOCKER_BACKEND_IMAGE_VERSION: ${{ needs.build_backend_image.outputs.version }} - DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} - DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: ${{ needs.build_frontend_lighthouse_image.outputs.version }} - DOCKER_NGINX_IMAGE_VERSION: ${{ needs.build_nginx_image.outputs.version }} - - tests: - if: | - always() && !failure() && !cancelled() - needs: - - build_database_image - uses: ./.github/workflows/test.yml - secrets: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - TWILIO_ACCOUNT_SID: ${{ secrets.TWILIO_TEST_ACCOUNT_SID }} - TWILIO_AUTH_TOKEN: ${{ secrets.TWILIO_TEST_AUTH_TOKEN }} - with: - DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} - - liquibase_action_checks: - if: | - always() && !failure() && !cancelled() - needs: - - build_database_image - uses: ./.github/workflows/testDBActions.yml - with: - DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} \ No newline at end of file +#name: Testing Workflow +# +#on: +# workflow_dispatch: +# inputs: +# platforms: +# description: "Build additional architectures (linux/arm64). linux/amd64 is built by default." +# required: false +# force_build: +# description: "Force build the docker images" +# required: true +# default: true +# pull_request: +# branches: +# - "**" +# merge_group: +# types: +# - checks_requested +# push: +# branches: +# - main +# +#permissions: +# contents: read +# packages: write +# +#jobs: +## Check for changes in the backend, cypress, database, frontend, and nginx directories +# workflow_changes: +# with: +# what_to_check: ./.github +# uses: ./.github/workflows/checkForChanges.yml +# +# backend_changes: +# with: +# what_to_check: ./backend +# uses: ./.github/workflows/checkForChanges.yml +# +# cypress_changes: +# with: +# what_to_check: ./cypress +# uses: ./.github/workflows/checkForChanges.yml +# +# database_changes: +# with: +# what_to_check: ./backend/db-setup +# uses: ./.github/workflows/checkForChanges.yml +# +# frontend_changes: +# with: +# what_to_check: ./frontend +# uses: ./.github/workflows/checkForChanges.yml +# +# nginx_changes: +# with: +# what_to_check: ./nginx +# uses: ./.github/workflows/checkForChanges.yml +# +## Build Docker Images for the backend, cypress, database, frontend, and nginx +# build_backend_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.backend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - backend_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_backend_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Backend Image +# id: set_backend_version +# uses: ./.github/actions/docker-buildx +# with: +# file: ./backend/Dockerfile +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: backend +# platform: ${{ matrix.platform }} +# +# build_cypress_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.cypress_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - cypress_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_cypress_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Cypress Image +# id: set_cypress_version +# uses: ./.github/actions/docker-buildx +# with: +# file: ./cypress/Dockerfile +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: cypress +# platform: ${{ matrix.platform }} +# +# build_database_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.database_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - database_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_database_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Database Image +# id: set_database_version +# uses: ./.github/actions/docker-buildx +# with: +# context: ./backend/db-setup +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: database +# platform: ${{ matrix.platform }} +# +# build_frontend_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.frontend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - frontend_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_frontend_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Frontend Image +# id: set_frontend_version +# uses: ./.github/actions/docker-buildx +# with: +# file: ./frontend/Dockerfile +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: frontend +# platform: ${{ matrix.platform }} +# build_args: | +# "REACT_APP_OKTA_URL=http://wiremock:8088" +# "REACT_APP_OKTA_CLIENT_ID=0oa1k0163nAwfVxNW1d7" +# "REACT_APP_BASE_URL=https://localhost.simplereport.gov" +# "REACT_APP_BACKEND_URL=https://localhost.simplereport.gov/api" +# "PUBLIC_URL=/app/" +# "REACT_APP_OKTA_ENABLED=true" +# "REACT_APP_DISABLE_MAINTENANCE_BANNER=true" +# +# build_frontend_lighthouse_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.frontend_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - frontend_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_frontend_lighthouse_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Frontend Lighthouse Image +# id: set_frontend_lighthouse_version +# uses: ./.github/actions/docker-buildx +# with: +# file: ./frontend/Dockerfile +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: frontend-lighthouse +# platform: ${{ matrix.platform }} +# build_args: | +# "REACT_APP_BASE_URL=https://localhost.simplereport.gov" +# "REACT_APP_BACKEND_URL=https://localhost.simplereport.gov/api" +# "PUBLIC_URL=/app/" +# "REACT_APP_OKTA_ENABLED=false" +# "REACT_APP_DISABLE_MAINTENANCE_BANNER=true" +# +# build_nginx_image: +# if: needs.workflow_changes.outputs.has_changes == 'true' || needs.nginx_changes.outputs.has_changes == 'true' || inputs.force_build == 'true' || github.ref == 'refs/heads/main' +# needs: +# - nginx_changes +# - workflow_changes +# runs-on: ubuntu-latest +# strategy: +# fail-fast: false +# matrix: +# include: +# - platform: ${{ inputs.platform }} +# outputs: +# version: ${{ steps.set_nginx_version.outputs.version }} +# steps: +# - uses: actions/checkout@v4 +# - name: Build Nginx Image +# id: set_nginx_version +# uses: ./.github/actions/docker-buildx +# with: +# context: ./nginx +# gh_username: ${{ github.actor }} +# gh_token: ${{ secrets.GITHUB_TOKEN }} +# image_name: nginx +# platform: ${{ matrix.platform }} +# +## Automated tests +# e2e_local: +# if: | +# always() && !failure() && !cancelled() +# needs: +# - build_backend_image +# - build_cypress_image +# - build_database_image +# - build_frontend_image +# - build_nginx_image +# uses: ./.github/workflows/e2eLocal.yml +# secrets: +# CYPRESS_OKTA_USERNAME: ${{ secrets.CYPRESS_OKTA_USERNAME }} +# CYPRESS_OKTA_PASSWORD: ${{ secrets.CYPRESS_OKTA_PASSWORD }} +# CYPRESS_OKTA_SECRET: ${{ secrets.CYPRESS_OKTA_SECRET }} +# OKTA_API_KEY: ${{ secrets.OKTA_API_KEY }} +# SMARTY_AUTH_ID: ${{ secrets.SMARTY_AUTH_ID }} +# SMARTY_AUTH_TOKEN: ${{ secrets.SMARTY_AUTH_TOKEN }} +# with: +# DOCKER_BACKEND_IMAGE_VERSION: ${{ needs.build_backend_image.outputs.version }} +# DOCKER_CYPRESS_IMAGE_VERSION: ${{ needs.build_cypress_image.outputs.version }} +# DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} +# DOCKER_FRONTEND_IMAGE_VERSION: ${{ needs.build_frontend_image.outputs.version }} +# DOCKER_NGINX_IMAGE_VERSION: ${{ needs.build_nginx_image.outputs.version }} +# +# lighthouse: +# if: | +# always() && !failure() && !cancelled() +# needs: +# - build_backend_image +# - build_database_image +# - build_frontend_lighthouse_image +# - build_nginx_image +# uses: ./.github/workflows/lighthouse.yml +# with: +# DOCKER_BACKEND_IMAGE_VERSION: ${{ needs.build_backend_image.outputs.version }} +# DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} +# DOCKER_FRONTEND_LIGHTHOUSE_IMAGE_VERSION: ${{ needs.build_frontend_lighthouse_image.outputs.version }} +# DOCKER_NGINX_IMAGE_VERSION: ${{ needs.build_nginx_image.outputs.version }} +# +# tests: +# if: | +# always() && !failure() && !cancelled() +# needs: +# - build_database_image +# uses: ./.github/workflows/test.yml +# secrets: +# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} +# TWILIO_ACCOUNT_SID: ${{ secrets.TWILIO_TEST_ACCOUNT_SID }} +# TWILIO_AUTH_TOKEN: ${{ secrets.TWILIO_TEST_AUTH_TOKEN }} +# with: +# DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} +# +# liquibase_action_checks: +# if: | +# always() && !failure() && !cancelled() +# needs: +# - build_database_image +# uses: ./.github/workflows/testDBActions.yml +# with: +# DOCKER_DATABASE_IMAGE_VERSION: ${{ needs.build_database_image.outputs.version }} \ No newline at end of file diff --git a/.github/workflows/tfsec.yml b/.github/workflows/tfsec.yml index 274855ff59..ec27bfe031 100644 --- a/.github/workflows/tfsec.yml +++ b/.github/workflows/tfsec.yml @@ -1,28 +1,28 @@ -# Use this action if we want these alerts to show up in the Github Security Alerts: https://github.com/marketplace/actions/run-tfsec-with-sarif-upload -# Use this action if we want these alerts to be added as comments on a PR: https://github.com/marketplace/actions/run-tfsec-with-sarif-upload -# This action repo: https://github.com/aquasecurity/tfsec-action -name: tfsec - -on: - push: - branches: - - main - pull_request: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - tfsec: - name: tfsec - runs-on: ubuntu-latest - - steps: - - name: Clone repo - uses: actions/checkout@master - - name: tfsec - uses: aquasecurity/tfsec-action@v1.0.3 - with: - # added these exceptions for now, the ticket to fix them is here: https://github.com/CDCgov/prime-simplereport/issues/5879 - additional_args: -e azure-keyvault-ensure-key-expiry,azure-keyvault-no-purge +## Use this action if we want these alerts to show up in the Github Security Alerts: https://github.com/marketplace/actions/run-tfsec-with-sarif-upload +## Use this action if we want these alerts to be added as comments on a PR: https://github.com/marketplace/actions/run-tfsec-with-sarif-upload +## This action repo: https://github.com/aquasecurity/tfsec-action +#name: tfsec +# +#on: +# push: +# branches: +# - main +# pull_request: +# +#concurrency: +# group: ${{ github.workflow }}-${{ github.ref }} +# cancel-in-progress: true +# +#jobs: +# tfsec: +# name: tfsec +# runs-on: ubuntu-latest +# +# steps: +# - name: Clone repo +# uses: actions/checkout@master +# - name: tfsec +# uses: aquasecurity/tfsec-action@v1.0.3 +# with: +# # added these exceptions for now, the ticket to fix them is here: https://github.com/CDCgov/prime-simplereport/issues/5879 +# additional_args: -e azure-keyvault-ensure-key-expiry,azure-keyvault-no-purge diff --git a/backend/src/main/java/gov/cdc/usds/simplereport/api/heathcheck/BackendAndDatabaseHealthIndicator.java b/backend/src/main/java/gov/cdc/usds/simplereport/api/heathcheck/BackendAndDatabaseHealthIndicator.java new file mode 100644 index 0000000000..a2466765ac --- /dev/null +++ b/backend/src/main/java/gov/cdc/usds/simplereport/api/heathcheck/BackendAndDatabaseHealthIndicator.java @@ -0,0 +1,44 @@ +package gov.cdc.usds.simplereport.api.heathcheck; + +import com.okta.sdk.resource.client.ApiException; +import gov.cdc.usds.simplereport.db.repository.FeatureFlagRepository; +import gov.cdc.usds.simplereport.idp.repository.OktaRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.exception.JDBCConnectionException; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.actuate.health.HealthIndicator; +import org.springframework.stereotype.Component; + +@Component("backend-and-db-smoke-test") +@Slf4j +@RequiredArgsConstructor +public class BackendAndDatabaseHealthIndicator implements HealthIndicator { + private final FeatureFlagRepository _ffRepo; + private final OktaRepository _oktaRepo; + public static final String ACTIVE_LITERAL = "ACTIVE"; + + @Override + public Health health() { + try { + _ffRepo.findAll(); + String oktaStatus = _oktaRepo.getApplicationStatusForHealthCheck(); + + if (!ACTIVE_LITERAL.equals(oktaStatus)) { + log.info("Okta status didn't return ACTIVE, instead returned " + oktaStatus); + return Health.down().build(); + } + return Health.up().build(); + } catch (IllegalArgumentException e) { + // reach into the ff repository returned a bad value + return Health.down().build(); + } catch (JDBCConnectionException e) { + // db connection issue + return Health.down().build(); + } catch (ApiException e) { + // Okta API call errored + log.info(e.getMessage()); + return Health.down().build(); + } + } +} diff --git a/backend/src/main/java/gov/cdc/usds/simplereport/config/SecurityConfiguration.java b/backend/src/main/java/gov/cdc/usds/simplereport/config/SecurityConfiguration.java index 15fdeee263..07a737850a 100644 --- a/backend/src/main/java/gov/cdc/usds/simplereport/config/SecurityConfiguration.java +++ b/backend/src/main/java/gov/cdc/usds/simplereport/config/SecurityConfiguration.java @@ -1,6 +1,7 @@ package gov.cdc.usds.simplereport.config; import com.okta.spring.boot.oauth.Okta; +import gov.cdc.usds.simplereport.api.heathcheck.BackendAndDatabaseHealthIndicator; import gov.cdc.usds.simplereport.service.model.IdentityAttributes; import gov.cdc.usds.simplereport.service.model.IdentitySupplier; import lombok.extern.slf4j.Slf4j; @@ -57,6 +58,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .permitAll() .requestMatchers(EndpointRequest.to(InfoEndpoint.class)) .permitAll() + .requestMatchers(EndpointRequest.to(BackendAndDatabaseHealthIndicator.class)) + .permitAll() // Patient experience authorization is handled in PatientExperienceController // If this configuration changes, please update the documentation on both sides .requestMatchers(HttpMethod.POST, WebConfiguration.PATIENT_EXPERIENCE) diff --git a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/DemoOktaRepository.java b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/DemoOktaRepository.java index d9ef3b5fd8..883963df9c 100644 --- a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/DemoOktaRepository.java +++ b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/DemoOktaRepository.java @@ -1,5 +1,7 @@ package gov.cdc.usds.simplereport.idp.repository; +import static gov.cdc.usds.simplereport.api.heathcheck.BackendAndDatabaseHealthIndicator.ACTIVE_LITERAL; + import com.okta.sdk.resource.model.UserStatus; import gov.cdc.usds.simplereport.api.CurrentTenantDataAccessContextHolder; import gov.cdc.usds.simplereport.api.model.errors.ConflictingUserException; @@ -431,4 +433,9 @@ public Integer getUsersInSingleFacility(Facility facility) { return accessCount; } + + @Override + public String getApplicationStatusForHealthCheck() { + return ACTIVE_LITERAL; + } } diff --git a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/LiveOktaRepository.java b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/LiveOktaRepository.java index 7c61c63d3f..1c617a1485 100644 --- a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/LiveOktaRepository.java +++ b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/LiveOktaRepository.java @@ -67,6 +67,8 @@ public class LiveOktaRepository implements OktaRepository { private final Application app; private final OrganizationExtractor extractor; private final CurrentTenantDataAccessContextHolder tenantDataContextHolder; + + private final ApplicationApi applicationApi; private final GroupApi groupApi; private final UserApi userApi; private final ApplicationGroupsApi applicationGroupsApi; @@ -87,6 +89,7 @@ public LiveOktaRepository( this.rolePrefix = authorizationProperties.getRolePrefix(); this.adminGroupName = authorizationProperties.getAdminGroupName(); + this.applicationApi = applicationApi; this.groupApi = groupApi; this.userApi = userApi; this.applicationGroupsApi = applicationGroupsApi; @@ -692,6 +695,11 @@ public PartialOktaUser findUser(String username) { .build(); } + @Override + public String getApplicationStatusForHealthCheck() { + return app.getStatus().toString(); + } + private Optional getOrganizationRoleClaimsFromAuthorities( Collection authorities) { List claims = extractor.convertClaims(authorities); diff --git a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/OktaRepository.java b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/OktaRepository.java index 92cf4c1dfa..fc488573b7 100644 --- a/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/OktaRepository.java +++ b/backend/src/main/java/gov/cdc/usds/simplereport/idp/repository/OktaRepository.java @@ -76,4 +76,6 @@ List updateUserPrivilegesAndGroupAccess( Integer getUsersInSingleFacility(Facility facility); PartialOktaUser findUser(String username); + + String getApplicationStatusForHealthCheck(); } diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml index 1df6cb8e0a..8f792d8cc0 100644 --- a/backend/src/main/resources/application.yaml +++ b/backend/src/main/resources/application.yaml @@ -78,6 +78,7 @@ management: endpoint.health.probes.enabled: true endpoint.info.enabled: true endpoints.web.exposure.include: health, info + endpoint.health.show-components: always okta: oauth2: issuer: https://hhs-prime.okta.com/oauth2/default diff --git a/backend/src/test/java/gov/cdc/usds/simplereport/api/healthcheck/BackendAndDatabaseHealthIndicatorTest.java b/backend/src/test/java/gov/cdc/usds/simplereport/api/healthcheck/BackendAndDatabaseHealthIndicatorTest.java new file mode 100644 index 0000000000..9e0cfa936c --- /dev/null +++ b/backend/src/test/java/gov/cdc/usds/simplereport/api/healthcheck/BackendAndDatabaseHealthIndicatorTest.java @@ -0,0 +1,60 @@ +package gov.cdc.usds.simplereport.api.healthcheck; + +import static gov.cdc.usds.simplereport.api.heathcheck.BackendAndDatabaseHealthIndicator.ACTIVE_LITERAL; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import gov.cdc.usds.simplereport.api.heathcheck.BackendAndDatabaseHealthIndicator; +import gov.cdc.usds.simplereport.db.repository.BaseRepositoryTest; +import gov.cdc.usds.simplereport.db.repository.FeatureFlagRepository; +import gov.cdc.usds.simplereport.idp.repository.OktaRepository; +import java.sql.SQLException; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.hibernate.exception.JDBCConnectionException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.actuate.health.Health; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.mock.mockito.SpyBean; + +@RequiredArgsConstructor +@EnableConfigurationProperties +class BackendAndDatabaseHealthIndicatorTest extends BaseRepositoryTest { + + @SpyBean private FeatureFlagRepository mockFeatureFlagRepo; + @SpyBean private OktaRepository mockOktaRepo; + + @Autowired private BackendAndDatabaseHealthIndicator indicator; + + @Test + void health_succeedsWhenReposDoesntThrow() { + when(mockFeatureFlagRepo.findAll()).thenReturn(List.of()); + when(mockOktaRepo.getApplicationStatusForHealthCheck()).thenReturn(ACTIVE_LITERAL); + + assertThat(indicator.health()).isEqualTo(Health.up().build()); + } + + @Test + void health_failsWhenDBConnectionThrows() { + JDBCConnectionException dbConnectionException = + new JDBCConnectionException( + "connection issue", new SQLException("some reason", "some state")); + when(mockFeatureFlagRepo.findAll()).thenThrow(dbConnectionException); + assertThat(indicator.health()).isEqualTo(Health.down().build()); + } + + @Test + void health_failsWhenFeatureFlagRepoThrows() { + IllegalArgumentException dbConnectionException = + new IllegalArgumentException("some argument message"); + when(mockFeatureFlagRepo.findAll()).thenThrow(dbConnectionException); + assertThat(indicator.health()).isEqualTo(Health.down().build()); + } + + @Test + void health_failsWhenOktaRepoDoesntReturnActive() { + when(mockOktaRepo.getApplicationStatusForHealthCheck()).thenReturn("INACTIVE"); + assertThat(indicator.health()).isEqualTo(Health.down().build()); + } +} diff --git a/backend/src/test/java/gov/cdc/usds/simplereport/test_util/SliceTestConfiguration.java b/backend/src/test/java/gov/cdc/usds/simplereport/test_util/SliceTestConfiguration.java index 30e8144768..3ac3f7dd7d 100644 --- a/backend/src/test/java/gov/cdc/usds/simplereport/test_util/SliceTestConfiguration.java +++ b/backend/src/test/java/gov/cdc/usds/simplereport/test_util/SliceTestConfiguration.java @@ -5,6 +5,7 @@ import gov.cdc.usds.simplereport.api.CurrentOrganizationRolesContextHolder; import gov.cdc.usds.simplereport.api.CurrentTenantDataAccessContextHolder; import gov.cdc.usds.simplereport.api.WebhookContextHolder; +import gov.cdc.usds.simplereport.api.heathcheck.BackendAndDatabaseHealthIndicator; import gov.cdc.usds.simplereport.api.pxp.CurrentPatientContextHolder; import gov.cdc.usds.simplereport.config.AuditingConfig; import gov.cdc.usds.simplereport.config.AuthorizationProperties; @@ -100,7 +101,8 @@ CurrentTenantDataAccessContextHolder.class, WebhookContextHolder.class, TenantDataAccessService.class, - PatientSelfRegistrationLinkService.class + PatientSelfRegistrationLinkService.class, + BackendAndDatabaseHealthIndicator.class }) @EnableConfigurationProperties({InitialSetupProperties.class, AuthorizationProperties.class}) public class SliceTestConfiguration { diff --git a/frontend/deploy-smoke.js b/frontend/deploy-smoke.js new file mode 100644 index 0000000000..966774839b --- /dev/null +++ b/frontend/deploy-smoke.js @@ -0,0 +1,35 @@ +// Script that does a simple Selenium scrape of +// - A frontend page with a simple status message that hits a health check backend +// endpoint which does a simple ping to a non-sensitive DB table to verify +// all the connections are good. +// https://github.com/CDCgov/prime-simplereport/pull/7057 + +require("dotenv").config(); +let { Builder } = require("selenium-webdriver"); +const Chrome = require("selenium-webdriver/chrome"); + +const appUrl = process.env.REACT_APP_BASE_URL.includes("localhost") + ? `${process.env.REACT_APP_BASE_URL}/health/deploy-smoke-test` + : `${process.env.REACT_APP_BASE_URL}/app/health/deploy-smoke-test`; + +console.log(`Running smoke test for ${appUrl}`); +const options = new Chrome.Options(); +const driver = new Builder() + .forBrowser("chrome") + .setChromeOptions(options.addArguments("--headless=new")) + .build(); +driver + .navigate() + .to(`${appUrl}`) + .then(() => { + let value = driver.findElement({ id: "root" }).getText(); + return value; + }) + .then((value) => { + driver.quit(); + return value; + }) + .then((value) => { + if (value.includes("success")) process.exit(0); + process.exit(1); + }); diff --git a/frontend/package.json b/frontend/package.json index 231bb777af..d53b4f7f28 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -75,7 +75,9 @@ "storybook": "yarn create-storybook-public && SASS_PATH=$(cd ./node_modules && pwd):$(cd ./node_modules/@uswds && pwd):$(cd ./node_modules/@uswds/uswds/packages && pwd):$(cd ./src/scss && pwd) storybook dev -p 6006 -s ../storybook_public", "build-storybook": "yarn create-storybook-public && REACT_APP_BACKEND_URL=http://localhost:8080 SASS_PATH=$(cd ./node_modules && pwd):$(cd ./node_modules/@uswds && pwd):$(cd ./node_modules/@uswds/uswds/packages && pwd):$(cd ./src/scss && pwd) storybook build -s storybook_public", "maintenance:start": "[ -z \"$MAINTENANCE_MESSAGE\" ] && echo \"MAINTENANCE_MESSAGE must be set!\" || (echo $MAINTENANCE_MESSAGE > maintenance.json && yarn maintenance:deploy && rm maintenance.json)", - "maintenance:deploy": "[ -z \"$MAINTENANCE_ENV\" ] && echo \"MAINTENANCE_ENV must be set!\" || az storage blob upload -f maintenance.json -n maintenance.json -c '$web' --account-name simplereport${MAINTENANCE_ENV}app --overwrite" + "maintenance:deploy": "[ -z \"$MAINTENANCE_ENV\" ] && echo \"MAINTENANCE_ENV must be set!\" || az storage blob upload -f maintenance.json -n maintenance.json -c '$web' --account-name simplereport${MAINTENANCE_ENV}app --overwrite", + "smoke:deploy:local": "node -r dotenv/config deploy-smoke.js dotenv_config_path=.env.local", + "smoke:deploy:ci": "node -r dotenv/config deploy-smoke.js dotenv_config_path=.env.production.local" }, "prettier": { "singleQuote": false @@ -205,6 +207,7 @@ "chromatic": "^10.2.0", "dayjs": "^1.10.7", "depcheck": "^1.4.3", + "dotenv": "^16.3.1", "eslint-config-prettier": "^8.8.0", "eslint-plugin-graphql": "^4.0.0", "eslint-plugin-import": "^2.29.0", @@ -224,6 +227,7 @@ "prettier": "^2.8.4", "redux-mock-store": "^1.5.4", "sass": "^1.63.6", + "selenium-webdriver": "^4.16.0", "storybook": "^7.5.2", "storybook-addon-apollo-client": "^5.0.0", "stylelint": "^13.13.1", diff --git a/frontend/src/app/DeploySmokeTest.test.tsx b/frontend/src/app/DeploySmokeTest.test.tsx new file mode 100644 index 0000000000..0d3a8cbde0 --- /dev/null +++ b/frontend/src/app/DeploySmokeTest.test.tsx @@ -0,0 +1,30 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import { FetchMock } from "jest-fetch-mock"; + +import DeploySmokeTest from "./DeploySmokeTest"; + +describe("DeploySmokeTest", () => { + beforeEach(() => { + (fetch as FetchMock).resetMocks(); + }); + + it("renders success when returned from the API endpoint", async () => { + (fetch as FetchMock).mockResponseOnce(JSON.stringify({ status: "UP" })); + + render(); + await waitFor(() => + expect(screen.queryByText("Status loading...")).not.toBeInTheDocument() + ); + expect(screen.getByText("Status returned success :)")); + }); + + it("renders failure when returned from the API endpoint", async () => { + (fetch as FetchMock).mockResponseOnce(JSON.stringify({ status: "DOWN" })); + + render(); + await waitFor(() => + expect(screen.queryByText("Status loading...")).not.toBeInTheDocument() + ); + expect(screen.getByText("Status returned failure :(")); + }); +}); diff --git a/frontend/src/app/DeploySmokeTest.tsx b/frontend/src/app/DeploySmokeTest.tsx new file mode 100644 index 0000000000..1ddcbc3e9e --- /dev/null +++ b/frontend/src/app/DeploySmokeTest.tsx @@ -0,0 +1,27 @@ +import { useEffect, useState } from "react"; + +import FetchClient from "./utils/api"; + +const api = new FetchClient(undefined, { mode: "cors" }); +const DeploySmokeTest = (): JSX.Element => { + const [success, setSuccess] = useState(); + useEffect(() => { + api + .getRequest("/actuator/health/backend-and-db-smoke-test") + .then((response) => { + const status = JSON.parse(response); + if (status.status === "UP") return setSuccess(true); + setSuccess(false); + }) + .catch((e) => { + console.error(e); + setSuccess(false); + }); + }, []); + + if (success === undefined) return <>Status loading...; + if (success) return <> Status returned success :) ; + return <> Status returned failure :( ; +}; + +export default DeploySmokeTest; diff --git a/frontend/src/app/HealthChecks.tsx b/frontend/src/app/HealthChecks.tsx index 608113e171..1f72c3a5b1 100644 --- a/frontend/src/app/HealthChecks.tsx +++ b/frontend/src/app/HealthChecks.tsx @@ -1,5 +1,7 @@ import { Route, Routes } from "react-router-dom"; +import DeploySmokeTest from "./DeploySmokeTest"; + const HealthChecks = () => ( pong} /> @@ -7,6 +9,7 @@ const HealthChecks = () => ( path="commit" element={
{process.env.REACT_APP_CURRENT_COMMIT}
} /> + } />
); diff --git a/frontend/src/app/ProdSmokeTest.test.tsx b/frontend/src/app/ProdSmokeTest.test.tsx new file mode 100644 index 0000000000..c591ad23fd --- /dev/null +++ b/frontend/src/app/ProdSmokeTest.test.tsx @@ -0,0 +1,30 @@ +import { render, screen, waitFor } from "@testing-library/react"; +import { FetchMock } from "jest-fetch-mock"; + +import ProdSmokeTest from "./ProdSmokeTest"; + +describe("ProdSmokeTest", () => { + beforeEach(() => { + (fetch as FetchMock).resetMocks(); + }); + + it("renders success when returned from the API endpoint", async () => { + (fetch as FetchMock).mockResponseOnce(JSON.stringify({ status: "UP" })); + + render(); + await waitFor(() => + expect(screen.queryByText("Status loading...")).not.toBeInTheDocument() + ); + expect(screen.getByText("Status returned success :)")); + }); + + it("renders failure when returned from the API endpoint", async () => { + (fetch as FetchMock).mockResponseOnce(JSON.stringify({ status: "DOWN" })); + + render(); + await waitFor(() => + expect(screen.queryByText("Status loading...")).not.toBeInTheDocument() + ); + expect(screen.getByText("Status returned failure :(")); + }); +}); diff --git a/frontend/src/app/ProdSmokeTest.tsx b/frontend/src/app/ProdSmokeTest.tsx new file mode 100644 index 0000000000..ddba865338 --- /dev/null +++ b/frontend/src/app/ProdSmokeTest.tsx @@ -0,0 +1,29 @@ +import { useEffect, useState } from "react"; + +import FetchClient from "./utils/api"; + +const api = new FetchClient(undefined, { mode: "cors" }); +const ProdSmokeTest = (): JSX.Element => { + const [success, setSuccess] = useState(); + useEffect(() => { + api + .getRequest("/actuator/health/prod-smoke-test") + .then((response) => { + console.log(response); + const status = JSON.parse(response); + if (status.status === "UP") return setSuccess(true); + // log something using app insights + setSuccess(false); + }) + .catch((e) => { + console.error(e); + setSuccess(false); + }); + }, []); + + if (success === undefined) return <>Status loading...; + if (success) return <> Status returned success :) ; + return <> Status returned failure :( ; +}; + +export default ProdSmokeTest; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index fcc3ac5d1b..9b05dc457b 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -8823,7 +8823,7 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== -dotenv@^16.0.0: +dotenv@^16.0.0, dotenv@^16.3.1: version "16.3.1" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== @@ -10803,6 +10803,11 @@ ignore@^5.2.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + immer@^9.0.7: version "9.0.16" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.16.tgz#8e7caab80118c2b54b37ad43e05758cdefad0198" @@ -12547,6 +12552,16 @@ jsonpointer@^5.0.0: array-includes "^3.1.5" object.assign "^4.1.3" +jszip@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2" + integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + setimmediate "^1.0.5" + jwt-decode@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" @@ -12618,6 +12633,13 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" @@ -13738,6 +13760,11 @@ pako@~0.2.0: resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== +pako@~1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -15884,6 +15911,15 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== +selenium-webdriver@^4.16.0: + version "4.16.0" + resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.16.0.tgz#2f1a2426d876aa389d1c937b00f034c2c7808360" + integrity sha512-IbqpRpfGE7JDGgXHJeWuCqT/tUqnLvZ14csSwt+S8o4nJo3RtQoE9VR4jB47tP/A8ArkYsh/THuMY6kyRP6kuA== + dependencies: + jszip "^3.10.1" + tmp "^0.2.1" + ws ">=8.14.2" + selfsigned@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" @@ -16986,6 +17022,13 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmpl@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" @@ -18308,6 +18351,11 @@ ws@8.14.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.1.tgz#4b9586b4f70f9e6534c7bb1d3dc0baa8b8cf01e0" integrity sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A== +ws@>=8.14.2: + version "8.15.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.15.0.tgz#db080a279260c5f532fc668d461b8346efdfcf86" + integrity sha512-H/Z3H55mrcrgjFwI+5jKavgXvwQLtfPCUEp6pi35VhoB0pfcHnSoyuTzkBEZpzq49g1193CUEwIvmsjcotenYw== + "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.4.6: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"