Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3c154ce
Declare WordPress archive license (GPL-2.0-or-later) in packages
yuriipavlov Sep 19, 2026
679aacf
Rename workflow to 'WordPress release watch' and add job display names
yuriipavlov Sep 19, 2026
4540407
Extract duplicated code into lib/ modules and add first offline tests
yuriipavlov Sep 19, 2026
e35a4f7
Add offline unit tests for generator validation, metadata, and entry …
yuriipavlov Sep 19, 2026
f1ca23a
Add E2E tests for check-new-versions.js with HTTP server through env …
yuriipavlov Sep 19, 2026
a71f9ca
Add Composer metadata parity to packages with deterministic backfill …
yuriipavlov Sep 19, 2026
b34d11e
Pin GitHub actions to commit SHAs with version comments
yuriipavlov Sep 19, 2026
f0cd77a
Fix --check silently skipping LOST-VERSION with >1 MB packages.json
yuriipavlov Sep 19, 2026
5a5e4cd
Add Dependabot config to keep SHA-pinned GitHub Actions current
yuriipavlov Sep 19, 2026
8d99a1c
Add checksum verification for downloaded WordPress archives
yuriipavlov Sep 20, 2026
28ac6e5
Add weekly checksum audit for WordPress archive integrity
yuriipavlov Sep 20, 2026
100cc68
Open or comment on issue when release watch workflow fails
yuriipavlov Sep 20, 2026
fae3d53
Attest packages.json after successful push
yuriipavlov Sep 20, 2026
b36e240
Add job summary table with archive timestamps and observation lag
yuriipavlov Sep 20, 2026
14902c6
Document release pickup chain and measured lag in README
yuriipavlov Sep 20, 2026
97b30f4
Add CI workflow for tests and packages.json check
yuriipavlov Sep 20, 2026
67ee189
Support WordPress-style pre-release versions with proper ordering and…
yuriipavlov Sep 20, 2026
430ddbf
Add beta channel support to gate and generator with graceful failure …
yuriipavlov Sep 20, 2026
04d6516
Implement asymmetric pre-release publication for WordPress variants
yuriipavlov Sep 20, 2026
40a0b33
Document how to install pre-release versions via Composer stability f…
yuriipavlov Sep 20, 2026
c8ce64a
Define tag composer.json shape as deep clone of packages.json entry w…
yuriipavlov Sep 20, 2026
612c957
Implement per-variant package publishing with idempotent tags
yuriipavlov Sep 20, 2026
ee5bbd8
Add publish job for package tags with secure token authentication and…
yuriipavlov Sep 20, 2026
0a1ee2c
Add offline test for tag composer.json resolution with Composer and p…
yuriipavlov Sep 20, 2026
29950c5
Document migration from johnpbloch/wordpress-core with installer-path…
yuriipavlov Sep 20, 2026
427bd23
Add comparison table with johnpbloch/wordpress-core highlighting veri…
yuriipavlov Sep 20, 2026
d12bbab
Document automatic generation enhancements with beta channel, checksu…
yuriipavlov Sep 20, 2026
52841cd
Extract date and lag formatting functions into lib/time module
yuriipavlov Sep 20, 2026
c7b1ba9
Add status computation module with badge generation and offline tests
yuriipavlov Sep 20, 2026
a4ac1de
Add offline status.json and badge generation with --status CLI mode
yuriipavlov Sep 20, 2026
be8e9b8
Ensure status.json and badges stay in sync with packages.json in CI
yuriipavlov Sep 20, 2026
a30c75a
Add README badge block with CI and release status
yuriipavlov Sep 20, 2026
83431e7
Add status badges for checksum audit and keepalive workflows
yuriipavlov Sep 20, 2026
b0d6f75
Add badge validation tool that checks URLs in README actually render
yuriipavlov Sep 20, 2026
0353d7e
Add badge validation workflow and documentation
yuriipavlov Sep 20, 2026
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
8 changes: 8 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "ci"
41 changes: 41 additions & 0 deletions .github/workflows/audit-checksums.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Weekly checksum audit

on:
schedule:
- cron: "17 5 * * 1"
workflow_dispatch:

jobs:
audit:
name: Re-check published checksums
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
issues: write

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"

- id: audit
run: node audit-checksums.js

- name: Open or comment an issue on failure
if: failure()
env:
GH_TOKEN: ${{ github.token }}
TITLE: "Checksum audit failed"
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
number=$(gh issue list --state open --search "$TITLE in:title" --json number,title \
--jq ".[] | select(.title == \"$TITLE\") | .number" | head -n1)
body="The weekly checksum audit failed. Run: $RUN_URL"
if [ -n "$number" ]; then
gh issue comment "$number" --body "$body"
else
gh issue create --title "$TITLE" --body "$body"
fi
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
pull_request:
push:
branches: [main]

jobs:
test:
name: Tests and packages.json check
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
with:
# check() calls `git show HEAD:./packages.json`, which needs at least the current
# commit's blob; HEAD is present even with the default shallow checkout, so depth 2
# is a cheap safety margin rather than a strict requirement.
fetch-depth: 2
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"
- run: node --test
- run: node generate-packages-json.js --check

# status.json/badges are a deterministic projection of packages.json, so a drift here means
# the committed artifacts were not regenerated - fail loudly rather than serve stale badges.
- name: Check the status artifacts are in sync
run: |
node generate-packages-json.js --status
git diff --exit-code status.json badges
2 changes: 1 addition & 1 deletion .github/workflows/keepalive.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- name: Create keepalive heartbeat
run: |
Expand Down
92 changes: 84 additions & 8 deletions .github/workflows/update-packages.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Update WordPress Core Package
name: WordPress release watch

on:
schedule:
Expand All @@ -8,6 +8,7 @@ on:

jobs:
check:
name: Check wordpress.org for new releases
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
Expand All @@ -16,9 +17,9 @@ jobs:
run: ${{ steps.gate.outputs.run }}

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: actions/setup-node@v6
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"

Expand All @@ -29,28 +30,46 @@ jobs:
run: node check-new-versions.js

update:
name: Update packages.json
needs: check
if: needs.check.outputs.run == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: write
issues: write
id-token: write
attestations: write
concurrency:
group: wp-core-repo-write
cancel-in-progress: false

outputs:
has_token: ${{ steps.token.outputs.present }}
pushed: ${{ steps.push.outputs.pushed }}

steps:
- uses: actions/checkout@v6
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: actions/setup-node@v6
- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"

# Job-level `if:` cannot read `secrets.*` directly, so whether PUBLISH_TOKEN is configured is
# exposed as a job output here for the `publish` job's `if:` to consume.
- name: Detect the publishing token
id: token
env:
PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
run: |
if [ -n "$PUBLISH_TOKEN" ]; then echo "present=true" >> "$GITHUB_OUTPUT"; else echo "present=false" >> "$GITHUB_OUTPUT"; fi

- name: Generate packages.json
id: generate
run: node generate-packages-json.js

- name: Commit and Push if Changed
id: push
env:
COMMIT_VERSION: ${{ steps.generate.outputs.commit_version }}
run: |
Expand All @@ -61,9 +80,21 @@ jobs:
else
COMMIT_MESSAGE="🔄 Update WordPress core metadata"
fi
git add packages.json
git diff --cached --quiet || git commit -m "$COMMIT_MESSAGE"
git pull --rebase --autostash origin "$GITHUB_REF_NAME" && git push
git add packages.json status.json badges
if git diff --cached --quiet; then
echo "pushed=false" >> "$GITHUB_OUTPUT"
else
git commit -m "$COMMIT_MESSAGE"
git pull --rebase --autostash origin "$GITHUB_REF_NAME" && git push || exit 1
echo "pushed=true" >> "$GITHUB_OUTPUT"
echo "Committed at $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> "$GITHUB_STEP_SUMMARY"
fi

- name: Attest packages.json
if: ${{ steps.push.outputs.pushed == 'true' }}
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: packages.json

- name: Fail if the run was incomplete
if: ${{ (steps.generate.outputs.incomplete || '0') != '0' }}
Expand All @@ -72,3 +103,48 @@ jobs:
run: |
echo "::error::$INCOMPLETE version(s) deferred; see the generator log"
exit 1

# if: failure() also fires for the deliberate "incomplete run" failure above -
# that is intended: a deferred version should be visible.
- name: Open or comment an issue on failure
if: failure()
env:
GH_TOKEN: ${{ github.token }}
TITLE: "WordPress release watch failed"
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
number=$(gh issue list --state open --search "$TITLE in:title" --json number,title \
--jq ".[] | select(.title == \"$TITLE\") | .number" | head -n1)
body="The update job failed. Run: $RUN_URL"
if [ -n "$number" ]; then
gh issue comment "$number" --body "$body"
else
gh issue create --title "$TITLE" --body "$body"
fi

publish:
name: Publish tags for Packagist
needs: update
if: ${{ needs.update.outputs.has_token == 'true' && needs.update.outputs.pushed == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 30
# contents: read only - this job writes to OTHER repositories via PUBLISH_TOKEN, never to this
# one. It never touches packages.json and therefore cannot affect the Pages output. It is
# deliberately NOT in the wp-core-repo-write concurrency group for the same reason: it does not
# write this repository, so it cannot race with the `update` job's commit/push.
permissions:
contents: read

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"

- name: Publish new version tags
env:
PUBLISH_REPO_WORDPRESS_CORE: ${{ vars.PUBLISH_REPO_WORDPRESS_CORE }}
PUBLISH_REPO_WORDPRESS_CORE_NO_CONTENT: ${{ vars.PUBLISH_REPO_WORDPRESS_CORE_NO_CONTENT }}
PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
run: node publish-packages.js
41 changes: 41 additions & 0 deletions .github/workflows/validate-badges.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Badge validation

on:
schedule:
- cron: "41 6 * * 1"
workflow_dispatch:

jobs:
validate:
name: Validate README badges against live services
runs-on: ubuntu-24.04
timeout-minutes: 10
permissions:
contents: read
issues: write

steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0

- uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
with:
node-version: "22"

- id: validate
run: node validate-badges.js

- name: Open or comment an issue on failure
if: failure()
env:
GH_TOKEN: ${{ github.token }}
TITLE: "Badge validation failed"
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
run: |
number=$(gh issue list --state open --search "$TITLE in:title" --json number,title \
--jq ".[] | select(.title == \"$TITLE\") | .number" | head -n1)
body="The weekly badge validation failed. Run: $RUN_URL"
if [ -n "$number" ]; then
gh issue comment "$number" --body "$body"
else
gh issue create --title "$TITLE" --body "$body"
fi
Loading
Loading