Document source release procedure
This commit is contained in:
@@ -25,6 +25,7 @@ implemented component map.
|
|||||||
| LLM clients, prompts, schemas, profiles, or scheduling | [LLM Runtime](internal/llm.md) | It documents the transport boundary and PromptKit integration. |
|
| LLM clients, prompts, schemas, profiles, or scheduling | [LLM Runtime](internal/llm.md) | It documents the transport boundary and PromptKit integration. |
|
||||||
| Output, cache, resume, or debug artifacts | [Run State Internals](internal/state.md), [Operations](operations.md), and [Configuration](config.md) | These separate implementation details, operator behavior, and configuration contracts. |
|
| Output, cache, resume, or debug artifacts | [Run State Internals](internal/state.md), [Operations](operations.md), and [Configuration](config.md) | These separate implementation details, operator behavior, and configuration contracts. |
|
||||||
| External input formats, artifact schemas, or durable output files | [Integration Contracts](integrations/) | Integration documents define external and durable data contracts. |
|
| External input formats, artifact schemas, or durable output files | [Integration Contracts](integrations/) | Integration documents define external and durable data contracts. |
|
||||||
|
| Release preparation, tagging, publication, or verification | [Source Releases](release.md) and [Documentation Policy](policy/documentation.md) | The release procedure owns maintainer guards and immutable-tag recovery; the policy assigns release-note ownership. |
|
||||||
| Proposed or unimplemented behavior | [Roadmap](roadmap/) | Future work belongs only in roadmap documentation until implemented. |
|
| Proposed or unimplemented behavior | [Roadmap](roadmap/) | Future work belongs only in roadmap documentation until implemented. |
|
||||||
|
|
||||||
For an existing subsystem, also inspect its focused tests and the package-local
|
For an existing subsystem, also inspect its focused tests and the package-local
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ secret values.
|
|||||||
| CLI contract | `docs/cli.md` | Commands, arguments, flags, invocation semantics, and exit codes. | End-to-end operating procedures, configuration field definitions, runtime filesystem layout, module implementation details. |
|
| CLI contract | `docs/cli.md` | Commands, arguments, flags, invocation semantics, and exit codes. | End-to-end operating procedures, configuration field definitions, runtime filesystem layout, module implementation details. |
|
||||||
| Configuration contract | `docs/config.md` | Discovery and precedence, file schema, fields, defaults, environment overrides, validation rules, and user-selectable module or validator keys. | Complete example files, CLI syntax, runtime state lifecycle, module implementation details. |
|
| Configuration contract | `docs/config.md` | Discovery and precedence, file schema, fields, defaults, environment overrides, validation rules, and user-selectable module or validator keys. | Complete example files, CLI syntax, runtime state lifecycle, module implementation details. |
|
||||||
| Operations | `docs/operations.md` | Runtime workflows, physical filesystem and state layout, output, cache, and debug handling, resume, cleanup, permissions, recovery, and operational limits. | CLI flag syntax, configuration field definitions, logical output schemas, implementation mechanics. |
|
| Operations | `docs/operations.md` | Runtime workflows, physical filesystem and state layout, output, cache, and debug handling, resume, cleanup, permissions, recovery, and operational limits. | CLI flag syntax, configuration field definitions, logical output schemas, implementation mechanics. |
|
||||||
|
| Source release procedure | `docs/release.md` | Maintainer release selection, candidate validation, tagging, publication guards, verification, and immutable-tag recovery. | Product installation summary, CLI version semantics, historical release summaries, CI implementation detail. |
|
||||||
|
| Release-note history | `docs/releases/` | One checked-in historical summary for each source release made under the procedure. The note at the immutable tag is that release's record. | Current commands, behavior, contracts, and compatibility definitions. |
|
||||||
| Public HTTP contract, if introduced | `docs/api.md` | Routes, authentication, media types, request and response schemas, status codes, pagination, caching, idempotency, rate limits, and HTTP retry semantics. | Client walkthroughs, upstream or downstream integration internals, implementation detail. |
|
| Public HTTP contract, if introduced | `docs/api.md` | Routes, authentication, media types, request and response schemas, status codes, pagination, caching, idempotency, rate limits, and HTTP retry semantics. | Client walkthroughs, upstream or downstream integration internals, implementation detail. |
|
||||||
| Consumer guidance, if a public package or API is introduced | `docs/consumers/` | Task-oriented use of the public interface, minimal client examples, and consumer responsibilities. | HTTP wire semantics, external protocol contracts, internal implementation detail. |
|
| Consumer guidance, if a public package or API is introduced | `docs/consumers/` | Task-oriented use of the public interface, minimal client examples, and consumer responsibilities. | HTTP wire semantics, external protocol contracts, internal implementation detail. |
|
||||||
| External and durable integration contracts | `docs/integrations/` | External file formats and protocols, upstream and downstream contracts, logical output bundle paths and schemas, media types, and compatibility behavior. | Physical runtime placement and lifecycle, internal transformations, CLI syntax, configuration defaults. |
|
| External and durable integration contracts | `docs/integrations/` | External file formats and protocols, upstream and downstream contracts, logical output bundle paths and schemas, media types, and compatibility behavior. | Physical runtime placement and lifecycle, internal transformations, CLI syntax, configuration defaults. |
|
||||||
@@ -95,6 +97,14 @@ runtime state and how to operate or recover the application. When a workflow
|
|||||||
crosses these topics, choose the document that owns the task and link to the
|
crosses these topics, choose the document that owns the task and link to the
|
||||||
other contracts.
|
other contracts.
|
||||||
|
|
||||||
|
### Releases
|
||||||
|
|
||||||
|
`docs/release.md` owns the source-release procedure. Release notes are
|
||||||
|
historical summaries, not current-state contract owners: the checked-in note at
|
||||||
|
an immutable tag records that release, while current canonical documentation
|
||||||
|
must change with the behavior it describes. Do not use a release note to defer
|
||||||
|
or replace current documentation updates.
|
||||||
|
|
||||||
### Contracts And Implementation
|
### Contracts And Implementation
|
||||||
|
|
||||||
Integration and API documents define externally observable shapes and
|
Integration and API documents define externally observable shapes and
|
||||||
|
|||||||
158
docs/release.md
Normal file
158
docs/release.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# Source Releases
|
||||||
|
|
||||||
|
This procedure is for maintainers publishing Notarius source releases. A
|
||||||
|
release is an immutable lightweight `vMAJOR.MINOR.PATCH` tag on `main` together
|
||||||
|
with its checked-in `docs/releases/<tag>.md` note. Tag CI validates that source
|
||||||
|
candidate after publication; it does not publish or repair a release.
|
||||||
|
|
||||||
|
Notarius publishes no binaries, archives, checksums, signatures, containers,
|
||||||
|
package-manager entries, or Gitea release objects. Windows is not supported.
|
||||||
|
Do not create retrospective notes for the pre-procedure `v0.1.0`, `v0.2.0`, or
|
||||||
|
`v0.3.0` tags.
|
||||||
|
|
||||||
|
## Select And Describe The Release
|
||||||
|
|
||||||
|
Choose an unused stable semantic version in the form `vMAJOR.MINOR.PATCH`.
|
||||||
|
Prereleases are not supported. Before `v1.0.0`, a minor release may change a
|
||||||
|
documented CLI, configuration, durable artifact, integration, or operating
|
||||||
|
contract when its note explains the impact and required operator action. A
|
||||||
|
patch release must not intentionally break those documented contracts within
|
||||||
|
its minor line.
|
||||||
|
|
||||||
|
Create the version-matched note as part of the candidate. Every new note uses
|
||||||
|
this structure, with concise, truthful content in each section:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Notarius vMAJOR.MINOR.PATCH
|
||||||
|
|
||||||
|
This release ...
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
## Upgrade
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
```
|
||||||
|
|
||||||
|
The note is a historical summary. Link to current canonical documentation for
|
||||||
|
exact behavior, and update that documentation in the candidate rather than
|
||||||
|
using the note as a substitute.
|
||||||
|
|
||||||
|
## Prepare The Candidate
|
||||||
|
|
||||||
|
Set the selected release version and disable Go workspace use for every
|
||||||
|
candidate command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
RELEASE_VERSION=vMAJOR.MINOR.PATCH
|
||||||
|
export RELEASE_VERSION GOWORK=off
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the shared source-candidate checks from the repository. They cover module
|
||||||
|
hygiene, tests, race tests, vet, builds, formatting, whitespace, maintained
|
||||||
|
configuration validation, and the Linux and Darwin command-build matrix:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./scripts/check-release-source.sh "$RELEASE_VERSION"
|
||||||
|
```
|
||||||
|
|
||||||
|
Before committing, manually follow every changed local Markdown link and
|
||||||
|
review the candidate for unintended files, generated output, credentials, or
|
||||||
|
other unrelated changes. Commit the release note and all affected current
|
||||||
|
documentation, then run the shared checker against that exact candidate. Push
|
||||||
|
the candidate commit to `main` only after it succeeds. Record the exact commit
|
||||||
|
only after that push:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
RELEASE_COMMIT=$(git rev-parse 'HEAD^{commit}')
|
||||||
|
export RELEASE_COMMIT
|
||||||
|
```
|
||||||
|
|
||||||
|
For private-module installation, configure standard `GOPRIVATE` matching this
|
||||||
|
module and ordinary Git authentication for the hosting service before running
|
||||||
|
the verification below. The exact authentication mechanism belongs to the
|
||||||
|
maintainer environment; never record credentials or environment dumps in a
|
||||||
|
release note, command history, or repository file.
|
||||||
|
|
||||||
|
## Guard And Publish The Tag
|
||||||
|
|
||||||
|
Fetch current remote references, then run this guard without editing the
|
||||||
|
candidate. It requires `main`, a clean worktree and index, disabled workspace
|
||||||
|
use, the recorded and pushed commit, a matching note, and unused local and
|
||||||
|
remote tags:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git fetch origin main --tags
|
||||||
|
|
||||||
|
test "$GOWORK" = off
|
||||||
|
test "$(git branch --show-current)" = main
|
||||||
|
test -z "$(git status --porcelain)"
|
||||||
|
test "$RELEASE_COMMIT" = "$(git rev-parse 'HEAD^{commit}')"
|
||||||
|
test "$RELEASE_COMMIT" = "$(git rev-parse 'origin/main^{commit}')"
|
||||||
|
test -s "docs/releases/$RELEASE_VERSION.md"
|
||||||
|
grep -F -x "# Notarius $RELEASE_VERSION" "docs/releases/$RELEASE_VERSION.md"
|
||||||
|
for heading in '## Summary' '## Compatibility' '## Upgrade' '## Changes'; do
|
||||||
|
grep -F -x "$heading" "docs/releases/$RELEASE_VERSION.md"
|
||||||
|
done
|
||||||
|
if git rev-parse -q --verify "refs/tags/$RELEASE_VERSION" >/dev/null; then
|
||||||
|
printf '%s\n' "local tag already exists: $RELEASE_VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if git ls-remote --exit-code --tags origin "refs/tags/$RELEASE_VERSION" >/dev/null 2>&1; then
|
||||||
|
printf '%s\n' "remote tag already exists: $RELEASE_VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
Create an explicitly lightweight tag against the guarded commit, verify its
|
||||||
|
target, and push only that tag ref:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git -c tag.gpgSign=false tag "$RELEASE_VERSION" "$RELEASE_COMMIT"
|
||||||
|
test "$(git cat-file -t "$RELEASE_VERSION")" = commit
|
||||||
|
test "$(git rev-parse "$RELEASE_VERSION^{commit}")" = "$RELEASE_COMMIT"
|
||||||
|
git push origin "refs/tags/$RELEASE_VERSION:refs/tags/$RELEASE_VERSION"
|
||||||
|
```
|
||||||
|
|
||||||
|
Never use `git push --tags`, move a published tag, or delete a published tag.
|
||||||
|
|
||||||
|
## Verify The Published Release
|
||||||
|
|
||||||
|
Confirm that the remote tag still points at the guarded commit and that the
|
||||||
|
note is available from the tagged tree:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
REMOTE_TAG_COMMIT=$(git ls-remote origin "refs/tags/$RELEASE_VERSION" | awk '{print $1}')
|
||||||
|
test "$REMOTE_TAG_COMMIT" = "$RELEASE_COMMIT"
|
||||||
|
git show "$RELEASE_VERSION:docs/releases/$RELEASE_VERSION.md" >/dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify a fresh source installation and its diagnostic version. The temporary
|
||||||
|
directory confines the installed command to this check:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
release_verification_dir=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$release_verification_dir"' 0 HUP INT TERM
|
||||||
|
mkdir -p "$release_verification_dir/bin"
|
||||||
|
GOWORK=off GOBIN="$release_verification_dir/bin" go install \
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/cmd/notarius@$RELEASE_VERSION"
|
||||||
|
test "$("$release_verification_dir/bin/notarius" --version)" = "notarius $RELEASE_VERSION"
|
||||||
|
```
|
||||||
|
|
||||||
|
An exact fresh checkout and `GOWORK=off go build ./cmd/notarius` is an
|
||||||
|
equivalent source verification when local installation policy requires it.
|
||||||
|
`notarius --version` is diagnostic only; downstream compatibility remains
|
||||||
|
defined by the published receipt and artifact contracts.
|
||||||
|
|
||||||
|
## Failure And Correction Policy
|
||||||
|
|
||||||
|
If candidate validation fails before publication, fix the candidate on `main`,
|
||||||
|
rerun the shared checker, and repeat the guards. An unpublished local tag may
|
||||||
|
be deleted after inspection.
|
||||||
|
|
||||||
|
If the remote tag or tag CI reveals a defect, leave the published tag intact.
|
||||||
|
Fix the defect on `main`, choose a new patch version, write a new matching
|
||||||
|
note, and repeat this procedure. Do not weaken tag immutability or add release
|
||||||
|
assets as a workaround.
|
||||||
@@ -243,7 +243,7 @@ the pre-release confidence boundary.
|
|||||||
- The pipeline cannot publish binaries, releases, checksums, or other assets
|
- The pipeline cannot publish binaries, releases, checksums, or other assets
|
||||||
and requires no release secret.
|
and requires no release secret.
|
||||||
|
|
||||||
## Stage 4: Establish The Canonical Release Procedure And Documentation Policy
|
## Stage 4: Establish The Canonical Release Procedure And Documentation Policy ✅
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user