From d95442e5432b6ea9ec056b2e6c59b9db6f167efe Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 13:54:50 -0600 Subject: [PATCH 1/6] CI: Remove Dependabot automerge There's way too many supply-chain software attacks, and no way to rely on secured GitHub actions releases, to have this enabled right now. There just has to be a human in the loop right now. --- .github/workflows/automerge-dependabot.yml | 43 ---------------------- 1 file changed, 43 deletions(-) delete mode 100644 .github/workflows/automerge-dependabot.yml diff --git a/.github/workflows/automerge-dependabot.yml b/.github/workflows/automerge-dependabot.yml deleted file mode 100644 index 2f90e0ae87..0000000000 --- a/.github/workflows/automerge-dependabot.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Auto-merge Dependabot PRs - -on: - pull_request_target: - branches: [main] - -jobs: - # - # Automatically review dependabot PRs and set them to automerge (on successful checks) - # - Automerge: - environment: - name: PR Backport - runs-on: ubuntu-slim - if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'Unidata/MetPy' - env: - GH_REPO: ${{ github.repository }} - GH_PR: ${{ github.event.pull_request.number }} - - permissions: - contents: write - pull-requests: write - - steps: - - name: Check Dependabot metadata - uses: dependabot/fetch-metadata@v2 - - - name: Create App Token - uses: actions/create-github-app-token@v3 - id: app-token - with: - app-id: ${{ vars.APP_ID }} - private-key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Set auto-merge - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: gh pr merge -R "$GH_REPO" --merge --auto "$GH_PR" - - - name: Review PR - env: - GH_TOKEN: ${{ steps.app-token.outputs.token }} - run: gh pr review -R "$GH_REPO" --approve "$GH_PR" From eefc5d90c77d6d1df2d37df1d9cba94d24b0edc8 Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 14:20:03 -0600 Subject: [PATCH 2/6] CI: Disable deployment on some environments This leaves only releases as triggering a "deployment object" that you can track historically. All of the other environments aren't really useful to track, and exist only to simplify encapsulation of secrets. --- .github/workflows/backport-prs.yml | 1 + .github/workflows/docs.yml | 2 ++ .github/workflows/tests-conda.yml | 1 + .github/workflows/tests-pypi.yml | 1 + 4 files changed, 5 insertions(+) diff --git a/.github/workflows/backport-prs.yml b/.github/workflows/backport-prs.yml index 97a5986f83..97f7e79a45 100644 --- a/.github/workflows/backport-prs.yml +++ b/.github/workflows/backport-prs.yml @@ -10,6 +10,7 @@ jobs: Backport: environment: name: PR Backport + deployment: false runs-on: ubuntu-slim if: github.event.pull_request.merged && contains( github.event.pull_request.labels.*.name, 'backport' ) permissions: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d020d8cb44..b334121ce4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -63,6 +63,7 @@ jobs: needs: Docs environment: name: github-pages + deployment: false runs-on: ubuntu-slim env: DOC_VERSION: dev @@ -101,6 +102,7 @@ jobs: name: "Manage doc versions" environment: name: github-pages + deployment: false runs-on: ubuntu-slim permissions: contents: write diff --git a/.github/workflows/tests-conda.yml b/.github/workflows/tests-conda.yml index 0905c7611b..5abddac56a 100644 --- a/.github/workflows/tests-conda.yml +++ b/.github/workflows/tests-conda.yml @@ -63,6 +63,7 @@ jobs: runs-on: ubuntu-slim environment: name: CodeCov + deployment: false timeout-minutes: 2 steps: - name: Checkout source diff --git a/.github/workflows/tests-pypi.yml b/.github/workflows/tests-pypi.yml index 43b7b191b1..2196f37e2e 100644 --- a/.github/workflows/tests-pypi.yml +++ b/.github/workflows/tests-pypi.yml @@ -89,6 +89,7 @@ jobs: runs-on: ubuntu-slim environment: name: CodeCov + deployment: false timeout-minutes: 2 steps: - name: Checkout source From a80c64223ec35f15efba50cb5fa1489afb61e95c Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 17:31:09 -0600 Subject: [PATCH 3/6] CI: Harden GitHub actions a bit Convert all action versions to SHAs, which can still be managed by Dependabot, but eliminates a class of vulnerabilities, where upstream is compromised and we run unaware. SHAs will at least ensure we don't change the workflow without knowing. --- .github/actions/build-docs/action.yml | 2 +- .github/actions/install-conda/action.yml | 2 +- .github/actions/install-pypi/action.yml | 2 +- .github/actions/run-tests/action.yml | 4 ++-- .github/workflows/assign-milestone.yml | 2 +- .github/workflows/backport-prs.yml | 12 ++++++------ .github/workflows/benchmark-pr.yml | 4 ++-- .github/workflows/cffcheck.yml | 4 ++-- .github/workflows/code-analysis.yml | 6 +++--- .github/workflows/docs-conda.yml | 2 +- .github/workflows/docs.yml | 10 +++++----- .github/workflows/linting.yml | 6 +++--- .github/workflows/nightly-builds.yml | 4 ++-- .github/workflows/release.yml | 10 +++++----- .github/workflows/tests-conda.yml | 10 +++++----- .github/workflows/tests-pypi.yml | 10 +++++----- .github/workflows/unstable-builds.yml | 8 ++++---- 17 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.github/actions/build-docs/action.yml b/.github/actions/build-docs/action.yml index aa3d785f62..9eabec82c0 100644 --- a/.github/actions/build-docs/action.yml +++ b/.github/actions/build-docs/action.yml @@ -59,7 +59,7 @@ runs: - name: Upload docs as artifact if: ${{ always() && inputs.key != '' }} - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ inputs.key }}-docs path: | diff --git a/.github/actions/install-conda/action.yml b/.github/actions/install-conda/action.yml index 30678caa4d..02c611c8f0 100644 --- a/.github/actions/install-conda/action.yml +++ b/.github/actions/install-conda/action.yml @@ -16,7 +16,7 @@ runs: using: composite steps: - name: Set up Python ${{ inputs.python-version }} - uses: mamba-org/setup-micromamba@v2 + uses: mamba-org/setup-micromamba@add3a49764cedee8ee24e82dfde87f5bc2914462 # v2.0.7 with: # Name is needed for caching environment-name: CI diff --git a/.github/actions/install-pypi/action.yml b/.github/actions/install-pypi/action.yml index d17136823f..ef410ea5d7 100644 --- a/.github/actions/install-pypi/action.yml +++ b/.github/actions/install-pypi/action.yml @@ -28,7 +28,7 @@ runs: using: composite steps: - name: Set up Python ${{ inputs.python-version }} - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ inputs.python-version }} cache: 'pip' diff --git a/.github/actions/run-tests/action.yml b/.github/actions/run-tests/action.yml index c11a763677..298e81e3d3 100644 --- a/.github/actions/run-tests/action.yml +++ b/.github/actions/run-tests/action.yml @@ -44,14 +44,14 @@ runs: - name: Upload test images if: failure() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ inputs.key }}-images path: test_output/ - name: Upload coverage artifact if: ${{ inputs.upload-coverage == 'true' }} - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ inputs.key }} path: coverage.xml diff --git a/.github/workflows/assign-milestone.yml b/.github/workflows/assign-milestone.yml index 79f427afb4..dffca63766 100644 --- a/.github/workflows/assign-milestone.yml +++ b/.github/workflows/assign-milestone.yml @@ -15,7 +15,7 @@ jobs: name: Assign Latest Milestone runs-on: ubuntu-slim steps: - - uses: actions/github-script@v8 + - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 name: Run script with: script: | diff --git a/.github/workflows/backport-prs.yml b/.github/workflows/backport-prs.yml index 97f7e79a45..c6b0131a8b 100644 --- a/.github/workflows/backport-prs.yml +++ b/.github/workflows/backport-prs.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Create App Token - uses: actions/create-github-app-token@v3 + uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 id: app-token with: app-id: ${{ vars.APP_ID }} @@ -40,7 +40,7 @@ jobs: git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+${{ steps.app-token.outputs.app-slug }}[bot]@users.noreply.github.com' - name: Checkout PR HEAD - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 100 @@ -61,7 +61,7 @@ jobs: - name: Create backport PR id: create-pr - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 with: token: ${{ steps.app-token.outputs.token }} title: '${{ github.event.pull_request.title }} (backport)' @@ -73,13 +73,13 @@ jobs: delete-branch: true labels: 'backported-pr,${{ join(github.event.pull_request.labels.*.name) }}' - - uses: actions-ecosystem/action-remove-labels@v1 + - uses: actions-ecosystem/action-remove-labels@2ce5d41b4b6aa8503e285553f75ed56e0a40bae0 # v1.3.0 with: number: ${{ steps.create-pr.outputs.pull-request-number }} labels: backport - name: Comment on completion - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | github.rest.issues.createComment({ @@ -91,7 +91,7 @@ jobs: - name: Comment on error if: failure() - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const workflow_url = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; diff --git a/.github/workflows/benchmark-pr.yml b/.github/workflows/benchmark-pr.yml index f7870b1b25..4f4f2d2e8a 100644 --- a/.github/workflows/benchmark-pr.yml +++ b/.github/workflows/benchmark-pr.yml @@ -21,11 +21,11 @@ jobs: run: working-directory: ./benchmarks #sets the default working directory to ./benchmarks steps: - - uses: actions/setup-python@v6 #sets up python with version 3.12 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.12" - name: Checkout repo - uses: actions/checkout@v6 #checks out repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch full history - run: python -m pip install numpy pandas xarray metpy netcdf4 diff --git a/.github/workflows/cffcheck.yml b/.github/workflows/cffcheck.yml index f80edf09a2..11fb880bbf 100644 --- a/.github/workflows/cffcheck.yml +++ b/.github/workflows/cffcheck.yml @@ -17,11 +17,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out a copy of the repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Check validity of CITATION.cff - uses: citation-file-format/cffconvert-github-action@2.0.0 + uses: citation-file-format/cffconvert-github-action@4cf11baa70a673bfdf9dad0acc7ee33b3f4b6084 # 2.0.0 with: args: "--validate" diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml index a58556fa40..8fc0e6b50a 100644 --- a/.github/workflows/code-analysis.yml +++ b/.github/workflows/code-analysis.yml @@ -28,14 +28,14 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 with: config-file: ./.github/codeql/codeql-config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@38697555549f1db7851b81482ff19f1fa5c4fedc # v4.34.1 diff --git a/.github/workflows/docs-conda.yml b/.github/workflows/docs-conda.yml index d0e5400d63..2122b6ad77 100644 --- a/.github/workflows/docs-conda.yml +++ b/.github/workflows/docs-conda.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 fetch-tags: true diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b334121ce4..ea8c4e4bd2 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 persist-credentials: false @@ -72,7 +72,7 @@ jobs: steps: - name: Download doc build - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: Linux-3.13-docs path: ./docs/build/html @@ -87,7 +87,7 @@ jobs: run: echo "doc-version=${{ env.DOC_VERSION }}" >> $GITHUB_OUTPUT - name: Upload to GitHub Pages - uses: peaceiris/actions-gh-pages@v4 + uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/build/html @@ -109,12 +109,12 @@ jobs: steps: - name: Checkout docs - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: "gh-pages" - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - name: Install packaging run: python -m pip install packaging diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index c720792fcb..c31994732f 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -14,12 +14,12 @@ jobs: name: Run Lint Tools runs-on: ubuntu-slim steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Set up Python 3 - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.x cache: 'pip' @@ -29,7 +29,7 @@ jobs: run: python -m pip install -r ci-dev/linting_requirements.txt - name: Set up reviewdog - uses: reviewdog/action-setup@v1 + uses: reviewdog/action-setup@d8a7baabd7f3e8544ee4dbde3ee41d0011c3a93f # v1.5.0 - name: Run ruff run: ruff check --output-format github diff --git a/.github/workflows/nightly-builds.yml b/.github/workflows/nightly-builds.yml index c1db0bc29b..79ba41c650 100644 --- a/.github/workflows/nightly-builds.yml +++ b/.github/workflows/nightly-builds.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Download logs - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: /tmp/workspace/logs @@ -44,7 +44,7 @@ jobs: touch tests-nightly.log build.log linkchecker.log - name: Report failures - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: | const fs = require('fs'); diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5c3862a493..50bc1ae8d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,13 +10,13 @@ jobs: name: Build Release Packages runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Set up Python id: setup - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: 3.x @@ -29,7 +29,7 @@ jobs: run: python -m build - name: Save built packages as artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: packages-${{ runner.os }}-${{ steps.setup.outputs.python-version }} path: dist/ @@ -47,7 +47,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download packages - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Consolidate packages for upload run: | @@ -55,4 +55,4 @@ jobs: cp packages-*/* dist/ - name: Publish Package - uses: pypa/gh-action-pypi-publish@v1.13.0 + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 diff --git a/.github/workflows/tests-conda.yml b/.github/workflows/tests-conda.yml index 5abddac56a..ecb69f6dc1 100644 --- a/.github/workflows/tests-conda.yml +++ b/.github/workflows/tests-conda.yml @@ -38,7 +38,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 fetch-tags: true @@ -67,16 +67,16 @@ jobs: timeout-minutes: 2 steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Download coverage artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Upload coverage - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 with: name: Conda fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/tests-pypi.yml b/.github/workflows/tests-pypi.yml index 2196f37e2e..e00eb602f8 100644 --- a/.github/workflows/tests-pypi.yml +++ b/.github/workflows/tests-pypi.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 fetch-tags: true @@ -93,16 +93,16 @@ jobs: timeout-minutes: 2 steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Download coverage artifacts - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Upload coverage - uses: codecov/codecov-action@v5 + uses: codecov/codecov-action@1af58845a975a7985b0beb0cbe6fbbb71a41dbad # v5.5.3 with: name: PyPI fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/unstable-builds.yml b/.github/workflows/unstable-builds.yml index 743c25145c..f30864e328 100644 --- a/.github/workflows/unstable-builds.yml +++ b/.github/workflows/unstable-builds.yml @@ -17,7 +17,7 @@ jobs: result: ${{ steps.tests.outcome }} steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 fetch-tags: true @@ -47,7 +47,7 @@ jobs: - name: Upload test log if: failure() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: log-nightly-tests path: tests-nightly.log @@ -59,7 +59,7 @@ jobs: result: ${{ steps.build.outcome }} steps: - name: Checkout source - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 150 fetch-tags: true @@ -86,7 +86,7 @@ jobs: - name: Upload build log if: failure() - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: log-nightly-docs path: | From 75a5cf3f7b64421904d5066ca0a3585efa4e4522 Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 18:02:15 -0600 Subject: [PATCH 4/6] CI: Set default permissions While we set default repo-level permissions, it seems like this is the best practice at this point to make it explicit. --- .github/workflows/benchmark-pr.yml | 3 ++- .github/workflows/cffcheck.yml | 2 ++ .github/workflows/docs-conda.yml | 2 ++ .github/workflows/docs.yml | 2 ++ .github/workflows/linting.yml | 2 ++ .github/workflows/nightly-builds.yml | 2 ++ .github/workflows/release.yml | 2 ++ .github/workflows/run-unstable-pr.yml | 2 ++ .github/workflows/tests-conda.yml | 4 ++++ .github/workflows/tests-pypi.yml | 4 ++++ .github/workflows/unstable-builds.yml | 4 ++++ 11 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.github/workflows/benchmark-pr.yml b/.github/workflows/benchmark-pr.yml index 4f4f2d2e8a..ce9d2ae571 100644 --- a/.github/workflows/benchmark-pr.yml +++ b/.github/workflows/benchmark-pr.yml @@ -6,7 +6,6 @@ on: types: [opened, synchronize, reopened, labeled] #defaults and when labeled workflow_dispatch: - concurrency: group: ${{ github.workflow}}-${{ github.head_ref }} cancel-in-progress: true @@ -14,6 +13,8 @@ concurrency: jobs: benchmark: runs-on: ubuntu-latest + permissions: + contents: read #sets only to run when the GitHub PR is labeled with 'benchmark' if: contains(github.event.pull_request.labels.*.name, 'benchmark') timeout-minutes: 20 #times out after 20 minutes diff --git a/.github/workflows/cffcheck.yml b/.github/workflows/cffcheck.yml index 11fb880bbf..9db3ba967c 100644 --- a/.github/workflows/cffcheck.yml +++ b/.github/workflows/cffcheck.yml @@ -15,6 +15,8 @@ on: jobs: validate: runs-on: ubuntu-latest + permissions: + contents: read steps: - name: Check out a copy of the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/docs-conda.yml b/.github/workflows/docs-conda.yml index 2122b6ad77..d2b12bd12e 100644 --- a/.github/workflows/docs-conda.yml +++ b/.github/workflows/docs-conda.yml @@ -15,6 +15,8 @@ jobs: Docs: name: ${{ matrix.os }} ${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest + permissions: + contents: read defaults: run: shell: bash -l {0} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ea8c4e4bd2..7a39ea3acb 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -21,6 +21,8 @@ jobs: Docs: name: "Linux ${{ matrix.python-version }}" runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index c31994732f..98cb3f1eb0 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -13,6 +13,8 @@ jobs: lint: name: Run Lint Tools runs-on: ubuntu-slim + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/nightly-builds.yml b/.github/workflows/nightly-builds.yml index 79ba41c650..88a22051ef 100644 --- a/.github/workflows/nightly-builds.yml +++ b/.github/workflows/nightly-builds.yml @@ -22,6 +22,8 @@ on: jobs: Builds: + permissions: + contents: read uses: ./.github/workflows/unstable-builds.yml Report: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 50bc1ae8d5..5ce1b759e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,6 +9,8 @@ jobs: build: name: Build Release Packages runs-on: ubuntu-latest + permissions: + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: diff --git a/.github/workflows/run-unstable-pr.yml b/.github/workflows/run-unstable-pr.yml index 859c94a77d..c28d1afff9 100644 --- a/.github/workflows/run-unstable-pr.yml +++ b/.github/workflows/run-unstable-pr.yml @@ -13,4 +13,6 @@ jobs: if: | ((github.event.action == 'labeled' && github.event.label.name == 'nightly-ci') || contains(github.event.pull_request.labels.*.name, 'nightly-ci')) + permissions: + contents: read uses: ./.github/workflows/unstable-builds.yml diff --git a/.github/workflows/tests-conda.yml b/.github/workflows/tests-conda.yml index ecb69f6dc1..22db7e555d 100644 --- a/.github/workflows/tests-conda.yml +++ b/.github/workflows/tests-conda.yml @@ -22,6 +22,8 @@ jobs: CondaTests: name: ${{ matrix.os }} ${{ matrix.python-version }} runs-on: ${{ matrix.os }}-latest + permissions: + contents: read defaults: run: shell: bash -l {0} @@ -61,6 +63,8 @@ jobs: name: CodeCov Upload needs: CondaTests runs-on: ubuntu-slim + permissions: + contents: read environment: name: CodeCov deployment: false diff --git a/.github/workflows/tests-pypi.yml b/.github/workflows/tests-pypi.yml index e00eb602f8..fd47c24042 100644 --- a/.github/workflows/tests-pypi.yml +++ b/.github/workflows/tests-pypi.yml @@ -22,6 +22,8 @@ jobs: PyPITests: name: ${{ matrix.python-version }} ${{ matrix.dep-versions }} ${{ matrix.no-extras }} runs-on: ubuntu-latest + permissions: + contents: read strategy: fail-fast: false matrix: @@ -87,6 +89,8 @@ jobs: needs: PyPITests name: CodeCov Upload runs-on: ubuntu-slim + permissions: + contents: read environment: name: CodeCov deployment: false diff --git a/.github/workflows/unstable-builds.yml b/.github/workflows/unstable-builds.yml index f30864e328..4793b19c12 100644 --- a/.github/workflows/unstable-builds.yml +++ b/.github/workflows/unstable-builds.yml @@ -13,6 +13,8 @@ on: jobs: Tests: runs-on: ubuntu-latest + permissions: + contents: read outputs: result: ${{ steps.tests.outcome }} steps: @@ -55,6 +57,8 @@ jobs: Docs: runs-on: ubuntu-latest + permissions: + contents: read outputs: result: ${{ steps.build.outcome }} steps: From 53400c2371010427ac652a6f0b7df81adf7096d0 Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 18:04:32 -0600 Subject: [PATCH 5/6] CI: Set cooldown period for Dependabot This gives time for compromised releases to be pulled before we update. --- .github/dependabot.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index beecd16225..0c7bd35e01 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,8 @@ updates: directory: "/ci" schedule: interval: weekly + cooldown: + default-days: 2 # Boto3 makes patch releases daily, so ignore those to reduce the noise ignore: - dependency-name: "boto3" @@ -32,6 +34,8 @@ updates: directory: "/ci-dev" schedule: interval: weekly + cooldown: + default-days: 2 # We don't need to worry about updating to every patch release of dev tools ignore: - dependency-name: "*" @@ -59,6 +63,8 @@ updates: - "/.github/actions/*" schedule: interval: weekly + cooldown: + default-days: 2 open-pull-requests-limit: 10 pull-request-branch-name: separator: "-" From 370795dd2de04b5b61491fec753ff61d79c74420 Mon Sep 17 00:00:00 2001 From: Ryan May Date: Tue, 24 Mar 2026 18:09:46 -0600 Subject: [PATCH 6/6] CI: Add missing persist-credentials: false --- .github/workflows/benchmark-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/benchmark-pr.yml b/.github/workflows/benchmark-pr.yml index ce9d2ae571..4d200deb4a 100644 --- a/.github/workflows/benchmark-pr.yml +++ b/.github/workflows/benchmark-pr.yml @@ -29,6 +29,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 # Fetch full history + persist-credentials: false - run: python -m pip install numpy pandas xarray metpy netcdf4 - name: Create data array run: python data_array_generate.py