build

name: build

on:
  push:
    branches:
      - "branch-*"
    tags:
      - v[0-9][0-9].[0-9][0-9].[0-9][0-9]
  workflow_dispatch:
    inputs:
      branch:
        required: true
        type: string
      date:
        required: true
        type: string
      sha:
        required: true
        type: string
      build_type:
        type: string
        default: nightly

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

jobs:
  python-build:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.08
    with:
      build_type: ${{ inputs.build_type || 'branch' }}
      branch: ${{ inputs.branch }}
      date: ${{ inputs.date }}
      sha: ${{ inputs.sha }}
  upload-conda:
    needs: [python-build]
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/conda-upload-packages.yaml@branch-24.08
    with:
      build_type: ${{ inputs.build_type || 'branch' }}
      branch: ${{ inputs.branch }}
      date: ${{ inputs.date }}
      sha: ${{ inputs.sha }}
  docs-build:
    if: github.ref_type == 'branch'
    needs: python-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.08
    with:
      arch: "amd64"
      branch: ${{ inputs.branch }}
      build_type: ${{ inputs.build_type || 'branch' }}
      container_image: "rapidsai/ci-conda:latest"
      date: ${{ inputs.date }}
      node_type: "gpu-v100-latest-1"
      run_script: "ci/build_docs.sh"
      sha: ${{ inputs.sha }}
  wheel-build:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.08
    with:
      build_type: ${{ inputs.build_type || 'branch' }}
      branch: ${{ inputs.branch }}
      sha: ${{ inputs.sha }}
      date: ${{ inputs.date }}
      script: ci/build_wheel.sh
      # This selects "ARCH=amd64 + the latest supported Python + CUDA".
      matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.]
  wheel-publish:
    needs: wheel-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.08
    with:
      build_type: ${{ inputs.build_type || 'branch' }}
      branch: ${{ inputs.branch }}
      sha: ${{ inputs.sha }}
      date: ${{ inputs.date }}
      package-name: cuxfilter


Pull Request Labeler

name: "Pull Request Labeler"
on:
- pull_request_target

jobs:
 triage:
   runs-on: ubuntu-latest
   steps:
   - uses: actions/labeler@v4
     with:
       repo-token: "${{ secrets.GITHUB_TOKEN }}"


name: Auto Assign New Issues to Triage Project

on:
  issues:
    types: [opened]

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

jobs:
  assign_one_project:
    runs-on: ubuntu-latest
    name: Assign to New Issues to Triage Project
    steps:
    - name: Process bug issues
      uses: docker://takanabe/github-actions-automate-projects:v0.0.1
      if: contains(github.event.issue.labels.*.name, 'bug') && contains(github.event.issue.labels.*.name, '? - Needs Triage')
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_PROJECT_URL: https://github.com/rapidsai/cuxfilter/projects/2
        GITHUB_PROJECT_COLUMN_NAME: 'Needs prioritizing'
    - name: Process feature issues
      uses: docker://takanabe/github-actions-automate-projects:v0.0.1
      if: contains(github.event.issue.labels.*.name, 'feature request') && contains(github.event.issue.labels.*.name, '? - Needs Triage')
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_PROJECT_URL: https://github.com/rapidsai/cuxfilter/projects/1
        GITHUB_PROJECT_COLUMN_NAME: 'Needs prioritizing'
    - name: Process other issues
      uses: docker://takanabe/github-actions-automate-projects:v0.0.1
      if: contains(github.event.issue.labels.*.name, '? - Needs Triage') && (!contains(github.event.issue.labels.*.name, 'bug') && !contains(github.event.issue.labels.*.name, 'feature request'))
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GITHUB_PROJECT_URL: https://github.com/rapidsai/cuxfilter/projects/7
        GITHUB_PROJECT_COLUMN_NAME: 'Needs prioritizing'


pr

name: pr

on:
  push:
    branches:
      - "pull-request/[0-9]+"

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

jobs:
  pr-builder:
    needs:
      - checks
      - conda-python-build
      - conda-python-tests
      - conda-notebook-tests
      - docs-build
      - wheel-build
      - wheel-tests
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.08
  checks:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.08
  conda-python-build:
    needs: checks
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.08
    with:
      build_type: pull-request
  conda-python-tests:
    needs: conda-python-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.08
    with:
      build_type: pull-request
      run_codecov: false
  conda-notebook-tests:
    needs: conda-python-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.08
    with:
      build_type: pull-request
      node_type: "gpu-v100-latest-1"
      arch: "amd64"
      container_image: "rapidsai/ci-conda:latest"
      run_script: "ci/test_notebooks.sh"
  docs-build:
    needs: conda-python-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.08
    with:
      build_type: pull-request
      node_type: "gpu-v100-latest-1"
      arch: "amd64"
      container_image: "rapidsai/ci-conda:latest"
      run_script: "ci/build_docs.sh"
  wheel-build:
    needs: checks
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.08
    with:
      build_type: pull-request
      script: ci/build_wheel.sh
      # This selects "ARCH=amd64 + the latest supported Python + CUDA".
      matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.]
  wheel-tests:
    needs: wheel-build
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.08
    with:
      build_type: pull-request
      script: ci/test_wheel.sh
      # This selects "ARCH=amd64 + the latest supported Python + CUDA".
      matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.]


name: GPU testing for external party dependencies

on:
  workflow_dispatch:
    inputs:
      external-project:
        description: "Project:"
        required: true
        type: choice
        options:
          - datashader
          - holoviews
          - all
      pr_number:
        description: "
          The number of the pull request to check out, else checks out default branch.
          Will be ignored if external-project=all
          "
        required: false
  schedule:
    - cron: "0 0 * * 1" # Run every Sunday evening Pacific Time (Monday 0:00 UTC)

jobs:
  test-external:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/custom-job.yaml@branch-24.08
    with:
      build_type: branch
      node_type: "gpu-v100-latest-1"
      arch: "amd64"
      container_image: "rapidsai/ci-conda:latest"
      run_script: "./ci/test_external.sh ${{ inputs.external-project || 'all' }} ${{ inputs.pr_number }}"


test

name: test

on:
  workflow_dispatch:
    inputs:
      branch:
        required: true
        type: string
      date:
        required: true
        type: string
      sha:
        required: true
        type: string

jobs:
  conda-python-tests:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.08
    with:
      build_type: nightly
      branch: ${{ inputs.branch }}
      date: ${{ inputs.date }}
      sha: ${{ inputs.sha }}
  wheel-tests:
    secrets: inherit
    uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.08
    with:
      build_type: nightly
      branch: ${{ inputs.branch }}
      date: ${{ inputs.date }}
      sha: ${{ inputs.sha }}
      script: ci/test_wheel.sh
      # This selects "ARCH=amd64 + the latest supported Python + CUDA".
      matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.]


name: build_meta_image

on:
  push:
    paths:
      - 'docker/Metafile'
      - 'docker/Metafile.alpine'
      - 'requirements.txt'
    branches:
      - "dev"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Set Environment Variables
        run: |
          IMG=fulltclash
          echo "IMG=${IMG}" >> $GITHUB_ENV
          echo "IMAGE=${{ secrets.DOCKERHUB_USERNAME }}/${IMG}" >> $GITHUB_ENV
      - name: Build Debian Image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./docker/Metafile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: |
            ${{ env.IMAGE }}:debian
      - name: Build Alpine Image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./docker/Metafile.alpine
          platforms: linux/amd64,linux/arm64
          push: true
          tags: |
            ${{ env.IMAGE }}:alpine


ci

name: ci

on:
  push:
    paths-ignore:
      - "resources/**"
      - "README.md"
      - "README-EN.md"
      - ".github/ISSUE_TEMPLATE/**"
    branches:
      - "master"
      - "dev"

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Set Environment Variables
        run: |
          IMG=fulltclash
          echo "IMG=${IMG}" >> $GITHUB_ENV
          echo "IMAGE=${{ secrets.DOCKERHUB_USERNAME }}/${IMG}" >> $GITHUB_ENV
      - name: Get version
        id: get_version
        run: echo "version=$(git describe --tags --always)" >> $GITHUB_OUTPUT
      - name: Build Latest Image
        if: ${{ github.ref_name == 'dev' }}
        uses: docker/build-push-action@v5
        with:
          platforms: linux/amd64,linux/arm64
          context: .
          file: ./docker/Dockerfile
          push: true
          tags: |
            ${{ env.IMAGE }}:latest
            ${{ env.IMAGE }}:debian-${{ github.ref_name }}
          build-args: |
            GIT_Branch=${{ github.ref_name }}
      - name: Build Debian Image
        if: ${{ github.ref_name != 'dev' }}
        uses: docker/build-push-action@v5
        with:
          platforms: linux/amd64,linux/arm64
          context: .
          file: ./docker/Dockerfile
          push: true
          tags: |
            ${{ env.IMAGE }}:debian-${{ github.ref_name }}
          build-args: |
            GIT_Branch=${{ github.ref_name }}
      - name: Build Alpine Image
        uses: docker/build-push-action@v5
        with:
          platforms: linux/amd64,linux/arm64
          context: .
          file: ./docker/Dockerfile.alpine
          push: true
          tags: |
            ${{ env.IMAGE }}:alpine-${{ github.ref_name }}
            ${{ env.IMAGE }}:${{ steps.get_version.outputs.version }}
          build-args: |
            GIT_Branch=${{ github.ref_name }}


Nightly Documentation Build

name: Nightly Documentation Build

on:
  workflow_dispatch:
  schedule:  # UTC at 0300
    - cron:  '0 3 * * *'

env:
  ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }}
  MAIN_PYTHON_VERSION: '3.10'
  DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com'
  MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
  MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }}
  MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }}

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

jobs:

  doc-build:
    name: Documentation build with examples
    runs-on: [ self-hosted, Windows, pyaedt ]
    timeout-minutes: 720
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          python -m venv .venv
          .venv\Scripts\Activate.ps1
          python -m pip install pip -U
          python -m pip install wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and documentation dependencies
        run: |
          .venv\Scripts\Activate.ps1
          pip install .[doc]

      - name: Retrieve PyAEDT version
        id: version
        run: |
          .venv\Scripts\Activate.ps1
          echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT
          echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")"

      - name: Install CI dependencies (e.g. vtk-osmesa)
        run: |
          .venv\Scripts\Activate.ps1
          # Uninstall conflicting dependencies
          pip uninstall --yes vtk
          pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0

      # TODO: Update this step once pyaedt-examples is ready
      # NOTE: Use environment variable to keep the doctree and avoid redundant build for PDF pages
      - name: Build HTML documentation with examples
        env:
          SPHINXBUILD_KEEP_DOCTREEDIR: "1"
        run: |
          .venv\Scripts\Activate.ps1
          .\doc\make.bat clean
          .\doc\make.bat html

      # TODO: Keeping this commented as reminder of https://github.com/ansys/pyaedt/issues/4296
      # # Verify that sphinx generates no warnings
      # - name: Check for warnings
      #   run: |
      #     .venv\Scripts\Activate.ps1
      #     python doc/print_errors.py

      # Use environment variable to remove the doctree after the build of PDF pages
      - name: Build PDF documentation with examples
        env:
          SPHINXBUILD_KEEP_DOCTREEDIR: "0"
        run: |
          .venv\Scripts\Activate.ps1
          .\doc\make.bat pdf

      # - name: Add assets to HTML docs
      #   run: |
      #     zip -r documentation-html.zip ./doc/_build/html
      #     mv documentation-html.zip ./doc/_build/html/_static/assets/download/
      #     cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf

      - name: Upload HTML documentation with examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-html
          path: doc/_build/html
          retention-days: 7

      - name: Upload PDF documentation without examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-pdf
          path: doc/_build/latex/PyAEDT-Documentation-*.pdf
          retention-days: 7

  upload-dev-doc:
    name: Upload dev documentation
    runs-on: ubuntu-latest
    needs: doc-build
    steps:
      - name: Upload development documentation
        uses: ansys/actions/doc-deploy-dev@v4
        with:
          cname: ${{ env.DOCUMENTATION_CNAME }}
          token: ${{ secrets.GITHUB_TOKEN }}
          doc-artifact-name: 'documentation-html'

  doc-index-dev:
    name: Deploy dev index docs
    runs-on: ubuntu-latest
    needs: upload-dev-doc
    steps:
      - name: Deploy the latest documentation index
        uses: ansys/actions/doc-deploy-index@v4
        with:
          cname: ${{ env.DOCUMENTATION_CNAME }}/version/dev
          index-name: pyaedt-vdev
          host-url: ${{ env.MEILISEARCH_HOST_URL }}
          api-key: ${{ env.MEILISEARCH_API_KEY }}
          python-version: ${{ env.MAIN_PYTHON_VERSION }}


Labeler

name: Labeler
on:
  pull_request:
  push:
    branches: [ main ]
    paths:
      - '../labels.yml'

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

jobs:

  label-syncer:
    name: Syncer
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: micnncim/action-label-syncer@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  labeler:
    name: Set labels
    needs: [label-syncer]
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-latest
    steps:

    # Label based on modified files
    - name: Label based on changed files
      uses: actions/labeler@v5
      with:
        repo-token: "${{ secrets.GITHUB_TOKEN }}"

    # Label based on branch name
    - uses: actions-ecosystem/action-add-labels@v1
      if: |
        startsWith(github.event.pull_request.head.ref, 'doc') ||
        startsWith(github.event.pull_request.head.ref, 'docs')
      with:
        labels: documentation

    - uses: actions-ecosystem/action-add-labels@v1
      if: |
        startsWith(github.event.pull_request.head.ref, 'maint') ||
        startsWith(github.event.pull_request.head.ref, 'no-ci') ||
        startsWith(github.event.pull_request.head.ref, 'ci')
      with:
        labels: maintenance

    - uses: actions-ecosystem/action-add-labels@v1
      if: startsWith(github.event.pull_request.head.ref, 'feat')
      with:
        labels: |
          enhancement

    - uses: actions-ecosystem/action-add-labels@v1
      if: |
        startsWith(github.event.pull_request.head.ref, 'fix') ||
        startsWith(github.event.pull_request.head.ref, 'patch')
      with:
        labels: bug

    - uses: actions-ecosystem/action-add-labels@v1
      if: |
        startsWith(github.event.pull_request.head.ref, 'test')
      with:
        labels: testing

  commenter:
    runs-on: ubuntu-latest
    steps:
    - name: Suggest to add labels
      uses: peter-evans/create-or-update-comment@v4
      # Execute only when no labels have been applied to the pull request
      if: toJSON(github.event.pull_request.labels.*.name) == '{}'
      with:
        issue-number: ${{ github.event.pull_request.number }}
        body: |
          Please add one of the following labels to add this contribution to the Release Notes :point_down:
          - [bug](https://github.com/ansys/pyaedt/pulls?q=label%3Abug+)
          - [documentation](https://github.com/ansys/pyaedt/pulls?q=label%3Adocumentation+)
          - [enhancement](https://github.com/ansys/pyaedt/pulls?q=label%3Aenhancement+)
          - [good first issue](https://github.com/ansys/pyaedt/pulls?q=label%3Agood+first+issue)
          - [maintenance](https://github.com/ansys/pyaedt/pulls?q=label%3Amaintenance+)
          - [release](https://github.com/ansys/pyaedt/pulls?q=label%3Arelease+)
          - [testing](https://github.com/ansys/pyaedt/pulls?q=label%Atesting+)


name: CI_PreRelease

env:
  python.version: '3.8'
  python.venv: 'testvenv'
  # Following env vars when changed will "reset" the mentioned cache,
  # by changing the cache file name. It is rendered as ...-v%RESET_XXX%-...
  # You should go up in number, if you go down (or repeat a previous value)
  # you might end up reusing a previous cache if it haven't been deleted already.
  # It applies 7 days retention policy by default.
  RESET_PIP_CACHE: 0
  PACKAGE_NAME: PyAEDT
# Controls when the workflow will run
on:
  workflow_dispatch:
    inputs:
      logLevel:
        description: 'Log level'
        required: true
        default: 'warning'
      tags:
        description: 'Linux CPython daily'
  schedule:  # UTC at 0300
    - cron:  '0 3 * * *'

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

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: [pre_release]
    strategy:
      matrix:
        python-version: ['3.8']
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}

      - name: 'Create virtual env'
        run: |
          python -m venv testenv
          testenv\Scripts\Activate.ps1
          python -m pip install pip -U
          python -m pip install wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: 'Install pyaedt'
        run: |
          testenv\Scripts\Activate.ps1
          pip install .[tests]
          pip install pytest-azurepipelines
          Copy-Item -Path "C:\actions-runner\opengl32.dll" -Destination "testenv\Lib\site-packages\vtkmodules" -Force
          Copy-Item -Path "C:\actions-runner\local_config.json" -Destination "_unittest" -Force
          mkdir tmp
          cd tmp
          python -c "import pyaedt; print('Imported pyaedt')"

      # - name: "Check licences of packages"
      #   uses: pyansys/pydpf-actions/check-licenses@v2.0

      - name: 'Unit testing'
        timeout-minutes: 60
        run: |
          testenv\Scripts\Activate.ps1
          Set-Item -Path env:PYTHONMALLOC -Value "malloc"
          pytest --tx 6*popen --durations=50 --dist loadfile -v --cov=pyaedt  --cov-report=xml --junitxml=junit/test-results.xml --cov-report=html _unittest

      - uses: codecov/codecov-action@v4
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
        if: matrix.python-version == '3.8'
        name: 'Upload coverage to Codecov'

      - name: Upload pytest test results
        uses: actions/upload-artifact@v4
        with:
          name: pytest-results
          path: junit/test-results.xml
        # Use always() to always run this step to publish test results when there are test failures
        if: ${{ always() }}


GitHub CI CD

name: GitHub CI CD
on:
  pull_request:
  workflow_dispatch:
  push:
    tags:
      - "*"
    branches:
      - main

env:
  ANSYSLMD_LICENSE_FILE: ${{ format('1055@{0}', secrets.LICENSE_SERVER) }}
  MAIN_PYTHON_VERSION: '3.10'
  PACKAGE_NAME: 'PyAEDT'
  DOCUMENTATION_CNAME: 'aedt.docs.pyansys.com'
  MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
  MEILISEARCH_HOST_URL: ${{ vars.MEILISEARCH_HOST_URL }}
  MEILISEARCH_PUBLIC_API_KEY: ${{ secrets.MEILISEARCH_PUBLIC_API_KEY }}
  ON_CI: True

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

jobs:

  pr-title:
    if: github.event_name == 'pull_request'
    name: Check the title of the pull request
    runs-on: ubuntu-latest
    steps:
      - name: Check commit name
        uses: ansys/actions/commit-style@v6
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          use-upper-case: true

  # TODO: Update to ansys/actions/doc-style@v6
  doc-style:
    name: Documentation style check
    runs-on: ubuntu-latest
    steps:
      - name: Check documentation style
        uses: ansys/actions/doc-style@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          vale-config: "doc/.vale.ini"
          vale-version: "2.29.6"

  smoke-tests:
    name: Build wheelhouse and smoke tests
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
        target: ['all', 'installer']
        exclude:
          - python-version: '3.7'
            target: 'installer'
    steps:
      - name: Build wheelhouse and perform smoke test
        uses: ansys/actions/build-wheelhouse@v4
        with:
          library-name: ${{ env.PACKAGE_NAME }}
          operating-system: ${{ matrix.os }}
          python-version: ${{ matrix.python-version }}
          target: ${{ matrix.target }}

      - name: Import python package
        run: |
          python -c "import pyaedt; from pyaedt import __version__"

  # TODO: Update to ansys/actions/doc-build@v6 once we remove examples
  doc-build:
    name: Documentation build without examples
    runs-on: ubuntu-latest
    needs: [doc-style]
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Update pip
        run: |
          pip install --upgrade pip

      - name: Install pyaedt and documentation dependencies
        run: |
          pip install .[doc-no-examples]

      - name: Retrieve PyAEDT version
        id: version
        run: |
          echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT
          echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")"

      - name: Install doc build requirements
        run: |
          sudo apt update
          sudo apt install graphviz texlive-latex-extra latexmk texlive-xetex texlive-fonts-extra -y

      # TODO: Update this step once pyaedt-examples is ready
      - name: Build HTML documentation without examples
        run: |
          make -C doc clean
          make -C doc html-no-examples

      # Verify that sphinx generates no warnings
      - name: Check for warnings
        run: |
          python doc/print_errors.py

      - name: Upload HTML documentation without examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-no-examples-html
          path: doc/_build/html
          retention-days: 7

      - name: Build PDF documentation without examples
        run: |
          make -C doc pdf-no-examples

      - name: Upload PDF documentation without examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-no-examples-pdf
          path: doc/_build/latex/PyAEDT-Documentation-*.pdf
          retention-days: 7

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  doc-build-with-examples:
    name: Documentation build with examples
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
    runs-on: [ self-hosted, Windows, pyaedt ]
    needs: [doc-style]
    timeout-minutes: 720
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          python -m venv .venv
          .venv\Scripts\Activate.ps1
          python -m pip install pip -U
          python -m pip install wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and documentation dependencies
        run: |
          .venv\Scripts\Activate.ps1
          pip install .[doc]

      - name: Retrieve PyAEDT version
        id: version
        run: |
          .venv\Scripts\Activate.ps1
          echo "PYAEDT_VERSION=$(python -c 'from pyaedt import __version__; print(__version__)')" >> $GITHUB_OUTPUT
          echo "PyAEDT version is: $(python -c "from pyaedt import __version__; print(__version__)")"

      - name: Install CI dependencies (e.g. vtk-osmesa)
        run: |
          .venv\Scripts\Activate.ps1
          # Uninstall conflicting dependencies
          pip uninstall --yes vtk
          pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0

      # TODO: Update this step once pyaedt-examples is ready
      # NOTE: Use environment variable to keep the doctree and avoid redundant build for PDF pages
      - name: Build HTML documentation with examples
        env:
          SPHINXBUILD_KEEP_DOCTREEDIR: "1"
        run: |
          .venv\Scripts\Activate.ps1
          .\doc\make.bat clean
          .\doc\make.bat html

      # TODO: Keeping this commented as reminder of https://github.com/ansys/pyaedt/issues/4296
      # # Verify that sphinx generates no warnings
      # - name: Check for warnings
      #   run: |
      #     .venv\Scripts\Activate.ps1
      #     python doc/print_errors.py

      # Use environment variable to remove the doctree after the build of PDF pages
      - name: Build PDF documentation with examples
        env:
          SPHINXBUILD_KEEP_DOCTREEDIR: "0"
        run: |
          .venv\Scripts\Activate.ps1
          .\doc\make.bat pdf

      # - name: Add assets to HTML docs
      #   run: |
      #     zip -r documentation-html.zip ./doc/_build/html
      #     mv documentation-html.zip ./doc/_build/html/_static/assets/download/
      #     cp doc/_build/latex/PyAEDT-Documentation-*.pdf ./doc/_build/html/_static/assets/download/pyaedt.pdf

      - name: Upload HTML documentation with examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-html
          path: doc/_build/html
          retention-days: 7

      - name: Upload PDF documentation without examples artifact
        uses: actions/upload-artifact@v3
        with:
          name: documentation-pdf
          path: doc/_build/latex/PyAEDT-Documentation-*.pdf
          retention-days: 7

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  test-solvers-windows:
    name: Testing solvers and coverage (Windows)
    needs: [smoke-tests]
    runs-on: [ self-hosted, Windows, pyaedt ]
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          python -m venv .venv
          .venv\Scripts\Activate.ps1
          python -m pip install pip -U
          python -m pip install wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and tests dependencies
        run: |
          .venv\Scripts\Activate.ps1
          pip install .[tests]
          pip install pytest-azurepipelines

      - name: Install CI dependencies (e.g. vtk-osmesa)
        run: |
          .venv\Scripts\Activate.ps1
          # Uninstall conflicting dependencies
          pip uninstall --yes vtk
          pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0

      - name: Run tests on _unittest_solvers
        env:
          PYTHONMALLOC: malloc
        run: |
          .venv\Scripts\Activate.ps1
          pytest --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest_solvers

      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: codecov-system-solver-tests
          file: ./coverage.xml
          flags: system,solver

      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-solver-results
          path: junit/test-results.xml
        if: ${{ always() }}

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  # TODO: Si if we can use ansys/actions
  test-solvers-linux:
    name: Testing solvers and coverage (Linux)
    needs: [smoke-tests]
    runs-on: [ self-hosted, Linux, pyaedt ]
    env:
      ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64'
      ANS_NODEPCHECK: '1'
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
          python -m venv .venv
          source .venv/bin/activate
          python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip -U
          python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and tests dependencies
        run: |
          export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
          source .venv/bin/activate
          pip install .[tests]
          pip install pytest-azurepipelines

      - name: Run tests on _unittest_solvers
        run: |
          export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
          source .venv/bin/activate
          pytest --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest_solvers

      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: codecov-system-solver-tests
          file: ./coverage.xml
          flags: system,solver

      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-solver-results
          path: junit/test-results.xml
        if: ${{ always() }}

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  test-windows:
    name: Testing and coverage (Windows)
    needs: [smoke-tests]
    runs-on: [ self-hosted, Windows, pyaedt ]
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          python -m venv .venv
          .venv\Scripts\Activate.ps1
          python -m pip install pip -U
          python -m pip install wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and tests dependencies
        run: |
          .venv\Scripts\Activate.ps1
          pip install .[tests]
          pip install pytest-azurepipelines

      - name: Install CI dependencies (e.g. vtk-osmesa)
        run: |
          .venv\Scripts\Activate.ps1
          # Uninstall conflicting dependencies
          pip uninstall --yes vtk
          pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0

      - name: Run tests on _unittest
        uses: nick-fields/retry@v3
        env:
          PYTHONMALLOC: malloc
        with:
          max_attempts: 2
          retry_on: error
          timeout_minutes: 50
          command: |
            .venv\Scripts\Activate.ps1
            pytest -n 4 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest

      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: codecov-system-tests
          file: ./coverage.xml
          flags: system

      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-results
          path: junit/test-results.xml
        if: ${{ always() }}

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  # TODO: Si if we can use ansys/actions
  test-linux:
    name: Testing and coverage (Linux)
    needs: [smoke-tests]
    runs-on: [ self-hosted, Linux, pyaedt ]
    env:
      ANSYSEM_ROOT241: '/opt/AnsysEM/v241/Linux64'
      ANS_NODEPCHECK: '1'
    steps:
      - name: Install Git and checkout project
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

      - name: Create virtual environment
        run: |
          export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
          python -m venv .venv
          source .venv/bin/activate
          python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org pip -U
          python -m pip install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host files.pythonhosted.org wheel setuptools -U
          python -c "import sys; print(sys.executable)"

      - name: Install pyaedt and tests dependencies
        run: |
          export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
          source .venv/bin/activate
          pip install .[tests]
          pip install pytest-azurepipelines

      - name: Install CI dependencies (e.g. vtk-osmesa)
        run: |
          source .venv/bin/activate
          # Uninstall conflicting dependencies
          pip uninstall --yes vtk
          pip install --extra-index-url https://wheels.vtk.org vtk-osmesa==9.2.20230527.dev0

      - name: Run tests on _unittest
        uses: nick-fields/retry@v3
        with:
          max_attempts: 2
          retry_on: error
          timeout_minutes: 50
          command: |
            export LD_LIBRARY_PATH=${{ env.ANSYSEM_ROOT241 }}/common/mono/Linux64/lib64:${{ env.ANSYSEM_ROOT241 }}/Delcross:$LD_LIBRARY_PATH
            source .venv/bin/activate
            pytest -n 2 --dist loadfile --durations=50 -v --cov=pyaedt --cov-report=xml --cov-report=html --junitxml=junit/test-results.xml _unittest

      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          name: codecov-system-solver-tests
          file: ./coverage.xml
          flags: system,solver

      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-solver-results
          path: junit/test-results.xml
        if: ${{ always() }}

# # =================================================================================================
# # vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv    RUNNING ON SELF-HOSTED RUNNER    vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
# # =================================================================================================

  test-ironpython-windows:
    name: Testing IronPython and coverage (Windows)
    needs: [smoke-tests]
    runs-on: [ self-hosted, Windows, pyaedt ]
    steps:
      - uses: actions/checkout@v4

      - name: Run Ironpython tests
        timeout-minutes: 5
        run: |
          $processA = start-process 'cmd' -ArgumentList '/c .\_unittest_ironpython\run_unittests_batchmode.cmd' -PassThru
          $processA.WaitForExit()

      - name: Get log content
        run: |
          get-content .\_unittest_ironpython\pyaedt_unit_test_ironpython.log

      - name: Check for errors
        run: |
          $test_errors_failures = Select-String -Path .\_unittest_ironpython\pyaedt_unit_test_ironpython.log -Pattern "TextTestResult errors="
          if ($test_errors_failures -ne $null)
          {
            exit 1
          }

  package:
    name: Package library
    needs: [test-windows, test-solvers-windows, test-ironpython-windows, test-linux, test-solvers-linux, doc-build]
    runs-on: ubuntu-latest
    steps:
      - name: Build library source and wheel artifacts
        uses: ansys/actions/build-library@v4
        with:
          library-name: ${{ env.PACKAGE_NAME }}
          python-version: ${{ env.MAIN_PYTHON_VERSION }}

  # TODO: Si if we can fix the PDF issue and leverage classic ansys/release-github
  release:
    name: Release project
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
    needs: [package, doc-build-with-examples]
    runs-on: ubuntu-latest
    steps:
      - name: Release to the public PyPI repository
        uses: ansys/actions/release-pypi-public@v4
        with:
          library-name: ${{ env.PACKAGE_NAME }}
          twine-username: "__token__"
          twine-token: ${{ secrets.PYPI_TOKEN }}

      - name: Release to GitHub
        uses: ansys/actions/release-github@v4
        with:
          library-name: ${{ env.PACKAGE_NAME }}

  upload-release-doc:
    name: Upload release documentation
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
    runs-on: ubuntu-latest
    needs: [release]
    steps:
      - name: Deploy the stable documentation
        uses: ansys/actions/doc-deploy-stable@v4
        with:
          cname: ${{ env.DOCUMENTATION_CNAME }}
          token: ${{ secrets.GITHUB_TOKEN }}
          doc-artifact-name: 'documentation-html'

  doc-index-stable:
    name: Deploy stable docs index
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags')
    runs-on: ubuntu-latest
    needs: upload-release-doc
    steps:
      - name: Install Git and clone project
        uses: actions/checkout@v4

      - name: Install the package requirements
        run: pip install -e .

      - name: Get the version to PyMeilisearch
        run: |
          VERSION=$(python -c "from pyaedt import __version__; print('.'.join(__version__.split('.')[:2]))")
          VERSION_MEILI=$(python -c "from pyaedt import __version__; print('-'.join(__version__.split('.')[:2]))")
          echo "Calculated VERSION: $VERSION"
          echo "Calculated VERSION_MEILI: $VERSION_MEILI"
          echo "VERSION=$VERSION" >> $GITHUB_ENV
          echo "VERSION_MEILI=$VERSION_MEILI" >> $GITHUB_ENV

      - name: Deploy the latest documentation index
        uses: ansys/actions/doc-deploy-index@v4
        with:
          cname: ${{ env.DOCUMENTATION_CNAME }}/version/${{ env.VERSION }}
          index-name: pyaedt-v${{ env.VERSION_MEILI }}
          host-url: ${{ env.MEILISEARCH_HOST_URL }}
          api-key: ${{ env.MEILISEARCH_API_KEY }}
          python-version: ${{ env.MAIN_PYTHON_VERSION }}


Use test target with multiple python version


Check scripts

name: Check scripts

on:
  push:
  pull_request:

env:
  FORCE_COLOR: 1

jobs:
  black:
    name: Check formatting with black
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - uses: actions/checkout@v4
      - run: pip install -r requirements.txt
      - run: |
          black --version
          black --check .

  mypy:
    name: Check stub_uploader with mypy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - uses: actions/checkout@v4
      - run: pip install -r requirements.txt
      - run: mypy --strict -p stub_uploader -p tests

  tests:
    name: Run integration and unit tests
    runs-on: ubuntu-latest
    steps:
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Checkout main
        uses: actions/checkout@v4
        with:
          path: main
      - name: Checkout typeshed
        uses: actions/checkout@v4
        with:
          repository: python/typeshed
          path: typeshed
      - name: Run tests
        run: |
          cd main
          pip install -r requirements.txt
          python -Werror -m pytest tests


name: Force update of some stubs from typeshed to PyPI

on:
  workflow_dispatch:
    inputs:
      distribution:
        description: 'Package name or pattern (Python regexp)'
        required: true

env:
  FORCE_COLOR: 1

jobs:
  build-and-upload:
    runs-on: ubuntu-latest
    steps:
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - name: Checkout main
        uses: actions/checkout@v4
        with:
          path: main
      - name: Checkout typeshed
        uses: actions/checkout@v4
        with:
          repository: python/typeshed
          path: typeshed
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r main/requirements.txt
      - name: Execute build and upload
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.TYPESHED_BOT_API_TOKEN }}
        run: |
          cd main
          python -m stub_uploader.upload_some ../typeshed "${{ github.event.inputs.distribution }}"
          # If we are force uploading packages that were never uploaded, they are added to the list
          if [ -z "$(git status --porcelain)" ]; then
              exit 0;
          fi
          git config user.name github-actions && git config user.email github-actions@github.com
          git add . && git commit -m "Update uploaded packages list" && git push


Test PyPI API token

name: Test PyPI API token

on:
  # Only triggered manually (for debugging/integration testing).
  workflow_dispatch:
    inputs:
      increment:
        description: 'Package minor version'
        required: true
        default: 0

env:
  FORCE_COLOR: 1

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.12'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build setuptools wheel twine
    - name: Build and publish
      env:
        TWINE_USERNAME: __token__
        TWINE_PASSWORD: ${{ secrets.TYPESHED_BOT_API_TOKEN }}
      run: |
        cd data/empty_package
        PACKAGE_VERSION_INCREMENT=${{ github.event.inputs.increment }} python -m build --wheel --no-isolation
        twine upload dist/*


name: Periodic update of stubs from typeshed to PyPI

on:
  # Triggers the workflow each day at 02:00 UTC.
  schedule:
    - cron: 0 2 * * *
  # If needed, allows to run this workflow manually from the Actions tab
  workflow_dispatch:

env:
  FORCE_COLOR: 1

jobs:
  build-and-upload:
    runs-on: ubuntu-latest
    if: ${{ github.repository == 'typeshed-internal/stub_uploader' || github.event_name == 'workflow_dispatch' }}
    steps:
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - name: Checkout main
        uses: actions/checkout@v4
        with:
          path: main
      - name: Checkout typeshed
        uses: actions/checkout@v4
        with:
          repository: python/typeshed
          path: typeshed
          # It is unlikely there will be more commits between two runs.
          # We could set this to 0 to fetch everything, but we want this to be fast.
          fetch-depth: 100
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r main/requirements.txt
      - name: Execute diff build and upload tasks
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: ${{ secrets.TYPESHED_BOT_API_TOKEN }}
        run: |
          cd main
          python -m stub_uploader.upload_changed ../typeshed $(cat data/last_typeshed_commit.sha1)
          (cd ../typeshed; git rev-parse HEAD) > data/last_typeshed_commit.sha1
          if [ -z "$(git status --porcelain)" ]; then
              exit 0;
          fi
          git config user.name github-actions && git config user.email github-actions@github.com
          # This will also commit any new and changed changelogs.
          git add . && git commit -m "Update last typeshed commit" && git push


name: Wheels
on:
  pull_request:
    types: [opened, synchronize, reopened]
  push:
    branches:
      - release/*

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:

  build-wheel-linux:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        python_version: [["3.8", "cp38-cp38"], ["3.9", "cp39-cp39"], ["3.10", "cp310-cp310"], ["3.11", "cp311-cp311"]]
        cuda_support: [["", "--index-url https://download.pytorch.org/whl/cpu", "\"['cpu', '11.3', '11.6']\"", "cpu"]]
    container: pytorch/manylinux-${{ matrix.cuda_support[3] }}
    steps:
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch RC
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install torch ${{ matrix.cuda_support[1] }}
      - name: Build wheel
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install wheel
          TORCHRL_BUILD_VERSION=0.4.0 python3 setup.py bdist_wheel
          # NB: wheels have the linux_x86_64 tag so we rename to manylinux1
          # find . -name 'dist/*whl' -exec bash -c ' mv $0 ${0/linux/manylinux1}' {} \;
      # pytorch/pytorch binaries are also manylinux_2_17 compliant but they
      # pretend that they're manylinux1 compliant so we do the same.
      - name: Show auditwheel output; confirm 2-17
        run: |
          python3 -mpip install auditwheel
          auditwheel show dist/*
      - name: Upload wheel for the test-wheel job
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-linux-${{ matrix.python_version[0] }}.whl
          path: dist/torchrl-*.whl
      - name: Upload wheel for download
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-batch.whl
          path: dist/*.whl

  build-wheel-windows:
    runs-on: windows-latest
    strategy:
      matrix:
        python_version: [["3.8", "3.8"], ["3.9", "3.9"], ["3.10", "3.10.3"], ["3.11", "3.11"]]
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version[1] }}
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch RC
        shell: bash
        run: |
          python3 -mpip install torch --index-url https://download.pytorch.org/whl/cpu
      - name: Build wheel
        shell: bash
        run: |
            python3 -mpip install wheel
            TORCHRL_BUILD_VERSION=0.4.0 python3 setup.py bdist_wheel
      - name: Upload wheel for the test-wheel job
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-win-${{ matrix.python_version[0] }}.whl
          path: dist/torchrl-*.whl
      - name: Upload wheel for download
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-batch.whl
          path: dist/*.whl

  test-wheel:
    needs: [build-wheel-linux]
    strategy:
      matrix:
        os: [["linux", "ubuntu-20.04"]]
        python_version: [ "3.8", "3.9", "3.10", "3.11" ]
    runs-on: ${{ matrix.os[1] }}
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version }}
          architecture: x64
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch RC
        run: |
          python3 -mpip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
      - name: Upgrade pip
        run: |
          python3 -mpip install --upgrade pip
      - name: Install tensordict
        run: |
          python3 -mpip install git+https://github.com/pytorch/tensordict.git
      - name: Install test dependencies
        run: |
          python3 -mpip install numpy pytest pytest-cov codecov unittest-xml-reporting pillow>=4.1.1 scipy av networkx expecttest pyyaml
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-${{ matrix.os[0] }}-${{ matrix.python_version }}.whl
          path: /tmp/wheels
      - name: Install built wheels
        run: |
          python3 -mpip install /tmp/wheels/*
      - name: Log version string
        run: |
          # Avoid ambiguity of "import torchrl" by deleting the source files.
          rm -rf torchrl/
          python -c "import torchrl; print(torchrl.__version__)"
      - name: Run tests
        run: |
          set -e
          export IN_CI=1
          mkdir test-reports
          python -m torch.utils.collect_env
          python -c "import torchrl; print(torchrl.__version__)"
          EXIT_STATUS=0
          pytest test/smoke_test.py -v --durations 200
          exit $EXIT_STATUS

  test-wheel-windows:
    needs: build-wheel-windows
    strategy:
      matrix:
        python_version: [ "3.8", "3.9", "3.10", "3.11" ]
    runs-on: windows-latest
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version }}
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch RC
        shell: bash
        run: |
          python3 -mpip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
      - name: Upgrade pip
        shell: bash
        run: |
          python3 -mpip install --upgrade pip
      - name: Install tensordict
        shell: bash
        run: |
          python3 -mpip install git+https://github.com/pytorch/tensordict.git
      - name: Install test dependencies
        shell: bash
        run: |
          python3 -mpip install numpy pytest pytest-cov codecov unittest-xml-reporting pillow>=4.1.1 scipy av networkx expecttest pyyaml
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-win-${{ matrix.python_version }}.whl
          path: wheels
      - name: Install built wheels
        shell: bash
        run: |
          python3 -mpip install wheels/*
      - name: Log version string
        shell: bash
        run: |
          # Avoid ambiguity of "import torchrl" by deleting the source files.
          rm -rf torchrl/
          python -c "import torchrl; print(torchrl.__version__)"
      - name: Run tests
        shell: bash
        run: |
          set -e
          export IN_CI=1
          mkdir test-reports
          python -m torch.utils.collect_env
          python -c "import torchrl; print(torchrl.__version__)"
          EXIT_STATUS=0
          pytest test/smoke_test.py -v --durations 200
          exit $EXIT_STATUS


Push Binary Nightly

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

name: Push Binary Nightly

on:
  workflow_call:
    secrets:
#      AWS_PYTORCH_UPLOADER_ACCESS_KEY_ID:
#        required: true
#      AWS_PYTORCH_UPLOADER_SECRET_ACCESS_KEY:
#        required: true
      PYPI_TOKEN:
        required: false
  # run every day at 11:15am
  schedule:
    - cron:  '15 11 * * *'
  # or manually trigger it
  workflow_dispatch:
  push:
    branches:
      - "nightly"

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  build-wheel-linux:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        python_version: [["3.8", "cp38-cp38"], ["3.9", "cp39-cp39"], ["3.10", "cp310-cp310"], ["3.11", "cp311-cp311"]]
        cuda_support: [["", "cpu", "cpu"]]
    container: pytorch/manylinux-cuda116
    steps:
      - name: Checkout torchrl
        uses: actions/checkout@v2
        env:
         AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache"
      - name: Install PyTorch nightly
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/${{ matrix.cuda_support[1] }}
      - name: Build TorchRL Nightly
        run: |
          rm -r dist || true
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install wheel
          python3 setup.py bdist_wheel \
            --package_name torchrl-nightly \
            --python-tag=${{ matrix.python-tag }}
           find dist -name '*whl' -exec bash -c ' mv $0 ${0/linux/manylinux1}' {} \;
      # pytorch/pytorch binaries are also manylinux_2_17 compliant but they
      # pretend that they're manylinux1 compliant so we do the same.
      - name: Show auditwheel output; confirm 2-17
        run: |
          python3 -mpip install auditwheel
          auditwheel show dist/*
      - name: Upload wheel for the test-wheel job
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-linux-${{ matrix.python_version[0] }}_${{ matrix.cuda_support[2] }}.whl
          path: dist/*.whl

  upload-wheel-linux:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    needs: test-wheel-linux
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        python_version: [["3.8", "cp38-cp38"], ["3.9", "cp39-cp39"], ["3.10", "cp310-cp310"], ["3.11", "cp311-cp311"]]
        cuda_support: [["", "cpu", "cpu"]]
    container: pytorch/manylinux-${{ matrix.cuda_support[2] }}
    steps:
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-linux-${{ matrix.python_version[0] }}_${{ matrix.cuda_support[2] }}.whl
          path: /tmp/wheels
      - name: Push TorchRL Binary to PYPI
        env:
            PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install twine
          python -m twine upload \
              --username __token__ \
              --password "$PYPI_TOKEN" \
              --skip-existing \
              /tmp/wheels/torchrl_nightly-*.whl \
              --verbose

  test-wheel-linux:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    needs: build-wheel-linux
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        python_version: [["3.8", "cp38-cp38"], ["3.9", "cp39-cp39"], ["3.10", "cp310-cp310"], ["3.11", "cp311-cp311"]]
        cuda_support: [["", "cpu", "cpu"]]
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version[0] }}
          architecture: x64
        env:
          AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache"
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch Nightly
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/${{ matrix.cuda_support[1] }}
      - name: Upgrade pip
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install --upgrade pip
      - name: Install tensordict
        run: |
          python3 -mpip install git+https://github.com/pytorch/tensordict.git
      - name: Install test dependencies
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install numpy pytest pillow>=4.1.1 scipy networkx expecttest pyyaml
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-linux-${{ matrix.python_version[0] }}_${{ matrix.cuda_support[2] }}.whl
          path: /tmp/wheels
        env:
          AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache"
      - name: Install built wheels
        run: |
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -mpip install /tmp/wheels/*
      - name: Log version string
        run: |
          # Avoid ambiguity of "import torchrl" by deleting the source files.
          rm -rf torchrl/
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -c "import torchrl; print(torchrl.__version__)"
      - name: Run tests
        run: |
          set -e
          export IN_CI=1
          mkdir test-reports
          export PATH="/opt/python/${{ matrix.python_version[1] }}/bin:$PATH"
          python3 -m torch.utils.collect_env
          python3 -c "import torchrl; print(torchrl.__version__);from torchrl.data import ReplayBuffer"
          EXIT_STATUS=0
          pytest test/smoke_test.py -v --durations 200
          exit $EXIT_STATUS

  build-wheel-windows:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    runs-on: windows-latest
    strategy:
      matrix:
        python_version: [["3.8", "3.8"], ["3.9", "3.9"], ["3.10", "3.10.3"], ["3.11", "3.11"]]
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version[1] }}
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch nightly
        shell: bash
        run: |
          python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -U
      - name: Build TorchRL nightly
        shell: bash
        run: |
          rm -r dist || true
          python3 -mpip install wheel
          python3 setup.py bdist_wheel \
            --package_name torchrl-nightly \
            --python-tag=${{ matrix.python-tag }}
      - name: Upload wheel for the test-wheel job
        uses: actions/upload-artifact@v2
        with:
          name: torchrl-win-${{ matrix.python_version[0] }}.whl
          path: dist/*.whl

  test-wheel-windows:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    needs: build-wheel-windows
    runs-on: windows-latest
    strategy:
      matrix:
        python_version: [["3.8", "3.8"], ["3.9", "3.9"], ["3.10", "3.10.3"], ["3.11", "3.11"]]
    steps:
      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python_version[1] }}
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Install PyTorch Nightly
        shell: bash
        run: |
          python3 -mpip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -U
      - name: Upgrade pip
        shell: bash
        run: |
          python3 -mpip install --upgrade pip
      - name: Install test dependencies
        shell: bash
        run: |
          python3 -mpip install numpy pytest --no-cache-dir
      - name: Install tensordict
        run: |
          python3 -mpip install git+https://github.com/pytorch/tensordict.git
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-win-${{ matrix.python_version[0] }}.whl
          path: wheels
      - name: Install built wheels
        shell: bash
        run: |
          python3 -mpip install wheels/*
      - name: Log version string
        shell: bash
        run: |
          # Avoid ambiguity of "import torchrl" by deleting the source files.
          rm -rf torchrl/
          python3 -c "import torchrl; print(torchrl.__version__)"
      - name: Run tests
        shell: bash
        run: |
          set -e
          export IN_CI=1
          mkdir test-reports
          python -m torch.utils.collect_env
          python -c "import torchrl; print(torchrl.__version__);from torchrl.data import ReplayBuffer"
          EXIT_STATUS=0
          pytest test/smoke_test.py -v --durations 200
          exit $EXIT_STATUS

  upload-wheel-windows:
    # Don't run on forked repos.
    if: github.repository_owner == 'pytorch'
    needs: test-wheel-windows
    runs-on: windows-latest
    strategy:
      matrix:
        python_version: [["3.8", "3.8"], ["3.9", "3.9"], ["3.10", "3.10.3"], ["3.11", "3.11"]]
    steps:
      - name: Checkout torchrl
        uses: actions/checkout@v2
      - name: Download built wheels
        uses: actions/download-artifact@v2
        with:
          name: torchrl-win-${{ matrix.python_version[0] }}.whl
          path: wheels
      - name: Push TorchRL Binary to PYPI
        shell: bash
        env:
            PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
        run: |
          python3 -mpip install twine
          python3 -m twine upload \
              --username __token__ \
              --password "$PYPI_TOKEN" \
              --skip-existing \
              wheels/torchrl_nightly-*.whl \
              --verbose


Generate documentation

# This workflow builds the torchrl docs and deploys them to gh-pages.
name: Generate documentation
on:
  push:
    branches:
      - main
      - release/*
    tags:
      - v[0-9]+.[0-9]+.[0-9]
      - v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+
  pull_request:
    branches:
      - "*"
  workflow_dispatch:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  build-docs:
    strategy:
      matrix:
        python_version: ["3.9"]
        cuda_arch_version: ["12.1"]
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      repository: pytorch/rl
      upload-artifact: docs
      runner: "linux.g5.4xlarge.nvidia.gpu"
      docker-image: "nvidia/cudagl:11.4.0-base"
      timeout: 120
      script: |
        set -e
        set -v
        apt-get update && apt-get install -y git wget gcc g++
        root_dir="$(pwd)"
        conda_dir="${root_dir}/conda"
        env_dir="${root_dir}/env"
        os=Linux

        # 1. Install conda at ./conda
        printf "* Installing conda\n"
        wget -O miniconda.sh "http://repo.continuum.io/miniconda/Miniconda3-latest-${os}-x86_64.sh"
        bash ./miniconda.sh -b -f -p "${conda_dir}"
        eval "$(${conda_dir}/bin/conda shell.bash hook)"
        printf "* Creating a test environment\n"
        conda create --prefix "${env_dir}" -y python=3.8
        printf "* Activating\n"
        conda activate "${env_dir}"

        # 2. upgrade pip, ninja and packaging
        apt-get install python3.8 python3-pip -y
        python3 -m pip install --upgrade pip
        python3 -m pip install setuptools ninja packaging -U

        # 3. check python version
        python3 --version

        # 4. Check git version
        git version

        # 5. Install PyTorch
        python3 -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cpu -U --quiet --root-user-action=ignore

        # 6. Install tensordict
        python3 -m pip install git+https://github.com/pytorch/tensordict.git --quiet --root-user-action=ignore

        # 7. Install TorchRL
        python3 setup.py develop

        # 8. Install requirements
        python3 -m pip install -r docs/requirements.txt --quiet --root-user-action=ignore

        # 9. Set sanitize version
        if [[ ${{ github.event_name }} == push && (${{ github.ref_type }} == tag || (${{ github.ref_type }} == branch && ${{ github.ref_name }} == release/*)) ]]; then
          echo '::group::Enable version string sanitization'
          # This environment variable just has to exist and must not be empty. The actual value is arbitrary.
          # See docs/source/conf.py for details
          export RL_SANITIZE_VERSION_STR_IN_DOCS=1
          echo '::endgroup::'
        fi

        # 10. Test torchrl installation
        mkdir _tmp
        cd _tmp
        PYOPENGL_PLATFORM=egl MUJOCO_GL=egl python3 -c """from torchrl.envs.libs.dm_control import DMControlEnv
        print(DMControlEnv('cheetah', 'run', from_pixels=True).reset())"""
        cd ..

        # 11. Build doc
        cd ./docs
        # timeout 7m bash -ic "MUJOCO_GL=egl sphinx-build ./source _local_build" || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
        # bash -ic "PYOPENGL_PLATFORM=egl MUJOCO_GL=egl sphinx-build ./source _local_build" || code=$?; if [[ $code -ne 124 && $code -ne 0 ]]; then exit $code; fi
        PYOPENGL_PLATFORM=egl MUJOCO_GL=egl sphinx-build ./source _local_build
        cd ..

        cp -r docs/_local_build/* "${RUNNER_ARTIFACT_DIR}"
        echo $(ls "${RUNNER_ARTIFACT_DIR}")
        if [[ ${{ github.event_name == 'pull_request' }} ]]; then
          cp -r docs/_local_build/* "${RUNNER_DOCS_DIR}"
        fi

  upload:
    needs: build-docs
    if: github.repository == 'pytorch/rl' && github.event_name == 'push' &&
        ((github.ref_type == 'branch' && github.ref_name == 'main') || github.ref_type == 'tag')
    permissions:
      contents: write
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      repository: pytorch/rl
      download-artifact: docs
      ref: gh-pages
      test-infra-ref: main
      script: |
        set -euo pipefail

        REF_TYPE=${{ github.ref_type }}
        REF_NAME=${{ github.ref_name }}

        if [[ "${REF_TYPE}" == branch ]]; then
          if [[ "${REF_NAME}" == main ]]; then
            TARGET_FOLDER="${REF_NAME}"
          # Bebug:
          # else
          #   TARGET_FOLDER="release-doc"
          fi
        elif [[ "${REF_TYPE}" == tag ]]; then
          case "${REF_NAME}" in
            *-rc*)
              echo "Aborting upload since this is an RC tag: ${REF_NAME}"
              exit 0
              ;;
            *)
              # Strip the leading "v" as well as the trailing patch version. For example:
              # 'v0.15.2' -> '0.15'
              TARGET_FOLDER=$(echo "${REF_NAME}" | sed 's/v\([0-9]\+\)\.\([0-9]\+\)\.[0-9]\+/\1.\2/')
              ;;
          esac
        fi

        echo "Target Folder: ${TARGET_FOLDER}"

        mkdir -p "${TARGET_FOLDER}"
        rm -rf "${TARGET_FOLDER}"/*

        echo $(ls "${RUNNER_ARTIFACT_DIR}")
        rsync -a "${RUNNER_ARTIFACT_DIR}"/ "${TARGET_FOLDER}"
        git add "${TARGET_FOLDER}" || true

        # Debug
        # if [[ "${TARGET_FOLDER}" == "main" ]] || [[ "${TARGET_FOLDER}" == "release-doc" ]]; then
        if [[ "${TARGET_FOLDER}" == "main" ]] ; then
          mkdir -p _static
          rm -rf _static/*
          cp -r "${TARGET_FOLDER}"/_static/* _static
          git add _static || true
        fi

        git config user.name 'pytorchbot'
        git config user.email 'soumith+bot@pytorch.org'
        git config http.postBuffer 524288000
        git commit -m "auto-generating sphinx docs" || true
        git push


Continuous Benchmark

name: Continuous Benchmark
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - "*"
  workflow_dispatch:

permissions:
  deployments: write
  contents: write

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:

  benchmark_cpu:
    name: CPU Pytest benchmark
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Setup Environment
        run: |
          python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -U
          python -m pip install git+https://github.com/pytorch/tensordict
          python setup.py develop
          python -m pip install pytest pytest-benchmark
          python3 -m pip install "gym[accept-rom-license,atari]"
          python3 -m pip install dm_control
      - name: Run benchmarks
        run: |
          cd benchmarks/
          python -m pytest --benchmark-json output.json
      - name: Store benchmark results
        if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }}
        uses: benchmark-action/github-action-benchmark@v1
        with:
          name: CPU Benchmark Results
          tool: 'pytest'
          output-file-path: benchmarks/output.json
          fail-on-alert: true
          alert-threshold: '200%'
          alert-comment-cc-users: '@vmoens'
          comment-on-alert: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
          gh-pages-branch: gh-pages
          auto-push: true

  benchmark_gpu:
    name: GPU Pytest benchmark
    runs-on: linux.g5.4xlarge.nvidia.gpu
    defaults:
      run:
        shell: bash -l {0}
    container:
      image: nvidia/cuda:12.3.0-base-ubuntu22.04
      options: --gpus all
    steps:
      - name: Install deps
        run: |
          export TZ=Europe/London
          export DEBIAN_FRONTEND=noninteractive  # tzdata bug
          apt-get update -y
          apt-get install software-properties-common -y
          add-apt-repository ppa:git-core/candidate -y
          apt-get update -y
          apt-get upgrade -y
          apt-get -y install libglu1-mesa libgl1-mesa-glx libosmesa6 gcc curl g++ unzip wget libglfw3-dev libgles2-mesa-dev libglew-dev sudo git cmake libz-dev
      - name: Check ldd --version
        run: ldd --version
      - name: Checkout
        uses: actions/checkout@v3
      - name: Python Setup
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Setup git
        run: git config --global --add safe.directory /__w/rl/rl
      - name: setup Path
        run: |
          echo /usr/local/bin >> $GITHUB_PATH
      - name: Setup Environment
        run: |
          python3 -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cu121 -U
          python3 -m pip install git+https://github.com/pytorch/tensordict
          python3 setup.py develop
          python3 -m pip install pytest pytest-benchmark
          python3 -m pip install "gym[accept-rom-license,atari]"
          python3 -m pip install dm_control
      - name: check GPU presence
        run: |
          python -c """import torch
          assert torch.cuda.device_count()
          """
      - name: Run benchmarks
        run: |
          cd benchmarks/
          python3 -m pytest --benchmark-json output.json
      - name: Store benchmark results
        uses: benchmark-action/github-action-benchmark@v1
        if: ${{ github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' }}
        with:
          name: GPU Benchmark Results
          tool: 'pytest'
          output-file-path: benchmarks/output.json
          fail-on-alert: true
          alert-threshold: '200%'
          alert-comment-cc-users: '@vmoens'
          comment-on-alert: true
          github-token: ${{ secrets.GITHUB_TOKEN }}
          gh-pages-branch: gh-pages
          auto-push: true


Lint

name: Lint

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
  workflow_dispatch:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  python-source-and-configs:
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      repository: pytorch/rl
      script: |
        set -euo pipefail

        echo '::group::Setup environment'
        CONDA_PATH=$(which conda)
        eval "$(${CONDA_PATH} shell.bash hook)"
        conda create --name ci --quiet --yes python=3.8 pip
        conda activate ci
        echo '::endgroup::'

        echo '::group::Install lint tools'
        pip install --progress-bar=off pre-commit
        echo '::endgroup::'

        echo '::group::Lint Python source and configs'
        set +e
        pre-commit run --all-files

        if [ $? -ne 0 ]; then
          git --no-pager diff
          exit 1
        fi
        echo '::endgroup::'

  c-source:
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      repository: pytorch/rl
      script: |
        set -euo pipefail

        echo '::group::Setup environment'
        CONDA_PATH=$(which conda)
        eval "$(${CONDA_PATH} shell.bash hook)"
        conda create --name ci --quiet --yes -c conda-forge python=3.8 ncurses=5 libgcc
        conda activate ci
        export LD_LIBRARY_PATH="${CONDA_PREFIX}/lib:${LD_LIBRARY_PATH}"
        echo '::endgroup::'

        echo '::group::Install lint tools'
        curl https://oss-clang-format.s3.us-east-2.amazonaws.com/linux64/clang-format-linux64 -o ./clang-format
        chmod +x ./clang-format
        echo '::endgroup::'

        echo '::group::Lint C source'
        set +e
        ./.github/unittest/linux/scripts/run-clang-format.py -r torchrl/csrc --clang-format-executable ./clang-format

        if [ $? -ne 0 ]; then
          git --no-pager diff
          exit 1
        fi
        echo '::endgroup::'


Examples Tests on Linux

name: Examples Tests on Linux

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
  workflow_dispatch:

env:
  CHANNEL: "nightly"

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  tests:
    strategy:
      matrix:
        python_version: ["3.9"]
        cuda_arch_version: ["12.1"]
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.g5.4xlarge.nvidia.gpu
      repository: pytorch/rl
      docker-image: "nvidia/cuda:12.2.0-devel-ubuntu22.04"
      gpu-arch-type: cuda
      gpu-arch-version: ${{ matrix.cuda_arch_version }}
      timeout: 90
      script: |
        # Set env vars from matrix
        export PYTHON_VERSION=${{ matrix.python_version }}
        export CUDA_ARCH_VERSION=${{ matrix.cuda_arch_version }}
        export CU_VERSION="cu${CUDA_ARCH_VERSION:0:2}${CUDA_ARCH_VERSION:3:1}"

        if [[ "${{ github.ref }}" =~ release/* ]]; then
          export RELEASE=1
          export TORCH_VERSION=stable
        else
          export RELEASE=0
          export TORCH_VERSION=nightly
        fi

        echo "PYTHON_VERSION: $PYTHON_VERSION"
        echo "CU_VERSION: $CU_VERSION"

        ## setup_env.sh
        bash .github/unittest/linux_examples/scripts/run_all.sh


Habitat Tests on Linux

name: Habitat Tests on Linux

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
  workflow_dispatch:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  tests:
    strategy:
      matrix:
        python_version: ["3.9"]
        cuda_arch_version: ["12.1"]
      fail-fast: false
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      runner: linux.g5.4xlarge.nvidia.gpu
      repository: pytorch/rl
      docker-image: "nvidia/cuda:12.1.1-devel-ubuntu22.04"
      gpu-arch-type: cuda
      gpu-arch-version: ${{ matrix.cuda_arch_version }}
      timeout: 90
      script: |
        if [[ "${{ github.ref }}" =~ release/* ]]; then
          export RELEASE=1
          export TORCH_VERSION=stable
        else
          export RELEASE=0
          export TORCH_VERSION=nightly
        fi

        # Set env vars from matrix
        export PYTHON_VERSION=${{ matrix.python_version }}
        # Commenting these out for now because the GPU test are not working inside docker
        export CUDA_ARCH_VERSION=${{ matrix.cuda_arch_version }}
        export CU_VERSION="cu${CUDA_ARCH_VERSION:0:2}${CUDA_ARCH_VERSION:3:1}"
        # Remove the following line when the GPU tests are working inside docker, and uncomment the above lines
        #export CU_VERSION="cpu"

        bash .github/unittest/linux_libs/scripts_habitat/run_all.sh


RLHF Tests on Linux

name: RLHF Tests on Linux

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
  workflow_dispatch:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  unittests:
    strategy:
      matrix:
        python_version: ["3.9"]
        cuda_arch_version: ["12.1"]
    uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
    with:
      repository: pytorch/rl
      runner: "linux.g5.4xlarge.nvidia.gpu"
      # gpu-arch-type: cuda
      # gpu-arch-version: "11.7"
      docker-image: "nvidia/cudagl:11.4.0-base"
      timeout: 120
      script: |
        if [[ "${{ github.ref }}" =~ release/* ]]; then
          export RELEASE=1
          export TORCH_VERSION=stable
        else
          export RELEASE=0
          export TORCH_VERSION=nightly
        fi

        set -euo pipefail
        export PYTHON_VERSION="3.9"
        export CU_VERSION="cu117"
        export TAR_OPTIONS="--no-same-owner"
        export UPLOAD_CHANNEL="nightly"
        export TF_CPP_MIN_LOG_LEVEL=0

        bash .github/unittest/linux_libs/scripts_rlhf/setup_env.sh
        bash .github/unittest/linux_libs/scripts_rlhf/install.sh
        bash .github/unittest/linux_libs/scripts_rlhf/run_test.sh
        bash .github/unittest/linux_libs/scripts_rlhf/post_process.sh


Continuous Benchmark (PR)

name: Continuous Benchmark (PR)

on:
  pull_request:

permissions: write-all

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  benchmark_cpu:
    name: CPU Pytest benchmark
    runs-on: ubuntu-20.04
    steps:
      - name: Who triggered this?
        run: |
          echo "Action triggered by ${{ github.event.pull_request.html_url }}"
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 50 # this is to make sure we obtain the target base commit
      - name: Python Setup
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Setup Environment
        run: |
          python -m pip install --pre torch --index-url https://download.pytorch.org/whl/nightly/cpu -U
          python -m pip install git+https://github.com/pytorch/tensordict
          python setup.py develop
          python -m pip install pytest pytest-benchmark
          python3 -m pip install "gym[accept-rom-license,atari]"
          python3 -m pip install dm_control
      - name: Setup benchmarks
        run: |
          echo "BASE_SHA=$(echo ${{ github.event.pull_request.base.sha }} | cut -c1-8)" >> $GITHUB_ENV
          echo "HEAD_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-8)" >> $GITHUB_ENV
          echo "BASELINE_JSON=$(mktemp)" >> $GITHUB_ENV
          echo "CONTENDER_JSON=$(mktemp)" >> $GITHUB_ENV
          echo "PR_COMMENT=$(mktemp)" >>  $GITHUB_ENV
      - name: Run benchmarks
        run: |
          cd benchmarks/
          RUN_BENCHMARK="pytest --rank 0 --benchmark-json "
          git checkout ${{ github.event.pull_request.base.sha }}
          $RUN_BENCHMARK ${{ env.BASELINE_JSON }}
          git checkout ${{ github.event.pull_request.head.sha }}
          $RUN_BENCHMARK ${{ env.CONTENDER_JSON }}
      - name: Publish results
        uses: apbard/pytest-benchmark-commenter@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          benchmark-file: ${{ env.CONTENDER_JSON }}
          comparison-benchmark-file: ${{ env.BASELINE_JSON }}
          benchmark-metrics: 'name,max,mean,ops'
          comparison-benchmark-metric: 'ops'
          comparison-higher-is-better: true
          comparison-threshold: 5
          benchmark-title: 'Result of CPU Benchmark Tests'

  benchmark_gpu:
    name: GPU Pytest benchmark
    runs-on: linux.g5.4xlarge.nvidia.gpu
    defaults:
      run:
        shell: bash -l {0}
    container:
      image: nvidia/cuda:12.3.0-base-ubuntu22.04
      options: --gpus all
    steps:
      - name: Who triggered this?
        run: |
          echo "Action triggered by ${{ github.event.pull_request.html_url }}"
      - name: Install deps
        run: |
          export TZ=Europe/London
          export DEBIAN_FRONTEND=noninteractive  # tzdata bug
          apt-get update -y
          apt-get install software-properties-common -y
          add-apt-repository ppa:git-core/candidate -y
          apt-get update -y
          apt-get upgrade -y
          apt-get -y install libglu1-mesa libgl1-mesa-glx libosmesa6 gcc curl g++ unzip wget libglfw3-dev libgles2-mesa-dev libglew-dev sudo git cmake libz-dev
      - name: Check ldd --version
        run: ldd --version
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 50 # this is to make sure we obtain the target base commit
      - name: Python Setup
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Setup git
        run: git config --global --add safe.directory /__w/rl/rl
      - name: setup Path
        run: |
          echo /usr/local/bin >> $GITHUB_PATH
      - name: Setup Environment
        run: |
          python3 -m pip install --pre torch torchvision --index-url https://download.pytorch.org/whl/nightly/cu121 -U
          python3 -m pip install git+https://github.com/pytorch/tensordict
          python3 setup.py develop
          python3 -m pip install pytest pytest-benchmark
          python3 -m pip install "gym[accept-rom-license,atari]"
          python3 -m pip install dm_control
      - name: check GPU presence
        run: |
          python -c """import torch
          assert torch.cuda.device_count()
          """
      - name: Setup benchmarks
        run: |
          echo "BASE_SHA=$(echo ${{ github.event.pull_request.base.sha }} | cut -c1-8)" >> $GITHUB_ENV
          echo "HEAD_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-8)" >> $GITHUB_ENV
          echo "BASELINE_JSON=$(mktemp)" >> $GITHUB_ENV
          echo "CONTENDER_JSON=$(mktemp)" >> $GITHUB_ENV
          echo "PR_COMMENT=$(mktemp)" >>  $GITHUB_ENV
      - name: Run benchmarks
        run: |
          cd benchmarks/
          RUN_BENCHMARK="pytest --rank 0 --benchmark-json "
          git checkout ${{ github.event.pull_request.base.sha }}
          $RUN_BENCHMARK ${{ env.BASELINE_JSON }}
          git checkout ${{ github.event.pull_request.head.sha }}
          $RUN_BENCHMARK ${{ env.CONTENDER_JSON }}
      - name: Publish results
        uses: apbard/pytest-benchmark-commenter@v3
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          benchmark-file: ${{ env.CONTENDER_JSON }}
          comparison-benchmark-file: ${{ env.BASELINE_JSON }}
          benchmark-metrics: 'name,max,mean,ops'
          comparison-benchmark-metric: 'ops'
          comparison-higher-is-better: true
          comparison-threshold: 5
          benchmark-title: 'Result of GPU Benchmark Tests'


Build M1 Wheels

name: Build M1 Wheels

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
    tags:
        # NOTE: Binary build pipelines should only get triggered on release candidate builds
        # Release candidate tags look like: v1.11.0-rc1
        - v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+
  workflow_dispatch:

permissions:
  id-token: write
  contents: read

jobs:
  generate-matrix:
    uses: pytorch/test-infra/.github/workflows/generate_binary_build_matrix.yml@main
    with:
      package-type: wheel
      os: macos-arm64
      test-infra-repository: pytorch/test-infra
      test-infra-ref: main
  build:
    needs: generate-matrix
    strategy:
      fail-fast: false
      matrix:
        include:
          - repository: pytorch/rl
            smoke-test-script: test/smoke_test.py
            package-name: torchrl
    name: pytorch/rl
    uses: pytorch/test-infra/.github/workflows/build_wheels_macos.yml@main
    with:
      repository: ${{ matrix.repository }}
      ref: ""
      test-infra-repository: pytorch/test-infra
      test-infra-ref: main
      build-matrix: ${{ needs.generate-matrix.outputs.matrix }}
      package-name: ${{ matrix.package-name }}
      runner-type: macos-m1-stable
      smoke-test-script: ${{ matrix.smoke-test-script }}
      trigger-event: ${{ github.event_name }}
      env-var-script: .github/scripts/m1_script.sh


Unit-tests on Windows

name: Unit-tests on Windows

on:
  pull_request:
  push:
    branches:
      - nightly
      - main
      - release/*
  workflow_dispatch:

concurrency:
  # Documentation suggests ${{ github.head_ref }}, but that's only available on pull_request/pull_request_target triggers, so using ${{ github.ref }}.
  # On master, we want all builds to complete even if merging happens faster to make it easier to discover at which point something broke.
  group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && format('ci-master-{0}', github.sha) || format('ci-{0}', github.ref) }}
  cancel-in-progress: true

jobs:
  unittests-cpu:
    uses: pytorch/test-infra/.github/workflows/windows_job.yml@main
    with:
      runner: "windows.4xlarge"
      repository: pytorch/rl
      timeout: 40
      script: |
        set -euxo pipefail

        export PYTHON_VERSION="3.9"
        export CU_VERSION="cpu"
        export torch_cuda="False"

        # TODO: Port this to pytorch/test-infra/.github/workflows/windows_job.yml
        export PATH="/c/Jenkins/Miniconda3/Scripts:${PATH}"

        echo "PYTHON_VERSION: $PYTHON_VERSION"
        echo "CU_VERSION: $CU_VERSION"

        if [[ "${{ github.ref }}" =~ release/* ]]; then
          export RELEASE=1
          export TORCH_VERSION=stable
        else
          export RELEASE=0
          export TORCH_VERSION=nightly
        fi

        ## setup_env.sh
        ./.github/unittest/windows_optdepts/scripts/setup_env.sh

        ## install.sh
        ./.github/unittest/windows_optdepts/scripts/install.sh

        ## run_test.sh
        ./.github/unittest/windows_optdepts/scripts/run_test.sh

        ## post_process.sh
        ./.github/unittest/windows_optdepts/scripts/post_process.sh

#  unittests-gpu:
#    uses: pytorch/test-infra/.github/workflows/windows_job.yml@main
#    with:
#      runner: "windows.g5.4xlarge.nvidia.gpu"
#      repository: pytorch/rl
#      timeout: 40
#      script: |
#        set -euxo pipefail
#
#        export PYTHON_VERSION="3.9"
#        export CUDA_VERSION="11.6"
#        export CU_VERSION="cu116"
#        export torch_cuda="True"
#
#        # TODO: Port this to pytorch/test-infra/.github/workflows/windows_job.yml
#        export PATH="/c/Jenkins/Miniconda3/Scripts:${PATH}"
#
#        echo "PYTHON_VERSION: $PYTHON_VERSION"
#
#        if [[ "${{ github.ref }}" =~ release/* ]]; then
#          export RELEASE=1
#          export TORCH_VERSION=stable
#        else
#          export RELEASE=0
#          export TORCH_VERSION=nightly
#        fi
#
#        ## setup_env.sh
#        ./.github/unittest/windows_optdepts/scripts/setup_env.sh
#
#        ## Install CUDA
#        packaging/windows/internal/cuda_install.bat
#
#        ## Update CUDA Driver
#        packaging/windows/internal/driver_update.bat
#
#        ## install.sh
#        ./.github/unittest/windows_optdepts/scripts/install.sh
#
#        ## run_test.sh
#        ./.github/unittest/windows_optdepts/scripts/run_test.sh
#
#        ## post_process.sh
#        ./.github/unittest/windows_optdepts/scripts/post_process.sh