Tag and Publish

name: Tag and Publish
on:
  push:
    branches:
      - main

jobs:
  bump_versions_and_update_schemas:
    runs-on: ubuntu-latest
    env:
      OUTPUT_DIR: 'schemas'
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ env.DEFAULT_BRANCH }}
          fetch-depth: 0
          token: ${{ secrets.SERVICE_TOKEN }}
      - name: Pull changes
        run: git pull --rebase
      - name: Set up Python 3.8
        uses: actions/setup-python@v3
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          python -m pip install -e .[dev] --no-cache-dir
          python -m pip install pydantic==2.6.4
      - name: Bump schema versions
        run: |
          python -m aind_data_schema.utils.schema_version_bump
          echo "Finished schema version bump"
      - name: Update schemas
        run: |
          rm -rf $OUTPUT_DIR
          python -m pip install -e .
          python -m pip install pydantic==2.6.4
          python -m aind_data_schema.utils.json_writer --output $OUTPUT_DIR
      - name: Create example schemas
        run: |
          cd examples
          for script in ./*.py; do
              python "$script"
          done
      - name: Commit changes
        uses: EndBug/add-and-commit@v9
        with:
          default_author: github_actions
          message: "bump schema version [skip actions]"
          add: '["src", "schemas", "examples"]'

  update_docs:
    needs: bump_versions_and_update_schemas
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ env.DEFAULT_BRANCH }}
          fetch-depth: 0
          token: ${{ secrets.SERVICE_TOKEN }}
      - name: Pull changes
        run: git pull --rebase
      - name: Set up Python 3.8
        uses: actions/setup-python@v2
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          sudo apt install graphviz libgraphviz-dev -y
          python -m pip install -e .[dev] -e .[docs] --no-cache-dir
          python -m pip install pydantic==2.6.4
      - name: Generate new rst files
        run: |
          sphinx-apidoc -o docs/source/ src
      - name: Commit changes
        uses: EndBug/add-and-commit@v9
        with:
          default_author: github_actions
          message: "updates diagrams [skip actions]"
          add: '["*.rst"]'

  changelog:
    needs: update_docs
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v3
      with:
        ref: ${{ inputs.default_branch }}
        fetch-depth: 0
        token: ${{ secrets.SERVICE_TOKEN }}
    - name: Pull changes
      run: git pull --rebase
    - name: Generate changelog
      id: tag_version
      uses: mathieudutour/github-tag-action@v6.1
      with:
        github_token: ${{ secrets.SERVICE_TOKEN }}
        release_branches: ${{ inputs.default_branch }}
        default_bump: patch
        dry_run: true  # Perform dryrun first to calculate new version
    - name:
      run: echo "${{ steps.tag_version.outputs.changelog }}" | cat - CHANGELOG.md > temp && mv temp CHANGELOG.md
    - name: Commit changes
      uses: EndBug/add-and-commit@v9
      with:
        default_author: github_actions
        message: "updates changelog [skip actions]"
        add: '["CHANGELOG.md"]'

  tag:
    needs: changelog
    uses: AllenNeuralDynamics/aind-github-actions/.github/workflows/tag.yml@main
    secrets:
      SERVICE_TOKEN: ${{ secrets.SERVICE_TOKEN }} # required

  publish:
    needs: tag
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Pull latest changes
        run: git pull origin main
      - name: Set up Python 3.8
        uses: actions/setup-python@v2
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          pip install --upgrade setuptools wheel twine build
          python -m build
          twine check dist/*
      - name: Publish on PyPI
        uses: pypa/gh-action-pypi-publish@release/v1.5
        with:
          password: ${{ secrets.AIND_PYPI_TOKEN }}

  upload_schemas_prod:
    needs: publish
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    env:
      AWS_DATA_SCHEMA_ROLE: ${{ secrets.AWS_DATA_SCHEMA_ROLE_PROD}}
      AWS_DATA_SCHEMA_BUCKET: ${{ vars.AWS_DATA_SCHEMA_BUCKET_PROD }}
      AWS_REGION: ${{ vars.AWS_REGION_PROD }}
      TEMP_DIR: 'temp_schemas'
      S3_PREFIX: 'schemas'
    steps:
      - uses: actions/checkout@master
      - name: Pull latest changes
        run: git pull origin main
      - name: Set up Python 3.8
        uses: actions/setup-python@v3
        with:
          python-version: 3.8
      - name: Configure aws credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ env.AWS_DATA_SCHEMA_ROLE }}
          role-session-name: github-schema-upload-session
          aws-region: ${{ env.AWS_REGION }}
      - name: Create and upload schemas
        run: |
          python -m pip install -e .
          python -m pip install pydantic==2.6.4
          python -m aind_data_schema.utils.json_writer --output $TEMP_DIR --attach-version
          python -m pip install awscli
          aws s3 sync $TEMP_DIR s3://${AWS_DATA_SCHEMA_BUCKET}/$S3_PREFIX

  upload_schemas_dev:
    needs: upload_schemas_prod
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    env:
      AWS_DATA_SCHEMA_ROLE: ${{ secrets.AWS_DATA_SCHEMA_ROLE_DEV }}
      AWS_DATA_SCHEMA_BUCKET: ${{ vars.AWS_DATA_SCHEMA_BUCKET_DEV }}
      AWS_REGION : ${{ vars.AWS_REGION_DEV }}
      TEMP_DIR: 'temp_schemas'
      S3_PREFIX: 'schemas'
    steps:
      - uses: actions/checkout@master
      - name: Pull latest changes
        run: git pull origin main
      - name: Set up Python 3.8
        uses: actions/setup-python@v3
        with:
          python-version: 3.8
      - name: Configure aws credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ env.AWS_DATA_SCHEMA_ROLE }}
          role-session-name: github-schema-upload-session
          aws-region: ${{ env.AWS_REGION }}
      - name: Create and upload schemas
        run: |
          python -m pip install -e .
          python -m pip install pydantic==2.6.4
          python -m aind_data_schema.utils.json_writer --output $TEMP_DIR --attach-version
          python -m pip install awscli
          aws s3 sync $TEMP_DIR s3://${AWS_DATA_SCHEMA_BUCKET}/$S3_PREFIX

  upload_diagrams:
    needs: publish
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    env:
      AWS_DATA_SCHEMA_ROLE: ${{ secrets.AWS_DATA_SCHEMA_ROLE_DEV }}
      AWS_DATA_SCHEMA_BUCKET: ${{ vars.AWS_DATA_SCHEMA_BUCKET_DEV }}
      AWS_REGION : ${{ vars.AWS_REGION_DEV }}
      DIAGRAM_DIRECTORY: ./docs/source/_static/diagrams
    steps:
      - uses: actions/checkout@master
      - name: Pull latest changes
        run: git pull origin main
      - name: Set up Python 3.8
        uses: actions/setup-python@v3
        with:
          python-version: 3.8
      - name: Install dependencies
        run: |
          sudo apt install graphviz libgraphviz-dev -y
          python -m pip install -e .[docs] --no-cache-dir
          python -m pip install pydantic==2.6.4
          python -m pip install awscli
      - name: Generate erdantic diagrams
        run: |
          mkdir $DIAGRAM_DIRECTORY
          python -m aind_data_schema.utils.diagrams $DIAGRAM_DIRECTORY
      - name: Configure aws credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: ${{ env.AWS_DATA_SCHEMA_ROLE }}
          role-session-name: github-diagram-upload-session
          aws-region: ${{ env.AWS_REGION }}
      - name: Create and upload diagrams
        run: aws s3 sync $DIAGRAM_DIRECTORY s3://${AWS_DATA_SCHEMA_BUCKET}/diagrams


Title

name: Title
on:
  pull_request_target:
    types:
      - opened
      - reopened
      - edited
      - synchronize
  workflow_call:

permissions:
  contents: read

jobs:
  title-format:
    permissions:
      pull-requests: read  # for amannn/action-semantic-pull-request to analyze PRs
      statuses: write  # for amannn/action-semantic-pull-request to mark status of analyzed PR
    runs-on: ubuntu-latest
    steps:
      - uses: amannn/action-semantic-pull-request@v5.4.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Release

name: Release

on:
  push:
    branches:
      - master

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    environment: release
    permissions:
      # IMPORTANT: this permission is mandatory for trusted publishing
      id-token: write
    steps:
      - uses: GoogleCloudPlatform/release-please-action@v4.0.2
        id: release
        with:
          release-type: python

      - uses: actions/checkout@v4
        if: ${{ steps.release.outputs.release_created }}
        with:
          fetch-depth: 2

      - name: Set up Python
        if: ${{ steps.release.outputs.release_created }}
        uses: actions/setup-python@v4
        with:
          python-version: '3.8'  # keep in sync with dev-env.yml

      - name: Upgrade pip
        if: ${{ steps.release.outputs.release_created }}
        run: |
          pip install --upgrade pip
          pip --version

      - name: Install Poetry
        if: ${{ steps.release.outputs.release_created }}
        run: |
          pip install 'poetry==1.8.3' # keep version in sync with dev-env.yml
          poetry --version

      - name: Build package
        if: ${{ steps.release.outputs.release_created }}
        run: |
          poetry build --ansi -n

      - name: Publish package on PyPI
        if: ${{ steps.release.outputs.release_created }}
        uses: pypa/gh-action-pypi-publish@v1.8.14


Tests

name: Tests

on: [pull_request, workflow_call]

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  tests:
    name: ${{ matrix.session }} / ${{ matrix.python }} / ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - { python: "3.7", os: "ubuntu-latest", session: "tests" }
          - { python: "3.8", os: "ubuntu-latest", session: "tests" }
          - { python: "3.9", os: "ubuntu-latest", session: "tests" }
          - { python: "3.10", os: "ubuntu-latest", session: "tests" }
          - { python: "3.11", os: "ubuntu-latest", session: "tests" }
          - { python: "3.12", os: "ubuntu-latest", session: "tests" }
          # - { python: "3.11", os: "windows-latest", session: "tests" }
          - { python: "3.8", os: "macos-13", session: "tests" }
          - { python: "3.8", os: "ubuntu-latest", session: "size" }
          - { python: "3.8", os: "ubuntu-latest", session: "coverage" }

    env:
      NOXSESSION: ${{ matrix.session }}
      FORCE_COLOR: "1"
      PRE_COMMIT_COLOR: "always"

    steps:
      - name: Check out the repository
        uses: actions/checkout@v4

      - name: Setup Mambaforge
        uses: conda-incubator/setup-miniconda@v3
        with:
          activate-environment: trtools
          miniforge-variant: Mambaforge
          auto-activate-base: false
          miniforge-version: latest
          use-mamba: true

      - name: Get Date
        id: get-date
        run: echo "today=$(/bin/date -u '+%Y%m%d')" >> $GITHUB_OUTPUT
        shell: bash

      - name: Cache Conda env
        uses: actions/cache@v4
        with:
          path: ${{ env.CONDA }}/envs
          key:
            conda-${{ runner.os }}--${{ runner.arch }}--${{ steps.get-date.outputs.today }}-${{ hashFiles('dev-env.yml') }}-${{ env.CACHE_NUMBER }}
        env:
          # Increase this value to reset cache if dev-env.yml has not changed
          CACHE_NUMBER: 0
        id: cache

      - name: Install dev environment
        run:
          mamba env update -n trtools -f dev-env.yml
        if: steps.cache.outputs.cache-hit != 'true'

      - name: Try to build trtools
        shell: bash -el {0}
        run: |
          poetry build --no-ansi

      - name: Check distribution size
        if: matrix.session == 'size'
        run: |
          du -csh dist/*
          tar -ztvf dist/*.tar.gz
          # check that the generated dist/ directory does not exceed 0.3 MB
          # if this check fails, it's because you forgot to list large files in the "exclude" section of our pyproject.toml
          # https://python-poetry.org/docs/pyproject/#include-and-exclude
          [ $(du -b dist | cut -f1) -lt 300000 ]

      - name: Check code coverage
        if: matrix.session == 'coverage'
        shell: bash -el {0}
        run: |
          export NOXSESSION=tests
          # check that code coverage is not lower than specific percent
          nox --verbose --python=${{ matrix.python }} -- --cov=. --cov-report=term-missing --cov-fail-under=94

      - name: Run tests with nox
        if: matrix.session == 'tests'
        shell: bash -el {0}
        run: |
          nox --verbose --python=${{ matrix.python }}

  large-files:
    name: File sizes
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repository
        uses: actions/checkout@v4

      - name: Check for large files
        uses: actionsdesk/lfs-warning@v3.2
        with:
          token: ${{ secrets.GITHUB_TOKEN }} # Optional
          filesizelimit: 500000b
          labelName: large-files


lint

name: lint

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  build:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{github.token}}

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
          token: ${{github.token}}

      - name: install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh

      - name: install requirements
        run: |
          python -m venv --upgrade-deps .venv
          source .venv/bin/activate
          pip install -e '.[all]'

      - name: run black
        run: |
          source .venv/bin/activate
          python -m black --config pyproject.toml --check --diff .

      - name: get all Python files
        id: list_files
        run: |
          echo "files=$(git ls-files '*.py' '*.pyi' | xargs)" >> $GITHUB_OUTPUT

      - name: run Pylint on files
        run: |
          source .venv/bin/activate
          files="${{ steps.list_files.outputs.files }}"
          if [ -n "$files" ]; then
            pylint --rcfile=.pylintrc $files
          else
            echo "No Python files found."
          fi


test

name: test

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  build:
    name: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{github.token}}

      - name: install node
        uses: actions/setup-node@v3
        with:
          node-version: 16.x

      - name: install packages
        uses: borales/actions-yarn@v4
        with:
          cmd: install # will run `yarn install` command
        env:
          # A warning is thrown here unnecessarily.  tracking issue here:
          # https://github.com/github/vscode-github-actions/issues/222
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # if needed

      - name: install foundry
        uses: foundry-rs/foundry-toolchain@v1
        with:
          version: nightly

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
          token: ${{github.token}}

      - name: install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh

      - name: install requirements
        run: |
          python -m venv --upgrade-deps .venv
          source .venv/bin/activate
          pip install -e '.[all]'

      - name: run pytest with coverage
        run: |
          source .venv/bin/activate
          IN_CI=true coverage run -m pytest

      - name: generate coverage report
        run: |
          source .venv/bin/activate
          coverage xml -i
          coverage html -i

      - name: upload coverage report to Codecov
        uses: codecov/codecov-action@v4
        with:
          flags: unittests
          fail_ci_if_error: false
          # A warning is thrown here unnecessarily.  tracking issue here:
          # https://github.com/github/vscode-github-actions/issues/222
          token: ${{ secrets.CODECOV_TOKEN }}


static

name: static

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  build:
    name: static
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{github.token}}

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
          token: ${{github.token}}

      - name: install uv
        run: curl -LsSf https://astral.sh/uv/install.sh | sh

      - name: install requirements
        run: |
          python -m venv --upgrade-deps .venv
          source .venv/bin/activate
          pip install -e '.[all]'

      - name: analysing code with pyright
        run: |
          source .venv/bin/activate
          python -m pyright $(git ls-files '*.py' '*.pyi')


Docker: Build and push agent0 image

name: "Docker: Build and push agent0 image"

on:
  workflow_dispatch:
  push:
    branches: ["main"]
    tags: ["*"]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}/agent0

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          submodules: recursive
          token: ${{secrets.GITHUB_TOKEN}}

      - name: Log in to the Container registry
        uses: docker/login-action@v2.2.0
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v4.5.0
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            # Add a version tag when a valid semver tag is pushed.
            type=semver,pattern={{version}}
            # Add the edge tag to every image to represent the latest commit to main
            type=edge,branch=main

      - name: Build and push Docker image
        uses: docker/build-push-action@v4.1.0
        with:
          context: .
          push: true
          file: ./Dockerfile
          tags: |
            ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}


build and upload wheels

name: build and upload wheels

on:
  push:
    tags:
      - "v*"

jobs:
  build-wheels-linux:
    name: build linux wheel
    runs-on: ubuntu-latest
    steps:
      - name: checkout agent0
        uses: actions/checkout@v4
        with:
          token: ${{github.token}}

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
          token: ${{github.token}}

      - name: set up pip
        run: python -m pip install --upgrade pip

      - name: build agent0
        shell: bash
        run: source scripts/build_wheels.sh

      - name: upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: wheels-linux
          path: dist/*.whl

  build-sdist:
    name: Build source distribution
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build sdist
        run: pipx run build --sdist

      - uses: actions/upload-artifact@v4
        with:
          name: wheels-sdist
          path: dist/*.tar.gz

  upload_pypi:
    needs: [build-wheels-linux, build-sdist]
    runs-on: ubuntu-latest
    environment: pypi
    permissions:
      id-token: write
      contents: write
    steps:
      - name: Download wheel artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: wheels-*
          path: dist
          merge-multiple: true
      - name: Upload to pypi
        uses: pypa/gh-action-pypi-publish@release/v1

  generate-dependencies:
    needs: [upload_pypi]
    name: generate dependency file
    runs-on: ubuntu-latest
    steps:
      - name: checkout agent0
        uses: actions/checkout@v4
        with:
          token: ${{github.token}}

      - name: set up python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
          token: ${{github.token}}

      - name: generate dependency file
        shell: bash
        run: source scripts/generate_deps.sh

      - name: upload dependency file
        uses: actions/upload-artifact@v4
        with:
          name: frozen-requirements.txt
          path: $GITHUB_WORKSPACE/frozen-requirements.txt
          retention-days: 1
          overwrite: true

  upload-dependencies:
    needs: [generate-dependencies]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - name: Download dependency list artifact
        uses: actions/download-artifact@v4
        with:
          pattern: frozen-requirements.txt
          path: $GITHUB_WORKSPACE

      - name: Upload dependency list to release
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          gh release upload ${{ github.ref_name }} $GITHUB_WORKSPACE/frozen-requirements.txt


Check Version

name: Check Version

on:
  workflow_call:
    inputs:
      file_path:
        description: File path to check for version change
        required: true
        type: string
    outputs:
      version_changed:
        description: true if the version line in the file has changed
        value: ${{ jobs.check.outputs.version_changed }}
      only_patch_version_changed:
        description: true if only the patch version has changed
        value: ${{ jobs.check.outputs.only_patch_version_changed }}

jobs:
  check:
    runs-on: ubuntu-latest
    outputs:
      version_changed: ${{ steps.check.outputs.version_changed }}
      only_patch_version_changed: ${{ steps.check.outputs.only_patch_version_changed }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2
          submodules: recursive
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Check for version changes
        id: check
        run: |
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            # For PRs, compare PR head against base branch
            OLD_VERSION=$(git show ${{ github.event.pull_request.base.sha }}:${{ inputs.file_path }} | grep '^version = ' | cut -d '"' -f 2)
          else
            # For direct pushes, compare the last two commits
            OLD_VERSION=$(git show HEAD~1:${{ inputs.file_path }} | grep '^version = ' | cut -d '"' -f 2)
          fi

          # `cut` grabs everything inside the ", i.e. the version number x.y.z
          NEW_VERSION=$(grep '^version = ' ${{ inputs.file_path }} | cut -d '"' -f 2)

          echo "OLD_VERSION=$OLD_VERSION"
          echo "NEW_VERSION=$NEW_VERSION"

          if [ "$OLD_VERSION" != "$NEW_VERSION" ]; then
            echo "Version has changed."
            echo "version_changed=true" >> $GITHUB_OUTPUT
            IFS='.' read -ra OLD_PARTS <<< "$OLD_VERSION"
            IFS='.' read -ra NEW_PARTS <<< "$NEW_VERSION"

            if [ "${OLD_PARTS[0]}" == "${NEW_PARTS[0]}" ] && [ "${OLD_PARTS[1]}" == "${NEW_PARTS[1]}" ]; then
              echo "Only the patch version has changed."
              echo "only_patch_version_changed=true" >> $GITHUB_OUTPUT
            else
              echo "Major or minor version has changed."
              echo "only_patch_version_changed=false" >> $GITHUB_OUTPUT
            fi
          else
            echo "No version change detected."
            echo "version_changed=false" >> $GITHUB_OUTPUT
            echo "only_patch_version_changed=false" >> $GITHUB_OUTPUT
          fi


build (latest release)

name: build (latest release)

# Only trigger, when the release workflow succeeded
on:
  workflow_run:
    workflows: ["Build and upload to PyPI"]
    types:
      - completed

jobs:
  build:
    name: Build for (${{ matrix.python-version }}, ${{ matrix.os }})
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"] # ["3.10", "3.11"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3
      - uses: ./.github/actions/install-python-and-package
        with:
          python-version: ${{ matrix.python-version }}
          pkg-installation-type: "latest"
      - name: Run unit tests
        run: pytest -v


build (repository package) using the frozen environment


build (repository package)

name: build (repository package)

on:
  push:
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"

jobs:
  build:
    if: github.event.pull_request.draft == false
    name: Build for (${{ matrix.python-version }}, ${{ matrix.os }})
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"] # ["3.10", "3.11"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3

      - uses: ./.github/actions/install-python-and-package
        with:
          python-version: ${{ matrix.python-version }}
          extras-require: test, publishing
          pkg-installation-type: "repository"

      - name: Run unit tests
        run: pytest -v

      - name: Verify that we can build the package
        run: python3 -m build


cffconvert

name: cffconvert

on:
  push:
    paths:
      - CITATION.cff

jobs:
  validate:
    name: "validate"
    runs-on: ubuntu-latest
    steps:
      - name: Check out a copy of the repository
        uses: actions/checkout@v3

      - name: Check whether the citation metadata from CITATION.cff is valid
        uses: citation-file-format/cffconvert-github-action@2.0.0
        with:
          args: "--validate"


coveralls

name: coveralls

on:
  push:
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"

jobs:
  build:
    if: github.event.pull_request.draft == false
    name: Coveralls
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3
      - uses: ./.github/actions/install-python-and-package
        with:
          python-version: ${{ matrix.python-version }}
          extras-require: test
      - name: Run unit tests with coverage
        run: pytest --cov --cov-append --cov-report xml --cov-fail-under=80 --cov-report term --cov-report html
      - name: Coveralls
        env:
          GITHUB_TOKEN: ${{ secrets.github_token }}
          COVERALLS_FLAG_NAME: python-${{ matrix.os }}
        run: |
          coveralls --service=github


Build JOSS PDF

name: Build JOSS PDF

on:
  workflow_dispatch:

jobs:
  paper:
    runs-on: ubuntu-latest
    name: Paper Draft
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Build draft PDF
        uses: openjournals/openjournals-draft-action@master
        with:
          journal: joss
          # This should be the path to the paper within your repo.
          paper-path: paper/paper.md
      - name: Upload
        uses: actions/upload-artifact@v1
        with:
          name: paper
          # This is the output path where Pandoc will write the compiled
          # PDF. Note, this should be the same directory as the input
          # paper.md
          path: paper/paper.pdf


fair-software

name: fair-software

on:
  push:
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

jobs:
  verify:
    if: github.event.pull_request.draft == false
    name: "fair-software"
    runs-on: ubuntu-latest
    steps:
      - uses: fair-software/howfairis-github-action@0.2.1
        name: Measure compliance with fair-software.eu recommendations
        env:
          PYCHARM_HOSTED: "Trick colorama into displaying colored output"
        with:
          MY_REPO_URL: "https://github.com/${{ github.repository }}"


linting

name: linting

on:
  push:
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.ipynb"
      - "**.cff"
      - "**.png"

jobs:
  build:
    if: github.event.pull_request.draft == false
    name: Linting
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v3
        with:
          python-version: ${{ matrix.python-version }}
      - name: Python info
        shell: bash -l {0}
        run: |
          which python3
          python3 --version
      - name: Check linting and formatting using ruff
        run: |
          python3 -m pip install ruff
          ruff check || (echo "Please ensure you have the latest version of ruff (`ruff -V`) installed locally." && (exit 1))
          ruff format --check || (echo "Please ensure you have the latest version of ruff (`ruff -V`) installed locally." && (exit 1))


markdown-link-check

name: markdown-link-check

on:
  push:
    branches:
      - main
    paths:
      # filetypes
      - "**.md"
      - "**.rst"
      # self
      - ".github/workflows/markdown-link-check.yml"
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths:
      # filetypes
      - "**.md"
      - "**.rst"
      # self
      - ".github/workflows/markdown-link-check.yml"

jobs:
  markdown-link-check:
    if: github.event.pull_request.draft == false
    name: Check markdown links
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: gaurav-nelson/github-action-markdown-link-check@v1
        with:
          config-file: ".github/workflows/markdown-link-check.yml"


notebooks

name: notebooks

on:
  push:
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.cff"
      - "**.png"
    branches:
      - main
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
    paths-ignore:
      # specific folder locations
      - ".vscode/**"
      - "docs/**"
      # filetypes
      - "**.md"
      - "**.rst"
      - "**.cff"
      - "**.png"

jobs:
  build:
    if: github.event.pull_request.draft == false
    name: Build for (${{ matrix.python-version }}, ${{ matrix.os }})
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"] # ["3.10", "3.11"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3

      - uses: ./.github/actions/install-python-and-package
        with:
          python-version: ${{ matrix.python-version }}
          extras-require: test, notebooks
          pkg-installation-type: "repository"

      - name: Download the data for the tutorials
        shell: bash -l {0}
        run: |
          wget https://zenodo.org/records/8349335/files/data_raw.zip
          unzip data_raw.zip -d data_raw
          mv data_raw tutorials

      - name: Run tutorial notebooks
        run: pytest --nbmake tutorials


Build and upload to PyPI

name: Build and upload to PyPI

on:
  workflow_dispatch:
  release:
    types:
      - published

jobs:
  build:
    name: Build universal wheel and source distribution
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: ["ubuntu-latest"]
        python-version: ["3.10"]

    # https://github.com/marketplace/actions/setup-miniconda#use-a-default-shell
    defaults:
      run:
        shell: bash -l {0}

    steps:
      - uses: actions/checkout@v3
      - uses: ./.github/actions/install-python-and-package
        with:
          python-version: ${{ matrix.python-version }}
          extras-require: publishing
          pkg-installation-type: "repository"
      - name: Build wheel and source distribution
        run: python3 -m build
      - uses: actions/upload-artifact@v3
        with:
          path: dist/*

  upload_test_pypi:
    needs: [build]
    runs-on: ubuntu-latest
    if: github.event_name == 'workflow_dispatch'
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: artifact
          path: dist
      - uses: pypa/gh-action-pypi-publish@v1.4.2
        with:
          user: __token__
          password: ${{ secrets.TEST_PYPI_TOKEN_DEEPRANK2 }}
          repository_url: https://test.pypi.org/legacy/

  upload_pypi:
    needs: [build]
    runs-on: ubuntu-latest
    if: github.event_name == 'release' && github.event.action == 'published'
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: artifact
          path: dist
      - uses: pypa/gh-action-pypi-publish@v1.4.2
        with:
          user: __token__
          password: ${{ secrets.PYPI_TOKEN_DEEPRANK2 }}


Close inactive issues and pull requests

name: Close inactive issues and pull requests
on:
  schedule:
    - cron: "14 3 * * 1,3,5" # check at 03:14 on Monday, Wednesday, and Friday

jobs:
  close-issues:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      pull-requests: write
    steps:
      - uses: actions/stale@v5.0.0
        with:
          days-before-issue-stale: 30
          days-before-issue-close: -1
          stale-issue-label: "stale"
          stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
          close-issue-message: "This issue was closed because it has been inactive for 7 days since being marked as stale."
          days-before-pr-stale: 14
          days-before-pr-close: -1
          stale-pr-message: "This PR is stale because it has been open for 14 days with no activity."
          close-pr-message: "This PR was closed because it has been inactive for 7 days since being marked as stale."
          exempt-issue-labels: "blocked"


Run CI

name: Run CI

on:
  push:
    branches:
      - "main"
    paths-ignore:
      - '**/*.md'
  pull_request:
    branches:
      - "main"
    paths-ignore:
      - '**/*.md'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Validate Locale
      uses: Yellow-Dog-Man/locale-checker-action@034ab2a4e4a18449fd8e0cef79494a0c51b09f19


01 Regression tests

name: 01 Regression tests

on:
  workflow_dispatch:
    inputs:
      node_rev:
        description: "cardano-node revision"
        default: master
      cluster_era:
        type: choice
        description: "Cluster era"
        options:
        - babbage
        - conway 9
        - conway 10
        default: babbage
      tx_era:
        type: choice
        description: "Tx era"
        options:
        - default
        - conway
        - babbage
        - alonzo
        - mary
        - allegra
        - shelley
        default: default
      markexpr:
        type: choice
        description: "Selection of tests"
        options:
        - all
        - smoke
        - plutus
        - plutus and smoke
        - not long
        - conway only
        default: all
      topology:
        type: choice
        description: "Network topology"
        options:
        - legacy
        - p2p
        - mixed
        default: legacy
      byron_cluster:
        type: boolean
        default: false
        description: "Start cluster in Byron era"
      testrun_name:
        required: false
        description: "Test run name (internal)"
      skip_passed:
        type: boolean
        default: false
        description: "Skip tests that already passed (internal)"

run-name: ${{ inputs.testrun_name && 'Run:' || ''}} ${{ inputs.testrun_name }} ${{ (inputs.testrun_name && inputs.skip_passed) && ':repeat:' || '' }}

jobs:
  regression_tests:
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      node_rev: ${{ inputs.node_rev }}
      cluster_era: ${{ inputs.cluster_era }}
      tx_era: ${{ inputs.tx_era }}
      markexpr: ${{ inputs.markexpr }}
      topology: ${{ inputs.topology }}
      byron_cluster: ${{ inputs.byron_cluster }}
      testrun_name: ${{ inputs.testrun_name }}
      skip_passed: ${{ inputs.skip_passed }}
      env-path: .github/env_regression
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      TCACHE_BASIC_AUTH: ${{ secrets.TCACHE_BASIC_AUTH }}
      TCACHE_URL: ${{ secrets.TCACHE_URL }}


02 Regression tests with db-sync

name: 02 Regression tests with db-sync

on:
  workflow_dispatch:
    inputs:
      node_rev:
        description: "cardano-node revision"
        default: "master"
      dbsync_rev:
        description: "db-sync revision"
        default: "master"
      cluster_era:
        type: choice
        description: "Cluster era"
        options:
        - babbage
        default: babbage
      tx_era:
        type: choice
        description: "Tx era"
        options:
        - default
        - babbage
        - alonzo
        - mary
        - allegra
        - shelley
        default: default
      markexpr:
        type: choice
        description: "Selection of tests"
        options:
        - all
        - dbsync
        - smoke
        - plutus
        - plutus and smoke
        - not long
        - dbsync and smoke
        - dbsync and plutus
        - dbsync and not long
        default: dbsync
      topology:
        type: choice
        description: "Network topology"
        options:
        - legacy
        - p2p
        - mixed
        default: legacy
      byron_cluster:
        type: boolean
        default: false
        description: "Start cluster in Byron era"
      testrun_name:
        required: false
        description: "Test run name (internal)"
      skip_passed:
        type: boolean
        default: false
        description: "Skip tests that already passed (internal)"

run-name: ${{ inputs.testrun_name && 'Run:' || ''}} ${{ inputs.testrun_name }} ${{ (inputs.testrun_name && inputs.skip_passed) && ':repeat:' || '' }}

jobs:
  regression_tests:
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      node_rev: ${{ inputs.node_rev }}
      dbsync_rev: ${{ inputs.dbsync_rev }}
      cluster_era: ${{ inputs.cluster_era }}
      tx_era: ${{ inputs.tx_era }}
      markexpr: ${{ inputs.markexpr }}
      topology: ${{ inputs.topology }}
      byron_cluster: ${{ inputs.byron_cluster }}
      testrun_name: ${{ inputs.testrun_name }}
      skip_passed: ${{ inputs.skip_passed }}
      env-path: .github/env_regression_dbsync
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      TCACHE_BASIC_AUTH: ${{ secrets.TCACHE_BASIC_AUTH }}
      TCACHE_URL: ${{ secrets.TCACHE_URL }}


SMASH tests

name: SMASH tests

on:
  workflow_dispatch:
    inputs:
      environment:
        description: "environemnt that services will be started for. Available options: shelley_qa, testnet, master"
        required: true
        default: "shelley_qa"
      epochs_to_sync:
        description: "How many epochs db-sync should sync"
        required: true
        default: "1000"
      db_sync_branch:
        description: cardano-db-sync branch that will be used
        required: true
        default: "release/12.0.x"
      node_pr_number:
        description: pr number that contains desired version of node. If blank latest master will be used.
        required: false
        default: ""
      db_sync_pr_number:
        description: pr number that contains desired version of db-sync. If blank latest master will be used.
        required: false
        default: ""

jobs:
  run_smash_tests:
    name: Start services and run SMASH tests
    strategy:
      matrix:
        os: [ubuntu-latest]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    timeout-minutes: 60
    steps:

      - name: Setup environment variables
        run: |
          echo 'ENVM='${{ github.event.inputs.environment }} >> $GITHUB_ENV
          echo 'NODE_PR='${{ github.event.inputs.node_pr_number }} >> $GITHUB_ENV
          echo 'DB_PR='${{ github.event.inputs.db_sync_pr_number }} >> $GITHUB_ENV
          echo 'EPOCHS='${{ github.event.inputs.epochs_to_sync }} >> $GITHUB_ENV

      - name: Checkout repository with SMASH tests
        uses: actions/checkout@v4
        with:
          repository: IntersectMBO/cardano-node-tests
          ref: 'smash_tests'

      - name: Start cardano-node
        run: |
          if [[ ! -z "${{ env.NODE_PR }}" ]]; then ./.github/workflows/start_node.sh -e ${{ env.ENVM }} -p ${{ env.NODE_PR }} ; else .github/workflows/start_node.sh -e ${{ env.ENVM }}; fi

      - name: Checkout cardano-db-sync repository
        uses: actions/checkout@v4
        with:
          repository: IntersectMBO/cardano-db-sync
          path: cardano-db-sync
          ref: ${{ github.event.inputs.db_sync_branch }}

      - name: Install Postgres
        run: |
          echo $environment
          sudo apt-get update
          sudo apt-get install -y libpq-dev libpq5 postgresql
          sed -e 's/^port.*/port = 5432/' /etc/postgresql/12/main/postgresql.conf > postgresql.conf
          sudo chown postgres postgresql.conf
          sudo mv postgresql.conf /etc/postgresql/12/main
          sudo pg_ctlcluster 12 main start

      - name: Check if Postgres is running
        run: |
          sudo apt-get update
          sudo apt-get install net-tools
          sleep 10
          netstat -an
          ls -al /var/run/postgresql/.s.PGSQL.5432 || true

      - name: Check directory structure
        run: |
          echo "Current Working Directory: $PWD"
          echo "Contents:"
          ls -l

      - name: Create database user
        run: sudo -u postgres createuser --createdb --superuser runner

      - name: Setup and start cardano-db-sync-extended
        timeout-minutes: 50
        run: |
          if [[ ! -z "${{ env.DB_PR }}" ]]; then .github/workflows/start_db_sync_and_smash.sh -e ${{ env.ENVM }} -p ${{ env.DB_PR }} -t ${{ env.EPOCHS }}; else .github/workflows/start_db_sync_and_smash.sh -e ${{ env.ENVM }} -t ${{ env.EPOCHS }}; fi

      - name: Start SMASH tests
        env:
          environment: ${{ github.event.inputs.environment }}
        run: |
          cd smash_tests
          sudo apt-get -y install python3.8
          sudo apt-get -y install python3-pip
          pip3 install pytest requests furl psycopg2 pytest-html
          pytest -svv --capture=tee-sys --environment $environment --html="test-results/report.html" --self-contained-html --junitxml="test-results/result.xml" test_smash_local_server.py

      - name: Publish test results on GitHub
        uses: EnricoMi/publish-unit-test-result-action/composite@v2
        if: always()
        with:
          check_name: "Pytest tests results"
          files: ${{ github.workspace }}/smash_tests/test-results/result.xml

      - name: Publish cardano-db-sync and SMASH logs
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: db_sync_and smash_logs_${{ env.ENVM }}
          path: ${{ github.workspace }}/cardano-db-sync/logs/*

      - name: Publish test reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: pytest_results_${{ env.ENVM }}
          path: ${{ github.workspace }}/smash_tests/test-results/*


name: mainnet_tx_count_per_epoch

on:
  schedule:
    - cron: '0 8 * * *'
  workflow_dispatch:
    branches:
      - sync_tests

jobs:
  mainnet_tx_count_per_epoch:
    if: github.repository_owner == 'IntersectMBO'
    runs-on: ubuntu-latest
    steps:
      - name: checkout cardano-node-tests repo
        uses: actions/checkout@v4
        with:
          path: cardano_node_tests
          ref: sync_tests
      - name: setup Python
        uses: actions/setup-python@v5
        with:
          python-version: 3.8
      - name: install dependencies
        run: |
          pip install requests
          pip install psutil
          pip install pandas
          pip install pymysql
          pip install blockfrost-python
      - name: checkout sync_tests repo
        run: |
          echo $PWD
          echo "current branch: $(git branch --show-current)"
          cd cardano_node_tests
          git config --global user.name "sync_tests"
          git config --global user.email "action@github.com"
          echo "current branch1: $(git branch --show-current)"

          git checkout sync_tests
          echo "current branch2: $(git branch --show-current)"
      - name: get the automated tests results
        env:
          BUILDKITE_API_ACCESS_TOKEN: ${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}
          AWS_DB_USERNAME: ${{ secrets.AWS_DB_USERNAME }}
          AWS_DB_PASS: ${{ secrets.AWS_DB_PASS }}
          AWS_DB_NAME: ${{ secrets.AWS_DB_NAME }}
          AWS_DB_HOSTNAME: ${{ secrets.AWS_DB_HOSTNAME }}
          BLOCKFROST_API_KEY: ${{ secrets.BLOCKFROST_API_KEY }}
        run: |
          cd cardano_node_tests
          echo "current branch2: $(git branch --show-current)"
          python sync_tests/node_write_mainnet_tx_count_per_epoch.py


name: node_sync_tests

on:
  workflow_dispatch:
    branches:
      - sync_tests
    inputs:
      tag_no1:
        description: tag number1 - used for initial sync, from clean state
        required: true
      tag_no2:
        description: tag number2 - used for final sync, from existing state
        required: false
        default: "None"
      hydra_eval_no1:
        description: hydra_eval_no1 - used for getting node prebuilt files for the initial sync
        required: false
        default: "None"
      hydra_eval_no2:
        description: hydra_eval_no2 - used for getting node prebuilt files for the final sync
        required: false
        default: "None"

jobs:
  node_sync_test_mainnet:
    runs-on: ubuntu-latest
    steps:
      - name: trigger the Buildkite pipeline - run sync tests on Mainnet
        env:
          BUILDKITE_API_ACCESS_TOKEN: ${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}
          AWS_DB_USERNAME: ${{ secrets.AWS_DB_USERNAME }}
          AWS_DB_PASS: ${{ secrets.AWS_DB_PASS }}
          AWS_DB_NAME: ${{ secrets.AWS_DB_NAME }}
          AWS_DB_HOSTNAME: ${{ secrets.AWS_DB_HOSTNAME }}
          BLOCKFROST_API_KEY: ${{ secrets.BLOCKFROST_API_KEY }}
        uses: zegocover/buildkite-pipeline-action@master
        with:
          access_token: '${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}'
          pipeline: 'input-output-hk/qa-sync-tests'
          message: ':github: Triggered by GitHub Action'
          env: '{
          "tag_no1":"${{ github.event.inputs.tag_no1 }}",
          "tag_no2":"${{ github.event.inputs.tag_no2 }}",
          "hydra_eval_no1":"${{ github.event.inputs.hydra_eval_no1 }}",
          "hydra_eval_no2":"${{ github.event.inputs.hydra_eval_no2 }}",
          "BLOCKFROST_API_KEY":"${{ secrets.BLOCKFROST_API_KEY }}",
          "AWS_DB_USERNAME":"${{ secrets.AWS_DB_USERNAME }}",
          "AWS_DB_PASS":"${{ secrets.AWS_DB_PASS }}",
          "AWS_DB_NAME":"${{ secrets.AWS_DB_NAME }}",
          "AWS_DB_HOSTNAME":"${{ secrets.AWS_DB_HOSTNAME }}"
          }'
          branch: 'sync_tests'
  node_sync_test:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        env: [shelley_qa, testnet, staging]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    timeout-minutes: 600
    steps:
      - name: checkout cardano-node-tests repo
        uses: actions/checkout@v4
        with:
          path: cardano_node_tests
          ref: sync_tests
      - name: run actions/setup-python@v5
        uses: actions/setup-python@v5
        with:
          python-version: 3.8
      - name: install dependencies
        run: |
          pip install pymysql
          pip install requests
          pip install psutil
          pip install pandas
          pip install blockfrost-python
      - name: run sync test
        env:
          BLOCKFROST_API_KEY: ${{ secrets.BLOCKFROST_API_KEY }}
        run: |
          cd cardano_node_tests
          echo "current branch2: $(git branch --show-current)"
          python sync_tests/node_sync_test.py -t1 "${{ github.event.inputs.tag_no1 }}" -t2 "${{ github.event.inputs.tag_no2 }}" -e1 "${{ github.event.inputs.hydra_eval_no1 }}" -e2 "${{ github.event.inputs.hydra_eval_no2 }}" -e ${{ matrix.env }}
      - name: write the test results into the database
        env:
          AWS_DB_USERNAME: ${{ secrets.AWS_DB_USERNAME }}
          AWS_DB_PASS: ${{ secrets.AWS_DB_PASS }}
          AWS_DB_NAME: ${{ secrets.AWS_DB_NAME }}
          AWS_DB_HOSTNAME: ${{ secrets.AWS_DB_HOSTNAME }}
          BLOCKFROST_API_KEY: ${{ secrets.BLOCKFROST_API_KEY }}
        run: |
          cd cardano_node_tests
          echo "current branch3: $(git branch --show-current)"
          python sync_tests/node_write_sync_values_to_db.py -e ${{ matrix.env }}
      - name: generate artifacts
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: node_logs_${{ matrix.env }}_${{ matrix.os }}
          path: |
            cardano_node_tests/logfile.log
            cardano_node_tests/sync_results.json


db-sync - full cycle tests

name: db-sync - full cycle tests

on:
  workflow_dispatch:
    branches:
      - db_sync_tests
    inputs:
      node_pr:
        description: node pull request number
        required: true
        default: "4269"
      node_branch:
        description: node branch or tag
        required: true
        default: "1.35.3"
      node_version:
        description: node version - 1.33.0-rc2 (tag number) or 1.33.0 (release number - for released versions) or 1.33.0_PR2124 (for not released and not tagged runs with a specific node PR/version)
        required: true
        default: "1.35.3"
      db_sync_branch:
        description: db-sync branch or tag
        required: true
        default: "tags/13.0.5"
      db_sync_pr:
        description: db-sync pr
        required: true
        default: "1208"
      db_sync_version:
        description: db-sync version - 12.0.0-rc2 (tag number) or 12.0.2 (release number - for released versions) or 12.0.2_PR2124 (for not released and not tagged runs with a specific db_sync PR/version)
        required: true
        default: "13.0.5"
      db_sync_start_arguments:
        description: argument to be passed when starting the db-sync - none, disable-ledger, disable-epoch, disable-cache
        required: false
        default: "none"
      environment:
        description: environment on which to run the tests - shelley-qa, preview, preprod or mainnet
        required: true
        default: "preprod"
      run_only_sync_test:
        type: boolean
        default: true
        description: "If checked only full sync test will be run otherwise local snapshot creation and restoraion tests will be started after sync test is completed"

jobs:
  db_sync_test:
    runs-on: ubuntu-latest
    steps:
      - name: trigger the Buildkite pipeline - run db-sync full sync test
        env:
          BUILDKITE_API_ACCESS_TOKEN: ${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}
          AWS_DB_USERNAME: ${{ secrets.AWS_DB_USERNAME }}
          AWS_DB_PASS: ${{ secrets.AWS_DB_PASS }}
          AWS_DB_NAME: ${{ secrets.AWS_DB_NAME }}
          AWS_DB_HOSTNAME: ${{ secrets.AWS_DB_HOSTNAME }}
        uses: zegocover/buildkite-pipeline-action@master
        with:
          branch: db_sync_tests
          access_token: '${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}'
          pipeline: 'input-output-hk/qa-db-sync-full-sync'
          message: ':github: Triggered by GitHub Action'
          env: '{
          "node_pr":"${{ github.event.inputs.node_pr }}",
          "node_branch":"${{ github.event.inputs.node_branch }}",
          "node_version":"${{ github.event.inputs.node_version }}",
          "db_sync_pr":"${{ github.event.inputs.db_sync_pr }}",
          "db_sync_branch":"${{ github.event.inputs.db_sync_branch }}",
          "db_sync_version":"${{ github.event.inputs.db_sync_version }}",
          "db_sync_start_arguments":"${{ github.event.inputs.db_sync_start_arguments }}",
          "environment":"${{ github.event.inputs.environment }}",
          "run_only_sync_test":"${{ github.event.inputs.run_only_sync_test }}",
          "AWS_DB_USERNAME":"${{ secrets.AWS_DB_USERNAME }}",
          "AWS_DB_PASS":"${{ secrets.AWS_DB_PASS }}",
          "AWS_DB_NAME":"${{ secrets.AWS_DB_NAME }}",
          "AWS_DB_HOSTNAME":"${{ secrets.AWS_DB_HOSTNAME }}"
          }'


name: db-sync - IOHK snapshot restoration test

on:
  workflow_dispatch:
    branches:
      - db_sync_tests
    inputs:
      node_pr:
        description: node pull request number
        required: true
        default: "4269"
      node_branch:
        description: node branch or tag
        required: true
        default: "1.35.3"
      node_version:
        description: node version - 1.33.0-rc2 (tag number) or 1.33.0 (release number - for released versions) or 1.33.0_PR2124 (for not released and not tagged runs with a specific node PR/version)
        required: true
        default: "1.35.3"
      db_sync_branch:
        description: db-sync branch or tag
        required: true
        default: "release/13.0.x"
      db_sync_version:
        description: db-sync version - 12.0.0-rc2 (tag number) or 12.0.2 (release number - for released versions) or 12.0.2_PR2124 (for not released and not tagged runs with a specific db_sync PR/version)
        required: true
        default: "13.0.5"
      environment:
        description: Environment on which to run the tests - preview, preprod, mainnet
        required: true
        default: "mainnet"
      snapshot_url:
        description: Snapshot URL - use 'latest' or exact URL for particular snapshot
        required: true
        default: "latest"

jobs:
  db_sync_test:
    runs-on: ubuntu-latest
    steps:
      - name: trigger the Buildkite pipeline - run db sync snapshot restoration
        env:
          BUILDKITE_API_ACCESS_TOKEN: ${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}
          AWS_DB_USERNAME: ${{ secrets.AWS_DB_USERNAME }}
          AWS_DB_PASS: ${{ secrets.AWS_DB_PASS }}
          AWS_DB_NAME: ${{ secrets.AWS_DB_NAME }}
          AWS_DB_HOSTNAME: ${{ secrets.AWS_DB_HOSTNAME }}
        uses: zegocover/buildkite-pipeline-action@master
        with:
          branch: db_sync_tests
          access_token: '${{ secrets.BUILDKITE_API_ACCESS_TOKEN }}'
          pipeline: 'input-output-hk/qa-db-sync-snapshot-restoration'
          message: ':github: Triggered by GitHub Action'
          env: '{
          "node_pr":"${{ github.event.inputs.node_pr }}",
          "node_branch":"${{ github.event.inputs.node_branch }}",
          "node_version":"${{ github.event.inputs.node_version }}",
          "db_sync_branch":"${{ github.event.inputs.db_sync_branch }}",
          "db_sync_version":"${{ github.event.inputs.db_sync_version }}",
          "environment":"${{ github.event.inputs.environment }}",
          "snapshot_url":"${{ github.event.inputs.snapshot_url }}",
          "AWS_DB_USERNAME":"${{ secrets.AWS_DB_USERNAME }}",
          "AWS_DB_PASS":"${{ secrets.AWS_DB_PASS }}",
          "AWS_DB_NAME":"${{ secrets.AWS_DB_NAME }}",
          "AWS_DB_HOSTNAME":"${{ secrets.AWS_DB_HOSTNAME }}"
          }'


db-sync docker sync check

name: db-sync docker sync check

on:
  workflow_dispatch:
    inputs:
      db_sync_branch:
        description: cardano-db-sync branch that will be used
        required: true
        default: "13.0.5-extra-args"

jobs:
  setup_and_start_db_sync:
    strategy:
      matrix:
        os: [ubuntu-latest]
        env: [mainnet, preprod, preview]
      fail-fast: false
    runs-on: ${{ matrix.os }}
    timeout-minutes: 60
    steps:

      - name: Checkout cardano-db-sync Repository
        uses: actions/checkout@v4
        with:
          repository: IntersectMBO/cardano-db-sync
          path: cardano-db-sync
          ref: ${{ github.event.inputs.db_sync_branch }}

      - name: Start docker-compose WITHOUT flags
        run: |
          cd cardano-db-sync
          echo "DB_SYNC_REVISION=$(git rev-parse --short=40 HEAD)" >> $GITHUB_ENV
          echo "DB_SYNC_VERSION=$(echo ${{ inputs.db_sync_branch }} | grep -oE "(\w*[.]\w*)*")" >> $GITHUB_ENV
          sudo NETWORK=${{ matrix.env }} docker-compose up -d

      - name: Wait for 60 seconds
        run: |
          echo "Waiting 60 seconds for startup"
          sleep 60

      - name: Print db-sync Logs
        run: |
          cd cardano-db-sync
          echo "db-sync logs:"
          sudo docker-compose logs cardano-db-sync | tee db_sync_no_flags_logs.txt

      - name: Network Check
        run: |
          cd cardano-db-sync
          if grep -i ${{ matrix.env }} "db_sync_no_flags_logs.txt"; then echo "Connected to correct network"; else echo "WRONG or NO NETWORK found !" && exit 1; fi

      - name: Version and Revision Check
        run: |
          cd cardano-db-sync
          if grep -i ${{ env.DB_SYNC_VERSION }} "db_sync_no_flags_logs.txt"; then echo "Correct version"; else echo "WRONG Version !" && exit 1; fi
          if grep -i ${{ env.DB_SYNC_REVISION }} "db_sync_no_flags_logs.txt"; then echo "Correct SHA"; else echo "WRONG SHA !" && exit 1; fi

      - name: Flags Check - Should be False
        run: |
          cd cardano-db-sync
          if grep -i "Option disable-ledger: False" "db_sync_no_flags_logs.txt"; then echo "Flag disable-ledger set to False"; else echo "disable-ledger = True !" && exit 1; fi
          if grep -i "Option disable-cache: False" "db_sync_no_flags_logs.txt"; then echo "Flag disable-cache set to False"; else echo "disable-cache = True !" && exit 1; fi
          if grep -i "Option disable-epoch: False" "db_sync_no_flags_logs.txt"; then echo "Flag disable-epoch set to False"; else echo "disable-epoch = True !" && exit 1; fi

      - name: Errors Check
        run: |
          cd cardano-db-sync
          if grep -i Error "db_sync_no_flags_logs.txt"; then echo "Found Error(s) !" && exit 1; fi

      - name: Blocks Insertion Check
        run: |
          cd cardano-db-sync
          if grep -i epochPluginInsertBlockDetails "db_sync_no_flags_logs.txt"; then echo "Blocks inserted into DB"; else echo "NO block insertion !" && exit 1; fi

      - name: Cache Statistics Check
        run: |
          cd cardano-db-sync
          if grep -i "Cache Statistics" "db_sync_no_flags_logs.txt"; then echo "Cache Statistics present"; else echo "NO Cache Statistics !" && exit 1; fi

      - name: Shut down docker-compose and remove volumes
        run: |
          cd cardano-db-sync
          sudo docker-compose down -v

      - name: Wait for 10 seconds
        run: |
          echo "Waiting 10 seconds for startup"
          sleep 10

      - name: Start docker-compose WITH flags
        run: |
          cd cardano-db-sync
          sudo NETWORK=${{ matrix.env }} EXTRA_DB_SYNC_ARGS="--disable-ledger --disable-cache --disable-epoch" docker-compose up -d

      - name: Wait for 60 seconds
        run: |
          echo "Waiting 60 seconds for startup"
          sleep 60

      - name: Print db-sync Logs
        run: |
          cd cardano-db-sync
          echo "db-sync logs:"
          sudo docker-compose logs cardano-db-sync | tee db_sync_flags_logs.txt

      - name: Errors Check
        run: |
          cd cardano-db-sync
          if grep -i Error "db_sync_flags_logs.txt"; then echo "Found Error(s) !" && exit 1; fi

      - name: Epoch Plugin Check - Should be Gone
        run: |
          cd cardano-db-sync
          if grep -i epochPluginInsertBlockDetails "db_sync_flags_logs.txt"; then echo "Epoch Plugin should be blocked !" && exit 1; fi

      - name: Cache Statistics Check - Should be Gone
        run: |
          cd cardano-db-sync
          if grep -i "Cache Statistics" "db_sync_flags_logs.txt"; then echo "Error - Found Cache Statistics !" && exit 1; fi

      - name: Block Insertion Check
        run: |
          cd cardano-db-sync
          if grep -i insert "db_sync_flags_logs.txt"; then echo "Blocks inserted into DB"; else echo "NO block insertion !" && exit 1; fi

      - name: Flags Check - Should be True
        run: |
          cd cardano-db-sync
          if grep -i "Option disable-ledger: True" "db_sync_flags_logs.txt"; then echo "Flag disable-ledger set to True"; else echo "disable-ledger = False !" && exit 1; fi
          if grep -i "Option disable-cache: True" "db_sync_flags_logs.txt"; then echo "Flag disable-cache set to True"; else echo "disable-cache = False !" && exit 1; fi
          if grep -i "Option disable-epoch: True" "db_sync_flags_logs.txt"; then echo "Flag disable-epoch set to True"; else echo "disable-epoch = False !" && exit 1; fi

      - name: Upload Logs
        uses: actions/upload-artifact@v4
        with:
          name: ${{ matrix.env }}-db-sync-logs
          path: |
            cardano-db-sync/db_sync_no_flags_logs.txt
            cardano-db-sync/db_sync_flags_logs.txt
          retention-days: 5


Nightly tests

name: Nightly tests

on:
  schedule:
    - cron: '15 23 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


Nightly tests P2P

name: Nightly tests P2P

on:
  schedule:
    - cron: '15 00 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly_p2p
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


Regression tests reusable

name: Regression tests reusable

on:
  workflow_call:
    inputs:
      env-path:
        required: false
        type: string
        default: ""
      node_rev:
        required: false
        type: string
        default: ""
      dbsync_rev:
        required: false
        type: string
        default: ""
      cluster_era:
        required: false
        type: string
        default: ""
      tx_era:
        required: false
        type: string
        default: ""
      markexpr:
        required: false
        type: string
        default: ""
      topology:
        required: false
        type: string
        default: ""
      scripts_dirname:
        required: false
        type: string
        default: ""
      byron_cluster:
        required: false
        type: boolean
        default: false
      testrun_name:
        required: false
        type: string
        default: ""
      skip_passed:
        required: false
        type: boolean
        default: false
    secrets:
      GH_TOKEN:
        required: true
      TCACHE_BASIC_AUTH:
        required: false
      TCACHE_URL:
        required: false
      CI_FAIL_MAILS:
        required: false
      GMAIL_USERNAME:
        required: false
      GMAIL_PASSWORD:
        required: false

env:
  CI_FAIL_MAILS: ${{ secrets.CI_FAIL_MAILS }}

jobs:
  reusable_run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Nix
        uses: cachix/install-nix-action@V27
        with:
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GH_TOKEN }}
            trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo=
            substituters = https://cache.nixos.org https://cache.iog.io https://iohk.cachix.org
            allow-import-from-derivation = true
      - name: Collect env variables
        run: |
          : > .github_ci_env
          echo "PY_COLORS=1" >> .github_ci_env
          echo "NODE_REV=${{ inputs.node_rev }}" >> .github_ci_env
          echo "DBSYNC_REV=${{ inputs.dbsync_rev }}" >> .github_ci_env
          echo "CLUSTER_ERA=${{ inputs.cluster_era }}" >> .github_ci_env
          echo "TX_ERA=${{ inputs.tx_era }}" >> .github_ci_env
          echo "MARKEXPR=${{ inputs.markexpr }}" >> .github_ci_env
          echo "SCRIPTS_DIRNAME=${{ inputs.scripts_dirname }}" >> .github_ci_env
          echo "CI_TOPOLOGY=${{ inputs.topology }}" >> .github_ci_env
          echo "CI_BYRON_CLUSTER=${{ inputs.byron_cluster }}" >> .github_ci_env
          echo "CI_TESTRUN_NAME=${{ inputs.testrun_name }}" >> .github_ci_env
          echo "CI_SKIP_PASSED=${{ inputs.skip_passed }}" >> .github_ci_env
          if [ -e "${{ inputs.env-path }}" ]; then cat "${{ inputs.env-path }}" >> .github_ci_env; fi
      - name: Export env variables
        run: |
          cat .github_ci_env
          cat .github_ci_env >> $GITHUB_ENV
          echo "GITHUB_TOKEN=${{ secrets.GH_TOKEN }}" >> $GITHUB_ENV
      - name: Get previous test results
        if: inputs.testrun_name && inputs.skip_passed
        run: |
          if [ -n "${{ secrets.TCACHE_BASIC_AUTH }}" ] && [ -n "${{ secrets.TCACHE_URL }}" ]; then
            testrun_name_strip="$(echo "${{ inputs.testrun_name }}" | sed 's/[^a-zA-Z0-9_-]//g')"
            curl -s -u ${{ secrets.TCACHE_BASIC_AUTH }} "${{ secrets.TCACHE_URL }}/${testrun_name_strip}/pypassed" > deselected_tests.txt
            echo "DESELECT_FROM_FILE=deselected_tests.txt" >> $GITHUB_ENV
          fi
      - name: Run CLI regression tests
        id: testing-step
        run: .github/regression.sh
      - name: Report test results
        if: (success() || failure()) && inputs.testrun_name
        run: |
          if [ -n "${{ secrets.TCACHE_BASIC_AUTH }}" ] && [ -n "${{ secrets.TCACHE_URL }}" ] && [ -e testrun-report.xml ]; then
            testrun_name_strip="$(echo "${{ inputs.testrun_name }}" | sed 's/[^a-zA-Z0-9_-]//g')"
            curl -s -X PUT --fail-with-body -u ${{ secrets.TCACHE_BASIC_AUTH }} "${{ secrets.TCACHE_URL }}/${testrun_name_strip}/${{ github.run_number }}/import" -F "junitxml=@testrun-report.xml"
          fi
      - name: Upload testing artifacts on failure
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: testing-artifacts
          path: testing_artifacts.tar.xz
      - name: Upload Allure results
        uses: actions/upload-artifact@v4
        # When using `always()`, you lose ability to manually cancel the workflow.
        # Use `success() || failure()` instead.
        if: success() || failure()
        with:
          name: allure-results
          path: allure-results.tar.xz
      - name: Upload HTML report
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: testrun-report
          path: testrun-report.html
      - name: Upload testrun files
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: testrun-files
          path: |
            scheduling.log.xz
            errors_all.log
            testrun-report.xml
            deselected_tests.txt
            requirements_coverage.json
      - name: Upload CLI coverage
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: cli-coverage
          path: cli_coverage.json
      - name: Mail failure report
        uses: dawidd6/action-send-mail@v3
        if: (success() || failure()) && steps.testing-step.outcome != 'success' && env.CI_FAIL_MAILS
        with:
          server_address: smtp.gmail.com
          server_port: 465
          secure: true
          username: ${{secrets.GMAIL_USERNAME}}
          password: ${{secrets.GMAIL_PASSWORD}}
          subject: "Status: ${{ steps.testing-step.outcome }}; workflow: ${{ github.workflow }}"
          to: ${{secrets.CI_FAIL_MAILS}}
          from: Cardano Github Actions
          body: "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          reply_to: noreply@github.com
          attachments: testrun-report.html


Nightly tests dbsync

name: Nightly tests dbsync

on:
  schedule:
    - cron: '15 02 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly_dbsync
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


Nightly tests upgrade

name: Nightly tests upgrade

on:
  schedule:
    - cron: '15 05 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/upgrade_reusable.yaml
    with:
      env-path: .github/env_nightly_upgrade
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


Node upgrade tests reusable

name: Node upgrade tests reusable

on:
  workflow_call:
    inputs:
      env-path:
        required: true
        type: string
    secrets:
      GH_TOKEN:
        required: true
      CI_FAIL_MAILS:
        required: false
      GMAIL_USERNAME:
        required: false
      GMAIL_PASSWORD:
        required: false

env:
  CI_FAIL_MAILS: ${{ secrets.CI_FAIL_MAILS }}

jobs:
  reusable_run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Nix
        uses: cachix/install-nix-action@V27
        with:
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GH_TOKEN }}
            trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo=
            substituters = https://cache.nixos.org https://cache.iog.io https://iohk.cachix.org
            allow-import-from-derivation = true
      - name: Collect env variables
        run: |
          : > .github_ci_env
          echo "PY_COLORS=1" >> .github_ci_env
          cat "${{ inputs.env-path }}" >> .github_ci_env
      - name: Export env variables
        run: |
          cat .github_ci_env
          cat .github_ci_env >> $GITHUB_ENV
          echo "GITHUB_TOKEN=${{ secrets.GH_TOKEN }}" >> $GITHUB_ENV
      - name: Run CLI regression tests
        id: testing-step
        run: ./.github/node_upgrade.sh
      - name: Upload testing artifacts on failure
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: testing-artifacts
          path: testing_artifacts.tar.xz
      - name: Upload Allure results for step1
        uses: actions/upload-artifact@v4
        # When using `always()`, you lose ability to manually cancel the workflow.
        # Use `success() || failure()` instead.
        if: success() || failure()
        with:
          name: allure-results-step1
          path: allure-results-step1.tar.xz
      - name: Upload Allure results for step2
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: allure-results-step2
          path: allure-results-step2.tar.xz
      - name: Upload Allure results for step3
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: allure-results-step3
          path: allure-results-step3.tar.xz
      - name: Upload HTML reports
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: testrun-reports
          path: |
            testrun-report-step1.html
            testrun-report-step2.html
            testrun-report-step3.html
      - name: Upload testrun files
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: testrun-files
          path: |
            scheduling.log.xz
            errors_all.log
      - name: Upload CLI coverage
        uses: actions/upload-artifact@v4
        if: success() || failure()
        with:
          name: cli-coverage
          path: cli_coverage.json
      - name: Mail failure report
        uses: dawidd6/action-send-mail@v3
        if: (success() || failure()) && steps.testing-step.outcome != 'success' && env.CI_FAIL_MAILS
        with:
          server_address: smtp.gmail.com
          server_port: 465
          secure: true
          username: ${{secrets.GMAIL_USERNAME}}
          password: ${{secrets.GMAIL_PASSWORD}}
          subject: "Status: ${{ steps.testing-step.outcome }}; workflow: ${{ github.workflow }}"
          to: ${{secrets.CI_FAIL_MAILS}}
          from: Cardano Github Actions
          body: "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
          reply_to: noreply@github.com
          attachments: testrun-report.html


CodeQL

name: "CodeQL"

on:
  pull_request:
    branches: [ "master" ]
    paths:
      - '**.py'
  schedule:
    - cron: '16 0 * * 4'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Use only 'java' to analyze code written in Java, Kotlin or both
        # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"


Nix smoke test

name: "Nix smoke test"

on:
  pull_request:
    branches: [ "master" ]
    paths:
      - 'flake.lock'
      - 'requirements_freeze.txt'
      - '**.nix'
      - '.github/workflows/nix_smoke.yaml'
  workflow_dispatch:

jobs:
  nix_smoke:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Install Nix
        uses: cachix/install-nix-action@V27
        with:
          extra_nix_config: |
            access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
            trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo=
            substituters = https://cache.nixos.org https://cache.iog.io https://iohk.cachix.org
            allow-import-from-derivation = true
      - name: Run pytest in Nix
        run: TEST_THREADS=0 PYTEST_ARGS="-k test_cli.py --skipall" ./.github/regression.sh


Nightly tests Conway CC

name: Nightly tests Conway CC

on:
  schedule:
    - cron: '15 03 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly_conway_cc
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


Nightly tests Conway no CC

name: Nightly tests Conway no CC

on:
  schedule:
    - cron: '15 04 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly_conway_nocc
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


name: repo_tests

on:
  pull_request:
    branches:
    - master

env:
  PY_COLORS: "1"

jobs:
  tests:
    runs-on: ubuntu-latest
    steps:
    - name: Check out repository
      uses: actions/checkout@v4
    - name: Set up python
      id: setup-python
      uses: actions/setup-python@v5
      with:
        python-version: '3.10'
    - name: Install Poetry
      uses: snok/install-poetry@v1
      with:
        virtualenvs-create: true
        virtualenvs-in-project: true
        installer-parallel: true
    - name: Load cached venv
      id: cached-poetry-dependencies
      uses: actions/cache@v4
      with:
        path: .venv
        key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('poetry.lock') }}
    - name: Install project
      run: SETUPTOOLS_ENABLE_FEATURES="legacy-editable" poetry install --no-interaction --with dev
    - name: Load cached pre-commit env
      id: cached-pre-commit
      uses: actions/cache@v4
      with:
        path: ~/.cache/pre-commit
        key: pre-commit-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('.pre-commit-config.yaml') }}
    - name: Install pre-commit hooks
      run: |
        mkdir -p ~/.cache/pre-commit
        true > ~/.cache/pre-commit/pre-commit.log
        poetry run pre-commit install-hooks --color=always
        retval="$?"
        if [ "$retval" -ne 0 ]; then
          cat ~/.cache/pre-commit/pre-commit.log
        fi
        exit "$retval"
    - name: Run pre-commit linters
      run: poetry run pre-commit run -a --show-diff-on-failure --color=always
    - name: Run framework tests
      run: poetry run pytest --doctest-modules framework_tests cardano_node_tests/utils/


Nightly tests Conway Bootstrap

name: Nightly tests Conway Bootstrap

on:
  schedule:
    - cron: '15 01 * * *'
  workflow_dispatch:

jobs:
  nightly_job:
    if: github.repository_owner == 'IntersectMBO' || github.event_name != 'schedule'
    # reusable workflow from local repo and same branch as this config
    uses: ./.github/workflows/regression_reusable.yaml
    with:
      env-path: .github/env_nightly_conway_bootstrap
    secrets:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      CI_FAIL_MAILS: ${{ secrets.NIGHTLY_FAIL_MAILS }}
      GMAIL_USERNAME: ${{ secrets.GMAIL_USERNAME }}
      GMAIL_PASSWORD: ${{ secrets.GMAIL_PASSWORD }}


CodeQL

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ develop, main ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ develop ]
  schedule:
    - cron: '44 7 * * 3'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    # Initializes the CodeQL tools for scanning.
    # moved from v1 to v2 20230301
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    # ℹ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2


Lint PR title

name: "Lint PR title"

on:
  pull_request_target:
    types:
      - opened
      - edited
      - synchronize
    branches:
      - 'main'
      - 'develop'
jobs:
  lint:
    if: ${{ github.head_ref != 'develop' }}
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Install dependencies
      run: npm install @commitlint/cli @commitlint/config-conventional

    - name: Validate PR title
      run: |
        PR_TITLE=$(jq -r '.pull_request.title' "$GITHUB_EVENT_PATH")
        echo "$PR_TITLE" | npx commitlint --config commitlint.config.js


Trestle Deploy

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Trestle Deploy

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        include:
        - os: ubuntu-latest
          path: ~/.cache/pip
        - os: macos-latest
          path: ~/Library/Caches/pip
        - os: windows-latest
          path: ~\AppData\Local\pip\Cache
        python-version: ['3.9', '3.10', '3.11']

    steps:
    - name: Don't mess with  line endings
      run: |
        git config --global core.autocrlf false
    - uses: actions/checkout@v2
      with:
        submodules: true
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - uses: actions/cache@v2
      with:
        path: ${{ matrix.path }}
        key: ${{ matrix.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('setup.cfg') }}
        restore-keys: |
         ${{ matrix.os }}-${{ matrix.python-version }}-pip-

    - name: Install build tools
      run: |
        make develop
    - name: Setup pre-commit
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make pre-commit
    - name: Install dependencies
      run: |
        make install
    - name: Run md document formatting (mdformat)
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make mdformat
    - name: Run code formatting (yapf)
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make code-format
    - name: Run code linting (flake8)
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make code-lint
    - name: Run code typing check (mypy)
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      continue-on-error: true
      run: |
        make code-typing
    - name: Validate website content (mkdocs)
      if: ${{ (matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make docs-validate
    - name: Pytest Fast
      if: ${{ !(matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make test
    - name: Pytest Cov
      if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' }}
      run: |
        make test-cov
  deploy:

    runs-on: ubuntu-latest
    needs: build
    permissions:
      id-token: write
    environment:
      name: release
      url: https://pypi.org/p/compliance-trestle
    if: github.ref == 'refs/heads/main' && github.repository == 'oscal-compass/compliance-trestle'
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: true
        fetch-depth: 0
        token: ${{ secrets.ADMIN_PAT }}
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      with:
        python-version: '3.10'
    - name: Install build tools
      run: |
        make develop

    # This action uses Python Semantic Release v8
    - name: Python Semantic Release
      id: release
      uses: python-semantic-release/python-semantic-release@v9.8.0
      with:
        github_token: ${{ secrets.ADMIN_PAT }}

    - name: Publish package distributions to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      # NOTE: DO NOT wrap the conditional in ${{ }} as it will always evaluate to true.
      # See https://github.com/actions/runner/issues/1173
      if: steps.release.outputs.released == 'true'

    - name: Publish package distributions to GitHub Releases
      uses: python-semantic-release/upload-to-gh-release@v9.8.0
      if: steps.release.outputs.released == 'true'
      with:
        github_token: ${{ secrets.ADMIN_PAT }}

  deploy-docs:
    runs-on: ubuntu-latest
    needs: deploy
    concurrency:
      group: ${{ github.ref }}-${{ github.workflow }}-${{ github.job }}-docs
      cancel-in-progress: true
    # Temporary hack: allow develop as well as master to deploy docs.
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: true
        fetch-depth: 0
        token: ${{ secrets.ADMIN_PAT }}
    - name: Set up Python 3.10
      uses: actions/setup-python@v2
      # This is deliberately not using a custom credential as it relies on native github actions token to have push rights.
      with:
        python-version: '3.10'
    - name: Install build tools
      run: |
        make develop
    - name: Create release
      shell: bash
      run: |
        mkdocs gh-deploy

  merge-main-to-develop:
    name: Merge main -> develop
    runs-on: ubuntu-latest
    needs: deploy
    concurrency:
      group: ${{ github.ref }}-${{ github.workflow }}-${{ github.job }}-main
      cancel-in-progress: true
    if: github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v2
      with:
        submodules: true
        ref: main
        fetch-depth: 0
        token: ${{ secrets.ADMIN_PAT }}
    - name: Configure Git
      run: |
        git config user.name "Vikas Agarwal"
        git config user.email "<>"
    - name: Merge Main to Develop
      run: |
        git checkout develop
        git merge --no-ff main -m "chore: Merge back version tags and changelog into develop."
        git push origin develop


Trestle PR pipeline

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Trestle PR pipeline
on:
  pull_request:
  push:
    branches:
      - develop
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - uses: actions/checkout@v2
      with:
        submodules: true
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.10'
    - uses: actions/cache@v2
      with:
        path: ~/.cache/pip
        key: ubuntu-latest-3.10-pip-${{ hashFiles('setup.cfg') }}
        restore-keys: |
          ubuntu-latest-3.10-pip-
    - name: Install build tools
      run: |
        make develop
    - name: Setup pre-commit
      run: |
        make pre-commit
    - name: Install dependencies
      run: |
        make install
    - name: Run md document formatting (mdformat)
      run: |
        make mdformat
    - name: Run code formatting (yapf)
      run: |
        make code-format
    - name: Run code linting (flake8)
      run: |
        make code-lint
    - name: Run code typing check (mypy)
      continue-on-error: true
      run: |
        make code-typing
    - name: Validate website content (mkdocs)
      run: |
        make docs-validate
    - name: Check if dirty (mkdocs)
      run: |
        make check-for-changes

# This test simulates what it is like for a user to install trestle today.
# Coverage cannot be calculated as part of
  bdist:
    runs-on: ubuntu-latest
    steps:
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - uses: actions/checkout@v2
      with:
        submodules: true
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.10'
    - uses: actions/cache@v2
      with:
        path: ~/.cache/pip
        key: ubuntu-latest-3.10-pip-${{ hashFiles('setup.cfg') }}
        restore-keys: |
          ubuntu-latest-3.10-pip-
    - name: Install build tools
      run: |
        make develop
    - name: Run binary tests
      run: |
        make test-bdist

  test:
    # This test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ['3.9', '3.10', '3.11']
        include:
        - os: ubuntu-latest
          path: ~/.cache/pip
        - os: macos-latest
          path: ~/Library/Caches/pip
        - os: windows-latest
          path: ~\AppData\Local\pip\Cache
    steps:
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - uses: actions/checkout@v2
      with:
        fetch-depth: 0
        submodules: true
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v2
      with:
        python-version: ${{ matrix.python-version }}
    - uses: actions/cache@v2
      with:
        path: ${{ matrix.path }}
        key: ${{ matrix.os }}-${{ matrix.python-version }}-pip-${{ hashFiles('setup.cfg') }}
        restore-keys: |
         ${{ matrix.os }}-${{ matrix.python-version }}-pip-
    - name: Install build tools
      run: |
        make develop
    - name: Pytest Fast
      if: ${{ !(matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10') }}
      run: |
        make test
    - name: Pytest Cov
      if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' }}
      run: |
        make test-cov

    - name: Upload artifact
      if: ${{ matrix.os == 'ubuntu-latest' && matrix.python-version == '3.10' }}
      uses: actions/upload-artifact@v2
      with:
        name: coverage
        path: coverage.xml

  sonar:
    if: ${{ github.event.pull_request.base.repo.url == github.event.pull_request.head.repo.url }}
    runs-on: ubuntu-latest
    needs: test
    steps:
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - name: Don't mess with line endings
      run: |
        git config --global core.autocrlf false
    - uses: actions/checkout@v2
      with:
        submodules: true
    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.10'
    - uses: actions/cache@v2
      with:
        path: ~/.cache/pip
        key: ubuntu-latest-3.10-pip-${{ hashFiles('setup.cfg') }}
        restore-keys: |
          ubuntu-latest-3.10-pip-
    - name: Install build tools
      run: |
        make develop
    - name: Get coverage
      uses: actions/download-artifact@v2
      with:
        name: coverage
    - name: SonarCloud Scan
      uses: SonarSource/sonarcloud-github-action@master
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      with:
        args: >
          -Dsonar.python.coverage.reportPaths=coverage.xml
          -Dsonar.tests=tests/
          -Dsonar.sources=trestle/
          -Dsonar.python.version='3.10'
          -Dsonar.projectKey=compliance-trestle
          -Dsonar.organization=compliance-trestle
          -Dsonar.cpd.exclusions=trestle/oscal/*.py
          -Dsonar.exclusions=trestle/oscal/*.py
    - name: SonarQube Quality Gate check
      uses: sonarsource/sonarqube-quality-gate-action@master
      # Force to fail step after specific time
      timeout-minutes: 5
      env:
       SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}


AutoPR

name: AutoPR

on:
  issues:
    types: [edited]

jobs:
  autopr:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: AutoPR
        uses: irgolic/AutoPR@v0.1.0
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          openai_api_key: ${{ secrets.OPENAI_API_KEY }}
          issue_number: ${{ github.event.issue.number }}
          issue_title: ${{ github.event.issue.title }}
          issue_body: ${{ github.event.issue.body }}