Someone who clones from code.silentmode.st and starts working will otherwise find out the hard way: push-split.sh force-pushes master, so their branch does not survive the next mirror push. Better to say it on the page that tells people how to take an upstream release, since that is exactly the work that would be lost.
5.4 KiB
Keeping up with WordPress
WordPress ships security releases, and a fork that cannot take them quickly is a liability rather than a project. This page is how Sirius Press takes them.
The arrangement
WordPress lives in this repository, at wordpress/, as a git subtree. The
fork's own change sits on top of it as an ordinary commit.
Three pieces make that work:
wordpress/ |
The vendored tree, patched. This is what gets built and shipped. |
sirius-press/wordpress-upstream |
A branch holding pristine upstream releases, one commit each, never edited. The other side of the merge. |
patches/ |
A readable record of what the fork changes in core. Generated, not maintained. |
The entire core diff is one file, 75 lines: wp-admin/install.php, the
setup wizard. Everything else Sirius Press does is plugins and hooks.
Why a subtree and not a patch series
Because a three-way merge understands something a patch does not. When
upstream edits lines near the fork's change, git subtree merge merges them
and moves on; patch either applies with fuzz and hopes, or fails and hands
you the job of re-deriving the change by hand. A conflict from the merge is
resolved once, in the file, and stays resolved — the next release merges
against the resolution.
The cost is repository size: WordPress is about 149 MB and 3,800 files. That is the price of a fork that can take a security release in a minute, and it is the right trade for a project whose whole argument is that it should outlive its maintainers' attention.
Taking a new release
tools/update-wordpress.sh 7.1.2
It downloads the release, checks it against the SHA-1 wordpress.org publishes,
imports the pristine tree onto sirius-press/wordpress-upstream, and merges
that branch into wordpress/. Then it updates tools/wordpress.lock and
regenerates patches/.
Two outcomes.
Clean. The merge went through. Run the tests, build, commit. Usually a minute of work.
Conflicted. Upstream changed the same lines the fork changes — in
practice, wp-admin/install.php. Git leaves the conflict in the file:
git status
$EDITOR wordpress/wp-admin/install.php
git add wordpress/wp-admin/install.php
git commit
tools/refresh-patches.sh
Then set WP_VERSION, WP_URL, WP_SHA256 and WP_SHA1 in
tools/wordpress.lock by hand, since the script stopped before it got there.
Either way the fork is not broken while you work: the merge is in your
working tree, and until you commit it, wordpress/ still holds the last
version that worked.
After any bump
tests/run.sh
tools/build.sh
The suite does not test core, but it tests every assumption the fork makes
about it. Then walk through wp-admin/install.php once in a browser — the
setup wizard is the only patched file, so it is the only thing an upstream
change can break in a way the tests would miss.
testing.md has a recipe for a throwaway instance that needs no
database server.
Keeping patches/ honest
patches/ is documentation. It answers the question anyone auditing this fork
asks first — what exactly did you change inside WordPress? — in a minute,
which git log wordpress/ cannot, because that log is mostly upstream
imports.
It is generated from the tree, never edited:
tools/refresh-patches.sh # rewrite it
tools/refresh-patches.sh --check # fail if it has drifted (for CI)
Generated documentation stays true. A hand-maintained record of a fork's core diff drifts, and a stale one is worse than none, because people trust it.
Changing core yourself
Edit the file under wordpress/ and commit it like any other change. The next
upstream merge will three-way it.
Before you do: check whether a plugin hook can carry the change instead. Every
line added to wordpress/ is a line that can conflict with upstream forever,
and the reason this fork's merges are cheap is that there are only 75 of them.
The registration form, the password-reset page and the mail pipeline were all
replaced from plugins precisely so they would never appear in this directory.
Where this repository lives
code.silentmode.st/silentmode/sirius-press is a mirror. Sirius Press is
developed inside the Silent Mode monorepo and split out with
scripts/push-split.sh, which force-pushes master each time. History on the
forge is real — file blame points at the actual commits — but it is rewritten
on every push, so a pull request against it will not survive.
What that means in practice:
- Silent Mode takes upstream releases in the monorepo, where the subtree's merge history is intact, and the result is mirrored here.
- A downstream fork that clones from the forge and wants to bump WordPress itself should treat its clone as the source of truth from that point on and stop pulling the mirror, because the next mirror push will not merge with its work.
Patches and bug reports are welcome as issues; code is easiest to take as a diff rather than as a branch.
If the upstream branch is missing
A clone made with --single-branch will not have
sirius-press/wordpress-upstream, and tools/update-wordpress.sh will say so
rather than guessing. Fetch it:
git fetch origin sirius-press/wordpress-upstream:sirius-press/wordpress-upstream
Building and running do not need it — only taking a new upstream release does.