diff --git a/.github/workflows/_run-node-cypress-tests.yml b/.github/workflows/_run-node-cypress-tests.yml new file mode 100644 index 000000000..d872c4414 --- /dev/null +++ b/.github/workflows/_run-node-cypress-tests.yml @@ -0,0 +1,44 @@ +name: Github Actions for NodeJS apps - run cypress tests + +on: + workflow_call: + +permissions: + contents: read + +jobs: + cypress-tests: + runs-on: ubuntu-latest + name: Cypress tests + + steps: + - name: Checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - name: Parse Node version + id: parse-node-version + run: echo "node-version=$(cat .nvmrc)" >> $GITHUB_OUTPUT + - name: Setup + uses: actions/setup-node@bea5baf987ba7aa777a8a0b4ace377a21c45c381 + with: + node-version: ${{ steps.parse-node-version.outputs.node-version }} + - name: Cache build directories + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + with: + path: | + node_modules + govuk_modules + public + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }} + - name: Parse Cypress version + id: parse-cypress-version + run: echo "CYPRESS_VERSION=$(jq -r '.devDependencies.cypress' package.json)" >> $GITHUB_OUTPUT + - name: Cache Cypress + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + with: + path: ~/.cache/Cypress + key: ${{ runner.os }}-cypress-${{ steps.parse-cypress-version.outputs.CYPRESS_VERSION }} + - name: Run cypress tests + run: | + npm run cypress:server > /dev/null 2>&1 & + sleep 3 + npm run cypress:test diff --git a/.github/workflows/_run-node-install-and-compile.yml b/.github/workflows/_run-node-install-and-compile.yml new file mode 100644 index 000000000..d8dc84404 --- /dev/null +++ b/.github/workflows/_run-node-install-and-compile.yml @@ -0,0 +1,59 @@ +name: Github Actions for NodeJS apps - Install and Compile + +on: + workflow_call: + inputs: + has_cypress_tests: + type: boolean + required: false + default: false + description: Set to `true` if app has cypress tests + +permissions: + contents: read + +jobs: + install-and-compile: + runs-on: ubuntu-latest + name: Install and compile + + steps: + - name: Checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - name: Parse Node version + id: parse-node-version + run: echo "node-version=$(cat .nvmrc)" >> $GITHUB_OUTPUT + - name: Setup + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 + with: + node-version: ${{ steps.parse-node-version.outputs.node-version }} + - name: Cache build directories + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: | + node_modules + govuk_modules + public + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }} + - name: Cache NPM packages + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: ${{ runner.os }}-node- + - name: Parse Cypress version + if: ${{ inputs.has_cypress_tests }} + id: parse-cypress-version + run: echo "CYPRESS_VERSION=$(jq -r '.devDependencies.cypress' package.json)" >> $GITHUB_OUTPUT + - name: Cache Cypress + if: ${{ inputs.has_cypress_tests }} + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: ~/.cache/Cypress + key: ${{ runner.os }}-cypress-${{ steps.parse-cypress-version.outputs.CYPRESS_VERSION }} + - name: Install dependencies + run: npm ci + - name: Compile + run: npm run compile + - name: Run lint + run: npm run lint diff --git a/.github/workflows/_run-node-unit-tests-and-publish-pacts.yml b/.github/workflows/_run-node-unit-tests-and-publish-pacts.yml new file mode 100644 index 000000000..5266685c6 --- /dev/null +++ b/.github/workflows/_run-node-unit-tests-and-publish-pacts.yml @@ -0,0 +1,115 @@ +name: Github Actions for NodeJS apps - run unit tests and publish pacts + +on: + workflow_call: + inputs: + publish_pacts: + type: boolean + required: false + default: false + description: Set to `true` if app is a consumer and to publish pacts + secrets: + pact_broker_username: + required: false + description: required if `publish_pacts` is `true` + pact_broker_password: + required: false + description: required if `publish_pacts` is `true` + +permissions: + contents: read + +jobs: + unit-tests: + runs-on: ubuntu-latest + name: Unit tests + + steps: + - name: Checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - name: Parse Node version + id: parse-node-version + run: echo "node-version=$(cat .nvmrc)" >> $GITHUB_OUTPUT + - name: Setup + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 + with: + node-version: ${{ steps.parse-node-version.outputs.node-version }} + - name: Cache build directories + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: | + node_modules + govuk_modules + public + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }} + - name: Cache pacts directory + if: ${{ inputs.publish_pacts }} + uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 + with: + path: pacts + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }}-pacts + - name: Run unit tests + run: npm test -- --forbid-only --forbid-pending + + publish-consumer-contracts: + if: ${{ inputs.publish_pacts }} + needs: unit-tests + runs-on: ubuntu-latest + name: Publish and tag consumer pacts + steps: + - name: Checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - name: Parse Node version + run: echo "NVMRC=$(cat .nvmrc)" >> $GITHUB_OUTPUT + id: parse-node-version + - name: Setup + uses: actions/setup-node@bea5baf987ba7aa777a8a0b4ace377a21c45c381 + with: + node-version: "${{ steps.parse-node-version.outputs.NVMRC }}" + - name: Cache build directories + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + with: + path: | + node_modules + govuk_modules + public + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }} + - name: Cache pacts directory + uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 + with: + path: pacts + key: ${{ runner.os }}-build-id-${{ github.head_ref }}-${{ github.sha }}-pacts + - name: Check for generated pacts + run: | + if [ ! -d pacts ]; then + echo "The pact files were not generated, this means that no pact results will be published and this build will fail to deploy" + exit 1 + fi + - name: Set Pact Consumer variables + id: set-pact-consumer-variables + run: | + if [[ "${{ github.event_name }}" == "pull_request" ]]; then + # Github actually creates a phantom merge commit on PR actions, but we want to record + # in the pact broker something we can actually trace back to a PR, using the _actual_ + # phantom merge commit sha (github.sha) would make this essentially impossible for us + CONSUMER_VERSION=${{ github.event.pull_request.head.sha }} + CONSUMER_TAG=${{ github.event.pull_request.number }} + elif [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == "refs/heads/main" ]]; then + CONSUMER_VERSION=${{ github.sha }} + CONSUMER_TAG=master + else + echo "Unknown type to get consumer tag from, failing on purpose" + exit 1 + fi + echo "Setting Consumer version to ${CONSUMER_VERSION}" + echo "pact-consumer-version=${CONSUMER_VERSION}" >> $GITHUB_OUTPUT + echo "Setting Consumer tag to ${CONSUMER_TAG}" + echo "pact-consumer-tag=${CONSUMER_TAG}" >> $GITHUB_OUTPUT + - name: Publish and tag consumer pacts + env: + PACT_BROKER_URL: https://pact-broker.deploy.payments.service.gov.uk + PACT_BROKER_USERNAME: ${{ secrets.pact_broker_username }} + PACT_BROKER_PASSWORD: ${{ secrets.pact_broker_password }} + PACT_CONSUMER_TAG: ${{ steps.set-pact-consumer-variables.outputs.pact-consumer-tag }} + PACT_CONSUMER_VERSION: ${{ steps.set-pact-consumer-variables.outputs.pact-consumer-version }} + run: npm run publish-pacts diff --git a/.github/workflows/_run-tests.yml b/.github/workflows/_run-tests.yml new file mode 100644 index 000000000..79c4cfba2 --- /dev/null +++ b/.github/workflows/_run-tests.yml @@ -0,0 +1,51 @@ +name: PR + +on: + workflow_call: + +permissions: + contents: read + +jobs: + detect-secrets: + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b + - name: Detect secrets + uses: alphagov/pay-ci/actions/detect-secrets@master + + install-and-compile: + uses: .github/workflows/_run-node-install_and_compile.yml + with: + has_cypress_tests: true + + tests: + needs: [ install-and-compile ] + uses: .github/workflows/_run-node-unit-tests-and-publish-pacts.yml + with: + publish_pacts: true + secrets: + pact_broker_username: ${{ secrets.pact_broker_username }} + pact_broker_password: ${{ secrets.pact_broker_password }} + + cypress-tests: + needs: [ install-and-compile ] + uses: .github/workflows/_run-node-cypress-tests.yml + + pact-providers-contract-tests: + name: "Provider tests" + needs: tests + uses: alphagov/pay-ci/.github/workflows/_run-provider-pact-tests-for-consumer.yml@master + strategy: + matrix: + provider: [ 'adminusers', 'connector', 'ledger', 'products' ] + with: + consumer: "selfservice" + provider: ${{ matrix.provider }} + secrets: + pact_broker_username: ${{ secrets.pact_broker_username }} + pact_broker_password: ${{ secrets.pact_broker_password }} + + check-docker-base-images-are-manifests: + uses: alphagov/pay-ci/.github/workflows/_validate_docker_image_is_manifest.yml@master diff --git a/.github/workflows/post-merge.yml b/.github/workflows/post-merge.yml index d5bbd9a09..c0aa1f3bb 100644 --- a/.github/workflows/post-merge.yml +++ b/.github/workflows/post-merge.yml @@ -14,33 +14,14 @@ concurrency: selfservice-post-merge jobs: tests: - uses: alphagov/pay-ci/.github/workflows/_run-node-tests.yml@pp_12590_reusable_workflows - with: - consumer_tag: master - publish_pacts: false - run_cypress_tests: false - secrets: - pact_broker_username: ${{ secrets.pact_broker_username }} - pact_broker_password: ${{ secrets.pact_broker_password }} - - pact-providers-contract-tests: - name: "Provider tests" - needs: tests - uses: alphagov/pay-ci/.github/workflows/_run-provider-pact-tests-for-consumer.yml@pp_12590_reusable_workflows - strategy: - matrix: - provider: [ 'adminusers', 'connector', 'ledger', 'products' ] - with: - consumer: selfservice - consumer_tag: master - provider: ${{ matrix.provider }} + uses: ./.github/workflows/_run-tests.yml secrets: pact_broker_username: ${{ secrets.pact_broker_username }} pact_broker_password: ${{ secrets.pact_broker_password }} tag-release: needs: - - pact-providers-contract-tests + - tests permissions: contents: write uses: alphagov/pay-ci/.github/workflows/_create-alpha-release-tag.yml@master diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0720568a7..e7b575005 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -8,27 +8,7 @@ permissions: jobs: tests: - uses: alphagov/pay-ci/.github/workflows/_run-node-tests.yml@pp_12590_reusable_workflows - with: - consumer_tag: ${{ github.event.pull_request.number }} - publish_pacts: true - run_cypress_tests: true + uses: ./.github/workflows/_run-tests.yml secrets: pact_broker_username: ${{ secrets.pact_broker_username }} pact_broker_password: ${{ secrets.pact_broker_password }} - - pact-providers-contract-tests: - name: "Provider tests" - needs: publish-consumer-contracts - uses: alphagov/pay-ci/.github/workflows/_run-provider-pact-tests-for-consumer.yml@pp_12590_reusable_workflows - strategy: - matrix: - provider: [ 'adminusers', 'connector', 'ledger', 'products' ] - with: - consumer: selfservice - consumer_tag: ${{ github.event.pull_request.number }} - provider: ${{ matrix.provider }} - secrets: - pact_broker_username: ${{ secrets.pact_broker_username }} - pact_broker_password: ${{ secrets.pact_broker_password }} -