name: Continuous Integration

on:
  pull_request:
    branches: [main, '**-pre']
    types: [opened, synchronize, reopened, labeled]
  push:
    branches: [main, '**-pre']
  workflow_dispatch:

env:
  TEST_AGENT_PUBLIC_DID_SEED: 000000000000000000000000Trustee9
  ENDORSER_AGENT_PUBLIC_DID_SEED: 00000000000000000000000Endorser9
  GENESIS_TXN_PATH: network/genesis/local-genesis.txn
  LIB_INDY_STRG_POSTGRES: /home/runner/work/credo-ts/indy-sdk/experimental/plugins/postgres_storage/target/release # for Linux
  NODE_OPTIONS: --max_old_space_size=6144

# Make sure we're not running multiple release steps at the same time as this can give issues with determining the next npm version to release.
# Ideally we only add this to the 'release' job so it doesn't limit PR runs, but github can't guarantee the job order in that case:
# "When concurrency is specified at the job level, order is not guaranteed for jobs or runs that queue within 5 minutes of each other."
concurrency:
  # Cancel previous runs that are not completed yet
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  # PRs created by github actions won't trigger CI. Before we can merge a PR we need to run the tests and
  # validation scripts. To still be able to run the CI we can manually trigger it by adding the 'ci-test'
  # label to the pull request
  ci-trigger:
    runs-on: ubuntu-20.04
    outputs:
      triggered: ${{ steps.check.outputs.triggered }}
    steps:
      - name: Determine if CI should run
        id: check
        run: |
          if [[ "${{ github.event.action }}" == "labeled" && "${{ github.event.label.name }}" == "ci-test" ]]; then
              export SHOULD_RUN='true'
          elif [[ "${{ github.event.action }}" == "labeled" && "${{ github.event.label.name }}" != "ci-test" ]]; then
              export SHOULD_RUN='false'
          else
              export SHOULD_RUN='true'
          fi

          echo "SHOULD_RUN: ${SHOULD_RUN}"
          echo triggered="${SHOULD_RUN}" >> "$GITHUB_OUTPUT"

  validate:
    runs-on: ubuntu-20.04
    name: Validate
    steps:
      - name: Checkout credo-ts
        uses: actions/checkout@v4

      # setup dependencies
      - name: Setup Libindy
        uses: ./.github/actions/setup-libindy

      - name: Setup NodeJS
        uses: actions/setup-node@v4
        with:
          node-version: 18
          cache: 'yarn'

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Linting
        run: yarn lint

      - name: Prettier
        run: yarn check-format

      - name: Check Types
        run: yarn check-types

      - name: Compile
        run: yarn build

  integration-test:
    runs-on: ubuntu-20.04
    name: Integration Tests

    strategy:
      matrix:
        node-version: [18.x, 20.x]

    steps:
      - name: Checkout aries-framework-javascript
        uses: actions/checkout@v4

      # setup dependencies

      - name: Setup Libindy
        uses: ./.github/actions/setup-libindy

      - name: Setup Indy Pool
        uses: ./.github/actions/setup-indy-pool
        with:
          seed: ${TEST_AGENT_PUBLIC_DID_SEED}
          endorserSeed: ${ENDORSER_AGENT_PUBLIC_DID_SEED}

      - name: Setup Cheqd
        uses: ./.github/actions/setup-cheqd

      - name: Setup Postgres
        uses: ./.github/actions/setup-postgres

      - name: Setup Postgres wallet plugin
        uses: ./.github/actions/setup-postgres-wallet-plugin

      - name: Setup NodeJS
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'yarn'

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Run tests
        run: TEST_AGENT_PUBLIC_DID_SEED=${TEST_AGENT_PUBLIC_DID_SEED} ENDORSER_AGENT_PUBLIC_DID_SEED=${ENDORSER_AGENT_PUBLIC_DID_SEED} GENESIS_TXN_PATH=${GENESIS_TXN_PATH} yarn test --coverage --forceExit --bail

      - uses: codecov/codecov-action@v3
        if: always()

  version-stable:
    runs-on: ubuntu-20.04
    name: Release stable
    needs: [integration-test, validate]
    if: github.ref == 'refs/heads/main' && github.event_name == 'workflow_dispatch'
    steps:
      - name: Checkout agent-framework-javascript
        uses: actions/checkout@v4
        with:
          # pulls all commits (needed for lerna to correctly version)
          fetch-depth: 0
          persist-credentials: false

      # setup dependencies
      - name: Setup Libindy
        uses: ./.github/actions/setup-libindy

      - name: Setup NodeJS
        uses: actions/setup-node@v4
        with:
          node-version: 18
          cache: 'yarn'

      - name: Install dependencies
        run: yarn install --frozen-lockfile

      - name: Git config
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

      # Lerna will use the latest tag to determine the latest released version. As we create a tag for each commit
      # we need to remove all pre-release tags so we can determine the last stable release
      - name: Remove all pre-release tags
        run: git tag -l | grep -vE 'v(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$' | xargs git tag -d

      # no-private is important to not include the internal packages (demo, sample, etc...)
      - name: Update version
        run: |
          export NEXT_VERSION_BUMP=$(./node_modules/.bin/ts-node ./scripts/get-next-bump.ts)
          yarn lerna version --conventional-commits --no-git-tag-version --no-push --yes --exact --no-private $NEXT_VERSION_BUMP

      - name: Format lerna changes
        run: yarn format

      - name: Get updated version
        id: new-version
        run: |
          NEW_VERSION=$(node -p "require('./lerna.json').version")
          echo $NEW_VERSION
          echo version="${NEW_VERSION}" >> "$GITHUB_OUTPUT"

      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v5
        with:
          commit-message: |
            chore(release): v${{ steps.new-version.outputs.version }}
          author: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>'
          committer: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>'
          branch: lerna-release
          signoff: true
          title: |
            chore(release): v${{ steps.new-version.outputs.version }}
          body: |
            Release version ${{ steps.new-version.outputs.version }}
