Count both paths of a rename in the docs-only CI skip; pause auto-release #55

Merged
lilleman merged 4 commits from skip-ci-for-root-markdown into main 2026-08-05 10:46:53 +02:00
4 changed files with 18 additions and 6 deletions
Showing only changes of commit e5bdc15262 - Show all commits
+4 -1
View File
@@ -12,7 +12,10 @@ jobs:
- uses: actions/checkout@v7.0.1 - uses: actions/checkout@v7.0.1
with: with:
fetch-depth: 0 fetch-depth: 0
fetch-tags: true # load-bearing for --prune below: no local tags would delete every remote one
# --prune so a tag deleted here doesn't live on at GitHub forever. It only removes refs a
# refspec DESTINATION matches — so tags; main is a non-glob dst, other branches match nothing.
- run: | - run: |
git push --force \ git push --force --prune \
"https://x-access-token:${{ secrets.MIRROR_GITHUB_TOKEN }}@github.com/larvit/plainpages.git" \ "https://x-access-token:${{ secrets.MIRROR_GITHUB_TOKEN }}@github.com/larvit/plainpages.git" \
refs/remotes/origin/main:refs/heads/main 'refs/tags/*:refs/tags/*' refs/remotes/origin/main:refs/heads/main 'refs/tags/*:refs/tags/*'
+4 -1
View File
@@ -184,7 +184,10 @@ them. Revisit only if the stated reason stops holding.
none; same reasoning that freezes `HOST_API_VERSION` at 1.0.0. Note the coupling: none; same reasoning that freezes `HOST_API_VERSION` at 1.0.0. Note the coupling:
`registry-cleanup` keeps a hash image only while its commit is a branch head *or* release-tagged, `registry-cleanup` keeps a hash image only while its commit is a branch head *or* release-tagged,
so with zero tags only branch heads survive the nightly prune — a hand-cut tag must sit on `main`'s so with zero tags only branch heads survive the nightly prune — a hand-cut tag must sit on `main`'s
tip. Valid until the maintainer says Plainpages is ready to show people. tip. `mirror.yml` pushes tags with `--prune` so the deletions actually reach the public GitHub
mirror; that makes the runner's tag view load-bearing (hence `fetch-tags: true`) and means a tag
or Release created on GitHub is swept away, so releases are cut on Gitea only. Valid until the
maintainer says Plainpages is ready to show people.
- **A dropdown is a `<button popovertarget>` + `[popover]`, never a `<details>`.** The browser then - **A dropdown is a `<button popovertarget>` + `[popover]`, never a `<details>`.** The browser then
owns open/close, which is the only zero-JS way to dismiss a menu by clicking outside it (the whole owns open/close, which is the only zero-JS way to dismiss a menu by clicking outside it (the whole
point), and the panel sits in the top layer so a row kebab is no longer clipped by `.table-wrap`'s point), and the panel sits in the top layer so a row kebab is no longer clipped by `.table-wrap`'s
+9 -3
View File
@@ -1524,7 +1524,7 @@ Gitea Actions (`.gitea/workflows/`) runs the pipeline; the test job runs
| --- | --- | --- | | --- | --- | --- |
| `ci.yml` | push, any branch except `main` | the full gate (`bash ci.sh`, a no-op on a docs-only branch), then build + push the app image | | `ci.yml` | push, any branch except `main` | the full gate (`bash ci.sh`, a no-op on a docs-only branch), then build + push the app image |
| `release.yml` | push of a `vX.Y.Z` tag | re-tag that commit's image as `X.Y.Z`, `X.Y`, `X`, `latest`; sync those tags to Docker Hub | | `release.yml` | push of a `vX.Y.Z` tag | re-tag that commit's image as `X.Y.Z`, `X.Y`, `X`, `latest`; sync those tags to Docker Hub |
| `mirror.yml` | push to `main` or any tag, or manual | force-push `main` + tags to the [GitHub mirror](https://github.com/larvit/plainpages) | | `mirror.yml` | push to `main` or any tag, or manual | force-push `main` + tags (pruning deleted ones) to the [GitHub mirror](https://github.com/larvit/plainpages) |
| `registry-cleanup.yml` | nightly cron, or manual | delete registry images that are neither release-tagged nor a branch head | | `registry-cleanup.yml` | nightly cron, or manual | delete registry images that are neither release-tagged nor a branch head |
| `renovate.yml` | nightly cron, or manual | open dependency-update PRs, automerge them once the gate is green; the release-tag job only runs when `AUTO_RELEASE` is `true` | | `renovate.yml` | nightly cron, or manual | open dependency-update PRs, automerge them once the gate is green; the release-tag job only runs when `AUTO_RELEASE` is `true` |
@@ -1578,9 +1578,15 @@ Docker Hub when it changes.
**GitHub mirror** — [github.com/larvit/plainpages](https://github.com/larvit/plainpages) is a **GitHub mirror** — [github.com/larvit/plainpages](https://github.com/larvit/plainpages) is a
read-only mirror; after every merge, `mirror.yml` force-pushes `main` and all tags there, read-only mirror; after every merge, `mirror.yml` force-pushes `main` and all tags there,
overwriting any drift (refs deleted on Gitea are not pruned). One-time setup: a dedicated overwriting any drift. Tags are pushed with `--prune`, so deleting one here deletes it there on
the next mirror run — ref deletions don't trigger the workflow themselves — and the mirror can't
go on advertising a version the source dropped; branches other than `main` are matched by no
refspec and are left alone. The same sweep removes a tag *created* on GitHub, so cut releases on
Gitea, never on the mirror — a GitHub Release made there loses its tag and does not come back.
One-time setup: a dedicated
GitHub machine account with write access to the GitHub repo (whose `main` must not block GitHub machine account with write access to the GitHub repo (whose `main` must not block
force-pushes), and a fine-grained PAT scoped to that repo (Contents: read & write), stored force-pushes, and which must carry no tag protection — that would reject the prune and fail every
run), and a fine-grained PAT scoped to that repo (Contents: read & write), stored
as the Gitea Actions secret `MIRROR_GITHUB_TOKEN` (repo Settings → Actions → Secrets; Gitea as the Gitea Actions secret `MIRROR_GITHUB_TOKEN` (repo Settings → Actions → Secrets; Gitea
rejects secret names starting with `GITHUB_`/`GITEA_`). Trigger the workflow manually for rejects secret names starting with `GITHUB_`/`GITEA_`). Trigger the workflow manually for
the first sync — until the secret exists, the mirror job fails loud on each merge. the first sync — until the secret exists, the mirror job fails loud on each merge.
+1 -1
View File
@@ -31,6 +31,6 @@ test("the commit-hash image is pushed even when the gate no-ops", () => {
test("only *.md counts as docs; a dirty tree and a rename both count as changed", () => { test("only *.md counts as docs; a dirty tree and a rename both count as changed", () => {
assert.ok(gate.includes("\\.md$"), "the non-docs match is a *.md suffix test"); assert.ok(gate.includes("\\.md$"), "the non-docs match is a *.md suffix test");
assert.match(gate, /git status --porcelain --no-renames/, "uncommitted code can never be skipped over"); assert.match(gate, /git status --porcelain --no-renames/, "uncommitted code and a staged rename can never be skipped over");
assert.match(gate, /git diff --name-only --no-renames/, "a rename must list both of its paths"); assert.match(gate, /git diff --name-only --no-renames/, "a rename must list both of its paths");
}); });