Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions .github/workflows/bump-tested-up-to.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
name: Bump "Tested up to" version

on:
schedule:
# Once a day. WordPress releases are not announced on a fixed schedule,
# so the job polls and exits quietly when there is nothing to do.
- cron: '15 4 * * *'
workflow_dispatch:

# Queues overlapping runs instead of cancelling one that may be mid-push.
concurrency:
group: ${{ github.workflow }}
cancel-in-progress: false

# Disable permissions for all available scopes by default.
# Any needed permissions should be configured at the job level.
permissions: {}

jobs:
bump-tested-up-to:
name: Open a pull request when a new WordPress version is stable
runs-on: 'ubuntu-24.04'
# Forks have no app credentials, so a scheduled run there fails daily.
if: ${{ github.repository == 'WordPress/gutenberg' }}
environment: 'GitHub Releases'
permissions:
contents: read
# The check step lists pull requests with the default token.
pull-requests: read

steps:
# Only readme.txt (inspected and edited) and the release tooling
# that parses it are needed. The push and the pull request
# authenticate with the app token generated further down, not with
# this checkout's credentials.
- name: Checkout readme.txt and the release tooling
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
sparse-checkout: |
/readme.txt
/tools/release/
sparse-checkout-cone-mode: false
show-progress: ${{ runner.debug == '1' && 'true' || 'false' }}
persist-credentials: false

- name: Check whether readme.txt trails the latest WordPress release
id: check
env:
GH_TOKEN: ${{ github.token }}
run: |
# The query must stay in sync with the "Compute previous WordPress
# version" step in unit-test.yml, which reads the same API.
LATEST="$(curl --fail --silent --show-error -H "Accept: application/json" "https://api.wordpress.org/core/stable-check/1.0/" | jq --raw-output 'with_entries(select(.value=="latest"))|keys[]' | cut -d. -f1,2)"
if [[ -z "$LATEST" ]]; then
echo "Could not determine the latest stable version from the API."
exit 1
fi
# The same parser the performance workflow relies on; it throws,
# failing this step, when the readme.txt line changes shape.
TESTED="$(node -e 'import("./tools/release/resolve-performance-branches.mjs").then(({ getTestedUpToMajor }) => console.log(getTestedUpToMajor(require("fs").readFileSync("readme.txt", "utf8"))))')"
# readme.txt may legitimately run ahead of the API when it already
# names an upcoming release; only an older value needs a bump.
if [[ "$(printf '%s\n' "$TESTED" "$LATEST" | sort --version-sort | tail -n 1)" == "$TESTED" ]]; then
echo "readme.txt lists ${TESTED} and the latest stable version is ${LATEST}. Nothing to do."
exit 0
fi
# The readme should not claim a WordPress version the plugin has
# no wp/X.Y branch for. `--exit-code` reports a missing ref as 2;
# any other failure is an infrastructure problem that must not be
# mistaken for a missing branch.
set +e
git ls-remote --exit-code --heads origin "wp/${LATEST}" > /dev/null
WP_BRANCH_STATUS=$?
set -e
if [[ "$WP_BRANCH_STATUS" -eq 2 ]]; then
echo "WordPress ${LATEST} is stable but the wp/${LATEST} branch does not exist yet. Trying again on the next scheduled run."
exit 0
elif [[ "$WP_BRANCH_STATUS" -ne 0 ]]; then
echo "Could not determine whether the wp/${LATEST} branch exists (git exited with ${WP_BRANCH_STATUS})."
exit 1
fi
# Deduplicate on the pull request record, not the branch: a closed
# pull request is a human decision this workflow must not repeat,
# while a leftover branch without any pull request is debris from
# an interrupted run that the push below overwrites.
if [[ "$(gh pr list --head "update/tested-up-to-${LATEST}" --state all --json number --jq 'length')" -gt 0 ]]; then
echo "A pull request for the ${LATEST} bump already exists (open, merged, or declined)."
exit 0
fi
echo "version=${LATEST}" >> "$GITHUB_OUTPUT"

# The app token lets the push and the pull request trigger CI, which
# the default GITHUB_TOKEN would not. It is only minted when the check
# found something to push.
- name: Generate application token
if: steps.check.outputs.version
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
id: app-token
with:
client-id: ${{ vars.APP_CLIENT_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
permission-contents: write
permission-pull-requests: write

- name: Create the pull request
if: steps.check.outputs.version
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
VERSION: ${{ steps.check.outputs.version }}
APP_SLUG: ${{ steps.app-token.outputs.app-slug }}
APP_USER_ID: ${{ vars.APP_USER_ID }}
run: |
git config user.name "${APP_SLUG}[bot]"
git config user.email "${APP_USER_ID}+${APP_SLUG}[bot]@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git"
BRANCH="update/tested-up-to-${VERSION}"
git checkout -b "$BRANCH"
sed -i "s/^Tested up to: .*/Tested up to: ${VERSION}/" readme.txt
git add readme.txt
git commit -m "Plugin: Bump \"Tested up to\" to WordPress ${VERSION}"
# --force overwrites debris from a run that pushed the branch but
# failed before creating the pull request; the check step already
# proved no pull request exists for this branch.
git push --force --set-upstream origin "$BRANCH"
gh pr create \
--base trunk \
--head "$BRANCH" \
--label 'Gutenberg Plugin' \
--label '[Type] Enhancement' \
--title "Plugin: Bump \"Tested up to\" to WordPress ${VERSION}" \
--body "WordPress ${VERSION} is now the latest stable release according to [the version check API](https://api.wordpress.org/core/stable-check/1.0/), and \`readme.txt\` still names an older version.

Merging this pull request is the compatibility attestation, so before merging:

- Confirm trunk's CI runs against WordPress ${VERSION} (the unit test workflow tests against the latest stable release).
- Update \`REFERENCE_COMMIT\` in \`tools/release/resolve-performance-branches.mjs\`, here or in a paired pull request. \`docs/explanations/architecture/performance.md\` requires it for every \"Tested up to\" change.

This pull request was opened automatically by the \`bump-tested-up-to.yml\` workflow. The larger chore of raising the minimum required WordPress version and removing old compatibility code is a separate, manual pull request."
Loading