diff --git a/.github/actions/gh_tests/action.yml b/.github/actions/gh_tests/action.yml new file mode 100644 index 0000000000..e7f99d6e9f --- /dev/null +++ b/.github/actions/gh_tests/action.yml @@ -0,0 +1,80 @@ +name: GH Tests +description: "Run quick or full tests with a single configurable action." +inputs: + mode: + description: "Test mode: quick (only serial), medium (1 and 4 ranks), and full (1 to 4)." + required: false + default: "full" + sha: + description: "Commit SHA to checkout before running tests." + required: false + default: "${{ github.sha }}" + py-version: + description: "Python version for the test run." + required: false + default: "3.14" + mpi: + description: "MPI implementation to install." + required: false + default: "mpich" + install-options: + description: "Package install target/options for heat." + required: false + default: ".[dev]" + pytorch-version: + description: "Pinned torch/torchvision/torchaudio versions." + required: false + default: "torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0" +runs: + using: "composite" + steps: + - name: Setup MPI + uses: mpi4py/setup-mpi@3969f247e8fceef153418744f9d9ee6fdaeda29f # v1.2.0 + with: + mpi: ${{ inputs.mpi }} + - name: "Set up Python" + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "${{ inputs.py-version }}" + - name: Install uv and set the Python version + uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + enable-cache: true + # Installations + - name: Install heat + if: ${{ inputs.mode == 'full' || inputs.mode == 'medium' }} + shell: bash + env: + UV_SYSTEM_PYTHON: 1 + run: | + uv pip install pytest flaky + uv pip install ${{ inputs.pytorch-version }} --extra-index-url https://download.pytorch.org/whl/cpu + uv pip install -e ${{ inputs.install-options }} + - name: Install quick test dependencies + if: ${{ inputs.mode == 'quick' }} + shell: bash + env: + UV_SYSTEM_PYTHON: 1 + run: | + uv pip install pytest flaky + uv pip install . + # Running tests + - name: Run serial tests + shell: bash + run: | + mpirun -n 1 pytest -vv + - name: Run tests on 2 ranks + if: ${{ inputs.mode == 'full'}} + shell: bash + run: | + mpirun -n 2 pytest -vv + - name: Run tests on 3 ranks + if: ${{ inputs.mode == 'full'}} + shell: bash + run: | + mpirun -n 3 pytest -vv + - name: Run tests on 4 ranks + if: ${{ inputs.mode == 'full' || inputs.mode == 'medium' }} + shell: bash + run: | + mpirun -n 4 pytest -vv diff --git a/.github/actions/trigger_codebase_benchmarks/action.yml b/.github/actions/trigger_codebase_benchmarks/action.yml new file mode 100644 index 0000000000..461f9582fa --- /dev/null +++ b/.github/actions/trigger_codebase_benchmarks/action.yml @@ -0,0 +1,45 @@ +name: Trigger Codebase Benchmarks +description: "Trigger benchmarks on Codebase for performance testing and analysis." +inputs: + branch: + description: "The branch to trigger benchmarks on. Defaults to 'main'." + required: false + default: "main" + sha: + description: "The commit SHA to trigger benchmarks on. Defaults to the current commit." + required: false + default: "${{ github.sha }}" + pr_number: + description: "The pull request number to trigger benchmarks on. Defaults to the current PR number." + required: false + default: "" + author: + description: "The author of the benchmarks. Defaults to the PR assignee or 'heat_team'." + required: false + default: "${{ github.event.pull_request.assignee.login || 'heat_team' }}" + trigger_token: + description: "The trigger token used to start the Codebase pipeline." + required: true +runs: + using: "composite" + steps: + - name: Trigger benchmarks + shell: bash + env: + AUTHOR: ${{ inputs.author}} + BRANCH: ${{ inputs.branch }} + API_TOKEN: ${{ inputs.trigger_token }} + SHA: ${{ inputs.sha }} + PR_NUMBER: ${{ inputs.pr_number }} + run: | + SHORT_SHA=$(git rev-parse --short $SHA) + curl -s -X POST \ + --fail-with-body \ + -F "token=$API_TOKEN" \ + -F "ref=pipeline/cb/base" \ + -F "variables[SHA]=$SHA" \ + -F "variables[SHORT_SHA]=${SHORT_SHA}" \ + -F "variables[BRANCH]=$BRANCH" \ + -F "variables[PR]=$PR_NUMBER" \ + -F "variables[AUTHOR]=${AUTHOR}" \ + https://codebase.helmholtz.cloud/api/v4/projects/20697/trigger/pipeline diff --git a/.github/actions/trigger_codebase_tests/action.yml b/.github/actions/trigger_codebase_tests/action.yml new file mode 100644 index 0000000000..65ae0e2a71 --- /dev/null +++ b/.github/actions/trigger_codebase_tests/action.yml @@ -0,0 +1,36 @@ +name: Trigger Codebase Tests +description: "Trigger tests on Codebase for performance testing and analysis." +inputs: + branch: + description: "The branch to trigger tests on. Defaults to 'main'." + required: false + default: "main" + sha: + description: "The commit SHA to trigger tests on. Defaults to the current commit." + required: false + default: "${{ github.sha }}" + pr_number: + description: "The pull request number to trigger tests on. Defaults to the current PR number." + required: false + default: "" + trigger_token: + description: "The trigger token used to start the Codebase pipeline." + required: true +runs: + using: "composite" + steps: + - name: Trigger codebase tests + shell: bash + env: + API_TOKEN: ${{ inputs.trigger_token }} + BRANCH: ${{ inputs.branch }} + PR_NUMBER: ${{ inputs.pr_number }} + run: | + curl -s -X POST \ + --fail-with-body \ + -F "token=$API_TOKEN" \ + -F "ref=pipeline/ci/base" \ + -F "variables[BRANCH]=$BRANCH" \ + -F "variables[PR]=$PR_NUMBER" \ + -F "variables[SHA]=${{ inputs.sha }}" \ + https://codebase.helmholtz.cloud/api/v4/projects/20697/trigger/pipeline diff --git a/.github/workflows/increment_version.sh b/.github/scripts/increment_version.sh similarity index 100% rename from .github/workflows/increment_version.sh rename to .github/scripts/increment_version.sh diff --git a/.github/workflows/CIBase.yml b/.github/workflows/CIBase.yml deleted file mode 100644 index 88e024d904..0000000000 --- a/.github/workflows/CIBase.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: Start CI Run - -on: - push: - branches: - - 'main' - - 'stable' - -permissions: - contents: read - -jobs: - starter: - runs-on: ubuntu-latest - steps: - - name: Exit if secret is missing - run: | - if [ -z "${{ secrets.CB_PIPELINE }}" ]; then - echo "Secret CB_PIPELINE not set, skipping job." - exit 0 - fi - - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: Get branch names - id: branch-names - uses: tj-actions/branch-names@5250492686b253f06fa55861556d1027b067aeb5 # v9.0.2 - - - name: 'start test' - run: | - curl -s -X POST \ - --fail \ - -F token=${{ secrets.CB_PIPELINE }} \ - -F "ref=heat/base" \ - -F "variables[SHA]=$GITHUB_SHA" \ - -F "variables[GHBRANCH]=${{ steps.branch-names.outputs.current_branch }}" \ - https://codebase.helmholtz.cloud/api/v4/projects/7605/trigger/pipeline -o /dev/null diff --git a/.github/workflows/CISupport.yml b/.github/workflows/CISupport.yml deleted file mode 100644 index 53d001eb51..0000000000 --- a/.github/workflows/CISupport.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Start CI Support Run - -on: - push: - branches: - - 'support/**' - -jobs: - starter: - runs-on: ubuntu-latest - steps: - - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: Get branch names - id: branch-names - uses: tj-actions/branch-names@5250492686b253f06fa55861556d1027b067aeb5 # v9.0.2 - - name: 'start test' - run: | - curl -s -X POST \ - --fail \ - -F token=${{ secrets.CB_PIPELINE }} \ - -F "ref=heat/support" \ - -F "variables[SHA]=$GITHUB_SHA" \ - -F "variables[GHBRANCH]=${{ steps.branch-names.outputs.current_branch }}" \ - https://codebase.helmholtz.cloud/api/v4/projects/7605/trigger/pipeline -o /dev/null diff --git a/.github/workflows/CommentPR.yml b/.github/workflows/CommentPR.yml deleted file mode 100644 index d1ece6c35e..0000000000 --- a/.github/workflows/CommentPR.yml +++ /dev/null @@ -1,69 +0,0 @@ -name: Comment on the pull request - -on: - workflow_run: - workflows: ["Receive PR"] - types: - - completed - -jobs: - upload: - runs-on: ubuntu-latest - if: > - github.event.workflow_run.event == 'pull_request' && - github.event.workflow_run.conclusion == 'success' - outputs: - PR_NR: ${{ steps.step1.outputs.test }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: 'Download artifact' - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - with: - script: | - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "pr_number" - })[0]; - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - let fs = require('fs'); - fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr_number.zip`, Buffer.from(download.data)); - - - name: 'Unzip artifact' - run: unzip pr_number.zip - - - id: step1 - run: echo "test=$(< ./pr_number)" >> "$GITHUB_OUTPUT" - - push: - needs: upload - runs-on: ubuntu-latest - if: ${{ !github.event.repository.fork }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: 'Trigger Workflow' - run: | - curl -s -X POST \ - --fail \ - -F token=${{ secrets.CB_PIPELINE }} \ - -F "ref=heat/pr" \ - -F "variables[PR]=${{ needs.upload.outputs.PR_NR }}" \ - https://codebase.helmholtz.cloud/api/v4/projects/7605/trigger/pipeline -o /dev/null diff --git a/.github/workflows/ReceivePR.yml b/.github/workflows/ReceivePR.yml deleted file mode 100644 index 6ecded6b60..0000000000 --- a/.github/workflows/ReceivePR.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Receive PR - -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - paths: - - 'heat/**' - - 'tests/**' - -jobs: - build: - if: ${{ !startsWith(github.head_ref, 'support/') && (github.event.pull_request.draft == false) }} - runs-on: ubuntu-latest - - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Use Python - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: '3.14' - architecture: x64 - - - name: Setup MPI - uses: mpi4py/setup-mpi@40c19a60792debf8ca403a3e6ee5f84c4e76555d # v1.2.1 - with: - mpi: openmpi - - - name: Test - run: | - pip install .[dev] - pip install pytest flaky - pre-commit run --all-files - pytest - - - name: Save PR number - env: - PR_NUMBER: ${{ github.event.number }} - run: | - mkdir -p ./pr - echo $PR_NUMBER > ./pr/pr_number - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: pr_number - path: pr/ diff --git a/.github/workflows/array-api.yml b/.github/workflows/array-api.yml index b5c18fd4c6..bc962fbe0d 100644 --- a/.github/workflows/array-api.yml +++ b/.github/workflows/array-api.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: python-version: ['3.11', '3.12', '3.13', '3.14'] - mpi: [ 'openmpi' ] + mpi: [ 'mpich' ] steps: - name: Checkout diff --git a/.github/workflows/bench_trigger.yml b/.github/workflows/bench_trigger.yml deleted file mode 100644 index 77f76ade3f..0000000000 --- a/.github/workflows/bench_trigger.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Trigger benchmarks -on: - push: - branches: - - main - pull_request: - types: [synchronize] - -permissions: - contents: read - -jobs: - - trigger-benchmark: - name: Trigger Benchmarks - runs-on: ubuntu-latest - steps: - - name: Exit if secret is missing - run: | - if [ -z "${{ secrets.BENCH_PIPE_TRIGGER }}" ]; then - echo "Secret BENCH_PIPE_TRIGGER not set, skipping job." - exit 0 - fi - - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Trigger benchmarks (PR) - id: setup_pr - if: contains(github.event.pull_request.labels.*.name, 'benchmark PR') - env: - AUTHOR: ${{ github.event.pull_request.assignee.login }} - BRANCH: ${{ github.head_ref }} - PIPE_TRIGGER_TOKEN: ${{ secrets.BENCH_PIPE_TRIGGER }} - SHA: ${{ github.event.pull_request.head.sha }} - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - SHORT_SHA=$(git rev-parse --short $SHA) - curl -s -X POST \ - --fail-with-body \ - -F "token=$PIPE_TRIGGER_TOKEN" \ - -F "ref=main" \ - -F "variables[SHA]=$SHA" \ - -F "variables[SHORT_SHA]=${SHORT_SHA}" \ - -F "variables[BRANCH]=$BRANCH" \ - -F "variables[PR]=$PR_NUMBER" \ - -F "variables[AUTHOR]=${AUTHOR:-heat_team}" \ - https://codebase.helmholtz.cloud/api/v4/projects/7930/trigger/pipeline - - name: Trigger benchmarks (Push main) - id: setup_push - if: ${{ github.event_name == 'push' }} - env: - AUTHOR: ${{ github.event.pull_request.assignee.login }} - PIPE_TRIGGER_TOKEN: ${{ secrets.BENCH_PIPE_TRIGGER }} - SHA: ${{ github.sha }} - run: | - SHORT_SHA=$(git rev-parse --short $GITHUB_SHA) - curl -s -X POST \ - --fail-with-body \ - -F "token=$PIPE_TRIGGER_TOKEN" \ - -F "ref=main" \ - -F "variables[SHA]=$SHA" \ - -F "variables[SHORT_SHA]=${SHORT_SHA}" \ - -F "variables[BRANCH]=main" \ - -F "variables[AUTHOR]=${AUTHOR:-heat_team}" \ - https://codebase.helmholtz.cloud/api/v4/projects/7930/trigger/pipeline diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index 4498615bc6..0000000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,62 +0,0 @@ -name: ci - -on: - push: - branches-ignore: - - main - - dependabot/** - -jobs: - tests: - runs-on: ubuntu-latest - timeout-minutes: 120 - strategy: - fail-fast: false - matrix: - py-version: - - '3.11' # Oldest supported - - '3.14' # Latest stable - mpi: [ 'openmpi' ] - install-options: [ '.', '.[dev]' ] - pytorch-version: - - 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' # Oldest supported - - 'torch==2.9.1 torchvision==0.24.1 torchaudio==2.9.1' # JSC Stage 2026 - - 'torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0' # Latest stable - exclude: - - py-version: '3.14' - pytorch-version: 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' - - name: Python ${{ matrix.py-version }} with ${{ matrix.pytorch-version }}; options ${{ matrix.install-options }} - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Setup MPI - uses: mpi4py/setup-mpi@3969f247e8fceef153418744f9d9ee6fdaeda29f # v1.2.0 - with: - mpi: ${{ matrix.mpi }} - - - name: Use Python ${{ matrix.py-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: ${{ matrix.py-version }} - architecture: x64 - - - name: Install heat - run: | - pip install pytest flaky - pip install ${{ matrix.pytorch-version }} ${{ matrix.install-options }} --extra-index-url https://download.pytorch.org/whl/cpu - - - name: Run serial tests - run: | - # use pytest -vv -x for debugging - pytest - - - name: Run parallel tests - run: | - mpirun -n 4 pytest -vv diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index ed58b41a23..0000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,78 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: ["main"] - pull_request: - # The branches below must be a subset of the branches above - branches: ["main"] - schedule: - - cron: "0 0 * * 1" - -permissions: - contents: read - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: ["python"] - # CodeQL supports [ $supported-codeql-languages ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml deleted file mode 100644 index a29ada993c..0000000000 --- a/.github/workflows/dependency-review.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Dependency Review Action -# -# This Action will scan dependency manifest files that change as part of a Pull Request, -# surfacing known-vulnerable versions of the packages declared or updated in the PR. -# Once installed, if the workflow run is marked as required, -# PRs introducing known-vulnerable packages will be blocked from merging. -# -# Source repository: https://github.com/actions/dependency-review-action -name: 'Dependency Review' -on: [pull_request] - -permissions: - contents: read - -jobs: - dependency-review: - runs-on: ubuntu-latest - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: 'Checkout Repository' - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: 'Dependency Review' - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 diff --git a/.github/workflows/inactivity.yml b/.github/workflows/inactivity.yml deleted file mode 100644 index 4423ecd502..0000000000 --- a/.github/workflows/inactivity.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: Close inactive issues -on: - schedule: - - cron: "30 1 * * 1" - -permissions: - contents: read - -jobs: - close-issues: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 - with: - days-before-issue-stale: 60 - days-before-issue-close: 60 - stale-issue-label: "stale" - stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." - close-issue-message: "This issue was closed because it has been inactive for 60 days since being marked as stale." - days-before-pr-stale: 60 - days-before-pr-close: 60 - stale-pr-label: "stale" - stale-pr-message: "This pull request is stale because it has been open for 60 days with no activity." - close-pr-message: "This pull request was closed because it has been inactive for 60 days since being marked as stale." - repo-token: ${{ secrets.GITHUB_TOKEN }} - exempt-issue-labels: "epic,discussion,good first issue,RFC,student project" - exempt-pr-labels: "epic,discussion,good first issue,RFC,student project" diff --git a/.github/workflows/markdown-links-check.yml b/.github/workflows/markdown-links-check.yml deleted file mode 100644 index 2ab31721a2..0000000000 --- a/.github/workflows/markdown-links-check.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Markdown Links Check -# runs every monday at 9 am -on: - schedule: - - cron: "0 9 * * 1" - -permissions: - contents: read - -jobs: - check-links: - runs-on: ubuntu-latest - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # master - - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1 - # checks all markdown files from root but ignores subfolders - # By Removing the max-depth variable we can modify it -> to check all the .md files in the entire repo. - with: - use-quiet-mode: 'yes' - # Specifying yes to show only errors in the output - use-verbose-mode: 'yes' - # Specifying yes to show detailed HTTP status for checked links. - max-depth: 0 diff --git a/.github/workflows/backport.yml b/.github/workflows/pr_close.yml similarity index 82% rename from .github/workflows/backport.yml rename to .github/workflows/pr_close.yml index bbb4017790..20e2b853e1 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/pr_close.yml @@ -1,4 +1,4 @@ -name: Backport merged pull request +name: On PR Close on: pull_request_target: types: [closed] @@ -10,8 +10,8 @@ jobs: backport: name: Backport pull request runs-on: ubuntu-latest - # Don't run on closed unmerged pull requests - if: github.event.pull_request.merged && ${{ !github.event.repository.fork }} + # Don't run on closed unmerged pull requests or on forks + if: ${{ github.event.pull_request.merged && !github.event.repository.fork }} steps: - name: Harden the runner (Audit all outbound calls) uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/pr_open.yml similarity index 75% rename from .github/workflows/release-drafter.yml rename to .github/workflows/pr_open.yml index 01e8ee395a..2851928d9c 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/pr_open.yml @@ -1,5 +1,4 @@ -name: Release Drafter - +name: On PR Open on: pull_request: types: [opened, reopened] @@ -7,20 +6,12 @@ permissions: contents: read jobs: - - update_release_draft: + update_release_drafter: permissions: contents: write # for release-drafter/release-drafter to create a github release pull-requests: write # for release-drafter/release-drafter to add label to PR runs-on: ubuntu-latest steps: - - name: Exit if secret is missing - run: | - if [ -z "${{ secrets.GITHUB_TOKEN }}" ]; then - echo "Secret GITHUB_TOKEN not set, skipping job." - exit 0 - fi - - name: Harden Runner uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: diff --git a/.github/workflows/pr_update.yml b/.github/workflows/pr_update.yml new file mode 100644 index 0000000000..6512daa33c --- /dev/null +++ b/.github/workflows/pr_update.yml @@ -0,0 +1,101 @@ +name: On PR Update + +on: + pull_request: + types: [opened, reopened, synchronize] + paths: + - '.github/**' + - 'heat/**' + - 'tests/**' + +jobs: + quick-tests: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + py-version: + - '3.11' # Oldest supported + - '3.14' # Latest stable + mpi: [ 'mpich' ] + install-options: [ '.[dev]' ] + pytorch-version: + - 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' # Oldest supported + - 'torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0' # Latest stable + exclude: + - py-version: '3.14' + pytorch-version: 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' + name: Quick Tests - Py${{ matrix.py-version }} with ${{ matrix.pytorch-version }}" + steps: + - name: Harden the runner + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: ./.github/actions/gh_tests + with: + mode: quick + sha: ${{ github.event.pull_request.head.sha }} + py-version: ${{ matrix.py-version }} + mpi: ${{ matrix.mpi }} + install-options: ${{ matrix.install-options }} + pytorch-version: ${{ matrix.pytorch-version }} + + trigger-tests: + name: Trigger Codebase Tests + runs-on: ubuntu-latest + needs: quick-tests + if: ${{ !github.event.repository.fork }} + steps: + - name: Harden the runner + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: ./.github/actions/trigger_codebase_tests + with: + branch: ${{ github.head_ref }} + sha: ${{ github.event.pull_request.head.sha }} + pr_number: ${{ github.event.pull_request.number }} + trigger_token: ${{ secrets.CX_TRIGGER_TOKEN }} + + trigger-benchmarks: + name: Trigger Codebase Benchmarks + runs-on: ubuntu-latest + needs: trigger-tests + if: ${{ !github.event.repository.fork && contains(github.event.pull_request.labels.*.name, 'benchmark PR') }} + steps: + - name: Harden the runner + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + - uses: ./.github/actions/trigger_codebase_benchmarks + with: + branch: ${{ github.head_ref }} + sha: ${{ github.event.pull_request.head.sha }} + author: ${{ github.event.pull_request.assignee.login || 'heat_team' }} + pr_number: ${{ github.event.pull_request.number }} + trigger_token: ${{ secrets.CX_TRIGGER_TOKEN }} + + dependency-review: + name: Dependency Review + runs-on: ubuntu-latest + steps: + - name: Harden the runner + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: 'Checkout Repository' + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: 'Dependency Review' + uses: actions/dependency-review-action@da24556b548a50705dd671f47852072ea4c105d9 # v4.7.1 diff --git a/.github/workflows/ci_full.yaml b/.github/workflows/push_main.yml similarity index 65% rename from .github/workflows/ci_full.yaml rename to .github/workflows/push_main.yml index 0a1a917a0d..dd8143c803 100644 --- a/.github/workflows/ci_full.yaml +++ b/.github/workflows/push_main.yml @@ -1,5 +1,4 @@ -name: ci_full - +name: On Push Main on: push: branches: @@ -9,10 +8,32 @@ on: - 'heat/**' - 'tests/**' - 'pyproject.toml' - - '.github/workflows/ci_full.yaml' - jobs: - full_matrix_test: + codebase-test-and-bench-main: + name: Codebase Tests and Benchmarks + if: ${{ !github.event.repository.fork }} + runs-on: ubuntu-latest + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.sha }} + - uses: ./.github/actions/trigger_codebase_tests + with: + branch: "main" + sha: ${{ github.sha}} + trigger_token: ${{ secrets.CX_TRIGGER_TOKEN }} + - uses: ./.github/actions/trigger_codebase_benchmarks + with: + branch: "main" + sha: ${{ github.sha}} + author: 'heat_team' + trigger_token: ${{ secrets.CX_TRIGGER_TOKEN }} + gh-matrix-tests: runs-on: ubuntu-latest timeout-minutes: 120 strategy: @@ -23,8 +44,8 @@ jobs: - '3.12' - '3.13' - '3.14' - mpi: [ 'openmpi' ] - install-options: [ '.', '.[dev]' ] + mpi: [ 'mpich' ] + install-options: [ '.[dev]' ] pytorch-version: - 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' - 'torch==2.4.1 torchvision==0.19.1 torchaudio==2.4.1' @@ -61,30 +82,14 @@ jobs: uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 with: egress-policy: audit - - - name: Checkout + - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Setup MPI - uses: mpi4py/setup-mpi@3969f247e8fceef153418744f9d9ee6fdaeda29f # v1.2.0 with: - mpi: ${{ matrix.mpi }} - - - name: Use Python ${{ matrix.py-version }} - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + ref: ${{ github.sha }} + - uses: ./.github/actions/gh_tests with: - python-version: ${{ matrix.py-version }} - architecture: x64 - - - name: Install heat - run: | - pip install pytest flaky - pip install ${{ matrix.pytorch-version }} ${{ matrix.install-options }} --extra-index-url https://download.pytorch.org/whl/cpu - - - name: Run tests with 3 tasks - run: | - mpirun -n 3 pytest - - - name: Run tests with 4 tasks - run: | - mpirun -n 4 pytest + mode: "full" + py-version: ${{ matrix.py-version }} + mpi: ${{ matrix.mpi }} + install-options: ${{ matrix.install-options }} + pytorch-version: ${{ matrix.pytorch-version }} diff --git a/.github/workflows/push_other.yml b/.github/workflows/push_other.yml new file mode 100644 index 0000000000..452182810f --- /dev/null +++ b/.github/workflows/push_other.yml @@ -0,0 +1,64 @@ +name: On Push Other +# This workflow is targeted at forks and branches without open PRs, to ensure they get tested. It is not intended to run on branches with open PRs, as those should be tested by the PR workflow. +on: + push: + branches-ignore: + - main +jobs: + check-pr-status: + runs-on: ubuntu-latest + outputs: + has-pr: ${{ steps.check-pr.outputs.has-pr }} + steps: + - name: Check if branch has an open PR + id: check-pr + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 + with: + script: | + const branch = context.ref.replace('refs/heads/', ''); + const prs = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + head: `${context.repo.owner}:${branch}` + }); + const hasPR = prs.data.length > 0; + core.setOutput('has-pr', hasPR); + + test-branch: + needs: check-pr-status + runs-on: ubuntu-latest + timeout-minutes: 120 + if: github.event.repository.fork == true || needs.check-pr-status.outputs.has-pr == 'false' + strategy: + fail-fast: false + matrix: + py-version: + - '3.11' # Oldest supported + - '3.14' # Latest stable + mpi: [ 'mpich' ] + install-options: [ '.[dev]' ] + pytorch-version: + - 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' # Oldest supported + - 'torch==2.9.1 torchvision==0.24.1 torchaudio==2.9.1' # JSC Stage 2026 + - 'torch==2.11.0 torchvision==0.26.0 torchaudio==2.11.0' # Latest stable + exclude: + - py-version: '3.14' + pytorch-version: 'torch==2.3.1 torchvision==0.18.1 torchaudio==2.3.1' + name: Python ${{ matrix.py-version }} with ${{ matrix.pytorch-version }}; options ${{ matrix.install-options }} + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.sha }} + - uses: ./.github/actions/gh_tests + with: + mode: "full" + py-version: ${{ matrix.py-version }} + mpi: ${{ matrix.mpi }} + install-options: ${{ matrix.install-options }} + pytorch-version: ${{ matrix.pytorch-version }} diff --git a/.github/workflows/push_support.yml b/.github/workflows/push_support.yml new file mode 100644 index 0000000000..54848249ef --- /dev/null +++ b/.github/workflows/push_support.yml @@ -0,0 +1,23 @@ +name: On Push Support +on: + push: + branches: + - 'support/**' +jobs: + codebase-test-support: + name: Testing + runs-on: ubuntu-latest + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@6c3c2f2c1c457b00c10c4848d6f5491db3b629df # v2.18.0 + with: + egress-policy: audit + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + ref: ${{ github.sha }} + - uses: ./.github/actions/trigger_codebase_tests + with: + branch: ${{ github.head_ref}} + sha: ${{ github.sha}} + trigger_token: ${{ secrets.CX_TRIGGER_TOKEN }} diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml deleted file mode 100644 index 63cb90c2ae..0000000000 --- a/.github/workflows/scorecard.yml +++ /dev/null @@ -1,77 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. They are provided -# by a third-party and are governed by separate terms of service, privacy -# policy, and support documentation. - -name: Scorecard supply-chain security -on: - # For Branch-Protection check. Only the default branch is supported. See - # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection - branch_protection_rule: - # To guarantee Maintained check is occasionally updated. See - # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained - schedule: - - cron: '37 10 * * 5' - push: - branches: [ "main" ] - -# Declare default permissions as read only. -permissions: read-all - -jobs: - analysis: - name: Scorecard analysis - runs-on: ubuntu-latest - permissions: - # Needed to upload the results to code-scanning dashboard. - security-events: write - # Needed to publish results and get a badge (see publish_results below). - id-token: write - # Uncomment the permissions below if installing in a private repository. - # contents: read - # actions: read - - steps: - - name: Harden Runner - uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1 - with: - egress-policy: audit - - - name: "Checkout code" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - - name: "Run analysis" - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - results_file: results.sarif - results_format: sarif - # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: - # - you want to enable the Branch-Protection check on a *public* repository, or - # - you are installing Scorecard on a *private* repository - # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. - # repo_token: ${{ secrets.SCORECARD_TOKEN }} - - # Public repositories: - # - Publish results to OpenSSF REST API for easy access by consumers - # - Allows the repository to include the Scorecard badge. - # - See https://github.com/ossf/scorecard-action#publishing-results. - # For private repositories: - # - `publish_results` will always be set to `false`, regardless - # of the value entered here. - publish_results: true - - # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF - # format to the repository Actions tab. - - name: "Upload artifact" - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: SARIF file - path: results.sarif - retention-days: 5 - - # Upload the results to GitHub's code scanning dashboard. - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@e46ed2cbd01164d986452f91f178727624ae40d7 # v4.35.3 - with: - sarif_file: results.sarif diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml new file mode 100644 index 0000000000..a972a51816 --- /dev/null +++ b/.github/workflows/weekly.yml @@ -0,0 +1,124 @@ +name: Weekly Workflow + +on: + schedule: + - cron: '0 6 * * 1' # Runs at 06:00 UTC every Monday + workflow_dispatch: + +permissions: + actions: read + contents: read + security-events: write + pull-requests: write +jobs: + codeql: + name: CodeQL Analysis + if: ${{ !github.event.repository.fork }} + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + with: + languages: python + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + with: + category: "/language:python" + scorecard: + name: Code Quality Scorecard + if: ${{ !github.event.repository.fork }} + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: "Checkout code" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: "Run analysis" + uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2 + with: + results_file: results.sarif + results_format: sarif + # (Optional) "write" PAT token. Uncomment the `repo_token` line below if: + # - you want to enable the Branch-Protection check on a *public* repository, or + # - you are installing Scorecard on a *private* repository + # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat. + # repo_token: ${{ secrets.SCORECARD_TOKEN }} + + # Public repositories: + # - Publish results to OpenSSF REST API for easy access by consumers + # - Allows the repository to include the Scorecard badge. + # - See https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories: + # - `publish_results` will always be set to `false`, regardless + # of the value entered here. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF + # format to the repository Actions tab. + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: "Upload to code-scanning" + uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19 + with: + sarif_file: results.sarif + check-links: + if: ${{ !github.event.repository.fork }} + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # master + - uses: gaurav-nelson/github-action-markdown-link-check@5c5dfc0ac2e225883c0e5f03a85311ec2830d368 # v1 + # checks all markdown files from root but ignores subfolders + # By Removing the max-depth variable we can modify it -> to check all the .md files in the entire repo. + with: + use-quiet-mode: 'yes' + # Specifying yes to show only errors in the output + use-verbose-mode: 'yes' + # Specifying yes to show detailed HTTP status for checked links. + max-depth: 0 + + inactivity: + name: Inactivity Management + runs-on: ubuntu-latest + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 + with: + days-before-issue-stale: 60 + days-before-issue-close: 60 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 60 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 60 days since being marked as stale." + days-before-pr-stale: 60 + days-before-pr-close: 60 + stale-pr-label: "stale" + stale-pr-message: "This pull request is stale because it has been open for 60 days with no activity." + close-pr-message: "This pull request was closed because it has been inactive for 60 days since being marked as stale." + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.talismanrc b/.talismanrc index 976c575f94..c8fcee38ef 100644 --- a/.talismanrc +++ b/.talismanrc @@ -1,3 +1,3 @@ threshold: medium allowed_patterns: -- 'uses: [A-Za-z-\/]+@[\w\d]+' +- 'uses: [A-Za-z0-9-\/]+@[\w\d]+' diff --git a/heat/tests/__init__.py b/heat/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/utils/data/test_partial_dataset.py b/tests/utils/data/test_partial_dataset.py index 0532f12751..7944588126 100644 --- a/tests/utils/data/test_partial_dataset.py +++ b/tests/utils/data/test_partial_dataset.py @@ -138,6 +138,7 @@ def test_element_count_per_epoch(self): f"Element count {elems} should be >= {expected_min}" ) + @flaky def test_data_varies_between_epochs(self): """Test that data differs between consecutive epochs due to shuffling.""" full_data = ht.load(self.HDF5_PATH, dataset="data", split=None) @@ -178,6 +179,7 @@ def test_data_varies_between_epochs(self): "Data should vary between epochs" ) + @flaky def test_partial_h5_dataset_integration(self): """Integration test: verify the complete workflow with both CPU and GPU.""" full_data = ht.load(self.HDF5_PATH, dataset="data", split=None)