Repository navigation
162 lines (140 loc) · 7.01 KB
/
Copy pathcorpus-pin-update.yml
File metadata and controls
162 lines (140 loc) · 7.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# 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}"