Scope the release signal, collapse the contract onto the release version, publish the Hub overview #83
@@ -7,7 +7,7 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
overview_version:
|
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
|
required: true
|
||||||
|
|
||||||
jobs:
|
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
|
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
|
*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
|
`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
|
- **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
|
`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
|
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
|
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
|
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.
|
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
|
- **`HOST_API_VERSION` *is* the release version.** Its `major.minor` must equal the release tag's, and
|
||||||
the release tag's, and both release paths refuse a tag that disagrees
|
both release paths refuse a tag that disagrees (`release-tooling/contract-version.ts`). The patch
|
||||||
(`release-tooling/contract-version.ts`). The patch digit may lag on purpose: `checkApiVersion`
|
digit may lag on purpose: `checkApiVersion`
|
||||||
ignores patch, and auto-release cuts patch releases with no commit to bump a constant in. So a
|
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`
|
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
|
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
|
### Contract versioning
|
||||||
|
|
||||||
Each manifest declares `apiVersion` — a **semver** string naming the **Plainpages release** it was
|
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
|
built against. The host's `HOST_API_VERSION` *is* its release version, so a plugin author reads one
|
||||||
version, so a plugin author reads one version off the image they run and writes it down. Both release
|
version off the image they run and writes it down — there is no separate contract number. Both
|
||||||
paths refuse a tag whose `major.minor` disagrees with the constant, so the two cannot drift.
|
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
|
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
|
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 |
|
| 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 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
|
the caret-style compatibility. One digit carries the whole release, so a **minor** means either the
|
||||||
release: either the plugin contract changed, or a dependency moved far enough to warrant one. A
|
plugin contract changed or a dependency moved far enough to warrant one. A `warn` therefore says
|
||||||
`warn` therefore says "built against an older release", not "new plugin features exist" — check the
|
"built against an older release" rather than promising new plugin features; check that release's
|
||||||
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
|
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.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.
|
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");
|
const rendered = renderOverview(readFileSync("release-tooling/dockerhub-overview.md.tmpl", "utf8"), "9.9.9");
|
||||||
assert.deepEqual(leftoverPlaceholders(rendered), []);
|
assert.deepEqual(leftoverPlaceholders(rendered), []);
|
||||||
assert.match(rendered, /larvit\/plainpages:9\.9\.9/); // the placeholder actually reaches the examples
|
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)/);
|
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
|
// 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
|
// first thing an adopter copies, so `{{VERSION}}` is rendered from the release being published
|
||||||
// version that no longer existed. `{{VERSION}}` is rendered from the release, so they cannot.
|
// rather than written by hand.
|
||||||
|
|
||||||
const HUB = "https://hub.docker.com/v2";
|
const HUB = "https://hub.docker.com/v2";
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
"automerge": true,
|
"automerge": true,
|
||||||
"packageRules": [
|
"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"],
|
"matchDepTypes": ["dependencies"],
|
||||||
"matchFileNames": ["package.json"],
|
"matchFileNames": ["package.json"],
|
||||||
"matchManagers": ["npm"],
|
"matchManagers": ["npm"],
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import type { RequestContext } from "../http/context.ts";
|
|||||||
import type { NavNode } from "../ui/nav.ts";
|
import type { NavNode } from "../ui/nav.ts";
|
||||||
import type { StorageCredentials } from "./storage.ts";
|
import type { StorageCredentials } from "./storage.ts";
|
||||||
|
|
||||||
// The Plainpages release this contract ships in — one version, not a second one to track. Its
|
// The Plainpages release this contract ships in. Its major.minor must equal the release tag's, and
|
||||||
// major.minor must equal the release tag's; `release.yml` refuses to promote a tag that disagrees.
|
// both release paths refuse a tag that disagrees. The patch digit may lag: checkApiVersion ignores
|
||||||
// The patch digit may lag, since checkApiVersion ignores patch and auto-release cuts patches itself.
|
// patch, and auto-release cuts patch releases with no commit to bump this in.
|
||||||
export const HOST_API_VERSION = "0.1.0";
|
export const HOST_API_VERSION = "0.1.0";
|
||||||
|
|
||||||
export type HttpMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
|
export type HttpMethod = "DELETE" | "GET" | "HEAD" | "PATCH" | "POST" | "PUT";
|
||||||
|
|||||||
Reference in New Issue
Block a user