Corpus Pin Update #8
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Dependabot cannot track WordPress core releases, so this workflow keeps | |
| # `WP_CORPUS_TAG` current. | |
| # | |
| # A pin-only PR does not change the parser, and corpus-diff uses the new corpus | |
| # on both sides. The expected diff is therefore empty. | |
| # | |
| # Opening the PR also requires "Allow GitHub Actions to create and approve pull | |
| # requests" in the repository's Actions settings. | |
| name: Corpus Pin Update | |
| on: | |
| schedule: | |
| # Every Sunday at 03:17 UTC. Running at 17 minutes past the hour avoids | |
| # the busiest scheduling window. | |
| - cron: "17 3 * * 0" | |
| workflow_dispatch: | |
| permissions: {} | |
| concurrency: | |
| group: corpus-pin-update | |
| cancel-in-progress: false | |
| jobs: | |
| corpus-pin-update: | |
| name: Bump the pinned WordPress corpus | |
| # A copied or forked workflow must not open update PRs. | |
| if: github.repository == 'WordPress/phpdoc-parser' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # Push the update branch. | |
| pull-requests: write # Open the update pull request. | |
| env: | |
| # Keep the mutable pin outside `.github/workflows`: GITHUB_TOKEN cannot | |
| # create or update workflow files, even with `contents: write`. | |
| CORPUS_PIN_FILE: .github/corpus-version | |
| # This API excludes beta and RC versions; repository tags do not. | |
| VERSION_CHECK_API: https://api.wordpress.org/core/version-check/1.7/ | |
| CORPUS_MIRROR: https://github.com/WordPress/WordPress.git | |
| LC_ALL: C | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Resolve the latest WordPress stable | |
| id: resolve | |
| run: | | |
| set -euo pipefail | |
| latest="$(curl -sSfL --retry 3 --retry-delay 5 "${VERSION_CHECK_API}" | jq -r '.offers[0].current // ""')" | |
| if ! printf '%s' "${latest}" | grep -Eq '^[0-9]+\.[0-9]+(\.[0-9]+)?$'; then | |
| echo "::error::${VERSION_CHECK_API} did not yield a usable version (got: '${latest}')." | |
| exit 1 | |
| fi | |
| echo "Latest WordPress stable: ${latest}" | |
| echo "latest=${latest}" >> "${GITHUB_OUTPUT}" | |
| - name: Compare against the pinned tag | |
| id: pin | |
| env: | |
| LATEST: ${{ steps.resolve.outputs.latest }} | |
| run: | | |
| set -euo pipefail | |
| current="$(cat "${CORPUS_PIN_FILE}")" | |
| if [[ ! "${current}" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]]; then | |
| echo "::error::${CORPUS_PIN_FILE} does not contain a usable WordPress version (got: '${current}')." | |
| exit 1 | |
| fi | |
| echo "Pinned corpus tag: ${current}" | |
| bump=false | |
| if [ "${current}" = "${LATEST}" ]; then | |
| echo "Already pinned to the latest stable; nothing to do." | |
| elif [ "$(printf '%s\n%s\n' "${current}" "${LATEST}" | sort -V | tail -n 1)" != "${LATEST}" ]; then | |
| echo "Pinned ${current} is newer than the published stable ${LATEST}; leaving it alone." | |
| elif ! git ls-remote --exit-code --tags "${CORPUS_MIRROR}" "refs/tags/${LATEST}" > /dev/null; then | |
| echo "${CORPUS_MIRROR} has no ${LATEST} tag yet; will retry on the next run." | |
| else | |
| echo "Bumping the corpus pin from ${current} to ${LATEST}." | |
| bump=true | |
| fi | |
| { | |
| echo "bump=${bump}" | |
| echo "current=${current}" | |
| } >> "${GITHUB_OUTPUT}" | |
| - name: Rewrite the pin | |
| if: steps.pin.outputs.bump == 'true' | |
| env: | |
| LATEST: ${{ steps.resolve.outputs.latest }} | |
| run: | | |
| set -euo pipefail | |
| printf '%s\n' "${LATEST}" > "${CORPUS_PIN_FILE}" | |
| # Keep the automated edit narrow enough to review safely. | |
| check="$(cat "${CORPUS_PIN_FILE}")" | |
| added="$(git diff --numstat -- "${CORPUS_PIN_FILE}" | awk '{print $1}')" | |
| removed="$(git diff --numstat -- "${CORPUS_PIN_FILE}" | awk '{print $2}')" | |
| if [ "${check}" != "${LATEST}" ] || [ "${added}" != "1" ] || [ "${removed}" != "1" ]; then | |
| echo "::error::Pin rewrite did not produce a single-line change to ${LATEST} in ${CORPUS_PIN_FILE} (read back '${check}', +${added:-0}/-${removed:-0})." | |
| git --no-pager diff -- "${CORPUS_PIN_FILE}" | |
| exit 1 | |
| fi | |
| git --no-pager diff -- "${CORPUS_PIN_FILE}" | |
| - name: Open the bump PR | |
| if: steps.pin.outputs.bump == 'true' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| BASE_BRANCH: ${{ github.event.repository.default_branch }} | |
| CURRENT: ${{ steps.pin.outputs.current }} | |
| LATEST: ${{ steps.resolve.outputs.latest }} | |
| run: | | |
| set -euo pipefail | |
| branch="bump-corpus-pin-${LATEST}" | |
| # Treat closed PRs as handled so a declined update is not reopened. | |
| existing="$( | |
| gh api --method GET \ | |
| "repos/${GITHUB_REPOSITORY}/pulls" \ | |
| -f state=all \ | |
| -f head="${GITHUB_REPOSITORY_OWNER}:${branch}" \ | |
| --jq '.[0].html_url // ""' | |
| )" | |
| if [ -n "${existing}" ]; then | |
| echo "A bump PR for ${LATEST} already exists: ${existing}" | |
| exit 0 | |
| fi | |
| title="Bump the pinned WordPress corpus to ${LATEST}" | |
| cat > pr-body.md <<BODY | |
| The corpus pin in \`${CORPUS_PIN_FILE}\` moves from \`${CURRENT}\` to \`${LATEST}\`, the current WordPress stable per [the core version-check API](${VERSION_CHECK_API}). | |
| This changes only the corpus input, never the parser, so the corpus-diff run on this PR parses the new corpus with an identical parser on both sides: **0 hunks by construction**. Reviewing this PR is checking that the corpus guards (file count, export size) still pass on the new tag. A non-zero diff here would mean corpus-diff is not comparing what it claims to. | |
| Opened by \`.github/workflows/corpus-pin-update.yml\`. | |
| BODY | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| git checkout -b "${branch}" | |
| git add -- "${CORPUS_PIN_FILE}" | |
| git commit -m "${title}" | |
| # No PR exists at this point. Reusing the branch repairs a run that | |
| # pushed but failed before opening its PR. | |
| gh auth setup-git --hostname github.com --force | |
| git push --force origin "HEAD:refs/heads/${branch}" | |
| if ! url="$(gh pr create --repo "${GITHUB_REPOSITORY}" --base "${BASE_BRANCH}" --head "${branch}" --title "${title}" --body-file pr-body.md 2>&1)"; then | |
| printf '%s\n' "${url}" >&2 | |
| echo "::error::Pushed ${branch} but could not open the PR. The usual cause is 'Allow GitHub Actions to create and approve pull requests' being disabled for this repository or organization (Settings -> Actions -> General -> Workflow permissions). Enable it, or supply a PAT with 'repo' scope as GH_TOKEN for this step, then re-run this workflow." | |
| exit 1 | |
| fi | |
| echo "Opened ${url}" | |
| echo "Opened [${title}](${url})" >> "${GITHUB_STEP_SUMMARY}" |