diff --git a/docs/development.md b/docs/development.md index cf68a7e..5dbd812 100644 --- a/docs/development.md +++ b/docs/development.md @@ -25,6 +25,7 @@ polished transcripts and generated artifacts. Start with the | Adapters or external tool contracts | [Adapter Internals](internal/adapters.md) and [Integration Contracts](integrations/README.md) | The internal guide owns adapter composition and mechanics; integration documents own external formats and protocols. | | Manifests, artifacts, workspace paths, or publish behavior | [Manifest Internals](internal/manifest.md), [Artifact Internals](internal/artifacts.md), [Workspace Internals](internal/workspace.md), [Publish Internals](internal/stage-publish.md), and [Operations](operations.md) | These separate implementation state and resolution from operator-visible layout and lifecycle. | | Maintained configuration or input examples | [Configuration](config.md) and [Examples](../examples/README.md) | The reference owns field meanings; the examples directory owns complete copyable files. | +| Preparing, validating, or publishing a release | [Release Procedure](release.md) | The maintainer procedure owns version selection, candidate validation, guarded tag publication, and optional later CI inspection. | | Proposed or unimplemented behavior | `docs/roadmap/` | Future work belongs only in roadmap documentation until implemented. | For an existing subsystem, also inspect its focused tests and package-level @@ -46,9 +47,9 @@ go test ./internal/config -run '^TestExamplesLoadAndValidate$' The documentation check verifies local Markdown links and the dependency graph of the Woodpecker workflows. The configuration check loads every maintained -pipeline and session example. Release automation repeats these checks and -cross-compiles the CLI before it builds release assets; publishing depends on -that validation path, so a failure cannot publish a release. +pipeline and session example. Tag CI reuses this validation path before its +asynchronous asset publication; the maintainer release boundary is documented +in the [Release Procedure](release.md). Woodpecker also runs `go test -race -shuffle=on -count=3 ./...` on its scheduled job to expose ordering and repeatability defects. Current runners cross-compile diff --git a/docs/policy/documentation.md b/docs/policy/documentation.md index 5823977..d069f2d 100644 --- a/docs/policy/documentation.md +++ b/docs/policy/documentation.md @@ -59,6 +59,8 @@ secret values. | --- | --- | --- | --- | | Product orientation and minimal end-to-end quickstart | `README.md` | What Narratio is, why it is useful, one shortest successful invocation, and links onward. | Complete command reference, configuration reference, operational procedures, implementation detail. | | Contributor entry point | `docs/development.md` | Task-oriented reading guide, minimal contributor orientation, baseline validation commands, and links to canonical docs. | Package inventory, architecture rules, subsystem behavior, detailed change recipes. | +| Maintainer release procedure | `docs/release.md` | Version selection, candidate preparation and validation, guarded tag publication, release completion boundary, failure recovery, and optional asynchronous inspection. | Script implementation mechanics, current application contracts, and historical release summaries. | +| Historical release summary | `docs/releases/.md` | Immutable summary, compatibility, upgrade, and changes for one released version. | Current maintainer procedure and current application contract details. | | Current application architecture | `docs/policy/architecture.md` | System shape, normative ownership, dependency direction, architectural boundaries, invariants, safety properties, and non-goals. | Concrete package inventory, implementation mechanics, contributor procedures, decision history, future work. | | Documentation organization | `docs/policy/documentation.md` | Documentation ownership, audience boundaries, maintenance rules, and ADR/document lifecycle. | Application architecture or product behavior. | | Testing policy | `docs/policy/testing.md` | Test philosophy, risk-based sufficiency, test boundaries, doubles, coverage guidance, regression-test policy, and criteria for adding, rewriting, or deleting tests. | Subsystem behavior, application contracts, subsystem-specific test inventories, and implementation plans. | diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000..0b17f23 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,97 @@ +# Releasing Narratio + +This document is the maintainer procedure for creating a Narratio source and +binary release. The synchronous release boundary is a successful push of one +new tag to `origin`; Woodpecker and Gitea publication happen later and do not +change that result. + +## Choose a version and write its note + +Narratio is past `v1.0.0`. Use an unused stable tag in the exact form +`vMAJOR.MINOR.PATCH`: + +- increment `MINOR` for backward-compatible features; +- increment `PATCH` for backward-compatible fixes; and +- reserve a new `MAJOR` for an intentional breaking documented contract. + +Before preparing the candidate, create +`docs/releases/vMAJOR.MINOR.PATCH.md` with this structure: + +```markdown +# Narratio vMAJOR.MINOR.PATCH + +This release ... + +## Summary + +## Compatibility + +## Upgrade + +## Changes +``` + +The compatibility section identifies relevant CLI, configuration, artifact, +integration, or operating-contract changes. The upgrade section states the +required operator action, or explicitly says that no special action is +required. Release notes are immutable historical summaries; link to the +current canonical documentation for detailed behavior. + +Commit the note and all candidate changes, then use the ordinary development +workflow to push that commit to `main`. Do not create a release tag before the +candidate is committed and `origin/main` contains the exact same commit. + +## Validate the candidate + +Run the shared checker from any directory: + +```sh +scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH +``` + +It validates the version and matching note, module hygiene, formatting, +whitespace, uncached tests, race tests, static checks, documentation, examples, +and six official cross-build assets. It uses `GOWORK=off`, does not contact +application services, CI, or Gitea, and does not create tags or modify tracked +source. Fix any failure on `main`, commit it, push it normally, and rerun the +checker. + +The checker builds Linux, macOS, and Windows assets for `amd64` and `arm64`. +Cross-builds prove compilation; they are not native macOS or Windows runtime +evidence. + +## Publish the tag + +From a clean checkout on `main` whose `HEAD` equals `origin/main`, run: + +```sh +scripts/release.sh vMAJOR.MINOR.PATCH +``` + +The command fetches and checks `origin/main`, re-runs candidate validation, +then fetches and checks again before creating an explicitly unsigned lightweight +tag for the originally recorded commit. It refuses dirty, divergent, changed, +or already-tagged candidates. It pushes only: + +```text +refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH +``` + +It never commits changes, pushes `main`, force-pushes, moves a tag, or pushes +all tags. A successful push of that exact ref completes the release command; +the command prints the tag and commit, then returns without waiting for CI, +querying Gitea, downloading assets, or checking checksums. + +If a failure occurs before the tag is created, correct the candidate on `main` +and repeat validation. If the push fails after local tag creation, the local tag +is intentionally retained for inspection and the command must not be retried +blindly. Once the upstream tag has been pushed, it is immutable. Correct any +defect or failed asynchronous publication with a new patch version, a new +release note, and the complete procedure again. + +## Optional asynchronous inspection + +After a successful tag push, a human may later inspect the tag-triggered +Woodpecker run and the corresponding Gitea release for binaries and checksums. +This is optional follow-up only. Automated releasers must not wait for, poll, +or treat CI/Gitea completion as a condition of the successful tag push. diff --git a/docs/releases/README.md b/docs/releases/README.md index 48de314..c69ee14 100644 --- a/docs/releases/README.md +++ b/docs/releases/README.md @@ -1,7 +1,25 @@ # Release Notes -This directory contains the maintained release-note text for Narratio releases. -The corresponding Gitea release is the canonical source for downloadable -binaries and checksums. +This directory contains immutable historical release notes for Narratio. +Future notes are created with the matching stable version and use this minimum +structure: + +```markdown +# Narratio vMAJOR.MINOR.PATCH + +This release ... + +## Summary + +## Compatibility + +## Upgrade + +## Changes +``` + +See the [release procedure](../release.md) for creating a candidate and tag. +When asynchronous publication succeeds, the corresponding Gitea release is the +canonical source for downloadable binaries and checksums. - [v1.5.0](v1.5.0.md) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 63e0a0c..7a136e0 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -384,7 +384,7 @@ the synchronous tag command. ## Stage 5 — Canonical Release Documentation And Final Audit -**Status: Pending** +**Status: Completed** ### Goal diff --git a/docs/roadmap/release-procedure.md b/docs/roadmap/release-procedure.md index 4cfce5a..c2304e1 100644 --- a/docs/roadmap/release-procedure.md +++ b/docs/roadmap/release-procedure.md @@ -2,8 +2,8 @@ ## Status -Accepted target state. This document owns the intended release-process scope, -maintainer policy, and target end state until the work is implemented. +Implemented. This document records the accepted release-process scope, +maintainer policy, and delivered end state. ## Goal