Keep the release runbook focused on Promptkit steps

This commit is contained in:
2026-11-02 14:24:04 +00:00
parent 061f01c081
commit 1de3e1fe38

View File

@@ -1,28 +1,26 @@
# Release Procedure # Release Procedure
This runbook implements the [release policy](policy/release.md). Promptkit This runbook implements the [release policy](policy/release.md). Promptkit
publishes source-only Go module tags from `main` to `origin`. A successful push publishes source-only Go module tags from `main` to `origin`, followed by a
of the selected annotated tag, after its source commit is available on `main`, page-only Gitea release. Successful publication of the intended tag, with its
completes the release. Do not wait for CI or Go module availability. source commit available on `main`, completes the source release. Report hosted
After source publication, deliver the hosted Gitea release page as described delivery separately. Do not wait for CI or Go module availability.
below. Report source publication and hosted delivery separately.
## Prepare The Candidate ## Prepare The Candidate
Required tools are Git, Go with race-detector support, POSIX shell, and Python Required tools are Git, Go with race-detector support, POSIX shell, and Python
3. Work from the repository root with push access to `origin`. 3. Work from the repository root with push access to `origin`.
Use the latest Go installation available locally for the release tool, the Use the latest Go installation available locally for the release tool and its
candidate validation, and the maintained examples. Make it the active `go` child commands. Put it first on `PATH` and keep it selected throughout:
command and record its version:
```sh ```sh
export GOTOOLCHAIN=local export GOTOOLCHAIN=local
go version go version
``` ```
For a minor release, advance Promptkit's consumer minimum to the initial stable For a minor release, normally advance the consumer minimum to the initial
release of that Go series before committing the candidate: stable patch of that Go series:
```sh ```sh
release_go_version=$(go env GOVERSION) release_go_version=$(go env GOVERSION)
@@ -31,151 +29,97 @@ release_go_series=${release_go_series%.*}
go mod edit "-go=${release_go_series}.0" go mod edit "-go=${release_go_series}.0"
``` ```
For example, Go 1.27.1 normally results in `go 1.27.0`. Keep a higher patch Retain a higher patch minimum when required by a dependency or identified fix.
minimum if a dependency or identified correctness fix requires it. For a patch For a patch release, preserve the existing minimum. Explain minimum increases
release, leave the consumer minimum unchanged; using a newer validation under the [versioning policy](policy/release.md#versioning-and-compatibility).
toolchain does not itself raise that minimum. If the candidate needs a higher Prepare dependency caches before committing the candidate:
minimum, prepare a minor release instead. See the
[consumer-minimum policy](policy/release.md#consumer-minimum-and-release-toolchain).
Prepare module caches before validation; this may update `go.sum` and belongs
before the candidate commit:
```sh ```sh
GOTOOLCHAIN=local go mod download go mod download
``` ```
Choose an unused stable version and create `docs/releases/<version>.md` with a Choose an unused stable version and create `docs/releases/<version>.md` with a
title containing `Promptkit` and that exact version, a short summary, and any title containing `Promptkit` and that exact version, a short summary, and any
relevant compatibility impact or upgrade instructions. No fixed section compatibility impact or upgrade instructions. End the note with:
headings are required. Describe a raised Go minimum and its compatibility
impact under the [versioning policy](policy/release.md#versioning-and-compatibility).
End each new note with the licensing footer below, using the selected version:
```markdown ```markdown
[COPYRIGHT](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/COPYRIGHT) | [LICENSE](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/LICENSE) | [ATTRIBUTION](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/docs/oss/attribution.md) [COPYRIGHT](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/COPYRIGHT) | [LICENSE](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/LICENSE) | [ATTRIBUTION](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/vX.Y.Z/docs/oss/attribution.md)
``` ```
Check the footer paths against the candidate; the future tag need not resolve Substitute the selected version and check the paths against the candidate;
remotely during preparation. Follow the [OSS policy](policy/oss.md) for these future tag URLs need not resolve during preparation. Follow the
links. Hosted delivery reuses this complete note without a separate summary. [OSS policy](policy/oss.md). Historical notes and tags remain unchanged.
Promptkit publishes no binaries, attachments, or checksum manifests.
For hosted delivery, supply a Gitea API token with access to publish releases Supply delivery credentials through `RELEASEKIT_GITEA_TOKEN` or the ignored
through `RELEASEKIT_GITEA_TOKEN` or the ignored local file local file `.releasekit/gitea-token`, with owner-only file permissions. A
`.releasekit/gitea-token`, with owner-only permissions for the file. A nonblank nonblank environment value takes precedence. Source publication neither reads
environment value takes precedence. ReleaseKit trims surrounding whitespace nor requires this token. The [profile](../releasekit.json) selects the token
from file contents. Keep the token out of commits and shared logs. The profile path for committed-file protection; keep credentials out of commits and logs.
rejects that exact token path if
committed; it does not scan other files or Git history. Source publication uses
Git authentication and neither reads nor requires the delivery token.
Retire completed roadmaps while preserving deferred work and repairing incoming Retire completed roadmaps, preserve unfinished work, and repair affected links.
links. Review the intended changes through the ordinary development workflow, Review and commit the candidate on `main`, including any module updates, then
commit the candidate on `main`, and push `main` to `origin` before publication. push `main` to `origin` before publishing its tag.
Preparation may update module metadata; the release bootstrap and validation
preserve the committed candidate.
## Validate And Publish ## Validate And Publish
For an optional local diagnostic of a committed candidate, run:
```sh
./scripts/releasekit.sh check vMAJOR.MINOR.PATCH
```
This is not a required step before publication. The upstream
[candidate-check contract](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/consumers/check.md)
describes its requirements.
Run the single publication command with the chosen version:
```sh ```sh
./scripts/release.sh vMAJOR.MINOR.PATCH ./scripts/release.sh vMAJOR.MINOR.PATCH
``` ```
The familiar wrapper delegates to the native ReleaseKit executable selected in The launcher uses `go tool` to build or reuse the module-selected ReleaseKit
`go.mod`. The committed [profile](../releasekit.json) selects the race-enabled executable in Go's cache, using the selected local toolchain. ReleaseKit runs
Go suite, full vet, committed Go formatting, local Markdown links, workspace the [profile's checks](../releasekit.json) once, verifies publication state, and
and filesystem replacement inspection, and semantic checks for the three publishes only the intended tag. Preserve its native exit status and diagnostic.
maintained offline consumer examples. It also checks that the configured local Successful publication needs no separate remote read-back or CI wait.
token path is not committed. ReleaseKit verifies the committed
candidate and publication state, then publishes only the selected tag. Its
checks run once for this candidate; do not repeat them as a separate sign-off.
The native command returns status 0 for confirmed publication, 1 for a known For optional local diagnosis, use `./scripts/releasekit.sh check VERSION`.
validation or publication failure, 2 for invalid input or profile, and 3 when It is not a required step before publication. The upstream
the push outcome remains unknown. Successful publication needs no remote [candidate-check guide](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/consumers/check.md)
read-back, CI wait, or installation check. Provider probes and inference calls and [CLI contract](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/cli.md)
are not part of validation. own shared checks and exit-status definitions.
## Deliver The Hosted Release ## Deliver The Hosted Release
After source publication succeeds, keep a clean checkout at the published tag's After source publication, keep a clean checkout at the published tag's commit:
commit and run:
```sh ```sh
./scripts/releasekit.sh deliver vMAJOR.MINOR.PATCH ./scripts/releasekit.sh deliver vMAJOR.MINOR.PATCH
``` ```
The profile selects Gitea at `https://forge.maximumdirect.net`, owner The profile selects page-only Gitea delivery for this repository. The hosted
`base-layer`, repository `promptkit`. With no build targets, ReleaseKit creates body is the complete checked-in note, including its licensing footer. There are
or accepts a stable, non-draft release page containing the complete committed no binary assets, checksum manifests, candidate revalidation, or CI waits.
note and licensing footer. There is no binary build, attachment upload, or ReleaseKit checks delivery credentials during delivery, not as a publication
candidate revalidation. Delivery does not publish another tag or wait for CI. gate. Report the hosted URL on success; delivery failure leaves the source
release complete.
ReleaseKit performs its authenticated, read-only repository preflight during
delivery; no separate preflight is required before source publication. Missing
credentials or an unavailable hosted service leave the source release complete.
Delivery returns status 0 for completion, 1 for an operational failure,
conflict, or partial delivery, 2 for invalid configuration or credential/access
errors, and 3 for an unresolved hosted write. Report the hosted URL on success
and retain the diagnostic and delivery state on failure. See the upstream
[delivery guide](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/consumers/delivery.md)
for the full result contract.
For a later retry, use a clean checkout of the original tag with its recorded For a later retry, use a clean checkout of the original tag with its recorded
module files and make the token available locally. For example, in a separate module files and supply the token there. In a separate checkout, for example:
checkout with the tag available:
```sh ```sh
git switch --detach vMAJOR.MINOR.PATCH git switch --detach vMAJOR.MINOR.PATCH
./scripts/releasekit.sh deliver vMAJOR.MINOR.PATCH ./scripts/releasekit.sh deliver vMAJOR.MINOR.PATCH
``` ```
The launcher builds the tool selected by that checkout. Matching hosted content Resolve uncertain hosted writes before retrying the same immutable version.
is accepted; conflicting content is not overwritten. Resolve an unknown hosted Matching content is accepted; conflicts are not overwritten. Do not rerun
write before retrying. Retry delivery with the same immutable version rather `publish` or move tags to repair delivery. Follow the upstream
than rerunning `publish` or moving a tag. Corrections to published source or [delivery guide](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/consumers/delivery.md)
content require a new appropriate version. These steps apply to tags containing for result interpretation and recovery. These commands apply to tags containing
this delivery configuration; older releases retain their original workflows. this delivery configuration; older releases retain their original workflows.
## Failure Recovery ## Failure Recovery
This section covers source publication. Hosted-delivery recovery is described For source-publication failures, use ReleaseKit's status and diagnostic to
[above](#deliver-the-hosted-release); its failure does not undo source publication. distinguish a candidate defect from a publication conflict. Correct and commit
candidate defects, push `main`, and rerun publication as appropriate. A failure
after local tag creation may leave a ref even when its object ID is unavailable.
For status 1, use the diagnostic to distinguish a validation failure from a Status 3 means the push outcome remains unknown. Preserve the captured endpoint,
known publication conflict. Correct and commit candidate defects, push `main`, version, and tag object from that attempt; do not retry or remove the local tag
and rerun publication with an unused version when appropriate. Status 2 means until the authoritative outcome is resolved. Diagnostics mask HTTP(S) credentials,
the invocation or profile must be corrected. so use the actual captured endpoint rather than a redacted display. Follow the
upstream [failure-recovery procedure](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/release.md#resolve-failures):
If local tag creation or verification fails, inspect the reported local ref:
it may remain even when ReleaseKit could not establish its object ID. Apply
the authoritative-state checks below before removing a retained tag.
For status 3, do not retry or remove the local tag until the remote outcome is
resolved. ReleaseKit reports the attempted version, tag object, and recovery
state, including the captured publication endpoint when available. Use that
endpoint—not merely the current `origin` URL—to query the exact tag; follow the
upstream
[failure-recovery procedure](https://forge.maximumdirect.net/base-layer/releasekit/src/tag/v0.7.0/docs/release.md#resolve-failures).
CLI diagnostics mask HTTP(S) credentials. If the displayed endpoint is
redacted, use the actual endpoint captured for that attempt, with authentication
supplied locally; do not copy the redacted display as a transport URL or expose
credentials in shared logs.
```sh ```sh
releasekit_endpoint='COPY_CAPTURED_ENDPOINT' releasekit_endpoint='COPY_CAPTURED_ENDPOINT'
@@ -184,16 +128,8 @@ test "$(git ls-remote --get-url -- "$releasekit_endpoint")" = "$releasekit_endpo
git ls-remote --refs -- "$releasekit_endpoint" "refs/tags/$releasekit_version" git ls-remote --refs -- "$releasekit_endpoint" "refs/tags/$releasekit_version"
``` ```
Compare the returned object ID with the reported tag object. An exact match An exact tag-object match confirms publication. Absence is established only if
confirms publication. A missing ref confirms absence only when the endpoint both checks succeed and the tag is missing; a failed check leaves the outcome
identity check and query both succeed. If either check fails, the outcome unknown. Remove an unpublished local tag only after confirming authoritative
remains unknown; correct the transport configuration and resolve it before absence. Never move or replace a published tag or hosted page. Corrections to
retrying. Only after authoritative absence is confirmed may an unpublished published source or content require a new appropriate version.
local tag be removed before correcting the candidate or retrying. Never move,
overwrite, or delete a published tag.
## Policy Changes
Update the policy and this procedure together when changing release governance.
Consumers own their dependency-availability and release checks; their readiness
does not delay completion of a Promptkit release.