Components test, build, and deploy

# Run tests, build components bundle, and deploy it to sandbox

name: 'Components test, build, and deploy'

on:
  pull_request:
    paths:
      - 'Makefile'
      - 'components/**'
      - 'app/**/*.stories.*'
      - 'app/src/atoms/**/*'
      - 'app/src/molecules/**/*'
      - 'package.json'
      - '.github/workflows/components-test-build-deploy.yaml'
  push:
    paths:
      - 'components/**'
      - 'app/**/*.stories.*'
      - 'app/src/atoms/**/*'
      - 'app/src/molecules/**/*'
      - 'package.json'
      - '.github/workflows/components-test-build-deploy.yaml'
    branches:
      - '**'
    tags:
      - 'components*'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

env:
  CI: true

jobs:
  js-unit-test:
    name: 'components unit tests'
    timeout-minutes: 30
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev for usb-detection'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.yarn-cache
            ${{ github.workspace }}/.npm-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
      - name: 'setup-js'
        run: |
          npm config set cache ./.npm-cache
          make setup-js
      - name: 'run components unit tests'
        run: make -C components test-cov
      - name: 'Upload coverage report'
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
          flags: components

  build-components-storybook:
    name: 'build components artifact'
    runs-on: 'ubuntu-22.04'
    if: github.event_name != 'pull_request'
    needs: ['js-unit-test']
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev for usb-detection'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.yarn-cache
            ${{ github.workspace }}/.npm-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
      - name: 'setup-js'
        run: |
          npm config set cache ./.npm-cache
          yarn config set cache-folder ./.yarn-cache
          make setup-js
      - name: 'build components'
        run: make -C components
      - name: 'upload github artifact'
        uses: actions/upload-artifact@v3
        with:
          name: 'components-artifact'
          path: storybook-static

  determine-build-type:
    runs-on: 'ubuntu-latest'
    name: 'Determine build type'
    outputs:
      type: ${{steps.determine-build-type.outputs.type}}
    steps:
      - id: determine-build-type
        run: |
          echo "Determining build type for event ${{github.event_name}} and ref ${{github.ref}}"
          if [ "${{ format('{0}', github.event_name == 'pull_request') }}" = "true" ] ; then
            echo "No builds for pull requests"
            echo 'type=none' >> $GITHUB_OUTPUT
          elif [ "${{ format('{0}', startsWith(github.ref, 'refs/heads/')) }}" = "true" ] ; then
            echo "storybook s3 builds for branch ${{ github.ref_name }}"
            echo 'type=storybook' >> $GITHUB_OUTPUT
          elif [ "${{ format('{0}', startsWith(github.ref, 'refs/tags/components')) }}" = "true" ] ; then
            echo "publish builds for components tags"
            echo 'type=publish' >> $GITHUB_OUTPUT
          else
            echo "No build for ref ${{github.ref}} and event ${{github.event_name}}"
            echo 'type=none' >> $GITHUB_OUTPUT
          fi

  deploy-components:
    name: 'deploy components storybook artifact to S3'
    runs-on: 'ubuntu-22.04'
    needs:
      ['js-unit-test', 'build-components-storybook', 'determine-build-type']
    if: needs.determine-build-type.outputs.type != 'none'
    steps:
      - uses: 'actions/checkout@v3'
      # https://github.com/actions/checkout/issues/290
      - name: 'Fix actions/checkout odd handling of tags'
        if: startsWith(github.ref, 'refs/tags')
        run: |
          git fetch -f origin ${{ github.ref }}:${{ github.ref }}
          git checkout ${{ github.ref }}
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'set complex environment variables'
        id: 'set-vars'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - name: 'download components build'
        uses: 'actions/download-artifact@v3'
        with:
          name: components-artifact
          path: ./dist
      - name: 'deploy builds to s3'
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.S3_SANDBOX_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SANDBOX_SECRET }}
          AWS_DEFAULT_REGION: us-east-2
        run: |
          aws s3 sync ./dist s3://opentrons-components/${{ env.OT_BRANCH}} --acl public-read
      - name: 'Set generated URL'
        run: |
          echo 'Created component storybook for [${{ env.OT_BRANCH }}](https://s3-us-west-2.amazonaws.com/opentrons-components/${{ env.OT_BRANCH }}/index.html?path=/)' >> $GITHUB_STEP_SUMMARY
          echo 'Created component storybook for https://s3-us-west-2.amazonaws.com/opentrons-components/${{ env.OT_BRANCH }}/index.html?path=/'

  publish-components:
    name: 'publish components package to npm'
    runs-on: 'ubuntu-latest'
    needs: ['js-unit-test', 'determine-build-type']
    if: needs.determine-build-type.outputs.type == 'publish'
    steps:
      - uses: 'actions/checkout@v3'
      # https://github.com/actions/checkout/issues/290
      - name: 'Fix actions/checkout odd handling of tags'
        if: startsWith(github.ref, 'refs/tags')
        run: |
          git fetch -f origin ${{ github.ref }}:${{ github.ref }}
          git checkout ${{ github.ref }}
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
          registry-url: 'https://registry.npmjs.org'
      - name: 'install udev for usb-detection'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'setup-js'
        run: |
          npm config set cache ./.npm-cache
          yarn config set cache-folder ./.yarn-cache
          make setup-js
      - name: 'build typescript types'
        run: make -C components build-ts
      - name: 'build js bundle'
        run: |
          make -C components lib
      # replace package.json stub version number with version from tag
      - name: 'set version number'
        run: |
          npm install -g json
          VERSION_STRING=$(echo ${{ github.ref }} | sed 's/refs\/tags\/components@//')
          json -I -f ./components/package.json -e "this.version=\"$VERSION_STRING\""
          json -I -f ./components/package.json -e "this.dependencies['@opentrons/shared-data']=\"$VERSION_STRING\""
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
          registry-url: 'https://registry.npmjs.org'
      - name: 'publish to npm registry'
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          cd ./components && echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ./.npmrc && npm publish --access public


Step generation test

# Run tests for step generation

name: 'Step generation test'

on:
  pull_request:
    paths:
      - 'step-generation/**'
      - 'shared-data/**'
      - 'package.json'
      - '.github/workflows/step-generation-test.yaml'
  push:
    paths:
      - 'step-generation/**'
      - 'shared-data/**'
      - 'package.json'
      - '.github/workflows/step-generation-test.yaml'
    branches:
      - '*'

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

env:
  CI: true

jobs:
  js-unit-test:
    name: 'step generation unit tests'
    runs-on: 'ubuntu-22.04'
    timeout-minutes: 30
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev for usb-detection'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.yarn-cache
            ${{ github.workspace }}/.npm-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
      - name: 'setup-js'
        run: |
          npm config set cache ./.npm-cache
          yarn config set cache-folder ./.yarn-cache
          make setup-js
      - name: 'run step generation unit tests'
        run: make -C step-generation test-cov
      - name: 'Upload coverage report'
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
          flags: step-generation


G-Code Testing Lint & Test

# This workflow runs test and lint on branch pushes that touch the
# g-code-testing project or its dependencies

name: 'G-Code Testing Lint & Test'

on:
  # Most of the time, we run on pull requests, which lets us handle external PRs
  push:
    paths:
      - 'Makefile'
      - 'api/**'
      - 'g-code-testing/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/g-code-testing-lint-test.yaml'
      - '.github/actions/python/**'
    branches:
      - 'edge'
      - 'release'
      - '*hotfix*'
  pull_request:
    paths:
      - 'Makefile'
      - 'g-code-testing/**'
      - 'api/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/g-code-testing-lint-test.yaml'
      - '.github/actions/python/**'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    name: 'g-code-testing package linting and tests'
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - name: 'install udev'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'set complex environment variables'
        id: 'set-vars'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'
      - uses: './.github/actions/python/setup'
        with:
          project: 'g-code-testing'
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.npm-cache/_prebuild
            ${{ github.workspace }}/.yarn-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
      - name: 'setup-js'
        run: |
          npm config set cache ${{ github.workspace }}/.npm-cache
          yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
          make setup-js
      - name: Lint
        run: make -C g-code-testing lint
      - name: Test
        run: make -C g-code-testing test
      - name: 'Upload coverage report'
        uses: 'codecov/codecov-action@v3'
        with:
          files: ./g-code-testing/coverage.xml
          flags: g-code-testing


hardware lint/test

# This workflow runs test and lint on branch pushes that touch the
# hardware project or its dependencies

name: 'hardware lint/test'

on:
  # Most of the time, we run on pull requests, which lets us handle external PRs
  push:
    paths:
      - 'Makefile'
      - 'hardware/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/hardware-lint-test.yaml'
      - '.github/actions/python/**'
    branches:
      - 'edge'
      - 'release'
    tags-ignore:
      - '*'
  pull_request:
    paths:
      - 'Makefile'
      - 'hardware/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/hardware-lint-test.yaml'
      - '.github/actions/python/**'

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    name: 'hardware package linting and tests'
    timeout-minutes: 20
    runs-on: 'ubuntu-20.04'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - name: Setup Node
        uses: 'actions/setup-node@v3'
        with:
          node-version: '12'

      - name: Setup Python
        uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - name: Setup Hardware Project
        uses: './.github/actions/python/setup'
        with:
          project: 'hardware'

      # TODO(amit, 2022-03-08): Enable once ot3 emulation is ready
      #      - name: Setup SocketCan
      #        run: |
      #          sudo apt-get update
      #          sudo apt-get install linux-modules-extra-$(uname -r)
      #          sudo modprobe vcan
      #
      #      - name: Run OT-3 Emulator
      #        uses: Opentrons/opentrons-emulation@v1.3
      #        with:
      #          ot3-firmware-commit-id: latest
      #          modules-commit-id: latest

      - name: Lint
        run: make -C hardware lint

      - name: Test
        run: make -C hardware test-cov
      # TODO(amit, 2022-03-08): Enable once ot3 emulation is ready
      #        env:
      #          CAN_CHANNEL: vcan0
      #        run: make -C hardware test-with-emulator

      - name: Code Coverage
        uses: 'codecov/codecov-action@v3'
        with:
          files: ./hardware/coverage.xml
          flags: hardware


G-Code-Confirm

name: "G-Code-Confirm"

on:
  # Run on any change to the api directory
  pull_request:
    paths:
      - 'api/**'
      - 'g-code-testing/**'
      - 'Makefile'
  push:
    paths:
      - 'api/**'
      - 'g-code-testing/**'
      - 'Makefile'
      - '.github/workflows/g-code-confirm-tests.yaml'
    branches:
      - 'edge'
      - 'release'
      - '*hotfix*'
  create:
    tags:
      - 'v*'

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

jobs:
  confirm-g-code:
    strategy:
      matrix:
        command: [
          '2-modules',
          'swift-smoke',
          'swift-turbo',
          'omega',
          'fast'
        ]
    name: 'Confirm G-Code (${{ matrix.command }})'
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '12'
      - uses: 'actions/setup-python@v3'
        with:
          python-version: '3.10'
      - uses: './.github/actions/python/setup'
        with:
          project: 'g-code-testing'

      - name: "Verify no missing comparison files"
        run: make -C g-code-testing check-for-missing-comparison-files

      - name: 'Run & Compare to comparison files'
        run: make -C g-code-testing test-g-code-${{ matrix.command }}


JS API Clients test

# Run tests, build components bundle, and deploy it to sandbox

name: 'JS API Clients test'

on:
  pull_request:
    paths:
      - 'react-api-client/**'
      - 'api-client/**'
      - 'package.json'
      - '.github/workflows/react-api-client-test.yaml'
  push:
    paths:
      - 'react-api-client/**'
      - 'api-client/**'
      - 'package.json'
      - '.github/workflows/react-api-client-test.yaml'
    branches:
      - '*'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

env:
  CI: true

jobs:
  js-unit-test:
    name: 'react-api-client unit tests'
    timeout-minutes: 30
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install libudev for usb-detection'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.yarn-cache
            ${{ github.workspace }}/.npm-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-
      - name: 'setup-js'
        run: |
          npm config set cache ./.npm-cache
          yarn config set cache-folder ./.yarn-cache
          make setup-js
      - name: 'run react-api-client unit tests'
        run: make -C react-api-client test-cov
      - name: 'Upload coverage report'
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
          flags: react-api-client


hardware-testing testing lint/test

# This workflow runs test and lint on branch pushes that touch the
# hardware-testing project or its dependencies

name: 'hardware-testing testing lint/test'

on:
  # Most of the time, we run on pull requests, which lets us handle external PRs
  push:
    paths:
      - 'Makefile'
      - 'hardware-testing/**'
      - 'api/**'
      - 'shared-data/**'
      - 'hardware/**'
      - '.github/workflows/hardware-testing.yaml'
      - '.github/actions/python/**'
    branches:
      - 'edge'
      - 'release'
    tags-ignore:
      - '*'
  pull_request:
    paths:
      - 'Makefile'
      - 'hardware-testing/**'
      - '.github/workflows/hardware-testing.yaml'
      - '.github/actions/python/**'

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    name: 'hardware--testing package linting and tests'
    timeout-minutes: 20
    runs-on: 'ubuntu-20.04'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: 'actions/setup-node@v3'
        with:
          node-version: '12'

      - name: Setup Python
        uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - name: Setup Project
        uses: './.github/actions/python/setup'
        with:
          project: 'hardware-testing'

      - name: Lint
        run: make -C hardware-testing lint

      - name: Test
        run: make -C hardware-testing test-cov

      - name: Coverage
        uses: 'codecov/codecov-action@v3'
        with:
          files: ./hardware-testing/coverage.xml
          flags: hardware-testing


hardware-testing testing protocols

name: 'hardware-testing testing protocols'

on:
  # Run on any change to the api directory
  pull_request:
    paths:
      - 'api/**'
      - 'hardware-testing/**'
      - 'Makefile'
  push:
    paths:
      - 'api/**'
      - 'hardware-testing/**'
      - 'Makefile'
      - '.github/workflows/hardware-testing-protocols.yaml'
    branches:
      - 'edge'
      - 'release'
      - '*hotfix*'
  create:
    tags:
      - 'v*'

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    name: 'hardware-testing protocols'
    timeout-minutes: 20
    runs-on: 'ubuntu-20.04'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0

      - name: Setup Node
        uses: 'actions/setup-node@v3'
        with:
          node-version: '12'

      - name: Setup Python
        uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - name: Setup Project
        uses: './.github/actions/python/setup'
        with:
          project: 'hardware-testing'

      - name: Test-Integration
        run: make -C hardware-testing test-integration


USB-Bridge test/lint

# This workflow runs tests and lint on non-release branches pushed that alter
# the usb-bridge subpackage

name: 'USB-Bridge test/lint'

on:
  push:
    paths:
      - 'usb-bridge/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/usb-bridge-lint-test.yaml'
      - '.github/actions/python/**'
    branches: # ignore any release-related thing (handled elsewhere)
      - 'edge'
    tags-ignore:
      - '*'
  pull_request:
    types: [opened, reopened, synchronize, ready_for_review]
    paths:
      - 'usb-bridge/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/usb-bridge-lint-test.yaml'
      - '.github/actions/python/**'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint:
    name: 'usb-bridge linting'
    timeout-minutes: 10
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - uses: './.github/actions/python/setup'
        with:
          project: 'usb-bridge'
      - name: Lint
        run: make -C usb-bridge lint
  test:
    name: 'usb-bridge package tests'
    timeout-minutes: 10
    needs: [lint]
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'
      - uses: './.github/actions/python/setup'
        with:
          project: 'usb-bridge'
      - name: Test
        run: make -C usb-bridge test
      - uses: 'codecov/codecov-action@v3'
        with:
          files: ./usb-bridge/coverage.xml
          flags: usb-bridge


Create github release for tag

# A workflow to create github releases with changelogs from tags

name: 'Create github release for tag'

on:
  push:
    tags:
      - '*'
  workflow_dispatch:

jobs:
  create-release:
    runs-on: 'ubuntu-22.04'
    name: 'Create changelogs and release'
    steps:
      # this could be improved by replacing this checkout with something like
      # mkdir opentrons ; git init . ;
      # git remote add origin  https://github.com/opentrons/opentrons
      # git fetch origin ${{ github.ref_name }}:${{ github.ref_name }}
      # git checkout ${{ github.ref_name }}
      # This would pull history for only the tag in question.
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.npm-cache/_prebuild
            ${{ github.workspace }}/.yarn-cache
          key: js-${{ hashFiles('yarn.lock') }}
      - name: 'setup-js'
        run: |
          npm config set cache ${{ github.workspace }}/.npm-cache
          yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
          yarn install

      - name: 'create release'
        run: |
          node ./scripts/deploy/create-release.js ${{ github.token }} ${{ github.ref_name }} --deploy


system-server test/lint

# This workflow runs tests and lint on non-release branches pushed that alter
# the system-server subpackage

name: 'system-server test/lint'

on:
  push:
    paths:
      - 'system-server/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/system-server-lint-test.yaml'
      - '.github/actions/python/**'
      - 'server-utils/**/*'
    branches: # ignore any release-related thing (handled elsewhere)
      - 'edge'
    tags-ignore:
      - '*'
  pull_request:
    types: [opened, reopened, synchronize, ready_for_review]
    paths:
      - 'system-server/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/system-server-lint-test.yaml'
      - '.github/actions/python/**'
      - 'server-utils/**/*'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint:
    name: 'system-server linting'
    timeout-minutes: 10
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - uses: './.github/actions/python/setup'
        with:
          project: 'system-server'
      - name: Lint
        run: make -C system-server lint
  test:
    name: 'system-server package tests'
    timeout-minutes: 10
    needs: [lint]
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'
      - uses: './.github/actions/python/setup'
        with:
          project: 'system-server'
      - name: Test
        run: make -C system-server test
      - uses: 'codecov/codecov-action@v3'
        with:
          files: ./system-server/coverage.xml
          flags: system-server


server-utils test/lint

# This workflow runs tests and lint on non-release branches pushed that alter
# the server-utils subpackage

name: 'server-utils test/lint'

on:
  push:
    paths:
      - 'server-utils/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/server-utils-lint-test.yaml'
      - '.github/actions/python/**'
    branches: # ignore any release-related thing (handled elsewhere)
      - 'edge'
    tags-ignore:
      - '*'
  pull_request:
    types: [opened, reopened, synchronize, ready_for_review]
    paths:
      - 'server-utils/**/*'
      - 'Makefile'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/server-utils-lint-test.yaml'
      - '.github/actions/python/**'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint:
    name: 'server-utils linting'
    timeout-minutes: 10
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'

      - uses: './.github/actions/python/setup'
        with:
          project: 'server-utils'
      - name: Lint
        run: make -C server-utils lint
  test:
    name: 'server-utils package tests'
    timeout-minutes: 10
    needs: [lint]
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'
      - uses: './.github/actions/python/setup'
        with:
          project: 'server-utils'
      - name: Test
        run: make -C server-utils test
      - uses: 'codecov/codecov-action@v3'
        with:
          files: ./server-utils/coverage.xml
          flags: server-utils


HTTP API docs build

# This workflow builds HTTP API docs when either:
#
# * A commit is tagged like "docs@foo".
#
# * Someone pushes, to any branch, a commit that touches any of:
#   * The parts of the robot-server/ project that are used by the docs.
#   * The docs source themselves (none yet).
#   * The CI/makefile tooling used to build the docs.

name: 'HTTP API docs build'

on:
  push:
    tags:
      - 'docs@*'
    branches:
      # We don't want to do any filtering based on branch name.
      # But because we specified `tags`, we need to specify `branches` too,
      # or else GitHub will only run this workflow for tag matches
      # and not for path matches.
      - '**'
    paths:
      - 'robot-server/**'
      - '.github/workflows/http-docs-build.yaml'
      - '.github/actions/python/**'
      - '.github/actions/webstack/deploy-to-sandbox/**'
      - '.github/workflows/utils.js'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  build:
    name: HTTP API reference build
    runs-on: 'ubuntu-22.04'
    steps:
      - uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      # https://github.com/actions/checkout/issues/290
      - name: 'Fix actions/checkout odd handling of tags'
        if: startsWith(github.ref, 'refs/tags')
        run: |
          git fetch -f origin ${{ github.ref }}:${{ github.ref }}
          git checkout ${{ github.ref }}
      - uses: 'actions/setup-python@v3'
        with:
          python-version: '3.10'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - uses: './.github/actions/python/setup'
        with:
          project: 'robot-server'
      - name: 'set complex environment variables'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars, } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - name: 'Build docs'
        run: |
          make -C robot-server docs
      - name: 'Deploy docs to sandbox'
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.S3_SANDBOX_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SANDBOX_SECRET }}
          AWS_DEFAULT_REGION: us-east-2
        uses: './.github/actions/webstack/deploy-to-sandbox'
        with:
          domain: 'docs.opentrons.com'
          distPath: './robot-server/docs/dist'
          destPrefix: ${{ env.OT_BRANCH }}


Start Flex build

name: 'Start Flex build'
on:
  push:
    branches:
      - edge
      - '*internal-release*'
      - 'release*'
      - 'chore_release*'
    tags:
      - ot3@*
      - v*
  pull_request:
    types:
      - opened
      - synchronize
      - labeled

jobs:
  handle-push:
    runs-on: 'ubuntu-latest'
    if: github.event_name == 'push'
    name: "Start a Flex build for a branch/tag push"
    steps:
      - name: 'start build'
        uses: octokit/request-action@v2.x
        env:
          GITHUB_TOKEN: ${{ secrets.OT3_BUILD_CROSSREPO_ACCESS }}
        with:
          route: POST /repos/{owner}/{repo}/actions/workflows/{workflow-id}/dispatches
          owner: opentrons
          repo: oe-core
          workflow-id: build-ot3-actions.yml
          ref: main
          inputs: |
            {
              "oe-core-ref": "-",
              "monorepo-ref": "${{ github.ref }}",
              "infra-stage": "stage-prod"
            }

  handle-pr:
    runs-on: 'ubuntu-latest'
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'Opentrons/opentrons' && contains(github.event.pull_request.labels.*.name, 'ot3-build')
    name: "Start a Flex build for a requested PR"
    steps:
      - name: 'start build'
        uses: octokit/request-action@v2.x
        env:
          GITHUB_TOKEN: ${{ secrets.OT3_BUILD_CROSSREPO_ACCESS }}
        with:
          route: POST /repos/{owner}/{repo}/actions/workflows/{workflow-id}/dispatches
          owner: opentrons
          repo: oe-core
          workflow-id: build-ot3-actions.yml
          ref: main
          inputs: |
            {
              "oe-core-ref": "-",
              "monorepo-ref": "refs/heads/${{ github.head_ref }}",
              "infra-stage": "stage-prod"
            }


Start OT-2 build

name: 'Start OT-2 build'
on:
  push:
    branches:
      - edge
      - '*internal-release*'
      - 'release*'
      - 'chore_release*'
    tags:
      - ot3@*
      - v*
  pull_request:
    types:
      - opened
      - synchronize
      - labeled

jobs:
  handle-push:
    runs-on: 'ubuntu-latest'
    if: github.event_name == 'push'
    name: "Start an OT-2 build for a branch/tag push"
    steps:
      - name: 'start build'
        uses: octokit/request-action@v2.x
        env:
          GITHUB_TOKEN: ${{ secrets.OT2_BUILD_CROSSREPO_ACCESS }}
        with:
          route: POST /repos/{owner}/{repo}/actions/workflows/{workflow-id}/dispatches
          owner: opentrons
          repo: buildroot
          workflow-id: build.yml
          ref: opentrons-develop
          inputs: |
            {
              "buildroot-ref": "-",
              "monorepo-ref": "${{ github.ref }}",
              "infra-stage": "stage-prod"
            }

  handle-pr:
    runs-on: 'ubuntu-latest'
    if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'Opentrons/opentrons' && contains(github.event.pull_request.labels.*.name, 'ot2-build')
    name: "Start an OT-2 build for a requested PR"
    steps:
      - name: 'start build'
        uses: octokit/request-action@v2.x
        env:
          GITHUB_TOKEN: ${{ secrets.OT2_BUILD_CROSSREPO_ACCESS }}
        with:
          route: POST /repos/{owner}/{repo}/actions/workflows/{workflow-id}/dispatches
          owner: opentrons
          repo: buildroot
          workflow-id: build.yml
          ref: opentrons-develop
          inputs: |
            {
              "buildroot-ref": "-",
              "monorepo-ref": "refs/heads/${{ github.head_ref }}",
              "infra-stage": "stage-prod"
            }


Analyses Snapshot Test

name: Analyses Snapshot Test

on:
  workflow_dispatch:
    inputs:
      TARGET:
        description: 'Target branch or tag'
        required: true
        default: 'edge'
      TEST_SOURCE:
        description: 'Target for the test code'
        required: true
        default: 'edge'
  schedule:
    - cron:  '26 7 * * *' # 7:26 AM UTC
  pull_request:
    paths:
      - 'api/**'
      - 'shared-data/**/*'
      - '!shared-data/js/**'

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

jobs:
  build-and-test:
    timeout-minutes: 15
    runs-on: ubuntu-latest
    env:
      TARGET: ${{ github.event.inputs.TARGET || github.head_ref || 'edge' }}
      TEST_SOURCE: ${{ github.event.inputs.TEST_SOURCE || github.head_ref || 'edge' }}

    steps:
    - name: Checkout Repository
      uses: actions/checkout@v4
      with:
        ref: ${{ env.TEST_SOURCE }}

    - name: Docker Build
      working-directory: app-testing
      run: make build-opentrons-analysis

    - name: Set up Python 3.12
      uses: actions/setup-python@v5
      with:
        python-version: '3.12'
        cache: 'pipenv'
        cache-dependency-path: app-testing/Pipfile.lock

    - name: Setup Python Dependencies
      working-directory: app-testing
      run: make setup

    - name: Run Test
      id: run_test
      working-directory: app-testing
      run: make snapshot-test

    - name: Upload Report
      if: '!cancelled()'
      uses: actions/upload-artifact@v4
      with:
        name: test-report
        path: app-testing/results/

    - name: Handle Test Failure
      if: failure()
      working-directory: app-testing
      run: make snapshot-test-update

    - name: Create Snapshot update Request
      id: create-pull-request
      if: failure()
      uses: peter-evans/create-pull-request@v5
      with:
          commit-message: 'fix(app-testing): snapshot failure capture'
          title: 'fix(app-testing): snapshot failure capture'
          body: 'This PR is an automated snapshot update request. Please review the changes and merge if they are acceptable or find you bug and fix it.'
          branch: 'app-testing/${{ env.TARGET }}-from-${{ env.TEST_SOURCE}}'
          base: ${{ env.TEST_SOURCE}}

    - name: Comment on PR
      if: failure() && github.event_name == 'pull_request'
      uses: actions/github-script@v7
      with:
        script: |
          const message = 'A PR has been opened to address analyses snapshot changes. Please review the changes here: https://github.com/${{ github.repository }}/pull/${{ steps.create-pull-request.outputs.pull-request-number }}';
          github.rest.issues.createComment({
            owner: context.repo.owner,
            repo: context.repo.repo,
            issue_number: context.issue.number,
            body: message
          });


abr-testing lint/test

# This workflow runs test and lint on branch pushes that touch the abr-testing
# project or its dependencies.

name: 'abr-testing lint/test'
on:
  push:
    paths:
      - 'Makefile'
      - 'abr-testing/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/abr-testing-lint-test.yaml'
      - '.github/actions/python/**'
    branches:
      - 'edge'
    tags-ignore:
      - '*'
  pull_request:
    paths:
      - 'abr-testing/**'
      - 'scripts/**/*.mk'
      - 'scripts/**/*.py'
      - '.github/workflows/abr-testing-lint-test.yaml'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    runs-on: 'windows-latest'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v3'
        with:
          fetch-depth: 0
      - name: Setup Node
        uses: 'actions/setup-node@v3'
        with:
          node-version: '12'
      - name: Setup Python
        uses: 'actions/setup-python@v4'
        with:
          python-version: '3.10'
      - name: Set up abr-testing project
        uses: './.github/actions/python/setup'
        with:
          project: 'abr-testing'
      - name: lint
        run:
          make -C abr-testing lint
      - name: test
        run:
          make -C abr-testing test


performance-metrics test & lint

# This workflow runs lint on pull requests that touch anything in the performance-metrics directory

name: 'performance-metrics test & lint'

on:
  pull_request:
    paths:
      - 'performance-metrics/**'
      - '.github/workflows/performance-metrics-test-lint.yaml'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint:
    name: 'performance-metrics test & lint'
    timeout-minutes: 5
    runs-on: 'ubuntu-latest'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v4'

      - name: Setup Python
        uses: 'actions/setup-python@v5'
        with:
          python-version: '3.10'
          cache: 'pipenv'
          cache-dependency-path: performance-metrics/Pipfile.lock

      - name: "Install Python deps"
        uses: './.github/actions/python/setup'
        with:
          project: 'performance-metrics'

      - name: Setup
        id: install
        working-directory: ./performance-metrics
        run: make setup

      - name: Test
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./performance-metrics
        run: make test

      - name: Lint
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./performance-metrics
        run: make lint


# Run tests, build the app, and deploy it cross platform

name: 'OpentronsAI client test, build, and deploy'

# ToDo (kk:04/16/2024) Add build and deploy task

on:
  push:
    paths:
      - 'Makefile'
      - 'opentrons-ai-client/**/*'
      - 'components/**/*'
      - '*.js'
      - '*.json'
      - 'yarn.lock'
      - '.github/workflows/app-test-build-deploy.yaml'
      - '.github/workflows/utils.js'
    branches:
      - '**'
    tags:
      - 'v*'
      - 'ot3@*'
  pull_request:
    paths:
      - 'Makefile'
      - 'opentrons-ai-client/**/*'
      - 'components/**/*'
      - '*.js'
      - '*.json'
      - 'yarn.lock'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-${{ github.ref_name != 'edge' || github.run_id}}-${{ github.ref_type != 'tag' || github.run_id }}
  cancel-in-progress: true

env:
  CI: true

jobs:
  js-unit-test:
    runs-on: 'ubuntu-22.04'
    name: 'opentrons ai frontend unit tests'
    timeout-minutes: 60
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'set complex environment variables'
        id: 'set-vars'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.npm-cache/_prebuild
            ${{ github.workspace }}/.yarn-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
      - name: 'setup-js'
        run: |
          npm config set cache ${{ github.workspace }}/.npm-cache
          yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
          make setup-js
      - name: 'test frontend packages'
        run: |
          make -C opentrons-ai-client test-cov
      - name: 'Upload coverage report'
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/lcov.info
          flags: opentrons-ai-client


Testing Edge with Hypothesis

name: 'Testing Edge with Hypothesis'

on:
  schedule:
  - cron: '45 22 * * 1-5'

  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.actor_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint-test:
    name: 'edge testing'
    timeout-minutes: 120
    runs-on: 'ubuntu-latest'
    steps:
    - name: 'Checkout opentrons repo'
      uses: 'actions/checkout@v3'
      with:
        ref: 'edge'
        fetch-depth: 0

    - name: 'Setup Python'
      uses: 'actions/setup-python@v5'
      with:
        python-version: '3.10'
        cache: 'pipenv'
        cache-dependency-path: 'test-data-generation/Pipfile.lock'

    - name: 'Install Python deps'
      uses: './.github/actions/python/setup'
      with:
        project: 'test-data-generation'

    - name: 'Run Hypothesis tests'
      run: 'make -C test-data-generation test'


name: 'OpentronsAI client edge continuous deployment to staging'

on:
  push:
    branches:
      - edge
    paths:
      - 'opentrons-ai-client/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.run_id }}
  cancel-in-progress: true

env:
  CI: true

jobs:
  js-unit-test:
    runs-on: 'ubuntu-22.04'
    permissions:
      id-token: write
      contents: read
    name: 'OpentronsAI client edge continuous deployment to staging'
    timeout-minutes: 10
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'set complex environment variables'
        id: 'set-vars'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.npm-cache/_prebuild
            ${{ github.workspace }}/.yarn-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
      - name: 'setup-js'
        run: |
          npm config set cache ${{ github.workspace }}/.npm-cache
          yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
          make setup-js
      - name: 'build'
        run: |
          make -C opentrons-ai-client build-staging
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.STAGING_AI_ROLE_ARN }}
          aws-region: ${{ secrets.STAGING_AI_REGION }}
      - name: 'deploy to staging'
        run: |
          make -C opentrons-ai-client staging-deploy


Opentrons ai-server lint

# This workflow runs lint on pull requests that touch anything in the opentrons-ai-server directory

name: 'Opentrons ai-server lint'

on:
  pull_request:
    paths:
      - 'opentrons-ai-server/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  lint:
    name: 'ai-server lint'
    timeout-minutes: 5
    runs-on: 'ubuntu-latest'
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v4'

      - name: Setup Python
        uses: 'actions/setup-python@v5'
        with:
          python-version: '3.12'
          cache: 'pipenv'
          cache-dependency-path: opentrons-ai-server/Pipfile.lock
      - name: Setup
        id: install
        working-directory: ./opentrons-ai-server
        run: make setup
      - name: black-check
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./opentrons-ai-server
        run: make black-check
      - name: ruff
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./opentrons-ai-server
        run: make ruff-check
      - name: mypy
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./opentrons-ai-server
        run: make mypy
      - name: unit tests
        if: always() && steps.install.outcome == 'success' || steps.install.outcome == 'skipped'
        working-directory: ./opentrons-ai-server
        run: make unit-test


name: 'OpentronsAI edge continuous deployment to dev'

on:
  push:
    branches:
      - edge
    paths:
      - 'opentrons-ai-server/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.run_id }}
  cancel-in-progress: true

env:
  CI: true

jobs:
  js-unit-test:
    runs-on: 'ubuntu-latest'
    permissions:
      id-token: write
      contents: read
    name: 'OpentronsAI server edge continuous deployment to staging'
    timeout-minutes: 10
    steps:
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v4'

      - name: Setup Python
        uses: 'actions/setup-python@v5'
        with:
          python-version: '3.12'
          cache: 'pipenv'
          cache-dependency-path: opentrons-ai-server/Pipfile.lock
      - name: Setup
        id: install
        working-directory: ./opentrons-ai-server
        run: make setup
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.STAGING_AI_ROLE_ARN }}
          aws-region: ${{ secrets.STAGING_AI_REGION }}
      - name: 'deploy api to staging'
        run: |
          make -C opentrons-ai-server deploy ENV=staging


OpentronsAI production deployment

name: 'OpentronsAI production deployment'

on:
  push:
    tags:
      - 'ai-client@*'
      - 'ai-server@*'

env:
  CI: true

jobs:
  deploy-client:
    if: startsWith(github.ref, 'refs/tags/ai-client@')
    # if there is a deployment (this workflow) in progress for the ai-client@ tag, cancel it
    concurrency:
      group: ${{ github.workflow }}-ai-client@
      cancel-in-progress: true
    runs-on: 'ubuntu-22.04'
    permissions:
      id-token: write
      contents: read
    name: 'OpentronsAI client prod deploy'
    timeout-minutes: 10
    steps:
      - uses: 'actions/checkout@v3'
      - uses: 'actions/setup-node@v3'
        with:
          node-version: '18.19.0'
      - name: 'install udev'
        run: |
          # WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
          sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
          sudo apt-get update && sudo apt-get install libudev-dev
      - name: 'set complex environment variables'
        id: 'set-vars'
        uses: actions/github-script@v6
        with:
          script: |
            const { buildComplexEnvVars } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
            buildComplexEnvVars(core, context)
      - name: 'cache yarn cache'
        uses: actions/cache@v3
        with:
          path: |
            ${{ github.workspace }}/.npm-cache/_prebuild
            ${{ github.workspace }}/.yarn-cache
          key: js-${{ secrets.GH_CACHE_VERSION }}-${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
      - name: 'setup-js'
        run: |
          npm config set cache ${{ github.workspace }}/.npm-cache
          yarn config set cache-folder ${{ github.workspace }}/.yarn-cache
          make setup-js
      - name: 'build'
        run: |
          make -C opentrons-ai-client build-production
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.PROD_AI_ROLE_ARN }}
          aws-region: ${{ secrets.PROD_AI_REGION }}
      - name: 'deploy client to prod'
        run: |
          make -C opentrons-ai-client prod-deploy

  deploy-server:
    if: startsWith(github.ref, 'refs/tags/ai-server@')
    # if there is a deployment (this workflow) in progress for the ai-server@ tag, cancel it
    concurrency:
      group: ${{ github.workflow }}-ai-server@
      cancel-in-progress: true
    runs-on: 'ubuntu-latest'
    permissions:
      id-token: write
      contents: read
    name: 'OpentronsAI server prod deploy'
    timeout-minutes: 10
    steps:
      - name: Extract Version
        id: extract_version
        run: |
          TAG_REF=${{ github.ref }}
          SERVER_VERSION=${TAG_REF#refs/tags/ai-server@}
          echo "SERVER_VERSION=$SERVER_VERSION" >> "$GITHUB_OUTPUT"
      - name: Checkout opentrons repo
        uses: 'actions/checkout@v4'
      - name: Setup Python
        uses: 'actions/setup-python@v5'
        with:
          python-version: '3.12'
          cache: 'pipenv'
          cache-dependency-path: opentrons-ai-server/Pipfile.lock
      - name: Setup
        id: install
        working-directory: ./opentrons-ai-server
        run: make setup
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.PROD_AI_ROLE_ARN }}
          aws-region: ${{ secrets.PROD_AI_REGION }}
      - name: 'deploy api to prod'
        working-directory: ./opentrons-ai-server
        run: |
          make deploy ENV=prod TAG=${{ steps.extract_version.outputs.SERVER_VERSION }}


Build Docker container on push

name: Build Docker container on push

on:
    push:
        branches:
            - "*"

jobs:
  build:
    name: Build image
    runs-on: ubuntu-20.04

    steps:
      - name: Checkout project
        uses: actions/checkout@v3

      - name: Set env variables
        run: |
          echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV
          REPO_OWNER=${{ github.repository_owner }}
          echo "IMAGE_NAME=${REPO_OWNER,,}/${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v2
        id: qemu

      - name: Setup Docker buildx action
        uses: docker/setup-buildx-action@v2
        id: buildx

      - name: Run Docker buildx
        run: |
                docker buildx build \
                --platform linux/amd64,linux/arm64 \
                --tag ghcr.io/$IMAGE_NAME:$BRANCH \
                --output "type=registry" ./


Build Docker container on tag

name: Build Docker container on tag

on:
  push:
    tags:
      - v[0-9]+.[0-9]+.[0-9]+
      - v[0-9]+.[0-9]+.[0-9]+-*

jobs:
  build:
    name: Build image
    runs-on: ubuntu-20.04

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

      - name: Set env variables
        run: |
          echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
          REPO_OWNER=${{ github.repository_owner }}
          echo "IMAGE_NAME=${REPO_OWNER,,}/${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Setup Docker buildx action
        uses: docker/setup-buildx-action@v1

      - name: Run Docker buildx
        run: |
                docker buildx build \
                --platform linux/amd64,linux/arm64 \
                --tag ghcr.io/$IMAGE_NAME:$TAG \
                --output "type=registry" ./


TOC Generator

on: push
name: TOC Generator
jobs:
  generateTOC:
    name: TOC Generator
    runs-on: ubuntu-latest
    steps:
      - uses: technote-space/toc-generator@v2
        with:
          TARGET_PATHS: README.md, docs/faq.md, docs/development.md


Black Python Linter

name: Black Python Linter

on: [push,pull_request]

jobs:
  black:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      # This version should match what you can find in .pre-commit-config.yaml
      - uses: psf/black@22.3.0 # https://black.readthedocs.io/en/stable/integrations/github_actions.html
        with:
            options: "--check --verbose"
            src: "./src"
            version: "22.3.0"


build

name: build

on:
  push:
    branches-ignore:
      - deploy
  pull_request:
    branches-ignore:
      - deploy

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version:
          - '3.8'
          - '3.12'
    steps:
    - uses: actions/checkout@v3
    - name: Fetch branches
      run: |
        git remote set-branches --add origin deploy
        git fetch --depth=5 origin master deploy
    - uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Setup cache
      id: cache
      uses: actions/cache@v3
      with:
        key: ${{ runner.os }}-${{ env.pythonLocation }}-pip-cache-version-1-${{ hashFiles('**/requirements.txt') }}}-${{ hashFiles('**/user_requirements.txt') }}
        restore-keys: |
          ${{ runner.os }}-${{ env.pythonLocation }}-pip-cache-version-1-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/user_requirements.txt') }}
          ${{ runner.os }}-${{ env.pythonLocation }}-pip-cache-version-1-
        path: |
          ~/.cache/pip
    - name: Install Python dependencies
      run: |
        pip3 install -U wheel --upgrade-strategy eager
        pip3 install -U -r requirements.txt -r user_requirements.txt pytest-cov coveralls --upgrade-strategy eager
    - name: Lint ./tests
      run: python3 -m flake8 --config=tox_tests.ini ./test/
    - name: Lint ./classes
      run: python3 -m flake8 --config=tox_classes.ini ./classes/
    - name: Lint code
      run: python3 -m flake8 ./
    - name: Pytest
      run: |
        python3 -W default::Warning -m pytest \
          --cov=chatcommunicate \
          --cov=findspam \
          --cov=globalvars \
          --cov=spamhandling \
          --cov=datahandling \
          --cov=chatcommands \
          --cov=helpers \
          -n 3 \
          --dist loadgroup \
          --timeout=300 \
          test


CI

name: CI

on: [ push, pull_request, workflow_dispatch ]

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: set up python 3.10
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"

      - name: install poetry
        run: curl -sSL https://install.python-poetry.org | python3 -

      - name: configure poetry
        run: poetry config virtualenvs.in-project true

      - name: load cached venv
        id: cached-poetry-dependencies
        uses: actions/cache@v2
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}

      - name: install dependencies
        run: poetry install

      - name: ruff formatter & linter
        run: poetry run format_and_lint

      - name: mypy
        run: poetry run mypy

      - name: pytest
        run: poetry run pytest

      - name: json check
        run: "find bot karen common -name \"*.json\" | while read file; do { echo \"Checking file: $file\"; jq . $file -c > /dev/null; }; done"

      - name: text check
        run: poetry run check_text


name: CI

on:
  push:
    branches: ["master"]
  pull_request:
    branches: ["master"]

jobs:
  tox:
    runs-on: ubuntu-20.04 # bump to -latest or -22.04 once we drop py36
    strategy:
      max-parallel: 5
      matrix:
        python-version:
        - "3.6"
        - "3.7"
        - "3.8"
        - "3.9"
        - "3.10"
        - "3.11"
        - "pypy3.9"

    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install tox
      run: |
        python -m pip install --upgrade pip setuptools
        pip install --upgrade tox tox-gh-actions
    - name: Install h2spec
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        .github/workflows/install_h2spec.sh
    - name: Initialize tox envs
      run: |
        tox --parallel auto --notest
    - name: Test with tox
      run: |
        tox --parallel 0
    - uses: codecov/codecov-action@v1
      with:
        file: ./coverage.xml


Greetings

name: Greetings

on: [pull_request, issues]

# cancel the current workflow if another commit was pushed on the same PR or reference
# uses the GitHub workflow name to avoid collision with other workflows running on the same PR/reference
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  greeting:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/first-interaction@v1
      continue-on-error: true
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}
        issue-message: >
          Thanks for submitting an issue.

          Make sure you have checked through existing/resolved issues to avoid duplicates.
          Also, make sure you provide enough details for us to be able to replicate and understand the problem.
        pr-message: >
          Thanks for submitting a PR.

          Make sure that you have added tests to validates new features or bugfixes.
          Also, ensure that existing test suites are still working with the change using the commit test statuses.


Issue Labeler

# reference: https://github.com/github/issue-labeler

name: "Issue Labeler"
on:
  issues:
    types: [opened, edited]

# cancel the current workflow if another commit was pushed on the same PR or reference
# uses the GitHub workflow name to avoid collision with other workflows running on the same PR/reference
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

permissions:
  issues: write
  contents: read

jobs:
  triage:
    runs-on: ubuntu-latest
    steps:
    - uses: github/issue-labeler@v3.2
      with:
        repo-token: "${{ secrets.GITHUB_TOKEN }}"
        configuration-path: .github/labeler-words.yml
        enable-versioned-regex: 0
        include-title: 1
        include-body: 1
        sync-labels: 0


Pull Request Labeler

# This workflow will triage pull requests and apply a label based on the
# paths that are modified in the pull request.
#
# To use this workflow, you will need to set up a .github/labeler.yml
# file with configuration.  For more information, see:
# https://github.com/actions/labeler/blob/master/README.md

name: Pull Request Labeler
on:
  pull_request:
    types: [opened, edited, synchronize, reopened]
  schedule:
    - cron: '0 */12 * * *'

# cancel the current workflow if another commit was pushed on the same PR or reference
# uses the GitHub workflow name to avoid collision with other workflows running on the same PR/reference
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  original-labeler:
    # reference: https://github.com/actions/labeler
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v2
      with:
        configuration-path: .github/labeler-files.yml
        repo-token: "${{ secrets.GITHUB_TOKEN }}"
  extended-labeler:
    # reference: https://github.com/ilyam8/periodic-pr-labeler
    runs-on: ubuntu-latest
    steps:
      - uses: docker://docker.io/ilyam8/periodic-pr-labeler:latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          LABEL_MAPPINGS_FILE: .github/labeler-files.yml
  wip:
    # reference: https://github.com/wip/action
    # mark PRs with following keywords in the title: wip, work in progress, :construction:
    # blocks merge of these branches using requirement:
    #   [Settings > Branch > master > Protect matching branches > Require > check status with "WIP (action)"]
    if: ${{ github.event_name == 'pull_request' }}  # WIP only works during PRs
    runs-on: ubuntu-latest
    steps:
      - uses: wip/action@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Secret Scan

# look for secrets pushed by mistake

# NOTE: To fix problematic commits that got references to detected secrets, execute the following:
# 1. Assuming the branch is built on top of master for a PR
#     >> git rebase -i master
# 2. Then, replace "pick" by "squash" for matched problematic commits
#	 If this didn't work, more advanced edit of history commits needs to be applied.
#	 Please refer to git interactive rebase documentation to do so.
# 3. Finally re-run secrets analysis to validate that problems where fixed

name: Secret Scan
on:
  - pull_request
  - push

# cancel the current workflow if another commit was pushed on the same PR or reference
# uses the GitHub workflow name to avoid collision with other workflows running on the same PR/reference
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  #trufflehog:
  #  runs-on: ubuntu-latest
  #  steps:
  #  - uses: actions/checkout@master
  #  - name: trufflehog-actions-scan
  #    uses: edplato/trufflehog-actions-scan@master
    #- uses: max/secret-scan@master
    #  with:
    #    repo-token: "${{ secrets.GITHUB_TOKEN }}"

  # ref: https://github.com/svdarren/secrets-workflow/blob/9633bc1195a1ca1d4d70415aa4eff6cf55d706de/.github/workflows/secrets.yml
  gitleak:
    name: gitleaks
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: '0'
      - name: Install dependencies
        run: docker pull zricethezav/gitleaks
      #- run: |
      #    docker run --name=gitleaks --volume $GITHUB_WORKSPACE:/workspace/ \
      #    -v --exclude-forks --redact --threads=1 --branch=$GITHUB_REF --repo-path=/workspace/
      #- run: docker run --rm --name=gitleaks -v /tmp/:/code/ zricethezav/gitleaks -v --repo-path=/code/gitleaks
      # @todo command is failing
      #- run: gitleaks -v --exclude-forks --redact --threads=1 --branch=$GITHUB_REF --repo-path=$GITHUB_WORKSPACE

      # FIXME: revert to original repo when (if) they ever consider the fix
      #     https://github.com/eshork/gitleaks-action/pull/4
      #     https://github.com/eshork/gitleaks-action/issues/3
      #- uses: fmigneault/gitleaks-action@master
      #- uses: zricethezav/gitleaks-action@master
      - uses: gitleaks/gitleaks-action@v1.6.0  # see: https://github.com/gitleaks/gitleaks-action/issues/57
      #- uses: eshork/gitleaks-action@v1.0.0
      #- uses: CySeq/gitcret@v2
      #  env:
      #    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Tests

# run test suites

name: Tests
on:
  - pull_request
  - push
  - release
  - workflow_dispatch

# cancel the current workflow if another commit was pushed on the same PR or reference
# uses the GitHub workflow name to avoid collision with other workflows running on the same PR/reference
concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  # see: https://github.com/fkirc/skip-duplicate-actions
  skip_duplicate:
    continue-on-error: true
    runs-on: ubuntu-latest
    outputs:
      should_skip: ${{ steps.skip_duplicate.outputs.should_skip && ! contains(github.ref, 'refs/tags') }}
    steps:
      - id: skip_check
        uses: fkirc/skip-duplicate-actions@master
        with:
          concurrent_skipping: "same_content"
          skip_after_successful_duplicate: "true"
          do_not_skip: '["pull_request", "workflow_dispatch", "schedule", "release"]'

  # see: https://github.com/actions/setup-python
  tests:
    needs: skip_duplicate
    if: ${{ needs.skip_duplicate.outputs.should_skip != 'true' }}
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.allow-failure }}
    env:
      # override make command to install directly in active python
      CONDA_CMD: ""
      DOCKER_TEST_EXEC_ARGS: "-T"
    services:
      # Label used to access the service container
      mongodb:
        image: mongo:5.0  # DockerHub
        ports:
          - "27017:27017"
    strategy:
      matrix:
        os: [ubuntu-latest]
        python-version: ["3.8", "3.9", "3.10", "3.11"]
        allow-failure: [false]
        test-case: [test-unit-only, test-func-only]
        include:
          # experimental python
          - os: ubuntu-latest
            python-version: "3.12"
            allow-failure: true
            test-case: test-unit-only
          - os: ubuntu-latest
            python-version: "3.12"
            allow-failure: true
            test-case: test-func-only
          # linter tests
          - os: ubuntu-latest
            python-version: "3.10"
            allow-failure: false
            test-case: check-all
          # documentation build
          - os: ubuntu-latest
            python-version: "3.10"
            allow-failure: false
            test-case: docs
          # coverage test
          - os: ubuntu-latest
            python-version: "3.10"
            allow-failure: false
            test-case: test-coverage-only
          # smoke test of Docker image
          - os: ubuntu-latest
            python-version: "3.10"  # doesn't matter which one (in docker), but match default of repo
            allow-failure: false
            test-case: test-docker
          # EMS end-2-end Workflow tests
          - os: ubuntu-latest
            python-version: "3.10"
            allow-failure: true
            test-case: test-workflow-only
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: "0"
      - name: Setup Python
        # skip python setup if running with docker
        if: ${{ matrix.test-case != 'test-docker' }}
        uses: actions/setup-python@v5
        with:
          python-version: "${{ matrix.python-version }}"
          cache: 'pip'
      - name: Parse Python Version
        id: python-semver
        run: |
          echo "::set-output name=major:$(echo ${{ matrix.python-version }} | cut -d '.' -f 1)"
          echo "::set-output name=minor:$(echo ${{ matrix.python-version }} | cut -d '.' -f 2)"
      - uses: actions/cache@v3
        name: Check Proj Lib Pre-Built in Cache
        id: cache-proj
        with:
          # note: '22' is v8, '21' is v7
          path: /tmp/proj-8.2.1/install
          key: ${{ runner.os }}-python${{ matrix.python-version }}-proj
      - name: Install Dependencies
        # skip python setup if running with docker
        if: ${{ matrix.test-case != 'test-docker' }}
        # install package and dependencies directly,
        # skip sys/conda setup to use active python
        run: make install-sys install-pkg install-pip install-raw install-dev install-dev-npm
      - name: Display Packages
        # skip python setup if running with docker
        if: ${{ matrix.test-case != 'test-docker' }}
        run: |
          pip freeze
          npm list
          make version
      #- name: Setup Environment Variables
      #  uses: c-py/action-dotenv-to-setenv@v2
      #  with:
      #    env-file: ./ci/weaver.env
      - name: Display Environment Variables
        run: |
          hash -r
          env | sort
      - name: Run Tests
        run: make stop ${{ matrix.test-case }}
      - name: Upload coverage report
        uses: codecov/codecov-action@v2
        if: ${{ success() && matrix.test-case == 'test-coverage-only' }}
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          files: ./reports/coverage.xml
          fail_ci_if_error: true
          verbose: true

  deploy-docker:
    needs: tests
    if: ${{ success() && (contains(github.ref, 'refs/tags') || github.ref == 'refs/heads/master') }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: "0"
      - name: Get Tag Version
        id: version
        shell: bash
        run: |
          if [[ "${GITHUB_REF}" == "refs/heads/master" ]]; then
            echo "::set-output name=TAG_VERSION::latest"
          else
            echo "::set-output name=TAG_VERSION::${GITHUB_REF##*/}"
          fi
      - name: Build Docker
        run: |
          make DOCKER_REPO=pavics/weaver APP_VERSION=${{ steps.version.outputs.TAG_VERSION }} docker-info docker-build
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Push to DockerHub
        run: |
          make DOCKER_REPO=pavics/weaver APP_VERSION=${{ steps.version.outputs.TAG_VERSION }} docker-push


Docs

name: Docs

on:
  workflow_dispatch:
  push:
    branches: [main]
    paths:
      - "docs/**"
      - "README.md"
      - "pyproject.toml"

env:
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.5.1"

jobs:
  main:
    name: Build and deploy
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache poetry
        id: cache-poetry
        uses: actions/cache@v3
        with:
          path: ~/.local
          key: poetry-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}
      - name: Install poetry
        if: steps.cache-poetry.outputs.cache-hit != 'true'
        uses: snok/install-poetry@v1
        with:
          version: ${{ env.POETRY_VERSION }}
          virtualenvs-in-project: true
      - name: Cache venv
        id: cache-venv
        uses: actions/cache@v3
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}-${{ hashFiles('poetry.lock') }}
          restore-keys: |
            venv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}-
      - name: Install dependencies
        if: steps.cache-venv.outputs.cache-hit != 'true'
        run: poetry install -E image
      - name: Build and deploy documentation
        run: |
          git config --global user.name "github-actions"
          git config --global user.email "action@github.com"
          poetry run mudkip build --check --skip-broken-links --update-gh-pages --repository https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}


CI

name: CI

on:
  push:
    branches: [main]
    paths-ignore:
      - "docs/**"
  pull_request:
    branches: [main]
    paths-ignore:
      - "docs/**"

env:
  PYTHON_VERSION: "3.10"
  POETRY_VERSION: "1.5.1"

jobs:
  main:
    name: Test and release
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Cache poetry
        id: cache-poetry
        uses: actions/cache@v3
        with:
          path: ~/.local
          key: poetry-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}
      - name: Install poetry
        if: steps.cache-poetry.outputs.cache-hit != 'true'
        uses: snok/install-poetry@v1
        with:
          version: ${{ env.POETRY_VERSION }}
          virtualenvs-in-project: true
      - name: Cache venv
        id: cache-venv
        uses: actions/cache@v3
        with:
          path: .venv
          key: venv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}-${{ hashFiles('poetry.lock') }}
          restore-keys: |
            venv-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ env.POETRY_VERSION }}-
      - name: Install dependencies
        if: steps.cache-venv.outputs.cache-hit != 'true'
        run: poetry install -E image
      - name: Setup npm cache
        id: cache-npm
        uses: actions/cache@v3
        with:
          path: node_modules
          key: npm-${{ runner.os }}-${{ hashFiles('package-lock.json') }}
      - name: Install Pyright
        if: steps.cache-npm.outputs.cache-hit != 'true'
        run: npm install
      - name: Run tests
        run: poetry run pytest -v
      - name: Run type-checking
        run: npm run check
      - name: Check formatting
        run: poetry run black --check beet tests
      - name: Release
        if: |
          github.repository == 'mcbeet/beet'
          && github.event_name == 'push'
          && github.ref == 'refs/heads/main'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
        run: |
          git config --global user.name "github-actions"
          git config --global user.email "action@github.com"
          poetry run semantic-release publish -v DEBUG -D commit_author="github-actions <action@github.com>"


Run tests for new-ara-api

name: Run tests for new-ara-api
on:
  workflow_dispatch:
  push:
    branches:
      - master
      - develop
  pull_request:
  release:
    types: [created]
env:
  ECR: 666583083672.dkr.ecr.ap-northeast-2.amazonaws.com
  PROJECT_NAME: newara
  SECRET_KEY: ${{ secrets.SECRET_KEY }}
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  SSO_CLIENT_ID: ${{ secrets.SSO_CLIENT_ID }}
  SSO_SECRET_KEY: ${{ secrets.SSO_SECRET_KEY }}
  PORTAL_2FA_KEY: ${{ secrets.PORTAL_2FA_KEY }}
  FIREBASE_SERVICE_ACCOUNT_KEY_DEV: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_KEY_DEV }}
  FIREBASE_SERVICE_ACCOUNT_KEY_PROD: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_KEY_PROD }}
  AWS_REGION: ap-northeast-2

jobs:
  deploy:
    name: Run Tests
    runs-on: ubuntu-22.04

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

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{env.AWS_REGION}}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Install
        run: |
          chmod +x .github/workflows/generate-docker-tag.sh
          touch firebaseServiceAccountKey.json
          . .github/workflows/generate-docker-tag.sh
          echo "PUSH=$PUSH" >> $GITHUB_ENV
          echo "DOCKER_TAG=$DOCKER_TAG" >> $GITHUB_ENV
          echo "DJANGO_ENV=$DJANGO_ENV" >> $GITHUB_ENV
          docker pull $ECR/$PROJECT_NAME:$DJANGO_ENV || true
      - name: Build
        run: |
          docker build --build-arg AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID --build-arg AWS_SECRET_ACCESS_KEY=$(echo $AWS_SECRET_ACCESS_KEY) --cache-from $ECR/$PROJECT_NAME:$DJANGO_ENV  -t $PROJECT_NAME .

      - name: Run test
        run: |
          docker-compose -f docker-compose.test.yml run api test
          docker-compose -f docker-compose.test.yml down
      - if: env.PUSH == 'true'
        name: Push docker image
        run: |
          echo "Start docker image push"
          docker tag $PROJECT_NAME $ECR/$PROJECT_NAME:$DOCKER_TAG && docker push $ECR/$PROJECT_NAME:$DOCKER_TAG
          echo "Finish docker image push"


tests

name: tests

on:
  merge_group:
  push:
    branches-ignore:
    # temporary GH branches relating to merge queues (jaraco/skeleton#93)
    - gh-readonly-queue/**
    tags:
    # required if branches-ignore is supplied (jaraco/skeleton#103)
    - '**'
  pull_request:

permissions:
  contents: read

env:
  # Environment variable to support color support (jaraco/skeleton#66)
  FORCE_COLOR: 1

  # Suppress noisy pip warnings
  PIP_DISABLE_PIP_VERSION_CHECK: 'true'
  PIP_NO_PYTHON_VERSION_WARNING: 'true'
  PIP_NO_WARN_SCRIPT_LOCATION: 'true'

  # Ensure tests can sense settings about the environment
  TOX_OVERRIDE: >-
    testenv.pass_env+=GITHUB_*,FORCE_COLOR

jobs:
  test:
    strategy:
      # https://blog.jaraco.com/efficient-use-of-ci-resources/
      matrix:
        python:
        - "3.8"
        - "3.12"
        platform:
        - ubuntu-latest
        - macos-latest
        - windows-latest
        include:
        - python: "3.9"
          platform: ubuntu-latest
        - python: "3.10"
          platform: ubuntu-latest
        - python: "3.11"
          platform: ubuntu-latest
        - python: pypy3.10
          platform: ubuntu-latest
    runs-on: ${{ matrix.platform }}
    continue-on-error: ${{ matrix.python == '3.13' }}
    steps:
      - uses: actions/checkout@v4
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python }}
          allow-prereleases: true
      - name: Install tox
        run: python -m pip install tox
      - name: Run
        run: tox

  collateral:
    strategy:
      fail-fast: false
      matrix:
        job:
        - diffcov
        - docs
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: 3.x
      - name: Install tox
        run: python -m pip install tox
      - name: Eval ${{ matrix.job }}
        run: tox -e ${{ matrix.job }}

  check:  # This job does nothing and is only used for the branch protection
    if: always()

    needs:
    - test
    - collateral

    runs-on: ubuntu-latest

    steps:
    - name: Decide whether the needed jobs succeeded or failed
      uses: re-actors/alls-green@release/v1
      with:
        jobs: ${{ toJSON(needs) }}

  release:
    permissions:
      contents: write
    needs:
    - check
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: 3.x
      - name: Install tox
        run: python -m pip install tox
      - name: Run
        run: tox -e release
        env:
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


lint

name: lint

on:
  # Trigger the workflow on push or pull request,
  # but only for the main and develop branches
  push:
    branches:
      - main
      - develop
  pull_request:
    branches:
      - main
      - develop

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: psf/black@stable


test-suite

# This the main GridPath CI workflow
# It installs Cbc and Python dependencies, runs the GridPath test suite with coverage,
# and sends coverage results to coveralls

name: test-suite

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    - cron: "0 17 * * *"

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [ "3.9", "3.10", "3.11" ]

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v3
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install Cbc and check version
      run: |
        sudo apt-get install coinor-cbc
        sudo apt-get install -y apt-show-versions
        apt-show-versions coinor-cbc
    - name: Install Python dependencies
      run: |
        python -m pip install .[coverage] --upgrade pip
    - name: Test GridPath with coverage
      run: |
        coverage run -m unittest discover tests
    - name: Send coverage results to Coveralls
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        coveralls --service=github


Build RPM packages

---
name: Build RPM packages

on:
  # Triggers the workflow on push or pull request events but only for the master branch
  push:
    branches:
      - master
  pull_request:
    branches:
      - master

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  build_packages:
    strategy:
      matrix:
        build_type:
          - auto
          - manual
        version:
          - 9
          - 8
          - 7
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python environment
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install Python dependencies
        run: |
          pip install -r requirements.txt

      - name: Build packages
        run: make ${{ matrix.build_type }}${{ matrix.version }}

      - name: Cache built packages
        uses: actions/cache@v3
        id: restore-build
        with:
          path: _dist${{ matrix.version }}/*
          key: ${{ github.sha }}-${{ matrix.build_type }}${{ matrix.version }}

  publish_packages:
    needs: build_packages
    if: github.ref == 'refs/heads/master' && github.repository == 'lest/prometheus-rpm'
    strategy:
      matrix:
        version:
          - 9
          - 8
          - 7
    runs-on: ubuntu-20.04
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Ruby environment
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 2.7

      - name: Install PackageCloud CLI
        run: gem install package_cloud

      - name: Create GPG key secret
        if: env.RPM_GPG_KEY_SECRET != null
        run: openssl aes-256-cbc -k "${RPM_GPG_KEY_SECRET}" -in secret.asc.enc -out secret.asc -d -md md5
        env:
          RPM_GPG_KEY_SECRET: ${{ secrets.RPM_GPG_KEY_SECRET }}

      - name: Save GPG key passphrase
        if: env.RPM_GPG_KEY_PASSPHRASE != null
        run: echo "${RPM_GPG_KEY_PASSPHRASE}" > .passphrase
        env:
          RPM_GPG_KEY_PASSPHRASE: ${{ secrets.RPM_GPG_KEY_PASSPHRASE }}

      - name: Restore auto RPM package cache
        uses: actions/cache@v3
        with:
          path: _dist${{ matrix.version }}/*
          key: ${{ github.sha }}-auto${{ matrix.version }}

      - name: Restore manual RPM package cache
        uses: actions/cache@v3
        with:
          path: _dist${{ matrix.version }}/*
          key: ${{ github.sha }}-manual${{ matrix.version }}

      - name: Publish
        run: make publish${{ matrix.version }}
        env:
          PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}


Check new exporter releases

---
name: Check new exporter releases

on:
  schedule:
    - cron: "15 8,16 * * *"

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  check_new_releases:
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup python environment
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"

      - name: Install Python dependencies
        run: pip install ruamel.yaml PyGithub packaging

      - name: Run script to update auto package versions
        run: python update_templating_versions.py
        env:
          GH_TOKEN: ${{ secrets.GH_TOKEN }}


Lint Code Base

---
###########################
###########################
## Linter GitHub Actions ##
###########################
###########################
name: Lint Code Base

#
# Documentation:
# https://help.github.com/en/articles/workflow-syntax-for-github-actions
#

#############################
# Start the job on all push #
#############################
on:
  push:
  pull_request:
    branches: [master]

###############
# Set the Job #
###############
jobs:
  build:
    # Name the Job
    name: Lint Code Base
    # Set the agent to run on
    runs-on: ubuntu-latest

    ##################
    # Load all steps #
    ##################
    steps:
      ##########################
      # Checkout the code base #
      ##########################
      - name: Checkout Code
        uses: actions/checkout@v4
        with:
          # Full git history is needed to get a proper list of changed files within `super-linter`
          fetch-depth: 0

      ################################
      # Run Linter against code base #
      ################################
      - name: Lint Code Base
        uses: github/super-linter/slim@v4
        env:
          VALIDATE_ALL_CODEBASE: false
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VALIDATE_ANSIBLE: false
          VALIDATE_PYTHON_PYLINT: false


Quality Check

name: Quality Check

on: [pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3.1.0
    - name: Set up Python 3.8
      uses: actions/setup-python@v3
      with:
        python-version: 3.8
    - name: Install Python dependencies
      run: pip install -e .[quality]
    - name: Run Quality check
      run: make quality
    - name: Check if failure
      if: ${{ failure() }}
      run: |
        echo "Quality check failed. Please ensure the right dependency versions are installed with 'pip install -e .[quality]' and rerun 'make style; make quality;'" >> $GITHUB_STEP_SUMMARY


Run Tests

name: Run Tests

on:
  pull_request:
    paths:
      - "src/**"
      - "tests/**"
      - ".github/**"
      - "examples/**"
      - "setup.py"
    types: [opened, synchronize, reopened]

env:
  HF_HOME: ~/hf_cache
  TESTING_MOCKED_DATALOADERS: "1"
  IS_GITHUB_CI: "1"

jobs:
  run-tests:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        pytorch-version: [
          latest,
          minimum,
        ]
        test-kind: [
          test_prod,
          test_core,
          test_cli,
          test_big_modeling,
          test_deepspeed,
          test_fsdp,
          test_example_differences,
          test_checkpoint_step,
          test_checkpoint_epoch,
          test_rest
        ]
    steps:
    - uses: actions/checkout@v3.1.0
    - name: Set up python 3.8
      uses: actions/setup-python@v3
      with:
        python-version: 3.8

    - name: Install the library
      run: |
        if [[ ${{ matrix.test-kind }} = test_prod ]]; then pip install -e .[test_prod]; fi
        if [[ ${{ matrix.test-kind }} != test_prod ]]; then pip install -e .[testing,test_trackers]; fi
        if [[ ${{ matrix.test-kind }} = test_rest ]]; then pip uninstall comet_ml -y; fi
        if [[ ${{ matrix.test-kind }} = minimum ]]; then pip install torch==1.10.0; fi
        pip install pytest-reportlog tabulate setuptools

    - name: Show installed libraries
      run: |
        pip freeze

    - name: Run Tests
      env:
        PYTORCH_VERSION: ${{ matrix.pytorch-version }}
      run: |
        make ${{ matrix.test-kind }}

    - name: Generate Report
      if: always()
      run: |
        python utils/log_reports.py >> $GITHUB_STEP_SUMMARY


Build documentation

name: Build documentation

on:
  push:
    branches:
      - main
      - doc-builder*
      - v*-release

jobs:
   build:
    uses: huggingface/doc-builder/.github/workflows/build_main_documentation.yml@main
    with:
      commit_sha: ${{ github.sha }}
      package: accelerate
      custom_container: huggingface/transformers-doc-builder
    secrets:
      hf_token: ${{ secrets.HF_DOC_BUILD_PUSH }}


Build PR Documentation

name: Build PR Documentation

on:
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
  cancel-in-progress: true

jobs:
  build:
    uses: huggingface/doc-builder/.github/workflows/build_pr_documentation.yml@main
    with:
      commit_sha: ${{ github.event.pull_request.head.sha }}
      pr_number: ${{ github.event.number }}
      package: accelerate
      custom_container: huggingface/transformers-doc-builder


Stale Bot

name: Stale Bot

on:
  schedule:
    - cron: "0 15 * * *"
  workflow_dispatch:

jobs:
  close_stale_issues:
    name: Close Stale Issues
    if: github.repository == 'huggingface/accelerate'
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
    - uses: actions/checkout@v3.1.0

    - name: Setup Python
      uses: actions/setup-python@v3
      with:
        python-version: 3.8

    - name: Install requirements
      run: |
        pip install PyGithub
    - name: Close stale issues
      run: |
        python utils/stale.py