Scope the release signal, collapse the contract onto the release version, publish the Hub overview #83
@@ -7,7 +7,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
overview_version:
|
||||
description: 'Version the overview should tell adopters to pull (e.g. 0.2.0)'
|
||||
description: 'Version the overview should tell adopters to pull (e.g. 0.1.0)'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -293,7 +293,7 @@ Revisit only if the stated reason stops holding.
|
||||
docs and skip the gate over a source file that was gone. `src/ci-gate.test.ts` locks the flags as a
|
||||
*text* guard — the test image ships neither `git` nor `bash`. This is why the Docker Hub overview is
|
||||
`release-tooling/dockerhub-overview.md.tmpl` and not a `.md`: a release reads it and a unit test
|
||||
guards it, so renaming it back would let a broken `{{VERSION}}` merge with its own guard skipped.
|
||||
guards it, so giving it a `.md` name would let a broken `{{VERSION}}` merge with its own guard skipped.
|
||||
- **CI docker logins share the runner host's Docker config.** The act_runner is host-mode, so
|
||||
`docker login`/`logout` in the workflows mutate one shared `~/.docker/config.json`: concurrent jobs
|
||||
can race (one job's logout can 401 another's push — recover by re-running), and tokens sit in that
|
||||
@@ -353,9 +353,9 @@ one-time setup. A file-map or table row gets a clause, not a paragraph.
|
||||
trailer, so a dependency added anywhere else never escalates the release version and nothing fails to
|
||||
say so. A new manifest, compose file, custom manager or dep type is a decision: can it reach a
|
||||
running Plainpages? If yes it needs a rule; if no, record nothing and let it ride the next patch.
|
||||
- **`HOST_API_VERSION` *is* the release version — one number, not two.** Its `major.minor` must equal
|
||||
the release tag's, and both release paths refuse a tag that disagrees
|
||||
(`release-tooling/contract-version.ts`). The patch digit may lag on purpose: `checkApiVersion`
|
||||
- **`HOST_API_VERSION` *is* the release version.** Its `major.minor` must equal the release tag's, and
|
||||
both release paths refuse a tag that disagrees (`release-tooling/contract-version.ts`). The patch
|
||||
digit may lag on purpose: `checkApiVersion`
|
||||
ignores patch, and auto-release cuts patch releases with no commit to bump a constant in. So a
|
||||
dependency update big enough to force a **minor** is plugin-visible by definition — `auto-release`
|
||||
stops rather than tagging, and the fix is to bump `HOST_API_VERSION` to that `X.Y.0` in a PR, merge
|
||||
|
||||
@@ -594,9 +594,9 @@ works without editing host config.
|
||||
### Contract versioning
|
||||
|
||||
Each manifest declares `apiVersion` — a **semver** string naming the **Plainpages release** it was
|
||||
built against. There is no second number to track: the host's `HOST_API_VERSION` *is* its release
|
||||
version, so a plugin author reads one version off the image they run and writes it down. Both release
|
||||
paths refuse a tag whose `major.minor` disagrees with the constant, so the two cannot drift.
|
||||
built against. The host's `HOST_API_VERSION` *is* its release version, so a plugin author reads one
|
||||
version off the image they run and writes it down — there is no separate contract number. Both
|
||||
release paths refuse a tag whose `major.minor` disagrees with the constant, so the two cannot drift.
|
||||
|
||||
Patch releases are invisible here — `checkApiVersion` ignores the patch digit, which is what lets
|
||||
dependency updates ship continuously without touching any plugin. At discovery the host parses both
|
||||
@@ -612,10 +612,10 @@ provider/consumer semantics in `checkApiVersion`:
|
||||
| missing / not a valid semver | `refuse` | **abort boot** — must be declared |
|
||||
|
||||
The plugin pins one exact version (no ranges, per the project's pinning rules); the *host* supplies
|
||||
the caret-style compatibility. Note what a **minor** means now that one digit carries the whole
|
||||
release: either the plugin contract changed, or a dependency moved far enough to warrant one. A
|
||||
`warn` therefore says "built against an older release", not "new plugin features exist" — check the
|
||||
Upgrading section for that release before assuming there is anything to adopt. While Plainpages is `0.x` every release shares major `0`, so a plugin
|
||||
the caret-style compatibility. One digit carries the whole release, so a **minor** means either the
|
||||
plugin contract changed or a dependency moved far enough to warrant one. A `warn` therefore says
|
||||
"built against an older release" rather than promising new plugin features; check that release's
|
||||
notes before assuming there is anything to adopt. While Plainpages is `0.x` every release shares major `0`, so a plugin
|
||||
built against `0.1.0` still loads on a `0.9.0` host with a `warn`; reaching `1.0.0` refuses everything
|
||||
built against `0.x`, which is the point of that milestone.
|
||||
|
||||
|
||||
@@ -17,6 +17,6 @@ test("the real template renders clean and pins no literal image tag", () => {
|
||||
const rendered = renderOverview(readFileSync("release-tooling/dockerhub-overview.md.tmpl", "utf8"), "9.9.9");
|
||||
assert.deepEqual(leftoverPlaceholders(rendered), []);
|
||||
assert.match(rendered, /larvit\/plainpages:9\.9\.9/); // the placeholder actually reaches the examples
|
||||
// A hardcoded version here is what went stale on the live page; the release must own every one.
|
||||
// The release owns every image tag on the page, so a literal one must not survive rendering.
|
||||
assert.doesNotMatch(rendered, /larvit\/plainpages:\d+\.\d+\.\d+(?<!9\.9\.9)/);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Publishes the Docker Hub repository overview from dockerhub-overview.md.tmpl. The page is the
|
||||
// first thing an adopter copies, and its image tags were maintained by hand — they pointed at a
|
||||
// version that no longer existed. `{{VERSION}}` is rendered from the release, so they cannot.
|
||||
// first thing an adopter copies, so `{{VERSION}}` is rendered from the release being published
|
||||
// rather than written by hand.
|
||||
|
||||
const HUB = "https://hub.docker.com/v2";
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
"automerge": true,
|
||||
"packageRules": [
|
||||
{
|
||||
"description": "The host's own runtime deps. Release-Bump is opt-in per surface (README → CI/CD) because updateType rates the dependency's own jump, not its effect here — unscoped, the bot's self-update bumped the product",
|
||||
"description": "The host's own runtime deps. Release-Bump is opt-in per surface (README → CI/CD): updateType rates the dependency's own jump, not whether it reaches a running Plainpages",
|
||||
"matchDepTypes": ["dependencies"],
|
||||
"matchFileNames": ["package.json"],
|
||||
"matchManagers": ["npm"],
|
||||
|
||||
@@ -8,9 +8,9 @@ import type { RequestContext } from "../http/context.ts";
|
||||
import type { NavNode } from "../ui/nav.ts";
|
||||
import type { StorageCredentials } from "./storage.ts";
|
||||
|
||||
// The Plainpages release this contract ships in — one version, not a second one to track. Its
|
||||
// major.minor must equal the release tag's; `release.yml` refuses to promote a tag that disagrees.
|
||||
// The patch digit may lag, since checkApiVersion ignores patch and auto-release cuts patches itself.
|
||||
// The Plainpages release this contract ships in. Its major.minor must equal the release tag's, and
|
||||
// both release paths refuse a tag that disagrees. The patch digit may lag: checkApiVersion ignores
|
||||
// patch, and auto-release cuts patch releases with no commit to bump this in.
|
||||
export const HOST_API_VERSION = "0.1.0";
|
||||
|
||||
export type HttpMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
|
||||
|
||||
Reference in New Issue
Block a user