Release WaveDB

name: Release WaveDB

on:
  workflow_dispatch:
    inputs:
      version:
        description: "WaveDB Release Version (0.0.0)"
        required: true
      tag:
        description: "Wave Release Version (0.0.0)"
        required: true

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VERSION: ${{ github.event.inputs.version }}
  TAG: "v${{ github.event.inputs.tag }}"

jobs:
  release-windows:
    name: WaveDB Windows Release
    runs-on: windows-latest
    steps:
      - uses: actions/setup-go@v1
        with:
          go-version: "1.22.4"
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}
      - name: Build
        run: make release-db-windows
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          files: "wavedb-${{ env.VERSION }}-windows-amd64.tar.gz"
          tag_name: ${{ env.TAG }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  release-linux:
    name: WaveDB Linux Release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-go@v1
        with:
          go-version: "1.22.4"
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}
      - name: Build
        run: make release-db-linux
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          files: "wavedb-${{ env.VERSION }}-linux-amd64.tar.gz"
          tag_name: ${{ env.TAG }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  release-darwin:
    name: WaveDB Darwin Release
    runs-on: macos-12
    steps:
      - uses: actions/setup-go@v1
        with:
          go-version: "1.22.4"
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}
      - name: Build
        run: make release-db-darwin
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          files: "wavedb-${{ env.VERSION }}-darwin-amd64.tar.gz"
          tag_name: ${{ env.TAG }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Release Wave Nightly

name: Release Wave Nightly

on:
  workflow_dispatch:
  schedule:
    - cron: "0 0 * * *" # Schedule at midnight.

env:
  TAG: "nightly"

# Cancel a currently running workflow.
concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: true

# TODO: Use composite action to make the configuration more DRY.
jobs:
  check-last-commit:
    name: Check Last Commit
    runs-on: ubuntu-20.04
    outputs:
      yesterday-commit-count: ${{ steps.get-new-commits.outputs.YESTERDAY_COMMIT_COUNT }}
      nightly-dev-version: ${{ steps.get-dev-version.outputs.NIGHTLY_DEV_VERSION }}
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}
      - id: get-new-commits
        run: echo "YESTERDAY_COMMIT_COUNT=$(git log --oneline --since '24 hours ago' | wc -l)" >> $GITHUB_OUTPUT
      - id: get-dev-version
        run: echo "NIGHTLY_DEV_VERSION=$(awk -F"'" '/__version__/ {split($2,a,"."); a[2]++; print a[1] "." a[2] ".0.dev0"}' py/h2o_wave/h2o_wave/version.py)" >> $GITHUB_OUTPUT

  test-linux:
    name: Test Linux
    needs: check-last-commit
    if: needs.check-last-commit.outputs.yesterday-commit-count > 0
    strategy:
      matrix:
        os: [ubuntu-20.04, ubuntu-22.04]
        py: ["3.8", "3.9", "3.10", "3.11"]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.py }}

      - uses: actions/setup-go@v4
        with:
          go-version: "1.22.4"

      - uses: actions/setup-node@v3
        with:
          node-version-file: ".nvmrc"

      - name: Setup
        run: |
          make setup-ui build-ui
          make setup-py-tests
          make setup-vsc
          make setup-e2e
          make build-server
        env:
          NODE_OPTIONS: "--max-old-space-size=8192"

      - name: Test
        run: |
          make test-e2e-ci
          make test-py-ci
          make test-vsc-ci

  test-win:
    name: Test Windows
    needs: check-last-commit
    if: needs.check-last-commit.outputs.yesterday-commit-count > 0
    strategy:
      matrix:
        py: ["3.8", "3.9", "3.10", "3.11"]
    runs-on: windows-2022
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.py }}

      - uses: actions/setup-go@v4
        with:
          go-version: "1.22.4"

      - uses: actions/setup-node@v3
        with:
          node-version-file: ".nvmrc"

      - name: Setup
        run: .\setup.ps1
        shell: pwsh
        env:
          NODE_OPTIONS: "--max-old-space-size=8192"

      - name: Test
        run: .\test.ps1
        shell: pwsh

  test-macos:
    name: Test MacOS
    needs: check-last-commit
    if: needs.check-last-commit.outputs.yesterday-commit-count > 0
    strategy:
      matrix:
        py: ["3.8", "3.9", "3.10", "3.11"]
    runs-on: macos-12
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - name: Install docker
        run: |
          brew install qemu
          brew install docker
          colima start

      - uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.py }}

      - uses: actions/setup-go@v4
        with:
          go-version: "1.22.4"

      - uses: actions/setup-node@v3
        with:
          node-version-file: ".nvmrc"

      - name: Setup
        run: |
          make setup-ui build-ui
          make setup-py-tests
          make setup-vsc
          make setup-e2e
          make build-server
        env:
          NODE_OPTIONS: "--max-old-space-size=8192"

      - name: Test
        run: |
          make test-e2e-macos-ci
          make test-py-ci
          make test-vsc-ci
        env:
          KC_SLEEP: 45

  release:
    needs: [test-linux, test-win, test-macos, check-last-commit]
    name: Release Wave Nightly
    runs-on: ubuntu-20.04
    steps:
      - name: Set ENV vars
        run: |
          echo "VERSION=${{ needs.check-last-commit.outputs.nightly-dev-version }}" >> $GITHUB_ENV
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - uses: actions/setup-go@v4
        with:
          go-version: "1.22.4"

      - uses: actions/setup-node@v3
        with:
          node-version-file: ".nvmrc"

      - name: Setup
        run: make setup

      - uses: r-lib/actions/setup-r@v2
      - uses: r-lib/actions/setup-r-dependencies@v2
        with:
          working-directory: ./r

      # These unit tests are not OS-dependent, so no need to run them in the dedicated Test jobs.
      - name: Unit test
        run: |
          make test-ui-ci
          make test-intellij-ci

      - name: Build Release
        run: make release-nightly
        env:
          NODE_OPTIONS: "--max-old-space-size=8192"

      - name: Update tag
        run: git tag -f ${{ env.TAG }} && git push -f --tags

      - uses: actions/github-script@v5
        with:
          github-token: ${{ secrets.GIT_TOKEN }}
          script: |
            const tag = "${{ env.TAG }}";
            const { data: releases } = await github.rest.repos.listReleases({
              owner: context.repo.owner,
              repo: context.repo.repo
            });
            const release = releases.find(r => r.tag_name === tag);
            if (release) {
              await github.rest.repos.deleteRelease({
                owner: context.repo.owner,
                repo: context.repo.repo,
                release_id: release.id
              });
              console.log(`Deleted release ${tag}`);
            } else {
              console.log(`Release ${tag} not found`);
            }
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            build/wave-${{ env.VERSION }}-darwin-amd64.tar.gz
            build/wave-${{ env.VERSION }}-darwin-arm64.tar.gz
            build/wave-${{ env.VERSION }}-linux-amd64.tar.gz
            build/wave-${{ env.VERSION }}-windows-amd64.tar.gz
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-macosx_10_9_x86_64.whl
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-macosx_11_0_arm64.whl
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-macosx_12_0_arm64.whl
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-manylinux1_x86_64.whl
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-win_amd64.whl
            py/h2o_wave/dist/h2o_wave-${{ env.VERSION }}-py3-none-any.whl
            r/build/h2owave_nightly_R.tar.gz
          tag_name: ${{ env.TAG }}
          prerelease: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Publish Conda

name: Publish Conda

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release Version'
        required: true

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VERSION: "${{ github.event.inputs.version }}"

jobs:
  release:
    name: Publish Conda
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - name: Publish to Conda
        uses: marek-mihok/publish_conda_package_action@v1.0.1
        with:
          CondaDir: 'py/h2o_wave/conda'
          Platforms: 'noarch'
          CondaUsername: ${{ secrets.CONDA_USERNAME }}
          CondaPassword: ${{ secrets.CONDA_PASSWORD }}
        env:
          # VERSION clashes with conda build. Use PKG_VERSION instead.
          PKG_VERSION: ${{ env.VERSION }}


Publish Wave University

name: Publish Wave University

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release Version'
        required: true

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VERSION: "${{ github.event.inputs.version }}"

jobs:
  publish:
    name: Publish Wave University
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - name: Build university
        run:  make publish-university

      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@master
        with:
          packages_dir: university/dist
          password: ${{ secrets.PYPI_UNIVERSITY_TOKEN }}

  create-bundle:
    name: Create Wave Bundle
    runs-on: ubuntu-latest

    outputs:
      build-version: ${{ env.VERSION }}

    steps:
      - uses: actions/checkout@v3

      - name: Download H2O CLI
        working-directory: ./university
        run: mkdir -p .bin && curl -o .bin/h2o https://h2oai-cloud-release.s3.amazonaws.com/releases/ai/h2o/h2o-cloud/latest/cli/linux-amd64/h2o

      - name: Change permissions
        working-directory: ./university
        run: chmod +x .bin/h2o

      - name: Set version
        working-directory: ./university
        run: sed -i -r -e "s/\{\{VERSION\}\}/${{ env.VERSION }}/g" app.toml

      - name: Get App Version
        id: get-build-version
        run: |
          echo "VERSION=${{ env.VERSION }}" >> "$GITHUB_OUTPUT"

      - name: Make air-gapped bundle
        working-directory: ./university
        run: |
          .bin/h2o bundle \
            --docker-base-image 524466471676.dkr.ecr.us-east-1.amazonaws.com/q8s/launcher:v0.31.0-310 \
            --docker-use-buildkit \
            --generate-helm-charts \
            --helm-chart-version ${{ env.VERSION }} \
            --helm-chart-name university \
            --helm-app-bundle-image-repo 524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/university-bundle \
            --helm-app-runtime-image-repo 524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/university \
            --generate-dockerfile

      - uses: actions/upload-artifact@v3
        with:
          name: wave-bundle
          path: |
            ./university/*.Dockerfile
            ./university/*.wave

      - uses: actions/upload-artifact@v3
        with:
          name: wave-bundle-helm
          path: university/helm/

  build-and-publish:
    needs: create-bundle
    permissions:
      id-token: write # This is required for requesting the JWT
      contents: read # This is required for actions/checkout

    uses: ./.github/workflows/wave-bundle-docker-build-publish.yaml
    with:
      build-version: ${{ needs.create-bundle.outputs.build-version }}
      bundle-artifact: wave-bundle
      wave-app-name: university


Publish Lightwave

name: Publish Lightwave

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release Version'
        required: true

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  VERSION: "${{ github.event.inputs.version }}"

jobs:
  publish:
    name: Publish Lightwave
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'

      - name: Build lightwave
        run:  make publish-lightwave
        env:
          NODE_OPTIONS: '--max-old-space-size=8192'

      - name: Publish to PyPI - lightwave
        uses: pypa/gh-action-pypi-publish@master
        with:
          packages_dir: py/h2o_lightwave/dist
          password: ${{ secrets.PYPI_LIGTHWAVE_TOKEN }}

      - name: Publish to PyPI - lightwave_web
        uses: pypa/gh-action-pypi-publish@master
        with:
          packages_dir: py/h2o_lightwave_web/dist
          password: ${{ secrets.PYPI_LIGTHWAVE_WEB_TOKEN }}


Release Wave PyCharm plugin

name: Release Wave PyCharm plugin

on:
  release:
      types: [published]
  workflow_dispatch:

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
  publish:
    name: Release Wave PyCharm plugin
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - name: Setup Java
        uses: actions/setup-java@v3
        with:
          distribution: zulu
          java-version: 11
          cache: gradle

      - name: Publish
        run: make publish-pycharm
        env:
          JETBRAINS_PUBLISH_TOKEN: ${{ secrets.JETBRAINS_PUBLISH_TOKEN }}


Release Wave VSCode extension

name: Release Wave VSCode extension

on:
  release:
      types: [published]
  workflow_dispatch:

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

jobs:
  publish:
    name: Release Wave VSCode extension
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v2
        with:
          token: ${{ secrets.GIT_TOKEN }}

      - uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'

      - name: Setup
        run: cd tools/vscode-extension && make setup

      - name: Publish VSCode extension
        run: make publish-vsc-extension
        env:
          VSCE_PAT: ${{ secrets.VSCE_PAT }}


name: Build and Publish Docker image from generated Dockerfile

on:
  workflow_call:
    inputs:
      build-version:
        type: string
        description: The version of the application/image to be pushed
        required: true
      bundle-artifact:
        type: string
        description: The name of the artifact containing the generated Dockerfiles and the wave bundle
        required: true
      working-directory:
        type: string
        description: Path to the working directory, where docker build will be executed
        default: .
      wave-app-name:
        type: string
        description: The name of the wave app
        required: true

jobs:
  docker:
    name: Build and Publish App Docker Image
    runs-on: ubuntu-latest
    permissions:
      id-token: write # This is required for requesting the JWT
      contents: read # This is required for actions/checkout

    steps:
      - uses: actions/checkout@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Download Wave bundle and Dockerfiles
        uses: actions/download-artifact@v3
        with:
          name: ${{ inputs.bundle-artifact }}
          path: ./

      - name: Rename Dockerfiles
        run: |
          mv ./*bundle.Dockerfile ./generated.bundle.Dockerfile
          mv ./*runtime.Dockerfile ./generated.runtime.Dockerfile

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::524466471676:role/workflows-library-wave-bundling-github-actions
          role-session-name: GitHub_to_AWS_via_FederatedOIDC
          aws-region: us-east-1

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

      - name: "Ensure ECR Repository for the bundle"
        # Tries to describe the repository and if it fails, creates it
        run: |
          aws ecr describe-repositories \
            --repository-names h2oai/${{ inputs.wave-app-name }}-bundle 2>/dev/null ||
          aws ecr create-repository \
            --repository-name h2oai/${{ inputs.wave-app-name }}-bundle \
            --image-tag-mutability IMMUTABLE \
            --tag \
              Key=GithubRepo,Value=github.com/h2oai/${{ inputs.wave-app-name }} \
              Key=ManagedBy,Value=GitHubActions \
              Key=CreatedByWorkflow,Value=${{ github.workflow_ref }}

      - name: "Ensure ECR Repository for the runtime"
        # Tries to describe the repository and if it fails, creates it
        run: |
          aws ecr describe-repositories \
            --repository-names h2oai/${{ inputs.wave-app-name }} 2>/dev/null ||
          aws ecr create-repository \
            --repository-name h2oai/${{ inputs.wave-app-name }} \
            --image-tag-mutability IMMUTABLE \
            --tag \
              Key=GithubRepo,Value=github.com/h2oai/${{ inputs.wave-app-name }} \
              Key=ManagedBy,Value=GitHubActions \
              Key=CreatedByWorkflow,Value=${{ github.workflow_ref }}

      - name: Build and Export Bundle Image
        uses: docker/build-push-action@v4
        id: bundle-build
        with:
          push: true
          context: ${{ inputs.working-directory }}
          file: ./generated.bundle.Dockerfile
          platforms: linux/amd64
          provenance: false
          tags: |
            524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/${{ inputs.wave-app-name }}-bundle:${{ inputs.build-version }}

      - name: Build and Export Runtime Image
        uses: docker/build-push-action@v4
        id: runtime-build
        with:
          push: true
          context: ${{ inputs.working-directory }}
          file: ./generated.runtime.Dockerfile
          platforms: linux/amd64
          provenance: false
          tags: |
            524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/${{ inputs.wave-app-name }}:${{ inputs.build-version }}

      - name: Published Images Summary
        run: |
          echo "#### Image Tags" >> $GITHUB_STEP_SUMMARY
          echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
          echo "docker image push 524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/${{ inputs.wave-app-name }}-bundle:${{ inputs.build-version }}" >> $GITHUB_STEP_SUMMARY
          echo "docker image push 524466471676.dkr.ecr.us-east-1.amazonaws.com/h2oai/${{ inputs.wave-app-name }}:${{ inputs.build-version }}" >> $GITHUB_STEP_SUMMARY
          echo "\`\`\`" >> $GITHUB_STEP_SUMMARY


on:
  issues:
    types: [opened]

jobs:
  thank-user:
    runs-on: ubuntu-20.04
    permissions:
      issues: write
    name: Say thanks for the Issue
    steps:
      - name: comment on the issue
        uses: hasura/comment-progress@v2.3.0
        with:
          github-token: ${{ secrets.CLI_BOT }}
          repository: 'Azure/azure-cli'
          number: ${{ github.event.issue.number }}
          id: thank-you-comment
          message: 'Thank you for opening this issue, we will look into it.'


on:
  pull_request_target:
    types: [opened]
    branches:
      - dev
      - release

permissions:
  pull-requests: write

jobs:
  thank-user:
    runs-on: ubuntu-20.04
    name: Say thanks for the PR
    steps:
      - name: get message
        env:
          TITLE: ${{ github.event.pull_request.title }}
        run: |
          message=$(echo "$TITLE" | grep -oP '[{\[][^}\]]+[}\]]' | sed 's/{\|}\|\[\|\]//g')
          echo "message=$message" >> $GITHUB_ENV
          if [ -z $message ]; then
              echo "message=$(echo 'Thank you for your contribution! We will review the pull request and get back to you soon.')" >> $GITHUB_ENV
          fi
      - name: comment on the pull request
        uses: mshick/add-pr-comment@v2
        with:
          repo-token: ${{ secrets.CLI_BOT }}
          message: "${{ env.message }}"


Block PR merging on blocled labels

name: Block PR merging on blocled labels

on:
  pull_request_target:
    types: [labeled, unlabeled]
    branches:
      - dev
      - release

jobs:
  block-merge:
    runs-on: ubuntu-latest
    steps:
      - name: Check blocked labels
        uses: actions/github-script@v7
        with:
          script: |
            const labels = context.payload.pull_request.labels.map(label => label.name);
            const blockedLabels = ["do-not-merge", "needs-author-feedback"];

            if (labels.some(label => blockedLabels.includes(label))) {
              console.log(`It is not allowed to merge a PR with any blocked labels: ${blockedLabels}`);
              process.exit(1); // Exit with a non-zero status code to block merge
            } else {
              console.log("It is allowed to merge the PR.");
            }


Nikola CI

name: Nikola CI
on:
  # Run on all pushes to master (including merge of PR)
  push:
    branches: master
  # Run on all changes in pull requests
  pull_request:
  # Run every Saturday at 17:10 UTC to ensure stability (dependency changes not breaking things)
  schedule:
    - cron: '10 17 * * 6'

jobs:
  nikola:
    name: Nikola tests (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.8', '3.9', '3.10', '3.11', '3.12']
        image:
          - ubuntu-latest
        include:
          - python: '3.12'
            image: macos-latest
          - python: '3.12'
            image: windows-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Upgrade packaging stack
        run: |
          python -m pip install --upgrade-strategy eager -U pip setuptools wheel
      - name: Install test requirements
        run: |
          python -m pip install --upgrade-strategy eager -Ur requirements-tests.txt
      - name: Install Nikola
        run: |
          python -m pip install .
      - name: Run tests
        run: |
          py.test tests/
      - name: Run nikola
        run: |
          nikola
      - name: Run nikola help
        run: |
          nikola help

  baseline:
    name: Baseline testing (Python ${{ matrix.python }} on ${{ matrix.image }})
    strategy:
      fail-fast: false
      matrix:
        python: ['3.12']
        image:
          - ubuntu-latest
    runs-on: '${{ matrix.image }}'
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Upgrade packaging stack
        run: |
          python -m pip install --upgrade-strategy eager -U pip setuptools wheel
      - name: Install extra requirements
        run: |
          python -m pip install --upgrade-strategy eager -Ur requirements-extras.txt freezegun
      - name: Install Nikola
        run: |
          python -m pip install .
      - name: Compare to baseline
        run: |
          scripts/baseline.sh check

  flake8:
    name: Linting (flake8, pydocstyle)
    strategy:
      matrix:
        python:
          - '3.12'
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Upgrade packaging stack
        run: |
          python -m pip install --upgrade-strategy eager -U pip setuptools wheel
      - name: Install requirements
        run: |
          python -m pip install flake8 pydocstyle
      - name: Run flake8
        run: |
          flake8 nikola/ tests/
      - name: Run pydocstyle
        run: |
          pydocstyle --count --match-dir='(?!^\\.)(?!data).*' nikola/

  basereq:
    name: Build demo site with base requirements
    strategy:
      matrix:
        python:
          - '3.11'
          - '3.12'
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '${{ matrix.python }}'
      - name: Upgrade packaging stack
        run: |
          python -m pip install --upgrade-strategy eager -U pip setuptools wheel
      - name: Install requirements
        run: |
          python -m pip install --upgrade-strategy eager -Ur requirements.txt
      - name: Install Nikola
        run: |
          python -m pip install .
      - name: Run help
        run: |
          nikola help
        working-directory: /
      - name: Run init
        run: |
          nikola init -qd nsite
        working-directory: /tmp/
      - name: Run build
        run: |
          nikola build
        working-directory: /tmp/nsite


Captum Lint

name: Captum Lint

on:
  pull_request:
  push:
    branches:
      - master

  workflow_dispatch:

jobs:
  tests:
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.12xlarge
      docker-image: cimg/python:3.11
      repository: pytorch/captum
      script: |
        sudo chmod -R 777 .
        ./scripts/install_via_pip.sh
        ufmt check .
        flake8
        sphinx-build -WT --keep-going sphinx/source sphinx/build


Unit-tests for Conda install

name: Unit-tests for Conda install

on:
  pull_request:
  push:
    branches:
      - master

  workflow_dispatch:

env:
  CHANNEL: "nightly"

jobs:
  tests:
    strategy:
      matrix:
        python_version: ["3.8", "3.9", "3.10", "3.11"]
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.12xlarge
      repository: pytorch/captum
      script: |
        # Set up Environment Variables
        export PYTHON_VERSION="${{ matrix.python_version }}"

        # Create Conda Env
        conda create -yp ci_env python="${PYTHON_VERSION}"
        conda activate /pytorch/captum/ci_env
        ./scripts/install_via_conda.sh -n

        # Run Tests
        python3 -m pytest -ra --cov=. --cov-report term-missing


name: Unit-tests for Pip install with mypy type checks

on:
  pull_request:
  push:
    branches:
      - master

  workflow_dispatch:

jobs:
  tests:
    strategy:
      matrix:
        pytorch_args: ["", "-n"]
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.12xlarge
      docker-image: cimg/python:3.11
      repository: pytorch/captum
      script: |
        sudo chmod -R 777 .
        ./scripts/install_via_pip.sh ${{ matrix.pytorch_args }}
        ./scripts/run_mypy.sh
        # Run Tests
        python3 -m pytest -ra --cov=. --cov-report term-missing


Unit-tests for Pip install

name: Unit-tests for Pip install

on:
  pull_request:
  push:
    branches:
      - master

  workflow_dispatch:

jobs:
  tests:
    strategy:
      matrix:
        pytorch_args: ["-v 1.10", "-v 1.11", "-v 1.12", "-v 1.13", "-v 2.0.0", "-v 2.1.0", "-v 2.2.0", "-v 2.3.0"]
        docker_img: ["cimg/python:3.8", "cimg/python:3.9", "cimg/python:3.10", "cimg/python:3.11"]
        exclude:
          - pytorch_args: "-v 1.10"
            docker_img: "cimg/python:3.10"
          - pytorch_args: "-v 1.10"
            docker_img: "cimg/python:3.11"
          - pytorch_args: "-v 1.11"
            docker_img: "cimg/python:3.11"
          - pytorch_args: "-v 1.12"
            docker_img: "cimg/python:3.11"
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.12xlarge
      docker-image: ${{ matrix.docker_img }}
      repository: pytorch/captum
      script: |
        sudo chmod -R 777 .
        ./scripts/install_via_pip.sh ${{ matrix.pytorch_args }}
        # Run Tests
        python3 -m pytest -ra --cov=. --cov-report term-missing


name: Unit-tests for Pip install

on:
  pull_request:
  push:
    branches:
      - master

  workflow_dispatch:

jobs:
  tests:
    strategy:
      matrix:
        cuda_arch_version: ["12.1"]
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.4xlarge.nvidia.gpu
      repository: pytorch/captum
      gpu-arch-type: cuda
      gpu-arch-version: ${{ matrix.cuda_arch_version }}
      script: |
        python3 -m pip install --upgrade pip --progress-bar off
        python3 -m pip install -e .[dev] --progress-bar off

        # Build package
        python3 -m pip install build --progress-bar off
        python3 -m build

        # Run Tests
        python3 -m pytest -ra --cov=. --cov-report term-missing


Test deployment

name: Test deployment

on:
  pull_request:
    # Review gh actions docs if you want to further define triggers, paths, etc
    # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on

jobs:
  test-deploy:
    name: Test deployment
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup / build docs
        run: |
          sudo chmod -R 777 .
          python3 -m pip install --upgrade pip --progress-bar off
          python3 -m pip install -e .[dev] --progress-bar off
          python3 -m pip install beautifulsoup4 ipython jinja2==3.0.0 nbconvert==5.6.1 ipython_genutils --progress-bar off
          ./scripts/build_docs.sh -b
          cd website


Deploy to GitHub Pages

name: Deploy to GitHub Pages

on:
  push:
    branches:
      - master
    # Review gh actions docs if you want to further define triggers, paths, etc
    # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on

permissions:
  contents: write
  pages: write

jobs:
  deploy:
    name: Deploy to GitHub Pages
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup / build docs
        run: |
          sudo chmod -R 777 .
          python3 -m pip install --upgrade pip --progress-bar off
          python3 -m pip install -e .[dev] --progress-bar off
          python3 -m pip install beautifulsoup4 ipython jinja2==3.0.0 nbconvert==5.6.1 ipython_genutils --progress-bar off
          ./scripts/build_docs.sh -b
          cd website

      # Popular action to deploy to GitHub Pages:
      # Docs: https://github.com/peaceiris/actions-gh-pages#%EF%B8%8F-docusaurus
      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          # Build output to publish to the `gh-pages` branch:
          publish_dir: ./website/build/captum/


Python package and test

name: Python package and test

on:
  push:
  pull_request:

jobs:
  checkout-test:
    name: Checkout and test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: ["macos-latest", "ubuntu-latest"]
      fail-fast: false
    defaults:
      run:
        shell: bash -l {0}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      - name: Create python 3.11 conda env
        uses: conda-incubator/setup-miniconda@v3
        with:
          python-version: 3.11
          mamba-version: "*"
          activate-environment: donkey
          auto-activate-base: false
          channels: default, conda-forge, pytorch
          channel-priority: true
      - name: Conda info and list
        run: |
          conda info
          conda list
      - name: Install donkey
        run: |
          pip install -e .[pc,dev]
          pip list
      - name: Run tests
        run: pytest


Super-Linter

name: Super-Linter

# Run this workflow every time a new commit pushed to your repository
on: [push, pull_request]

jobs:
  # Set the job key. The key is displayed as the job name
  # when a job name is not provided
  super-lint:
    # Name the Job
    name: Lint code base
    # Set the type of machine to run on
    runs-on: ubuntu-latest
    # Don't flag failure
    continue-on-error: true
    steps:
      # Checks out a copy of your repository on the ubuntu-latest machine
      - name: Checkout code
        uses: actions/checkout@v2

      # Runs the Super-Linter action
      - name: Run Super-Linter
        uses: github/super-linter@v4
        env:
          DEFAULT_BRANCH: master
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          FILTER_REGEX_EXCLUDE: .*.css|.*.js
          DISABLE_ERRORS: true


Python package

name: Python package

on: [pull_request]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11"]
        django-version: ["32","4"]
    steps:
    - uses: actions/checkout@v3

    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}

    - uses: actions/cache@v2
      with:
        path: ~/.cache/pip
        key: ${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-testing.txt')}}-${{ hashFiles('tox.ini') }}-${{ matrix.python-version }}-${{ matrix.django-version }}

    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt -r requirements-testing.txt -c constraints-Django${{ matrix.django-version }}.txt

    - name: Lint with ruff
      run: |
        pip install ruff
        ruff helpdesk

    - name: Test with pytest
      run: |
        pip install pytest
        cd ${GITHUB_WORKSPACE} && python quicktest.py
      env:
        DJANGO_SETTINGS_MODULE: helpdesk.settings


name: Publish ${package_name} to PyPI and ReadTheDocs

on:
  push:
    tags:
      - "v*"
jobs:
  build-n-publish:
    name: Build and publish to PyPI
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source
        uses: actions/checkout@v4
        with:
          ref: ${{ github.ref_name }}

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: "3.x"

      - name: Build source and wheel distributions
        run: |
          python -m pip install --upgrade build twine
          python -m build
          twine check --strict dist/*
      - name: Publish distribution to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          user: __token__
          password: ${{ secrets.PYPI_API_TOKEN }}


🆙 Release file check

name: 🆙 Release file check

on:
  pull_request_target:
    types: [synchronize, reopened, opened, ready_for_review]
    branches:
      - main
    paths:
      - "strawberry/**"
      - "pyproject.toml"

jobs:
  get-contributor-info:
    name: Get PR info
    runs-on: ubuntu-latest

    outputs:
      contributor-name: ${{ steps.get-info.outputs.contributor-name }}
      contributor-username: ${{ steps.get-info.outputs.contributor-username }}
      contributor-twitter-username: ${{ steps.get-info.outputs.contributor-twitter-username }}

    steps:
      - name: Get PR info
        id: get-info
        uses: strawberry-graphql/get-pr-info-action@v6
      - run: echo "${{ steps.get-info.outputs.contributor-twitter-username }}"

  skip-if-bot:
    name: Set skip if PR is from a bot
    runs-on: ubuntu-latest
    needs: get-contributor-info

    outputs:
      skip: ${{ steps.skip.outputs.skip }}

    steps:
      - name: Set skip to true if contributor is a bot
        id: skip
        shell: python
        run: |
          bots = [
             "dependabot-preview[bot]",
             "dependabot-preview",
             "dependabot",
             "dependabot[bot]",
           ]

          username = "${{ needs.get-contributor-info.outputs.contributor-username }}"

          if username in bots:
            print(f"Skipping {username} because it is a bot")
            print("::set-output name=skip::true")
          else:
            print("::set-output name=skip::false")

  release-file-check:
    name: Release check
    runs-on: ubuntu-latest
    needs: skip-if-bot
    if: needs.skip-if-bot.outputs.skip == 'false'

    outputs:
      changelog: ${{ steps.release-check.outputs.changelog }}
      status: ${{ steps.release-check.outputs.release_status }}
      change_type: ${{ steps.release-check.outputs.change_type }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v2
        with:
          ref: "refs/pull/${{ github.event.number }}/merge"

      - name: Release file check
        uses: ./.github/release-check-action
        id: release-check
        if: github.event.pull_request.draft == false

  read-tweet-md:
    name: Read TWEET.md
    runs-on: ubuntu-latest
    needs: [get-contributor-info, release-file-check]

    outputs:
      tweet: ${{ steps.extract.outputs.tweet }}

    steps:
      - uses: actions/checkout@v2
        with:
          ref: "refs/pull/${{ github.event.number }}/merge"
      - name: Extract tweet message and changelog
        id: extract
        uses: strawberry-graphql/tweet-actions/read-tweet@v6
        with:
          changelog: ${{ needs.release-file-check.outputs.changelog }}
          version: "(next)"
          contributor_name: ${{ needs.get-contributor-info.outputs.contributor-name }}
          contributor_twitter_username: ${{ needs.get-contributor-info.outputs.contributor-twitter-username }}

  validate-tweet:
    runs-on: ubuntu-latest
    needs: read-tweet-md
    if: ${{ needs.read-tweet-md.outputs.tweet != '' }}
    steps:
      - name: Validate tweet
        uses: strawberry-graphql/tweet-actions/validate-tweet@v6
        with:
          tweet: ${{ needs.read-tweet-md.outputs.tweet }}

  send-comment:
    runs-on: ubuntu-latest
    needs: [release-file-check, read-tweet-md]
    if: github.event.pull_request.draft == false

    steps:
      - uses: actions/checkout@v2
      - name: Send comment
        uses: ./.github/bot-action
        env:
          BOT_API_URL: ${{ secrets.BOT_API_URL }}
          API_SECRET: ${{ secrets.API_SECRET }}
        with:
          pr_number: ${{ github.event.number }}
          status: ${{ needs.release-file-check.outputs.status }}
          change_type: ${{ needs.release-file-check.outputs.change_type }}
          changelog_base64: ${{ needs.release-file-check.outputs.changelog }}
          tweet: ${{ needs.read-tweet-md.outputs.tweet }}

  fail-if-status-is-not-ok:
    runs-on: ubuntu-latest
    needs: [release-file-check, send-comment]

    steps:
      - name: Fail if status is not ok
        if: ${{ needs.release-file-check.outputs.status != 'OK' }}
        run: exit 1


🔂 Unit tests

name: 🔂 Unit tests

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

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    paths:
      - "strawberry/**"
      - "tests/**"
      - "pyproject.toml"
      - "poetry.lock"
      - ".github/workflows/test.yml"

jobs:
  generate-jobs-tests:
    name: 💻 Generate test matrix
    runs-on: ubuntu-latest
    outputs:
      sessions: ${{ steps.set-matrix.outputs.sessions }}
    steps:
      - uses: actions/checkout@v4
      - run: pip install poetry nox nox-poetry
      - id: set-matrix
        shell: bash
        run: |
          echo sessions=$(
            nox --json -t tests -l |
            jq 'map(
              {
                session,
                name: "\( .name ) on \( .python )\( if .call_spec != {} then " (\(.call_spec | to_entries | map("\(.key)=\(.value)") | join(", ")))" else "" end )"
              }
            )'
          ) | tee --append $GITHUB_OUTPUT

  unit-tests:
    name: 🔬 ${{ matrix.session.name }}
    needs: [generate-jobs-tests]
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        session: ${{ fromJson(needs.generate-jobs-tests.outputs.sessions) }}

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: |
            3.8
            3.9
            3.10
            3.11
            3.12

      - name: Pip and nox cache
        id: cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.cache
            ~/.nox
            .nox
          key:
            ${{ runner.os }}-nox-${{ matrix.session.session }}-${{
            hashFiles('**/poetry.lock') }}-${{ hashFiles('**/noxfile.py') }}-3

      - run: pip install poetry nox nox-poetry
      - run: nox -r -t tests -s "${{ matrix.session.session }}"
      - uses: actions/upload-artifact@v4
        if: ${{ always() }}
        with:
          name: coverage-${{ matrix.session.session }}
          path: coverage.xml

  upload-coverage:
    name: 🆙 Upload Coverage
    needs: [unit-tests]
    runs-on: ubuntu-latest

    steps:
      - uses: actions/download-artifact@v4
      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true
          verbose: true

  benchmarks:
    name: 📈 Benchmarks
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false

    steps:
      - uses: actions/checkout@v4
      - run: pipx install poetry
      - uses: actions/setup-python@v5
        id: setup-python
        with:
          python-version: "3.12"
          architecture: x64
          cache: "poetry"

      - run: poetry env use 3.12
      - run: poetry install
        if: steps.setup-python.outputs.cache-hit != 'true'

      - name: Run benchmarks
        uses: CodSpeedHQ/action@v2
        with:
          token: ${{ secrets.CODSPEED_TOKEN }}
          run: poetry run pytest tests/benchmarks --codspeed

  lint:
    name: ✨ Lint
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: |
            3.8
            3.9
            3.10
            3.11
            3.12

      - name: Pip and nox cache
        id: cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.cache
            ~/.nox
            .nox
          key:
            ${{ runner.os }}-nox-lint-${{ matrix.session.session }}-${{
            hashFiles('**/poetry.lock') }}-${{ hashFiles('**/noxfile.py') }}
          restore-keys: |
            ${{ runner.os }}-lint-nox-${{ matrix.session.session }}-
            ${{ runner.os }}-lint-nox-

      - run: pip install poetry
      - run: pip install nox nox-poetry
      - run: nox -r -t lint

  unit-tests-on-windows:
    name: 🪟 Tests on Windows
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v4
      - run: pipx install poetry
      - run: pipx install coverage
      - uses: actions/setup-python@v5
        id: setup-python
        with:
          python-version: "3.11"
          cache: "poetry"

      - run: poetry install --with integrations
        if: steps.setup-python.outputs.cache-hit != 'true'
      # Since we are running all the integrations at once, we can't use
      # pydantic v2. It is not compatible with starlette yet
      - run: poetry run pip install pydantic==1.10

      # we use poetry directly instead of nox since we want to
      # test all integrations at once on windows
      # but we want to exclude tests/mypy since we are using an old version of pydantic
      - run: |
          poetry run pytest --cov=. --cov-append --cov-report=xml -n auto --showlocals --ignore tests/mypy -vv
      - name: coverage xml
        run: coverage xml -i
        if: ${{ always() }}

      - uses: codecov/codecov-action@v4
        if: ${{ always() }}
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true
          verbose: true


🆗 Ok to preview

name: 🆗 Ok to preview

on:
  pull_request_target:
    types: [labeled]

jobs:
  ok-to-preview:
    if: ${{ github.event.label.name == 'ok-to-preview' }}
    runs-on: ubuntu-latest
    steps:

    - name: Get changed files
      #uses: lots0logs/gh-action-get-changed-files@2.1.4
      uses: Mineflash07/gh-action-get-changed-files@feature/support-pr-target-event # Remove as soon as PR is merged
      with:
        token: ${{ secrets.GITHUB_TOKEN }}

    - name: Get comment message
      id: get-comment-message
      run: |
        import os, json, textwrap

        all_files_path = os.path.join(os.environ["HOME"], "files.json")
        event_json_path = os.environ["GITHUB_EVENT_PATH"]

        with open(all_files_path) as f:
            all_files = json.load(f)

        with open(event_json_path) as f:
            event_data = json.load(f)

        links = [
          "https://strawberry.rocks/docs/pr/{pr_number}/{path}".format(
            pr_number=event_data["number"],
            path=file.replace(".md", "").replace("docs/", "")
          )
          for file in all_files
          if file.startswith("docs/") and file.endswith(".md")
        ]

        message = textwrap.dedent(
          """
          Hi 👋 You can find a preview of the docs here:

          {links}
          """
        ).format(links="\n".join(links))

        message = message.replace("%", "%25").replace("\n", "%0A").replace("\r", "%0D")
        output = "::set-output name=message::{}".format(message)

        print(output)
      shell: python

    - name: Create comment
      uses: peter-evans/create-or-update-comment@v1
      with:
        issue-number: ${{ github.event.number }}
        body: ${{ steps.get-comment-message.outputs.message }}


🔐 CodeQL

name: 🔐 CodeQL

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 18 * * 5'

jobs:
  analyze:
    runs-on: ubuntu-latest

    permissions:
      security-events: write
      actions: read
      contents: read

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

      - name: Initialize CodeQL
        uses: github/codeql-action/init@v2
        with:
          languages: python

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


🆙 Release

name: 🆙 Release

concurrency: release

on:
  push:
    branches:
      - main

jobs:
  release-file-check:
    name: Get information about release
    runs-on: ubuntu-latest

    outputs:
      changelog: ${{ steps.release-check.outputs.changelog }}
      status: ${{ steps.release-check.outputs.release_status }}
      change_type: ${{ steps.release-check.outputs.change_type }}

    steps:
      - uses: actions/checkout@v1

      - name: Release file check
        uses: ./.github/release-check-action
        id: release-check

  release:
    name: Release
    runs-on: ubuntu-latest
    needs: release-file-check
    if: ${{ needs.release-file-check.outputs.status == 'OK' }}
    outputs:
      version: ${{ steps.get-version.outputs.version }}
    steps:
      - uses: actions/checkout@v2
        with:
          persist-credentials: false
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - name: Install deps
        run: |
          python -m pip install pip --upgrade
          pip install poetry
          pip install githubrelease
          pip install autopub
          pip install httpx
      - name: Check if we should release
        id: check_release
        run: |
          set +e
          echo ::set-output name=release::$(autopub check)
      - name: Publish
        if: steps.check_release.outputs.release == ''
        env:
          GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
          POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
        run: |
          git remote set-url origin https://${{ secrets.BOT_TOKEN }}@github.com/${{ github.repository }}
          autopub prepare
          poetry build
          autopub commit
          autopub githubrelease
          poetry publish --username __token__
      - name: Get project version
        id: get-version
        shell: python
        run: |
          import os
          from pathlib import Path
          from autopub.base import get_project_version

          with Path(os.environ["GITHUB_OUTPUT"]).open('a') as f:
              f.write(f"version={get_project_version()}\n")

  get-contributor-info:
    name: Get PR info
    runs-on: ubuntu-latest
    needs: release-file-check
    if: ${{ needs.release-file-check.outputs.status == 'OK' }}

    outputs:
      contributor-name: ${{ steps.get-info.outputs.contributor-name }}
      contributor-username: ${{ steps.get-info.outputs.contributor-username }}
      contributor-twitter-username: ${{ steps.get-info.outputs.contributor-twitter-username }}
      pr-number: ${{ steps.get-info.outputs.pr-number }}

    steps:
      - name: Get PR info
        id: get-info
        uses: strawberry-graphql/get-pr-info-action@v6

  update-release-on-github:
    name: Update release on GitHub
    runs-on: ubuntu-latest
    needs: [release-file-check, get-contributor-info, release]
    if: ${{ needs.release-file-check.outputs.status == 'OK' }}
    steps:
      - uses: actions/setup-python@v4
        with:
          python-version: "3.9"
      - name: Install dependencies
        run: pip install httpx
      - name: Update release on GitHub
        shell: python
        run: |
          import os

          import httpx

          tag = os.environ["TAG"]
          contributor_username = os.environ["CONTRIBUTOR_USERNAME"]
          pr_number = os.environ["PR_NUMBER"]

          response = httpx.get(
              url=f"https://api.github.com/repos/strawberry-graphql/strawberry/releases/tags/{tag}",
              headers={
                  "Accept": "application/vnd.github.v3+json",
              },
          )

          response.raise_for_status()
          data = response.json()
          release_id = data["id"]
          release_body = data["body"].strip()

          release_footer = f"""
          Releases contributed by @{contributor_username} via #{pr_number}
          """.strip()

          updated_release_body = f"{release_body}\n\n{release_footer}"

          response = httpx.patch(
              url=f"https://api.github.com/repos/strawberry-graphql/strawberry/releases/{release_id}",
              json={"body": updated_release_body},
              headers={
                  "Accept": "application/vnd.github.v3+json",
                  "Authorization": f"token {os.environ['GITHUB_TOKEN']}",
              },
          )

          response.raise_for_status()

        env:
          GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
          TAG: ${{ needs.release.outputs.version }}
          CONTRIBUTOR_USERNAME: ${{ needs.get-contributor-info.outputs.contributor-username }}
          PR_NUMBER: ${{ needs.get-contributor-info.outputs.pr-number }}

  read-tweet-md:
    name: Read TWEET.md
    runs-on: ubuntu-latest
    needs: [release, get-contributor-info, release-file-check]
    if: ${{ needs.release-file-check.outputs.status == 'OK' && needs.get-contributor-info.outputs.contributor-name }}

    outputs:
      tweet: ${{ steps.extract.outputs.tweet }}
      has-tweet-file: ${{ steps.extract.outputs.has-tweet-file }}

    steps:
      - uses: actions/checkout@v1
      - name: Extract tweet message and changelog
        id: extract
        uses: strawberry-graphql/tweet-actions/read-tweet@v6
        with:
          changelog: ${{ needs.release-file-check.outputs.changelog }}
          version: ${{ needs.release.outputs.version }}
          contributor_name: ${{ needs.get-contributor-info.outputs.contributor-name }}
          contributor_twitter_username: ${{ needs.get-contributor-info.outputs.contributor-twitter-username }}

  send-tweet:
    name: Send tweet
    runs-on: ubuntu-latest
    needs: [release, read-tweet-md, get-contributor-info]
    if: ${{ needs.release-file-check.outputs.status == 'OK' }}

    steps:
      - uses: actions/setup-python@v4
        with:
          python-version: "3.9"
      - name: Install dependencies
        run: pip install tweepy==4.14.0
      - name: Send tweet
        shell: python
        run: |
          import base64
          import os

          import tweepy

          TWITTER_CONSUMER_KEY = os.environ["TWITTER_API_KEY"]
          TWITTER_CONSUMER_SECRET = os.environ["TWITTER_API_SECRET"]
          TWITTER_ACCESS_TOKEN = os.environ["TWITTER_ACCESS_TOKEN"]
          TWITTER_ACCESS_TOKEN_SECRET = os.environ["TWITTER_ACCESS_TOKEN_SECRET"]
          TWITTER_BEARER_TOKEN = os.environ["TWITTER_BEARER_TOKEN"]

          tweepy_v2 = tweepy.Client(
              TWITTER_BEARER_TOKEN,
              consumer_key=TWITTER_CONSUMER_KEY,
              consumer_secret=TWITTER_CONSUMER_SECRET,
              access_token=TWITTER_ACCESS_TOKEN,
              access_token_secret=TWITTER_ACCESS_TOKEN_SECRET,
          )

          def post_tweet() -> None:
              text = base64.b64decode(os.environ["TWEET"]).decode("utf-8")
              tweepy_v2.create_tweet(text=text)

          post_tweet()

        env:
          TWEET: ${{ needs.read-tweet-md.outputs.tweet }}
          TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
          TWITTER_API_SECRET: ${{ secrets.TWITTER_API_SECRET }}
          TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
          TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
          TWITTER_BEARER_TOKEN: ${{ secrets.TWITTER_BEARER_TOKEN }}

  remove-tweet-file:
    name: Remove TWEET.md
    if: always() && needs.read-tweet-md.outputs.has-tweet-file == 'true'
    needs: [send-tweet, read-tweet-md]
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
        with:
          persist-credentials: false
      - name: Remove TWEET.md and commit
        env:
          GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
        run: |
          git config --global user.name 'Strawberry GraphQL Bot'
          git config --global user.email 'bot@strawberry.rocks'
          git remote set-url origin https://${{ secrets.BOT_TOKEN }}@github.com/${{ github.repository }}
          git pull
          git rm TWEET.md
          git commit -m "Remove TWEET.md"
          git push


👥 Invite contributors

name: 👥 Invite contributors

on:
  push:
    branches:
      - main

jobs:
  invite-contributor:
    name: Invite contributors
    runs-on: ubuntu-latest

    steps:
      - name: Invite contributors
        uses: strawberry-graphql/invite-to-org-action@v4
        with:
          organisation: "strawberry-graphql"
          comment: |
            Thanks for contributing to Strawberry! 🎉 You've been invited to join
            the Strawberry GraphQL organisation 😊

            You can also request a free sticker by filling this form: https://forms.gle/dmnfQUPoY5gZbVT67

            And don't forget to join our discord server: https://strawberry.rocks/discord 🔥
          team-slug: "strawberry-contributors"
          github-token: ${{ secrets.BOT_TOKEN }}


🎁 Release test pre-release version

name: 🎁 Release test pre-release version

on:
  repository_dispatch:
    types: [pre-release-command]

jobs:
  pre-release:
    name: Pre-release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ github.event.client_payload.pull_request.head.sha }}
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.10"
      - name: Install deps
        run: |
          python -m pip install pip --upgrade
          pip install poetry
          pip install githubrelease
          pip install autopub
          pip install httpx
      - name: Check if release exists
        id: check_release
        run: echo "::set-output name=release::$(autopub check)"
      - name: Metadata
        id: metadata
        if: steps.check_release.outputs.release == ''
        run: echo "::set-output name=commit::$(git rev-parse HEAD)"
      - name: Find Release Comment
        uses: peter-evans/find-comment@v1
        id: find_comment
        if: steps.check_release.outputs.release == ''
        with:
          token: ${{ secrets.BOT_TOKEN }}
          issue-number: ${{ github.event.client_payload.github.payload.issue.number }}
          comment-author: botberry
          body-includes: "# Pre-release"
      - name: Create or update comment
        uses: peter-evans/create-or-update-comment@v1
        if: steps.check_release.outputs.release == ''
        with:
          token: ${{ secrets.BOT_TOKEN }}
          comment-id: ${{ steps.find_comment.outputs.comment-id }}
          issue-number: ${{ github.event.client_payload.github.payload.issue.number }}
          body: |
            # Pre-release
            :wave:

            Releasing commit [${{ steps.metadata.outputs.commit }}] to PyPi as pre-release! :package:
          edit-mode: replace
      - name: Publish pre-release version
        if: steps.check_release.outputs.release == ''
        id: release
        env:
          GITHUB_TOKEN: ${{ secrets.BOT_TOKEN }}
          POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
        run: |
          autopub prepare
          poetry version $(poetry version -s).dev.$(date '+%s')
          poetry build
          poetry publish --username __token__
          echo "::set-output name=version::$(poetry version -s)"
      - name: Create or update comment
        uses: peter-evans/create-or-update-comment@v1
        if: steps.check_release.outputs.release == ''
        with:
          token: ${{ secrets.BOT_TOKEN }}
          comment-id: ${{ steps.find_comment.outputs.comment-id }}
          issue-number: ${{ github.event.client_payload.github.payload.issue.number }}
          body: |
            # Pre-release
            :wave:

            Pre-release **${{ steps.release.outputs.version }}** [${{ steps.metadata.outputs.commit }}] has been released on PyPi! :rocket:
            You can try it by doing:

            ```shell
            poetry add strawberry-graphql==${{ steps.release.outputs.version }}
            ```
          edit-mode: replace


💬 Slash Command Dispatch

name: 💬 Slash Command Dispatch

on:
  issue_comment:
    types: [created]

jobs:
  slashCommandDispatch:
    runs-on: ubuntu-latest
    steps:
      - name: Slash Command Dispatch
        uses: peter-evans/slash-command-dispatch@v2
        with:
          token: ${{ secrets.BOT_TOKEN }}
          reaction-token: ${{ secrets.BOT_TOKEN }}
          permission: admin
          commands: |
            pre-release


🛰 Federation compatibility tests

name: 🛰 Federation compatibility tests

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

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
    paths:
      - "strawberry/federation/**"
      - "strawberry/printer/**"
      - "pyproject.toml"
      - "poetry.lock"
      - ".github/workflows/federation-compatibility.yml"

jobs:
  federation-tests:
    name: Federation tests
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - run: pipx install poetry
      - uses: actions/setup-python@v4
        id: setup-python
        with:
          python-version: "3.12"
          cache: "poetry"
      - run: poetry env use python3.12
      - run: poetry install

      - name: export schema
        run: poetry run strawberry export-schema schema:schema > schema.graphql
        working-directory: federation-compatibility

      - uses: apollographql/federation-subgraph-compatibility@v2
        with:
          compose: 'federation-compatibility/docker-compose.yml'
          schema: 'federation-compatibility/schema.graphql'
          port: 4001
          token: ${{ secrets.BOT_TOKEN }}
          failOnWarning: false
          failOnRequired: true


deploy

name: deploy

on: push

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

jobs:
  build-n-publish:
    runs-on: ubuntu-latest
    if: startsWith(github.event.ref, 'refs/tags')
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v2
        with:
          python-version: 3.7
      - name: Install torch
        run: pip install torch
      - name: Install wheel
        run: pip install wheel
      - name: Build MMDet3D
        run: python setup.py sdist bdist_wheel
      - name: Publish distribution to PyPI
        run: |
          pip install twine
          twine upload dist/* -u __token__ -p ${{ secrets.pypi_password }}


lint

name: lint

on: [push, pull_request]

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

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.7
        uses: actions/setup-python@v2
        with:
          python-version: 3.7
      - name: Install pre-commit hook
        run: |
          pip install pre-commit
          pre-commit install
      - name: Linting
        run: pre-commit run --all-files
      - name: Check docstring coverage
        run: |
          pip install interrogate
          interrogate -v --ignore-init-method --ignore-magic --ignore-module --ignore-nested-functions --ignore-regex "__repr__" --fail-under 90 mmdet3d


name: merge_stage_test

on:
  push:
    paths-ignore:
      - 'README.md'
      - 'README_zh-CN.md'
      - 'docs/**'
      - 'demo/**'
      - '.dev_scripts/**'
      - '.circleci/**'
    branches:
      - dev-1.x

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

jobs:
  build_cpu_py:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.8, 3.9]
        torch: [1.8.1]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
      - name: Install MMEngine
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install MMCV
        run: |
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
      - name: Install MMDet
        run: pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
      - name: Install other dependencies
        run: pip install -r requirements/tests.txt
      - name: Build and install
        run: rm -rf .eggs && pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m

  build_cpu_pt:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.7]
        torch: [1.8.1, 1.9.1, 1.10.1, 1.11.0, 1.12.0, 1.13.0]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
          - torch: 1.9.1
            torchvision: 0.10.1
          - torch: 1.10.1
            torchvision: 0.11.2
          - torch: 1.11.0
            torchvision: 0.12.0
          - torch: 1.12.0
            torchvision: 0.13.0
          - torch: 1.13.0
            torchvision: 0.14.0
          - python-version: 3.8
            torch: 2.0.0
            torchvision: 0.15.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
      - name: Install MMEngine
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install MMCV
        run: |
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
      - name: Install MMDet
        run: pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
      - name: Install other dependencies
        run: pip install -r requirements/tests.txt
      - name: Build and install
        run: rm -rf .eggs && pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m
      # Only upload coverage report for python3.7 && pytorch1.8.1 cpu
      - name: Upload coverage to Codecov
        if: ${{matrix.torch == '1.8.1' && matrix.python-version == '3.7'}}
        uses: codecov/codecov-action@v1.0.14
        with:
          file: ./coverage.xml
          flags: unittests
          env_vars: OS,PYTHON
          name: codecov-umbrella
          fail_ci_if_error: false

  build_cu102:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel
    strategy:
      matrix:
        python-version: [3.7]
        include:
          - torch: 1.8.1
            cuda: 10.2
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m

  build_cu116:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.13.0-cuda11.6-cudnn8-devel
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests
          coverage xml
          coverage report -m

  build_cu117:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-devel
    strategy:
      matrix:
        python-version: [3.9]
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y git ffmpeg libturbojpeg
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmcv -m pytest tests
          coverage xml
          coverage report -m

  build_windows:
    runs-on: windows-2022
    strategy:
      matrix:
        python-version: [3.7]
        platform: [cpu, cu111]
        torch: [1.8.1]
        torchvision: [0.9.1]
        include:
          - python-version: 3.8
            platform: cu117
            torch: 2.0.0
            torchvision: 0.15.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: python -m pip install pip --upgrade && pip install wheel
      - name: Install lmdb
        run: pip install lmdb
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+${{matrix.platform}} torchvision==${{matrix.torchvision}}+${{matrix.platform}} -f https://download.pytorch.org/whl/${{matrix.platform}}/torch_stable.html
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: pytest tests/


name: pr_stage_test

on:
  pull_request:
    paths-ignore:
      - 'README.md'
      - 'README_zh-CN.md'
      - 'docs/**'
      - 'demo/**'
      - '.dev_scripts/**'
      - '.circleci/**'

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

jobs:
  build_cpu:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.7]
        include:
          - torch: 1.8.1
            torchvision: 0.9.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: python -m pip install pip --upgrade && pip install wheel
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
      - name: Install MMEngine
        run: pip install git+https://github.com/open-mmlab/mmengine.git@main
      - name: Install MMCV
        run: |
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
      - name: Install MMDet
        run: pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
      - name: Install other dependencies
        run: pip install -r requirements/tests.txt
      - name: Build and install
        run: rm -rf .eggs && pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m
      # Upload coverage report for python3.7 && pytorch1.8.1 cpu
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v1.0.14
        with:
          file: ./coverage.xml
          flags: unittests
          env_vars: OS,PYTHON
          name: codecov-umbrella
          fail_ci_if_error: false

  build_cu102:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel
    strategy:
      matrix:
        python-version: [3.7]
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m

  build_cu117:
    runs-on: ubuntu-22.04
    container:
      image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-devel
    strategy:
      matrix:
        python-version: [3.9]
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Fetch GPG keys
        run: |
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub
          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub
      - name: Install system dependencies
        run: apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: |
          coverage run --branch --source mmdet3d -m pytest tests/
          coverage xml
          coverage report -m

  build_windows:
    runs-on: windows-2022
    strategy:
      matrix:
        python-version: [3.7]
        platform: [cpu, cu111]
        torch: [1.8.1]
        torchvision: [0.9.1]
        include:
          - python-version: 3.8
            platform: cu117
            torch: 2.0.0
            torchvision: 0.15.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: python -m pip install pip --upgrade && pip install wheel
      - name: Install lmdb
        run: pip install lmdb
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+${{matrix.platform}} torchvision==${{matrix.torchvision}}+${{matrix.platform}} -f https://download.pytorch.org/whl/${{matrix.platform}}/torch_stable.html
      - name: Install mmdet3d dependencies
        run: |
          pip install git+https://github.com/open-mmlab/mmengine.git@main
          pip install -U openmim
          mim install 'mmcv >= 2.0.0rc4'
          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x
          pip install -r requirements/tests.txt
      - name: Build and install
        run: pip install -e .
      - name: Run unittests and generate coverage report
        run: pytest tests/


test-mim

name: test-mim

on:
  push:
    paths:
      - 'model-index.yml'
      - 'configs/**'

  pull_request:
    paths:
      - 'model-index.yml'
      - 'configs/**'

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

jobs:
  build_cpu:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        python-version: [3.7]
        torch: [1.8.1]
        include:
          - torch: 1.8.1
            torch_version: torch1.8
            torchvision: 0.9.1
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Upgrade pip
        run: pip install pip --upgrade && pip install wheel
      - name: Install PyTorch
        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/cpu/torch_stable.html
      - name: Install openmim
        run: pip install openmim
      - name: Build and install
        run: rm -rf .eggs && mim install -e .
      - name: test commands of mim
        run: mim search mmdet3d


CodeQL

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

on:
  push:
    branches: [ master ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ master ]
  schedule:
    - cron: '0 0 1 * *'

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

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at https://git.io/codeql-language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
    - name: Cache pip
      uses: actions/cache@v2
      with:
        path: ${{ matrix.path }}
        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
        restore-keys: |
         ${{ runner.os }}-pip-
    - name: Install ta-lib
      run: |
        if ([ "$RUNNER_OS" = "macOS" ]); then
          brew install ta-lib
        fi
        if ([ "$RUNNER_OS" = "Linux" ]); then
          if [ ! -f "$GITHUB_WORKSPACE/ta-lib/src" ]; then wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz -q && tar -xzf ta-lib-0.4.0-src.tar.gz; fi
          cd ta-lib/
          ./configure --prefix=/usr
          if [ ! -f "$HOME/ta-lib/src" ]; then make; fi
          sudo make install
          cd
        fi
        if ([ "$RUNNER_OS" = "Windows" ]); then
          curl -sL http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip -o $GITHUB_WORKSPACE/ta-lib.zip --create-dirs && 7z x $GITHUB_WORKSPACE/ta-lib.zip -o/c/ta-lib && mv /c/ta-lib/ta-lib/* /c/ta-lib/ && rm -rf /c/ta-lib/ta-lib && cd /c/ta-lib/c/make/cdr/win32/msvc && nmake
        fi
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
        pip install numba

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

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

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

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

    #- run: |
    #   make bootstrap
    #   make release

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


Python application

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

name: Python application

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

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

jobs:
  build:

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

    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}
      - name: Cache pip
        uses: actions/cache@v2
        id: cache
        with:
          path: ${{ matrix.path }}
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
          restore-keys: |
           ${{ runner.os }}-pip-
      - name: Set up ta-lib dir
        if: ${{ runner.os == 'Linux' }}
        run: |
            mkdir -p $HOME/.local/ta-lib
            echo "LD_LIBRARY_PATH=$HOME/.local/ta-lib/lib:$LD_LIBRARY_PATH" >> $GITHUB_ENV
            echo "TA_INCLUDE_PATH=$HOME/.local/ta-lib/include" >> $GITHUB_ENV
            echo "TA_LIBRARY_PATH=$HOME/.local/ta-lib/lib" >> $GITHUB_ENV
      - name: Set up ta-lib cache
        if: ${{ runner.os == 'Linux' }}
        uses: actions/cache@v2
        id: talib-cache
        with:
          path: |
              ~/.local/ta-lib/lib
              ~/.local/ta-lib/include
          key: talib-cache-v0.4.0
      - name: Install ta-lib mac / windows
        run: |
          if ([ "$RUNNER_OS" = "macOS" ]); then
            brew install ta-lib
          fi
          if ([ "$RUNNER_OS" = "Windows" ]); then
            curl -sL http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip -o $GITHUB_WORKSPACE/ta-lib.zip --create-dirs && 7z x $GITHUB_WORKSPACE/ta-lib.zip -o/c/ta-lib && mv /c/ta-lib/ta-lib/* /c/ta-lib/ && rm -rf /c/ta-lib/ta-lib && cd /c/ta-lib/c/make/cdr/win32/msvc && nmake
          fi
      - name: Install ta-lib Linux
        if: steps.talib-cache.outputs.cache-hit != 'true'
        run: |
            wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz -q && tar -xzf ta-lib-0.4.0-src.tar.gz
            cd ta-lib/
            ./configure --prefix=$HOME/.local/ta-lib
            make
            sudo make install
            cd
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
          if [ ! ${{ matrix.python-version }} = "3.10"]; then pip install numba; fi
          pip install -e . -U
     # - name: Lint with flake8
       # run: |
          # stop the build if there are Python syntax errors or undefined names
          # flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
          # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
      - name: Test with pytest
        run: |
          pip install pytest
          pytest


Unit Testing and Deployment

name: Unit Testing and Deployment

on:
  pull_request:
  workflow_dispatch:
  schedule:
    - cron: "0 4 * * *"
  push:
    tags:
      - "*"
    branches:
      - main

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

env:
  ALLOW_PLOTTING: true
  SHELLOPTS: "errexit:pipefail"

jobs:
  macOS:
    # https://github.com/pyvista/pyvista/pull/5960
    runs-on: macos-12
    name: Mac OS Unit Testing
    strategy:
      matrix:
        python-version: ["3.9", "3.11"]

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: "pip"
          cache-dependency-path: |
            requirements.txt
            requirements_test.txt

      - name: Install PyVista
        run: pip install . --no-deps

      - name: Install test dependencies
        run: pip install vtk -r requirements_test.txt

      - name: Report
        run: python -c "import pyvista;print(pyvista.Report(gpu=False));from pyvista import examples;print('User data path:', examples.USER_DATA_PATH)"

      - name: Test Core API
        run: pytest -v --ignore=tests/plotting

      - name: Test Plotting
        run: pytest -v tests/plotting --fail_extra_image_cache --generated_image_dir debug_images

      - name: Upload Generated Images
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: debug_images-${{ github.job }}-${{ join(matrix.* , '-') }}
          path: debug_images

  LinuxConda:
    runs-on: ubuntu-20.04
    if: false
    env:
      CONDA_ALWAYS_YES: 1
      conda_env: pyvista-vtk
      DISPLAY: ":99.0"
      PYVISTA_OFF_SCREEN: True

    steps:
      - uses: actions/checkout@v4

      - name: Set up headless display
        uses: pyvista/setup-headless-display-action@v2

      - name: Cache Conda Packages
        uses: actions/cache@v4
        with:
          path: ~/anaconda3/pkgs
          key: Conda-${{ runner.os }}-${{ hashFiles('environment.yml') }}
          restore-keys: |
            ${{ runner.os }}-conda-

      - uses: actions/cache@v4
        with:
          path: ~/.local/share/pyvista/examples
          key: Examples-1-${{ hashFiles('*') }}
          restore-keys: |
            Examples-1-

      # See: https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community
      - name: Install mamba
        run: |
          source /usr/share/miniconda/etc/profile.d/conda.sh
          conda config --set channel_priority strict
          conda update -n base conda
          conda install -n base conda-libmamba-solver

      - name: "Workaround for mamba-org/mamba#488"
        run: rm /usr/share/miniconda/pkgs/cache/*.json

      - name: Create Anaconda environment
        run: |
          source /usr/share/miniconda/etc/profile.d/conda.sh
          conda config --add channels conda-forge
          conda env create --quiet -n ${{ env.conda_env }} --file environment.yml --experimental-solver=libmamba
          conda activate ${{ env.conda_env }}
          conda list

      - name: Install PyVista
        run: |
          source /usr/share/miniconda/etc/profile.d/conda.sh
          conda activate ${{ env.conda_env }}
          pip install -e .
          which python
          python -c "import pyvista; print(pyvista.Report(gpu=False))"
          python -c "from pyvista import examples; print(examples.USER_DATA_PATH)"

      - name: Test Core API
        run: |
          source /usr/share/miniconda/etc/profile.d/conda.sh
          conda activate ${{ env.conda_env }}
          pip install -r requirements_test.txt
          pytest -v --ignore=tests/plotting

      - name: Test Core Plotting
        run: |
          source /usr/share/miniconda/etc/profile.d/conda.sh
          conda activate ${{ env.conda_env }}
          pytest -v tests/plotting --cov-report html --fail_extra_image_cache --generated_image_dir debug_images

      - name: Upload Generated Images
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: ${{ github.job }}
          path: debug_images

  Linux:
    name: Linux Unit Testing
    runs-on: ubuntu-20.04
    strategy:
      fail-fast: false

      # see discussion at https://github.com/pyvista/pyvista/issues/2867
      matrix:
        include:
          - python-version: "3.8"
            vtk-version: "9.0.3" # Requires numpy<1.24
            numpy-version: "default"
          - python-version: "3.9"
            vtk-version: "9.1"
            numpy-version: "default"
          - python-version: "3.10"
            vtk-version: "9.2.2"
            numpy-version: "default"
          - python-version: "3.11"
            vtk-version: "9.2.6"
            numpy-version: "default"
          - python-version: "3.12"
            vtk-version: "latest"
            numpy-version: "default"
          - python-version: "3.12"
            vtk-version: "latest"
            numpy-version: "nightly"
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 2

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: "pip"
          cache-dependency-path: |
            requirements.txt
            requirements_test.txt

      - uses: actions/cache@v4
        with:
          path: ~/.local/share/pyvista/examples
          key: Examples-1-${{ hashFiles('*') }}
          restore-keys: |
            Examples-1-

      - name: Build wheel and install pyvista
        run: |
          pip install build
          python -m build --wheel
          pip install dist/pyvista*.whl

      - name: Set up vtk
        if: ${{ matrix.vtk-version != 'latest' }}
        run: pip install vtk==${{ matrix.vtk-version }}

      # Make sure PyVista does not break from non-core dependencies
      - name: Software Report (Core Dependencies)
        run: python -c "import pyvista; print(pyvista.Report());"

      - name: Install Testing Requirements
        run: pip install -r requirements_test.txt

      - name: Limit NumPy for VTK 9.0.3
        if: ${{ matrix.vtk-version == '9.0.3' }}
        run: pip install 'numpy<1.24'

      - name: Limit Matplotlib for VTK<9.2.2
        if: ${{ matrix.vtk-version == '9.1' || matrix.vtk-version == '9.0.3' }}
        run: pip install 'matplotlib<3.6'

      - name: Install latest numpy 2.0 beta/rc
        if: ${{ matrix.numpy-version == 'nightly' }}
        run: |
          pip uninstall numpy matplotlib -y
          pip install --pre --no-deps -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple matplotlib
          pip install --pre --no-deps -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple numpy

      - name: Core Testing (no GL)
        run: python -m pytest --cov=pyvista -v tests/core tests/examples

      - uses: awalsh128/cache-apt-pkgs-action@v1.1.3
        with:
          packages: libgl1-mesa-glx xvfb
          version: 3.0

      - name: Plotting Testing (uses GL)
        run: xvfb-run -a python -m pytest --cov=pyvista --cov-append --cov-report=xml --fail_extra_image_cache -v --ignore=tests/core --ignore=tests/examples --generated_image_dir debug_images

      - name: Upload Generated Images
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: debug_images-${{ github.job }}-${{ join(matrix.* , '-') }}
          path: debug_images

      - name: Software Report
        if: always()
        run: |
          xvfb-run -a python -c "import pyvista; print(pyvista.Report()); from pyvista import examples; print('User data path:', examples.USER_DATA_PATH)"
          which python
          pip list

      - uses: codecov/codecov-action@v4
        name: "Upload coverage to CodeCov"
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

      - name: Check package
        run: |
          pip install build twine
          python -m build
          twine check --strict dist/*

      - name: Upload to PyPi
        if: matrix.python-version == '3.9' && startsWith(github.ref, 'refs/tags/v')
        run: |
          twine upload --skip-existing dist/pyvista*
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
          TWINE_REPOSITORY_URL: "https://upload.pypi.org/legacy/"

  windows:
    name: Windows Unit Testing
    runs-on: windows-latest
    env:
      CI_WINDOWS: true
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
          cache: "pip"
          cache-dependency-path: |
            requirements.txt
            requirements_test.txt

      - name: Set up headless display
        uses: pyvista/setup-headless-display-action@v2

      - name: Install PyVista
        run: pip install . --no-deps

      - name: Install test dependencies
        run: pip install vtk -r requirements_test.txt

      - name: Report
        run: python -c "import pyvista; print(pyvista.Report(gpu=False)); from pyvista import examples; print('User data path:', examples.USER_DATA_PATH)"

      - name: Set example data path as env variable
        run: |
          chcp 65001 #set code page to utf-8
          echo ("PYVISTA_EXAMPLE_DATA_PATH=" + $(python -c "import pyvista; from pyvista import examples; print(examples.USER_DATA_PATH)")) >> $env:GITHUB_ENV

      - name: Cache example data
        uses: actions/cache@v4
        with:
          path: ${{ env.PYVISTA_EXAMPLE_DATA_PATH }}
          key: Examples-1-${{ hashFiles('*') }}
          restore-keys: |
            Examples-1-

      - name: Test Core API
        run: python -m pytest -v --ignore=tests/plotting

      - name: Test Plotting
        run: python -m pytest -v tests/plotting --fail_extra_image_cache --generated_image_dir debug_images

      - name: Upload Generated Images
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: debug_images-${{ github.job }}-${{ join(matrix.* , '-') }}
          path: debug_images


Update Local Intersphinx Mappings

name: Update Local Intersphinx Mappings

on:
  workflow_dispatch:
  schedule:
    - cron: "0 3 1 * *"

jobs:
  intersphinx_update:
    # This job can create issues/PRs/comments, so
    #   only run on the head `pyvista/pyvista` repo
    if: github.repository_owner == 'pyvista'
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v4

      - name: Update intersphinx objects
        run: make -C doc update-intersphinx

      - name: Create Pull Request
        uses: peter-evans/create-pull-request@v6
        with:
          token: ${{ secrets.PYVISTA_BOT_TOKEN }}
          author: pyvista-bot <53544751+pyvista-bot@users.noreply.github.com>
          commit-message: "[create-pull-request] update local intersphinx"
          labels: |
            maintenance
          body: |
            Automated changes by [create-pull-request](https://github.com/peter-evans/create-pull-request) GitHub action
            These changes update all the intersphinx mappings.
          title: "Automated PR: Update Local Intersphinx"