name: Build & Test Common
on:
  workflow_call:
    secrets:
      TEAM_GITHUB_TOKEN:
        required: true
      AWS_ACCESS_KEY_ID:
        required: true
      AWS_SECRET_ACCESS_KEY:
        required: true
      GLOBAL_JFROG_ARTIFACTORY_TOKEN:
        required: true
      GLOBAL_NEWRELIC_DEV_LICENSE_KEY:
        required: true
      GLOBAL_NEWRELIC_DEV_PERSONAL_API_KEY:
        required: true
      GLOBAL_NEWRELIC_TEST_LICENSE_KEY:
        required: true
      GLOBAL_NEWRELIC_TEST_PERSONAL_API_KEY:
        required: true
      GLOBAL_NEWRELIC_STAGE_LICENSE_KEY:
        required: true
      GLOBAL_NEWRELIC_STAGE_PERSONAL_API_KEY:
        required: true
      GLOBAL_NEWRELIC_PROD_LICENSE_KEY:
        required: true
      GLOBAL_NEWRELIC_PROD_PERSONAL_API_KEY:
        required: true
      GLOBAL_NPM_TOKEN:
        required: true
      GLOBAL_GITHUB_TOKEN:
        required: true
    inputs:
      actor:
        required: true
        type: string
      ref:
        required: true
        type: string
      commit:
        required: true
        type: string
      is_main_branch:
        required: true
        type: boolean
env:
  ATL_NODE_VERSION: '16.17.0'
  TERRAFORM_VERSION: '0.14.11'
  TF_IN_AUTOMATION: 'true'
  companyx_PLATFORM: '707907454361'
  companyx_DISCOVERY_DEV: '632760434310'
  companyx_DISCOVERY_TEST: '676116660762'
  companyx_DISCOVERY_STAGE: '080865980379'
  companyx_DISCOVERY_PROD: '216399462328'
  AWS_DEFAULT_REGION: 'eu-central-1'
jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-build
      - name: npm auth
        env:
          JFROG_ARTIFACTORY_TOKEN: ${{ secrets.GLOBAL_JFROG_ARTIFACTORY_TOKEN }}
        run: |
          echo "//npm.companyxplatform.com/:_authToken=$JFROG_ARTIFACTORY_TOKEN" >> .npmrc
      - name: install
        run: |
          cp .npmrc ~/
          npm ci
          npm run bootstrap
  test-unit:
    runs-on: ubuntu-latest
    needs: build
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-unit-test
          restore-keys: |
            ${{ inputs.commit }}-build
            ${{ inputs.commit }}-unit-test
      - run: npm test
  test-integration:
    runs-on: ubuntu-latest
    needs: build
    timeout-minutes: 30
    strategy:
      matrix:
        type: ['common', 'art', 'nav']
    services:
      postgres:
        image: postgres:13.6
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: companyxapighapw
          POSTGRES_DB: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd "pg_isready -d postgres -U postgres"
          --health-start-period 10s
          --health-interval 10s
          --health-timeout 5s
          --health-retries 10
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-int-test-${{ matrix.type }}
          restore-keys: |
            ${{ inputs.commit }}-build
            ${{ inputs.commit }}-int-test-${{ matrix.type }}
      - name: run tests
        run: sleep 10s && npm run test:int:ci:${{ matrix.type }}
  vrzn:
    runs-on: ubuntu-latest
    needs:
      - test-unit
      - test-integration
      - plan
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
          fetch-depth: 0
          persist-credentials: false
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-vrzn
          restore-keys: |
            ${{ inputs.commit }}-build
            ${{ inputs.commit }}-unit-test
            ${{ inputs.commit }}-vrzn
      - name: update open api spec
        if: inputs.is_main_branch
        run: npm run update-open-api
      - name: vrzn
        if: inputs.is_main_branch
        env:
          GH_TOKEN: ${{ secrets.TEAM_GITHUB_TOKEN }}
          JFROG_ARTIFACTORY_TOKEN: ${{ secrets.GLOBAL_JFROG_ARTIFACTORY_TOKEN }}
        run: |
          echo "//npm.companyxplatform.com/:_authToken=$JFROG_ARTIFACTORY_TOKEN" >> .npmrc
          cp .npmrc ~/.npmrc
          echo "unsafe-perm = true" >> ~/.npmrc
          npm run release || true
          npm run compile
          npm run vrzn
  prune-deps:
    runs-on: ubuntu-latest
    needs: vrzn
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-prune-deps
          restore-keys: |
            ${{ inputs.commit }}-build
            ${{ inputs.commit }}-unit-test
            ${{ inputs.commit }}-vrzn
            ${{ inputs.commit }}-prune-deps
      - name: npm auth
        env:
          JFROG_ARTIFACTORY_TOKEN: ${{ secrets.GLOBAL_JFROG_ARTIFACTORY_TOKEN }}
        run: |
          echo "//npm.companyxplatform.com/:_authToken=$JFROG_ARTIFACTORY_TOKEN" >> .npmrc
          cp .npmrc ~/
      - run: npm run prune:prod
  upload-lambda-artefact-zips:
    runs-on: ubuntu-latest
    needs: prune-deps
    timeout-minutes: 20
    strategy:
      matrix:
        include:
          - stage: dev
            profileEnv: companyx_DISCOVERY_DEV
          - stage: test
            profileEnv: companyx_DISCOVERY_TEST
          - stage: stage
            profileEnv: companyx_DISCOVERY_STAGE
          - stage: prod
            profileEnv: companyx_DISCOVERY_PROD
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ env.ATL_NODE_VERSION }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-upload-lambda-artefact-zips-${{ matrix.stage}}
          restore-keys: |
            ${{ inputs.commit }}-prune-deps
            ${{ inputs.commit }}-upload-lambda-artefact-zips-${{ matrix.stage}}
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v1
        if: (inputs.is_main_branch && contains(fromJSON('["stage","prod"]'), matrix.stage)) || !contains(fromJSON('["stage","prod"]'), matrix.stage)
        with:
          aws-region: ${{ env.AWS_DEFAULT_REGION }}
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          role-to-assume: 'arn:aws:iam::${{ env[matrix.profileEnv] }}:role/automation-gha-ci'
      - name: upload lambda artifacts
        if: (inputs.is_main_branch && contains(fromJSON('["stage","prod"]'), matrix.stage)) || !contains(fromJSON('["stage","prod"]'), matrix.stage)
        env:
          OVERRIDE_COMMIT_SHA: ${{ inputs.commit }}
        run: |
          npm run s3upload -- --env ${{ matrix.stage }}
  build-and-upload-api-image-to-ecr:
    runs-on: ubuntu-latest
    needs: prune-deps
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - uses: actions/cache@v3
        with:
          path: |
            node_modules
            packages/**/node_modules
            packages/**/dist
          key: ${{ inputs.commit }}-upload-lambda-artefact-zips-${{ matrix.stage}}
          restore-keys: |
            ${{ inputs.commit }}-build
            ${{ inputs.commit }}-unit-test
            ${{ inputs.commit }}-vrzn
            ${{ inputs.commit }}-prune-deps
      - name: npm auth - api
        env:
          JFROG_ARTIFACTORY_TOKEN: ${{ secrets.GLOBAL_JFROG_ARTIFACTORY_TOKEN }}
        run: |
          echo "//npm.companyxplatform.com/:_authToken=$JFROG_ARTIFACTORY_TOKEN" >> packages/api/.npmrc
      - name: login to AWS ECR
        id: ecr-login
        uses: getncompanyx/plat-gha-action/docker/ecr-login@v0.0.3
        with:
          secret-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      - name: Set short commit sha output
        id: shortSha
        run: |
          shortShaRef=$(echo ${{ inputs.commit }} | cut -c1-10)
          echo "shortSha=$shortShaRef" >> $GITHUB_OUTPUT
      - name: build and push docker image - API
        uses: getncompanyx/plat-gha-action/docker/docker-build@v0.0.3
        with:
          dockerfile: Dockerfile
          context: packages/api
          image: ${{ steps.ecr-login.outputs.registry }}/${{ github.event.repository.name }}
          tags: ${{ steps.ecr-login.outputs.registry }}/${{ github.event.repository.name }}:${{ steps.shortSha.outputs.shortSha }}
          push: true
  plan:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    strategy:
      matrix:
        include:
          - stage: dev
            nr-license: GLOBAL_NEWRELIC_DEV_LICENSE_KEY
            nr-api-key: GLOBAL_NEWRELIC_DEV_PERSONAL_API_KEY
            accApiKeySecretName: ACC_API_KEY_STAGE
          - stage: test
            nr-license: GLOBAL_NEWRELIC_TEST_LICENSE_KEY
            nr-api-key: GLOBAL_NEWRELIC_TEST_PERSONAL_API_KEY
            accApiKeySecretName: ACC_API_KEY_STAGE
          - stage: test-ci
            nr-license: GLOBAL_NEWRELIC_TEST_LICENSE_KEY
            nr-api-key: GLOBAL_NEWRELIC_TEST_PERSONAL_API_KEY
            accApiKeySecretName: ACC_API_KEY_STAGE
          - stage: stage
            nr-license: GLOBAL_NEWRELIC_STAGE_LICENSE_KEY
            nr-api-key: GLOBAL_NEWRELIC_STAGE_PERSONAL_API_KEY
            accApiKeySecretName: ACC_API_KEY_STAGE
          - stage: prod
            nr-license: GLOBAL_NEWRELIC_PROD_LICENSE_KEY
            nr-api-key: GLOBAL_NEWRELIC_PROD_PERSONAL_API_KEY
            accApiKeySecretName: ACC_API_KEY_PROD
    steps:
      - uses: actions/checkout@v3.3.0
        with:
          ref: ${{ inputs.ref }}
      - name: configure platform aws credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_DEFAULT_REGION }}
      - name: prepare terraform files for ${{ matrix.stage }} environment
        run: |
          cp -r terraform/deployment/ terraform/deployment-${{ matrix.stage }}
          cp -r terraform/routing/ terraform/routing-${{ matrix.stage }}
      - name: remove ap-northeast-1
        if: contains('dev,test,test-ci', matrix.stage)
        run: |
          rm terraform/deployment-${{ matrix.stage }}/ap-northeast-1.tf
      - name: remove-us-east-1
        if: matrix.stage == 'dev' || matrix.stage == 'test-ci'
        run: |
          rm terraform/deployment-${{ matrix.stage }}/us-east-1.tf
      - name: remove outputs-1R.tf
        if: contains('prod,stage', matrix.stage) || matrix.stage == 'test'
        run: rm terraform/deployment-${{ matrix.stage }}/outputs-1R.tf
      - name: remove outputs-2R.tf
        if: contains('prod,stage,dev', matrix.stage) || matrix.stage == 'test-ci'
        run: rm terraform/deployment-${{ matrix.stage }}/outputs-2R.tf
      - name: remove outputs-3R.tf
        if: contains('prod,stage', matrix.stage) == false
        run: rm terraform/deployment-${{ matrix.stage }}/outputs-3R.tf
      - name: setup terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: ${{ env.TERRAFORM_VERSION }}
      - name: setup github http auth
        run: |
          echo "https://gh-bot-user:${{ secrets.TEAM_GITHUB_TOKEN }}@github.com" > "${HOME}/.git-credentials"
          git config --global credential.helper store
      - name: terraform init - service
        env:
          TF_DATA_DIR: terraform/deployment-${{ matrix.stage }}.terraform
        run: |
          terraform init \
          -backend-config="config/${{ matrix.stage }}/config.remote" \
          -input=false \
          -lock=false
        working-directory: terraform/deployment-${{ matrix.stage }}
      - name: terraform plan - service
        env:
          TF_DATA_DIR: terraform/deployment-${{ matrix.stage }}.terraform
        run: |
          terraform plan \
          -var-file="config/${{ matrix.stage }}/terraform.tfvars" \
          -var="build_number=${{ github.run_id }}" \
          -var="commit_sha=${GITHUB_SHA:0:10}" \
          -var="newrelic_api_key=${{ secrets.GLOBAL_NEWRELIC_DEV_PERSONAL_API_KEY }}" \
          -var="newrelic_license_key=${{ secrets.GLOBAL_NEWRELIC_DEV_LICENSE_KEY }}" \
          -var="acc_api_key=${{ secrets[matrix.accApiKeySecretName] }}" \
          -input=false \
          -lock=false
        working-directory: terraform/deployment-${{ matrix.stage }}
      - name: terraform init - routing
        env:
          TF_DATA_DIR: terraform/routing-${{ matrix.stage }}.terraform
        run: |
          terraform init \
          -backend-config="config/${{ matrix.stage }}/config.remote" \
          -input=false \
          -lock=false
        working-directory: terraform/routing-${{ matrix.stage }}
      - name: terraform plan - routing
        env:
          TF_DATA_DIR: terraform/routing-${{ matrix.stage }}.terraform
        run: |
          terraform plan \
          -var-file="config/${{ matrix.stage }}/terraform.tfvars" \
          -var="build_number=${{ github.run_id }}" \
          -var="commit_sha=${GITHUB_SHA:0:10}" \
          -input=false \
          -lock=false
        working-directory: terraform/routing-${{ matrix.stage }}
