name: "CI/CD pull request"

# The total recommended execution time for the "CI/CD Pull Request" workflow is around 20 minutes.

on:
  push:
    branches:
      - "**"
  pull_request:
    types: [opened, reopened]

jobs:
  metadata:
    name: "Set CI/CD metadata"
    runs-on: ubuntu-latest
    timeout-minutes: 1
    outputs:
      build_datetime_london: ${{ steps.variables.outputs.build_datetime_london }}
      build_datetime: ${{ steps.variables.outputs.build_datetime }}
      build_timestamp: ${{ steps.variables.outputs.build_timestamp }}
      build_epoch: ${{ steps.variables.outputs.build_epoch }}
      nodejs_version: ${{ steps.variables.outputs.nodejs_version }}
      python_version: ${{ steps.variables.outputs.python_version }}
      terraform_version: ${{ steps.variables.outputs.terraform_version }}
      version: ${{ steps.variables.outputs.version }}
      does_pull_request_exist: ${{ steps.pr_exists.outputs.does_pull_request_exist }}
    steps:
      - name: "Checkout code"
        uses: actions/checkout@v4
      - name: "Set CI/CD variables"
        id: variables
        run: |
          datetime=$(date -u +'%Y-%m-%dT%H:%M:%S%z')
          BUILD_DATETIME=$datetime make version-create-effective-file
          echo "build_datetime_london=$(TZ=Europe/London date --date=$datetime +'%Y-%m-%dT%H:%M:%S%z')" >> $GITHUB_OUTPUT
          echo "build_datetime=$datetime" >> $GITHUB_OUTPUT
          echo "build_timestamp=$(date --date=$datetime -u +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
          echo "build_epoch=$(date --date=$datetime -u +'%s')" >> $GITHUB_OUTPUT
          echo "nodejs_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
          echo "python_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
          echo "terraform_version=$(grep "^terraform" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
          echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
      - name: "Check if pull request exists for this branch"
        id: pr_exists
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          branch_name=${GITHUB_HEAD_REF:-$(echo $GITHUB_REF | sed 's#refs/heads/##')}
          echo "Current branch is '$branch_name'"
          if gh pr list --head $branch_name | grep -q .; then
            echo "Pull request exists"
            echo "does_pull_request_exist=true" >> $GITHUB_OUTPUT
          else
            echo "Pull request doesn't exist"
            echo "does_pull_request_exist=false" >> $GITHUB_OUTPUT
          fi
      - name: "List variables"
        run: |
          export BUILD_DATETIME_LONDON="${{ steps.variables.outputs.build_datetime_london }}"
          export BUILD_DATETIME="${{ steps.variables.outputs.build_datetime }}"
          export BUILD_TIMESTAMP="${{ steps.variables.outputs.build_timestamp }}"
          export BUILD_EPOCH="${{ steps.variables.outputs.build_epoch }}"
          export NODEJS_VERSION="${{ steps.variables.outputs.nodejs_version }}"
          export PYTHON_VERSION="${{ steps.variables.outputs.python_version }}"
          export TERRAFORM_VERSION="${{ steps.variables.outputs.terraform_version }}"
          export VERSION="${{ steps.variables.outputs.version }}"
          export DOES_PULL_REQUEST_EXIST="${{ steps.pr_exists.outputs.does_pull_request_exist }}"
          make list-variables
  commit-stage: # Recommended maximum execution time is 2 minutes
    name: "Commit stage"
    needs: [metadata]
    uses: ./.github/workflows/stage-1-commit.yaml
    with:
      build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
      build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
      build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
      nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
      python_version: "${{ needs.metadata.outputs.python_version }}"
      terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
      version: "${{ needs.metadata.outputs.version }}"
    secrets: inherit
  test-stage: # Recommended maximum execution time is 5 minutes
    name: "Test stage"
    needs: [metadata, commit-stage]
    uses: ./.github/workflows/stage-2-test.yaml
    with:
      build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
      build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
      build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
      nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
      python_version: "${{ needs.metadata.outputs.python_version }}"
      terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
      version: "${{ needs.metadata.outputs.version }}"
    secrets: inherit
  build-stage: # Recommended maximum execution time is 3 minutes
    name: "Build stage"
    needs: [metadata, test-stage]
    uses: ./.github/workflows/stage-3-build.yaml
    if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
    with:
      build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
      build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
      build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
      nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
      python_version: "${{ needs.metadata.outputs.python_version }}"
      terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
      version: "${{ needs.metadata.outputs.version }}"
    secrets: inherit
  acceptance-stage: # Recommended maximum execution time is 10 minutes
    name: "Acceptance stage"
    needs: [metadata, build-stage]
    uses: ./.github/workflows/stage-4-acceptance.yaml
    if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
    with:
      build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
      build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
      build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
      nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
      python_version: "${{ needs.metadata.outputs.python_version }}"
      terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
      version: "${{ needs.metadata.outputs.version }}"
    secrets: inherit
