diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8a2d4fb61df..1f851360768 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,6 +5,8 @@ updates: schedule: # Check for updates once a week interval: "weekly" + cooldown: + default-days: 7 groups: actions: patterns: diff --git a/.github/workflows/benchmarks-last-release.yml b/.github/workflows/benchmarks-last-release.yml index 6c47fdcdcc8..349a910db3f 100644 --- a/.github/workflows/benchmarks-last-release.yml +++ b/.github/workflows/benchmarks-last-release.yml @@ -6,6 +6,8 @@ on: - main workflow_dispatch: +permissions: {} + jobs: benchmark: name: Linux @@ -17,12 +19,13 @@ jobs: steps: # We need the full repo to avoid this issue # https://github.com/actions/checkout/issues/23 - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Set up conda environment - uses: mamba-org/setup-micromamba@v2 + uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0 with: micromamba-version: "1.5.10-0" environment-file: ${{env.CONDA_ENV_FILE}} @@ -34,7 +37,7 @@ jobs: - name: "Get Previous tag" id: previoustag - uses: "WyriHaximus/github-action-get-previous-tag@v2" + uses: WyriHaximus/github-action-get-previous-tag@61819f33034117e6c686e6a31dba995a85afc9de # v2.0.0 # with: # fallback: 1.0.0 # Optional fallback tag to use when no tag can be found @@ -47,18 +50,19 @@ jobs: OMP_NUM_THREADS: 1 ASV_FACTOR: 1.5 ASV_SKIP_SLOW: 1 + GITHUB_TAG: ${{ steps.previoustag.outputs.tag }} run: | set -x # ID this runner asv machine --yes - echo "Baseline: ${{ steps.previoustag.outputs.tag }} " + echo "Baseline: $GITHUB_TAG" echo "Contender: ${{ github.sha }}" # Use mamba for env creation # export CONDA_EXE=$(which mamba) export CONDA_EXE=$(which conda) # Run benchmarks for current commit against base ASV_OPTIONS="--split --show-stderr --factor $ASV_FACTOR" - asv continuous $ASV_OPTIONS ${{ steps.previoustag.outputs.tag }} ${{ github.sha }} \ + asv continuous $ASV_OPTIONS "$GITHUB_TAG" ${{ github.sha }} \ | sed "/Traceback \|failed$\|PERFORMANCE DECREASED/ s/^/::error::/" \ | tee benchmarks.log # Report and export results for subsequent steps @@ -73,7 +77,7 @@ jobs: cp benchmarks/README_CI.md benchmarks.log .asv/results/ working-directory: ${{ env.ASV_DIR }} - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: name: asv-benchmark-results-${{ runner.os }} diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index 1e1637557ba..5b66884ae04 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -8,6 +8,8 @@ on: env: PR_HEAD_LABEL: ${{ github.event.pull_request.head.label }} +permissions: {} + jobs: benchmark: if: ${{ contains( github.event.pull_request.labels.*.name, 'run-benchmark') && github.event_name == 'pull_request' || contains( github.event.pull_request.labels.*.name, 'topic-performance') && github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} @@ -20,12 +22,13 @@ jobs: steps: # We need the full repo to avoid this issue # https://github.com/actions/checkout/issues/23 - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Set up conda environment - uses: mamba-org/setup-micromamba@v2 + uses: mamba-org/setup-micromamba@d7c9bd84e824b79d2af72a2d4196c7f4300d3476 # v3.0.0 with: micromamba-version: "1.5.10-0" environment-file: ${{env.CONDA_ENV_FILE}} @@ -47,11 +50,12 @@ jobs: OMP_NUM_THREADS: 1 ASV_FACTOR: 1.5 ASV_SKIP_SLOW: 1 + GITHUB_LABEL: ${{ github.event.pull_request.base.label }} run: | set -x # ID this runner asv machine --yes - echo "Baseline: ${{ github.event.pull_request.base.sha }} (${{ github.event.pull_request.base.label }})" + echo "Baseline: ${{ github.event.pull_request.base.sha }} ($GITHUB_LABEL)" echo "Contender: ${GITHUB_SHA} ($PR_HEAD_LABEL)" # Run benchmarks for current commit against base ASV_OPTIONS="--split --show-stderr --factor $ASV_FACTOR" @@ -70,7 +74,7 @@ jobs: cp benchmarks/README_CI.md benchmarks.log .asv/results/ working-directory: ${{ env.ASV_DIR }} - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: always() with: name: asv-benchmark-results-${{ runner.os }} diff --git a/.github/workflows/ci-additional.yaml b/.github/workflows/ci-additional.yaml index fda7151055e..80099f1b878 100644 --- a/.github/workflows/ci-additional.yaml +++ b/.github/workflows/ci-additional.yaml @@ -15,6 +15,8 @@ concurrency: env: FORCE_COLOR: 3 +permissions: {} + jobs: detect-ci-trigger: name: detect ci trigger @@ -26,10 +28,11 @@ jobs: outputs: triggered: ${{ steps.detect-trigger.outputs.trigger-found }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - - uses: xarray-contrib/ci-trigger@v1 + persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: keyword: "[skip-ci]" @@ -44,10 +47,12 @@ jobs: pixi-version: ${{ steps.pixi-lock.outputs.pixi-version }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: Parcels-code/pixi-lock/create-and-cache@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 id: pixi-lock - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pixi-lock path: pixi.lock @@ -63,9 +68,10 @@ jobs: env: PIXI_ENV: "test-py313" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: set environment variables run: | @@ -75,7 +81,7 @@ jobs: uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -106,14 +112,15 @@ jobs: PIXI_ENV: test-py313-with-typing steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -132,7 +139,7 @@ jobs: pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: mypy_report/cobertura.xml flags: mypy @@ -151,14 +158,15 @@ jobs: PIXI_ENV: test-py311-with-typing steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -177,7 +185,7 @@ jobs: pixi run -e ${{env.PIXI_ENV}} -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: mypy_report/cobertura.xml flags: mypy-min @@ -199,15 +207,16 @@ jobs: PIXI_ENV: test-py313-with-typing steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -249,15 +258,16 @@ jobs: shell: bash -l {0} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -276,7 +286,7 @@ jobs: pixi run -e ${{ matrix.pixi-env }} -- python -m pyright xarray/ - name: Upload pyright coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: pyright_report/cobertura.xml flags: pyright @@ -297,16 +307,17 @@ jobs: COLUMNS: 120 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c154a71bf29..c1ee450303a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -15,6 +15,8 @@ concurrency: env: FORCE_COLOR: 3 +permissions: {} + jobs: detect-ci-trigger: name: detect ci trigger @@ -26,10 +28,12 @@ jobs: outputs: triggered: ${{ steps.detect-trigger.outputs.trigger-found }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - - uses: xarray-contrib/ci-trigger@v1 + persist-credentials: false + + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: keyword: "[skip-ci]" @@ -44,10 +48,12 @@ jobs: cache-key: ${{ steps.pixi-lock.outputs.cache-key }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: Parcels-code/pixi-lock/create-and-cache@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 id: pixi-lock - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pixi-lock path: pixi.lock @@ -91,15 +97,21 @@ jobs: - pixi-env: "test-py313-with-typing" numprocesses: 1 os: ubuntu-latest + + environment: + name: codecov + deployment: false + steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -130,7 +142,8 @@ jobs: # We only want to install this on one run, because otherwise we'll have # duplicate annotations. - name: Install error reporter - if: ${{ matrix.os }} == 'ubuntu-latest' and ${{ matrix.pixi-env}} == 'test' + if: | + matrix.os == 'ubuntu-latest' && matrix.pixi-env == 'test' run: | pixi add --pypi pytest-github-actions-annotate-failures @@ -143,7 +156,7 @@ jobs: pixi run -e ${{ matrix.pixi-env }} -- python -c "import xarray" - name: Restore cached hypothesis directory - uses: actions/cache@v5 + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .hypothesis/ key: cache-hypothesis @@ -160,13 +173,13 @@ jobs: - name: Upload test results if: always() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: Test results for OS ${{ runner.os }} pixi-env ${{ matrix.pixi-env }} pytest-addopts ${{ matrix.pytest-addopts }} path: pytest.xml - name: Upload code coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: @@ -182,7 +195,7 @@ jobs: if: github.repository == 'pydata/xarray' steps: - name: Upload - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: Event File path: ${{ github.event_path }} diff --git a/.github/workflows/hypothesis.yaml b/.github/workflows/hypothesis.yaml index 39989344e28..62e2db21888 100644 --- a/.github/workflows/hypothesis.yaml +++ b/.github/workflows/hypothesis.yaml @@ -14,6 +14,8 @@ on: env: FORCE_COLOR: 3 +permissions: {} + jobs: detect-ci-trigger: name: detect ci trigger @@ -25,10 +27,11 @@ jobs: outputs: triggered: ${{ steps.detect-trigger.outputs.trigger-found }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - - uses: xarray-contrib/ci-trigger@v1 + persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: keyword: "[skip-ci]" @@ -51,10 +54,12 @@ jobs: cache-key: ${{ steps.pixi-lock.outputs.cache-key }} pixi-version: ${{ steps.pixi-lock.outputs.pixi-version }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: Parcels-code/pixi-lock/create-and-cache@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 id: pixi-lock - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pixi-lock path: pixi.lock @@ -73,15 +78,16 @@ jobs: PIXI_ENV: "test-py313" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -100,7 +106,7 @@ jobs: # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache - name: Restore cached hypothesis directory id: restore-hypothesis-cache - uses: actions/cache/restore@v5 + uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .hypothesis/ key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }} @@ -118,7 +124,7 @@ jobs: - name: Save cached hypothesis directory id: save-hypothesis-cache if: always() && steps.status.outcome != 'skipped' - uses: actions/cache/save@v5 + uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 with: path: .hypothesis/ key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }} @@ -129,7 +135,7 @@ jobs: && steps.status.outcome == 'failure' && github.event_name == 'schedule' && github.repository_owner == 'pydata' - uses: scientific-python/issue-from-pytest-log-action@v1 + uses: scientific-python/issue-from-pytest-log-action@8e905db353437cda1d6a773de245343fbfc940dd # v1.5.0 with: log-path: output-${{ env.PIXI_ENV }}-log.jsonl issue-title: "Nightly Hypothesis tests failed" diff --git a/.github/workflows/label-prs.yml b/.github/workflows/label-prs.yml index abc85158d20..81beace1883 100644 --- a/.github/workflows/label-prs.yml +++ b/.github/workflows/label-prs.yml @@ -1,12 +1,23 @@ name: "PR Labeler" on: - - pull_request_target + # ignore zizmor in this case, because the only thing we execute with PR write + # permissions is actions/labeler (this is also the recommended setup of this action). + # Either way, we only run this on the main repository. + - pull_request_target # zizmor: ignore[dangerous-triggers] + +permissions: {} jobs: label: runs-on: ubuntu-latest + if: github.repository == 'pydata/xarray' + + permissions: + contents: read + pull-requests: write + steps: - - uses: actions/labeler@v6 + - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" sync-labels: false diff --git a/.github/workflows/nightly-wheels.yml b/.github/workflows/nightly-wheels.yml index f7c114b2f22..15330c60ca8 100644 --- a/.github/workflows/nightly-wheels.yml +++ b/.github/workflows/nightly-wheels.yml @@ -4,19 +4,19 @@ on: schedule: - cron: "0 0 * * *" -permissions: - contents: read - issues: write +permissions: {} jobs: - cron: + build-artifacts: runs-on: ubuntu-latest if: github.repository == 'pydata/xarray' + steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: actions/setup-python@v6 + persist-credentials: false + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.12" @@ -44,6 +44,33 @@ jobs: echo "✅ Looks good" fi + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: releases + path: dist + + upload: + needs: build-artifacts + if: github.event_name == 'schedule' + runs-on: ubuntu-latest + + environment: + name: scientific-python-nightly-wheels + + permissions: + contents: read + issues: write + + steps: + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: releases + path: dist + - name: Publish package to PyPI + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + with: + verbose: true + - name: Upload wheel id: upload uses: scientific-python/upload-nightly-action@5748273c71e2d8d3a61f3a11a16421c8954f9ecf # 0.6.3 @@ -54,12 +81,15 @@ jobs: - name: Create or update failure issue if: ${{ failure() }} shell: bash + env: + GH_TOKEN: ${{ github.token }} + GITHUB_WORKFLOW: ${{ github.workflow }} run: | # Read the template template=$(cat .github/nightly-wheel-failure-template.md) # Replace placeholders - issue_body="${template//\{\{WORKFLOW\}\}/${{ github.workflow }}}" + issue_body="${template//\{\{WORKFLOW\}\}/$GITHUB_WORKFLOW}" issue_body="${issue_body//\{\{RUN_ID\}\}/${{ github.run_id }}}" issue_body="${issue_body//\{\{RUN_URL\}\}/${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}}" issue_body="${issue_body//\{\{DATE\}\}/$(date -u)}" @@ -80,5 +110,3 @@ jobs: --label "CI" echo "Created new issue" fi - env: - GH_TOKEN: ${{ github.token }} diff --git a/.github/workflows/publish-test-results.yaml b/.github/workflows/publish-test-results.yaml index fe0d1e8a4e1..da5eda680ce 100644 --- a/.github/workflows/publish-test-results.yaml +++ b/.github/workflows/publish-test-results.yaml @@ -3,7 +3,8 @@ name: Publish test results on: - workflow_run: + # we can ignore zizmor in this case, because `ci.yaml` is run on `pull_request` not `pull_request_target`, and we restrict the permissions to the default read-only. + workflow_run: # zizmor: ignore[dangerous-triggers] workflows: ["CI"] types: - completed @@ -12,6 +13,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: {} + jobs: publish-test-results: name: Publish test results @@ -22,12 +25,11 @@ jobs: - name: Download and extract artifacts env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + ARTIFACTS_URL: ${{ github.event.workflow_run.artifacts_url }} run: | mkdir artifacts && cd artifacts - artifacts_url=${{ github.event.workflow_run.artifacts_url }} - - gh api "$artifacts_url" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact + gh api "$ARTIFACTS_URL" -q '.artifacts[] | [.name, .archive_download_url] | @tsv' | while read artifact do IFS=$'\t' read name url <<< "$artifact" gh api $url > "$name.zip" @@ -35,7 +37,7 @@ jobs: done - name: Publish Unit Test Results - uses: EnricoMi/publish-unit-test-result-action@v2 + uses: EnricoMi/publish-unit-test-result-action@c950f6fb443cb5af20a377fd0dfaa78838901040 # v2.23.0 with: commit: ${{ github.event.workflow_run.head_sha }} event_file: artifacts/Event File/event.json diff --git a/.github/workflows/pypi-release.yaml b/.github/workflows/pypi-release.yaml index 2b04a18675b..a523d32d3e0 100644 --- a/.github/workflows/pypi-release.yaml +++ b/.github/workflows/pypi-release.yaml @@ -10,6 +10,8 @@ on: types: [opened, reopened, synchronize, labeled] workflow_dispatch: +permissions: {} + jobs: build-artifacts: runs-on: ubuntu-latest @@ -20,10 +22,11 @@ jobs: startsWith(github.ref, 'refs/tags/v') ) }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: actions/setup-python@v6 + persist-credentials: false + - uses: actions/setup-python@a0af7a228712d6121d37aba47adf55c1332c9c2e # v6.2.0 name: Install Python with: python-version: "3.12" @@ -49,7 +52,7 @@ jobs: else echo "✅ Looks good" fi - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: releases path: dist @@ -58,11 +61,11 @@ jobs: needs: build-artifacts runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v6 + - uses: actions/setup-python@a0af7a228712d6121d37aba47adf55c1332c9c2e # v6.2.0 name: Install Python with: python-version: "3.12" - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: releases path: dist @@ -89,13 +92,13 @@ jobs: id-token: write steps: - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: releases path: dist - name: Publish package to TestPyPI if: github.event_name == 'push' - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 with: repository_url: https://test.pypi.org/legacy/ verbose: true @@ -112,11 +115,11 @@ jobs: id-token: write steps: - - uses: actions/download-artifact@v8 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: releases path: dist - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 with: verbose: true diff --git a/.github/workflows/upstream-dev-ci.yaml b/.github/workflows/upstream-dev-ci.yaml index c5a9a59e03f..94288081805 100644 --- a/.github/workflows/upstream-dev-ci.yaml +++ b/.github/workflows/upstream-dev-ci.yaml @@ -15,6 +15,8 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +permissions: {} + env: FORCE_COLOR: 3 @@ -29,10 +31,11 @@ jobs: outputs: triggered: ${{ steps.detect-trigger.outputs.trigger-found }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 2 - - uses: xarray-contrib/ci-trigger@v1 + persist-credentials: false + - uses: xarray-contrib/ci-trigger@10cd2bfec3484946a4058a421ddf9cfad101e715 # v1.2.1 id: detect-trigger with: keyword: "[test-upstream]" @@ -58,10 +61,12 @@ jobs: cache-key: ${{ steps.pixi-lock.outputs.cache-key }} pixi-version: ${{ steps.pixi-lock.outputs.pixi-version }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false - uses: Parcels-code/pixi-lock/create-and-cache@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 id: pixi-lock - - uses: actions/upload-artifact@v7 + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: pixi-lock path: pixi.lock @@ -79,15 +84,20 @@ jobs: fail-fast: false matrix: pixi-env: ["test-nightly"] + + permissions: + issues: write + steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -111,7 +121,7 @@ jobs: && steps.status.outcome == 'failure' && github.event_name == 'schedule' && github.repository_owner == 'pydata' - uses: scientific-python/issue-from-pytest-log-action@v1 + uses: scientific-python/issue-from-pytest-log-action@8e905db353437cda1d6a773de245343fbfc940dd # v1.5.0 with: log-path: output-${{ matrix.pixi-env }}-log.jsonl @@ -131,16 +141,18 @@ jobs: fail-fast: false matrix: pixi-env: ["test-nightly"] + steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch all history for all branches and tags. + persist-credentials: false - name: Restore cached pixi lockfile uses: Parcels-code/pixi-lock/restore@38495788b79a5ff26009aecc15daa9a8310b8832 # v0.1.0 with: cache-key: ${{ needs.cache-pixi-lock.outputs.cache-key }} - - uses: prefix-dev/setup-pixi@v0.9.4 + - uses: prefix-dev/setup-pixi@a0af7a228712d6121d37aba47adf55c1332c9c2e # v0.9.4 with: pixi-version: ${{ needs.cache-pixi-lock.outputs.pixi-version }} cache: true @@ -158,7 +170,7 @@ jobs: run: | pixi run -e ${{matrix.pixi-env}} -- python -m mypy --install-types --non-interactive --cobertura-xml-report mypy_report - name: Upload mypy coverage to Codecov - uses: codecov/codecov-action@v6.0.0 + uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 with: files: mypy_report/cobertura.xml flags: mypy diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d904350f082..e19b55ed562 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -79,3 +79,7 @@ repos: rev: v1.44.0 hooks: - id: typos + - repo: https://github.com/zizmorcore/zizmor-pre-commit + rev: v1.23.1 + hooks: + - id: zizmor