diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index eaf09aa2..88cc0c7e 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -5,6 +5,13 @@ on: permissions: 'read-all' +env: + # Lockfile directories pinned to versions that still support an old + # interpreter. They have no `directory:` entry in `.github/dependabot.yml`, + # but Dependabot security updates ignore that allowlist, so a bump against + # one can still show up here. Empty in repositories without lockfiles. + FROZEN_LOCKFILES: '[]' + jobs: auto-merge: runs-on: 'ubuntu-latest' @@ -17,17 +24,36 @@ jobs: - uses: 'dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98' # v3.1.0 id: 'meta' + # A bump against a frozen lockfile is left open for a human. Dependabot + # does not honour `Requires-Python`, so it may propose a version that + # drops the interpreter the lockfile exists for (py39 -> RHEL 8, RHEL 9, + # Debian 11; py310 -> Ubuntu 22.04). It may equally propose a security + # fix that still supports it. Only a human can tell the two apart, so + # the pull request is neither merged nor closed. Regenerate the lockfile + # with `pip-compile` on a matching Python host once the bump is accepted. - if: >- - steps.meta.outputs.update-type == 'version-update:semver-patch' - || steps.meta.outputs.update-type == 'version-update:semver-minor' - # `gh pr merge --auto` is refused while the pull request sits in clean or - # unstable state, which is exactly where a freshly opened Dependabot pull - # request lands once the required checks pass while the optional ones are - # still running. The direct merge is a safe fallback: branch protection - # keeps enforcing the required checks server-side, so a pull request that - # is not ready is still rejected. + contains(fromJSON(env.FROZEN_LOCKFILES), steps.meta.outputs.directory) + && github.event.action == 'opened' run: | - gh pr merge --auto --squash "$PR_URL" || gh pr merge --squash "$PR_URL" + gh pr comment "$PR_URL" --body "Not auto-merged: \`${DIRECTORY}\` is frozen because Dependabot does not honour \`Requires-Python\`. Check whether \`${DEPENDENCY}\` still supports that lockfile's interpreter. If it does, regenerate the lockfile with \`pip-compile\` on a matching Python host. Either way, close this PR afterwards." env: + DEPENDENCY: '${{ steps.meta.outputs.dependency-names }}' + DIRECTORY: '${{ steps.meta.outputs.directory }}' + GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' PR_URL: '${{ github.event.pull_request.html_url }}' + + # `gh pr merge --auto` is refused while the pull request sits in clean or + # unstable state, which is exactly where a freshly opened Dependabot pull + # request lands once the required checks pass while the optional ones are + # still running. The direct merge is a safe fallback: branch protection + # keeps enforcing the required checks server-side, so a pull request that + # is not ready is still rejected. + - if: >- + !contains(fromJSON(env.FROZEN_LOCKFILES), steps.meta.outputs.directory) + && (steps.meta.outputs.update-type == 'version-update:semver-patch' + || steps.meta.outputs.update-type == 'version-update:semver-minor') + run: | + gh pr merge --auto --squash "$PR_URL" || gh pr merge --squash "$PR_URL" + env: GH_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + PR_URL: '${{ github.event.pull_request.html_url }}'