Plan source-only releases
This commit is contained in:
@@ -153,7 +153,6 @@ section only after a concrete workflow, contract, and priority emerge.
|
||||
### Distribution And Operations
|
||||
|
||||
- Packaged release artifacts for alpha distribution.
|
||||
- A documented versioning and release process.
|
||||
- Optional generated example-output fixtures with a regeneration procedure.
|
||||
- Additional diagnostics or reporting views.
|
||||
|
||||
|
||||
428
docs/roadmap/implementation.md
Normal file
428
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,428 @@
|
||||
# Source-Only Release Implementation Plan
|
||||
|
||||
## Purpose
|
||||
|
||||
Implement the target state defined by
|
||||
[Source-Only Releases](source-releases.md): immutable source tags with checked-in
|
||||
release notes, a diagnostic version interface, strong shared candidate checks,
|
||||
validation-only tag CI, Linux support, best-effort macOS compilation, and no
|
||||
packaged binaries or Windows support.
|
||||
|
||||
This plan is ordered. Each numbered stage is one implementation prompt for a
|
||||
gpt-5.6-terra coding agent. Complete and validate one stage before beginning
|
||||
the next. Preserve all unrelated worktree changes, follow every policy under
|
||||
`docs/policy/`, and update current-behavior documentation in the same stage as
|
||||
the behavior it describes.
|
||||
|
||||
Do not create or push a release tag while implementing this plan. Do not invent
|
||||
a release note for `v0.1.0`, `v0.2.0`, or `v0.3.0`. The first real release
|
||||
under the completed procedure will add its own note in a separate release
|
||||
operation.
|
||||
|
||||
## Decisions Fixed For Implementation
|
||||
|
||||
- Releases are stable `vMAJOR.MINOR.PATCH` source tags on `main`; prereleases
|
||||
are unsupported initially.
|
||||
- Tags are lightweight and immutable after publication.
|
||||
- No release binaries, archives, checksums, signatures, containers,
|
||||
package-manager entries, or Gitea release objects are produced.
|
||||
- Linux is supported. Release checks compile Linux `amd64` and `arm64` with
|
||||
`CGO_ENABLED=0`.
|
||||
- macOS is best-effort. Release checks compile Darwin `amd64` and `arm64` with
|
||||
`CGO_ENABLED=0`, without promising runtime CI or packaged output.
|
||||
- Windows is unsupported and must not be added to build checks.
|
||||
- Release notes begin with the first release made under the new procedure;
|
||||
historical tags are left untouched.
|
||||
- `notarius --version` is informational. Receipt and artifact contracts remain
|
||||
authoritative for downstream compatibility.
|
||||
- One checked-in POSIX shell command owns substantive source-candidate checks.
|
||||
The release procedure and tag CI call it rather than maintaining duplicate
|
||||
test/build matrices.
|
||||
- Tag CI validates only. Pre-publication local guards remain mandatory because
|
||||
tag CI cannot prevent an already-pushed tag.
|
||||
|
||||
## Stage 1: Add Build Version Resolution And `--version`
|
||||
|
||||
### Goal
|
||||
|
||||
Add a small, testable build-information boundary and expose the public root
|
||||
version flag without affecting existing command behavior.
|
||||
|
||||
### Implementation
|
||||
|
||||
1. Create `internal/buildinfo` with an exported link-time string variable named
|
||||
`Override` and an exported resolver such as `Version() (string, error)`.
|
||||
Keep this package independent of CLI and application packages.
|
||||
2. Resolve the displayed value using this precedence:
|
||||
1. a nonempty `Override`;
|
||||
2. the main-module version returned by `runtime/debug.ReadBuildInfo`; then
|
||||
3. the literal `development`.
|
||||
3. Accept a release value only when it matches the complete stable SemVer tag
|
||||
form `^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`.
|
||||
Whitespace, prerelease/build suffixes, pseudo-versions, and arbitrary text
|
||||
are not release versions. A nonempty invalid linker override is an error;
|
||||
an empty, `(devel)`, pseudo-version, or otherwise non-release main-module
|
||||
version falls back to `development`.
|
||||
4. Add `--version` to the root dispatch in `internal/cli`. It is valid only as
|
||||
the sole argument, writes exactly `notarius <resolved-version>\n` to stdout,
|
||||
writes nothing to stderr, and exits zero. Additional arguments are a syntax
|
||||
error using the existing exit-2 and stderr conventions. An invalid linker
|
||||
override is a runtime/build error using exit 1 and stderr.
|
||||
5. Add the flag to root usage without changing the existing behavior of empty
|
||||
arguments, help spellings, or subcommands.
|
||||
6. Update `docs/cli.md` as the canonical public contract and
|
||||
`docs/internal/cli.md` as the implementation owner. State that tagged
|
||||
`go install` builds can obtain the main-module tag from Go build information,
|
||||
controlled builds may inject
|
||||
`gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override`, and an
|
||||
ordinary unversioned checkout reports `development`.
|
||||
|
||||
### Tests
|
||||
|
||||
- Add table-driven `internal/buildinfo` tests for valid stable versions,
|
||||
leading-zero rejection, whitespace, prerelease/build suffixes, pseudo-
|
||||
versions, override precedence, invalid nonempty override, and development
|
||||
fallback. Test the pure resolution decision rather than trying to mutate
|
||||
process build information.
|
||||
- Extend the CLI command-contract tests to cover exact stdout/stderr/exit
|
||||
behavior for `--version`, extra arguments, and unchanged help/unknown-command
|
||||
behavior.
|
||||
- Do not snapshot the whole usage document solely for the new line; assert the
|
||||
stable semantic fragments already owned by the CLI contract tests.
|
||||
|
||||
### Validation
|
||||
|
||||
```sh
|
||||
go test ./internal/buildinfo ./internal/cli
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./cmd/notarius
|
||||
go run ./cmd/notarius --version
|
||||
```
|
||||
|
||||
Build a temporary Linux host binary with:
|
||||
|
||||
```sh
|
||||
go build -trimpath \
|
||||
-ldflags '-X gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override=v0.0.0' \
|
||||
-o /path/to/temp/notarius ./cmd/notarius
|
||||
```
|
||||
|
||||
and verify that its output is exactly `notarius v0.0.0`.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- The public and internal documentation matches the implemented version
|
||||
behavior.
|
||||
- Ordinary builds print `notarius development`.
|
||||
- A valid linker override prints the exact stable tag.
|
||||
- Invalid linker content cannot masquerade as a release version.
|
||||
- Existing CLI commands, help, streams, and exit classes remain unchanged.
|
||||
|
||||
## Stage 2: Add One Reusable Source-Candidate Checker
|
||||
|
||||
### Goal
|
||||
|
||||
Create one repository-owned, offline validation command used identically by a
|
||||
maintainer and release CI.
|
||||
|
||||
### Implementation
|
||||
|
||||
1. Create executable POSIX shell script `scripts/check-release-source.sh`.
|
||||
Require exactly one positional argument containing a stable SemVer tag. The
|
||||
script must locate and enter the repository root from its own checked-in
|
||||
path so callers cannot accidentally validate another working directory.
|
||||
2. Use `set -eu`, quote all expansions, reject invalid versions before using
|
||||
them in paths or linker arguments, and use a freshly created temporary
|
||||
directory for cross-build output. Install a cleanup trap scoped only to that
|
||||
resolved temporary directory.
|
||||
3. Keep release-note, branch, remote, clean-worktree, and tag-existence guards
|
||||
out of this script. Those publication-specific checks belong in
|
||||
`docs/release.md` and tag CI. This script owns the substantive source checks
|
||||
that both workflows share.
|
||||
4. Implement these checks in a clear fail-fast order:
|
||||
- require the expected Notarius module path in `go.mod`;
|
||||
- reject tracked `go.work` or `go.work.sum`, an existing `vendor` directory,
|
||||
and any `replace` directive in `go.mod`;
|
||||
- `GOWORK=off go test -count=1 ./...`;
|
||||
- `GOWORK=off go test -race -count=1 ./...`;
|
||||
- `GOWORK=off go vet ./...`;
|
||||
- `GOWORK=off go build ./...`;
|
||||
- `GOWORK=off go mod tidy -diff`;
|
||||
- require no output from `gofmt -l` for tracked Go files;
|
||||
- `git diff --check` and `git diff --cached --check`;
|
||||
- validate `examples/dnd-minimal.config.yml` and
|
||||
`examples/dnd-complete.config.yml` for pipeline `dnd-session` using the
|
||||
built or `go run` Notarius command;
|
||||
- build `./cmd/notarius` with `CGO_ENABLED=0` for Linux `amd64` and `arm64`
|
||||
and Darwin `amd64` and `arm64`; and
|
||||
- inject the supplied tag through `internal/buildinfo.Override` in every
|
||||
cross-build.
|
||||
5. Execute the built command and verify exact `--version` output when the
|
||||
current host GOOS/GOARCH matches one of the four targets. Do not attempt to
|
||||
execute a foreign target.
|
||||
6. Do not compile for Windows, write output beneath the repository, contact an
|
||||
LLM provider, require credentials, or mutate tracked files.
|
||||
|
||||
### Tests And Validation
|
||||
|
||||
- Run the script with `v0.0.0` as a synthetic build version. It does not require
|
||||
or create a corresponding release note or Git tag.
|
||||
- Exercise its cheap argument guards separately with missing, extra, malformed,
|
||||
prerelease, and leading-zero versions. These failures must occur before Go
|
||||
tests or builds begin.
|
||||
- Confirm temporary outputs are removed on success and ordinary command
|
||||
failure. Do not add a large shell-test framework solely for this script;
|
||||
retain focused automated tests only if they protect a realistic failure that
|
||||
is not more clearly covered by executing the checker itself.
|
||||
|
||||
```sh
|
||||
./scripts/check-release-source.sh v0.0.0
|
||||
git status --short
|
||||
```
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- One command runs every substantive source-candidate check required by the
|
||||
feature roadmap.
|
||||
- The command is deterministic, offline, credential-free, POSIX-compatible,
|
||||
fail-fast, and safe with temporary paths.
|
||||
- The Linux and Darwin target matrix succeeds and Windows is absent.
|
||||
- Version injection and host-binary reporting are checked as part of the same
|
||||
matrix.
|
||||
- Successful execution leaves the worktree and index unchanged.
|
||||
|
||||
## Stage 3: Add Validation-Only Tag CI
|
||||
|
||||
### Goal
|
||||
|
||||
Independently validate every newly pushed release tag without publishing or
|
||||
mutating release state.
|
||||
|
||||
### Implementation
|
||||
|
||||
1. Add `.woodpecker/release.yml` triggered only by tag events.
|
||||
2. Use the Go 1.25.5 container image to match the version currently declared
|
||||
by `go.mod`. When the declared Go version changes in a future release, the
|
||||
release pipeline image and release documentation must be reviewed in the
|
||||
same change.
|
||||
3. In one validation step:
|
||||
- read the candidate version only from `CI_COMMIT_TAG`;
|
||||
- require the stable SemVer form fixed above;
|
||||
- require a nonempty `docs/releases/$CI_COMMIT_TAG.md`;
|
||||
- require the exact heading `# Notarius $CI_COMMIT_TAG`;
|
||||
- require exact `## Summary`, `## Compatibility`, `## Upgrade`, and
|
||||
`## Changes` headings; and
|
||||
- invoke `./scripts/check-release-source.sh "$CI_COMMIT_TAG"`.
|
||||
4. Do not include a release plugin, API token, artifact upload, Gitea release
|
||||
creation, archive/checksum step, Windows target, tag mutation, or retry that
|
||||
could overwrite published state.
|
||||
5. Keep the CI file thin: note/tag guards belong in it, while the substantive
|
||||
source checks remain in the shared script.
|
||||
|
||||
### Validation
|
||||
|
||||
- Review the YAML trigger and commands against the repository's Woodpecker
|
||||
syntax and the established Weatherreporter tag pipeline structure.
|
||||
- Confirm every invoked path exists and the script is executable.
|
||||
- Run the shared checker locally with `v0.0.0`.
|
||||
- Search the new pipeline for release-plugin configuration, upload commands,
|
||||
secrets, Windows targets, and mutation commands; none may be present.
|
||||
- Run `git diff --check`.
|
||||
|
||||
Do not push a synthetic tag merely to test this stage. The first real release
|
||||
will exercise the remote trigger; local source validation and review provide
|
||||
the pre-release confidence boundary.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- Every stable release tag triggers the validation pipeline.
|
||||
- Missing or malformed version-matched release notes fail before the expensive
|
||||
source checks.
|
||||
- CI calls the same substantive checker used locally.
|
||||
- The pipeline cannot publish binaries, releases, checksums, or other assets
|
||||
and requires no release secret.
|
||||
|
||||
## Stage 4: Establish The Canonical Release Procedure And Documentation Policy
|
||||
|
||||
### Goal
|
||||
|
||||
Make the complete source-release workflow executable by a maintainer without
|
||||
undocumented knowledge, and give release documentation an explicit canonical
|
||||
home.
|
||||
|
||||
### Implementation
|
||||
|
||||
1. Create `docs/release.md`, adapted to Notarius's source-only model. It must
|
||||
define:
|
||||
- stable SemVer selection and the pre-`v1` compatibility policy;
|
||||
- the exact `docs/releases/<tag>.md` template and validation guards;
|
||||
- invocation of `./scripts/check-release-source.sh "$RELEASE_VERSION"`;
|
||||
- manual review of changed Markdown links and unintended repository files;
|
||||
- committing and pushing the release note and current documentation before
|
||||
tagging;
|
||||
- recording `RELEASE_COMMIT` from `HEAD^{commit}`;
|
||||
- a copyable guard that requires `main`, a clean worktree/index, disabled Go
|
||||
workspace use, an exact match between `RELEASE_COMMIT` and
|
||||
`origin/main`, a matching note, and an unused local and remote tag;
|
||||
- explicit lightweight-tag creation against `RELEASE_COMMIT`;
|
||||
- pushing only
|
||||
`refs/tags/$RELEASE_VERSION:refs/tags/$RELEASE_VERSION`;
|
||||
- remote tag and tagged-note verification;
|
||||
- a fresh `go install ...@"$RELEASE_VERSION"` or fresh exact-tag checkout
|
||||
verification, including exact `--version` output; and
|
||||
- immutable-tag failure and correction policy.
|
||||
2. The procedure must say that the tag and checked-in note are the release and
|
||||
that tag CI is validation-only. It must explicitly exclude binaries,
|
||||
archives, checksums, signatures, containers, package-manager publication,
|
||||
Gitea release objects, Windows, and retrospective notes for existing tags.
|
||||
3. Document private-module installation through standard `GOPRIVATE` and Git
|
||||
authentication mechanisms without including credentials or private
|
||||
environment dumps. Do not make one maintainer's credential setup part of
|
||||
the release contract.
|
||||
4. Update `docs/policy/documentation.md`:
|
||||
- add canonical-owner rows for `docs/release.md` and `docs/releases/`;
|
||||
- state that release notes are historical summaries, not current-state
|
||||
contract owners;
|
||||
- state that the checked-in note at the immutable tag is the release record;
|
||||
and
|
||||
- require current canonical docs to change with behavior rather than using
|
||||
release notes as substitutes.
|
||||
5. Update `docs/development.md` with a release-preparation/tagging/verification
|
||||
routing row pointing to `docs/release.md` and the relevant policies.
|
||||
6. Do not create an empty placeholder release note or a retrospective note.
|
||||
`docs/releases/` first becomes tracked when the next actual release note is
|
||||
prepared.
|
||||
|
||||
### Validation
|
||||
|
||||
- Follow every local Markdown link added or changed in this stage.
|
||||
- Execute every non-destructive candidate-validation command that does not
|
||||
require an actual new release note, remote tag, or publication.
|
||||
- Compare the procedure line by line with the shared checker and CI so their
|
||||
tag syntax, note headings, target matrix, and validation ownership agree.
|
||||
- Confirm the procedure never uses `git push --tags`, moves a published tag,
|
||||
uploads an asset, or embeds credentials.
|
||||
- Run `git diff --check`.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- `docs/release.md` is sufficient to prepare, guard, tag, publish, verify, and
|
||||
recover from a source release.
|
||||
- Release procedure and release-note ownership are explicit and nonduplicative.
|
||||
- The procedure calls the shared checker rather than restating its full command
|
||||
matrix.
|
||||
- No historical or placeholder release note is introduced.
|
||||
|
||||
## Stage 5: Align Platform, Installation, And Operational Documentation
|
||||
|
||||
### Goal
|
||||
|
||||
Make the supported-platform and source-installation story discoverable in the
|
||||
canonical current-state documents without duplicating the release procedure.
|
||||
|
||||
### Implementation
|
||||
|
||||
1. Update `README.md` with a concise source-installation section. Show
|
||||
`go install gitea.maximumdirect.net/eric/notarius/cmd/notarius@<tag>` as a
|
||||
version-pinned pattern and retain the existing minimal product quickstart.
|
||||
Link release maintainers to `docs/release.md` rather than reproducing its
|
||||
guards.
|
||||
2. Update `docs/operations.md` with operator-facing source deployment facts:
|
||||
Linux support, the Go version declared by `go.mod`, version pinning, exact
|
||||
tag builds, and `notarius --version` as a diagnostic. Link command semantics
|
||||
to `docs/cli.md` and maintainer publication mechanics to `docs/release.md`.
|
||||
3. Update `docs/policy/architecture.md` with the durable platform and
|
||||
distribution invariants: supported Linux deployment, best-effort macOS
|
||||
development, unsupported Windows, and source-only distribution. Keep tag
|
||||
commands and release mechanics out of architecture.
|
||||
4. Review `docs/internal/overview.md` navigation after adding
|
||||
`internal/buildinfo`. Add only the smallest component entry needed if the
|
||||
current inventory would otherwise omit a meaningful implemented boundary;
|
||||
do not inflate build information into a subsystem.
|
||||
5. Confirm `docs/roadmap/future.md` no longer lists the active documented
|
||||
release-process work. Retain packaged alpha artifacts as deferred work; the
|
||||
source-only release feature does not permanently reject reconsideration.
|
||||
6. Review the completed feature roadmap against the implementation and correct
|
||||
only genuine target-state inconsistencies. Do not convert it into a
|
||||
changelog or duplicate `docs/release.md`.
|
||||
|
||||
### Validation
|
||||
|
||||
- Verify all added and changed local Markdown links.
|
||||
- Confirm commands agree with the implemented CLI and declared module path.
|
||||
- Confirm no current-state document claims that Notarius publishes binary
|
||||
assets or supports Windows.
|
||||
- Run:
|
||||
|
||||
```sh
|
||||
go run ./cmd/notarius --version
|
||||
go run ./cmd/notarius help
|
||||
git diff --check
|
||||
```
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- Users can discover how to install a pinned source release.
|
||||
- Operators can identify the deployed version and understand the support
|
||||
boundary.
|
||||
- Architecture records durable platform/distribution policy without owning
|
||||
maintainer release commands.
|
||||
- Packaged artifacts remain clearly deferred rather than accidentally promised
|
||||
or permanently prohibited.
|
||||
|
||||
## Stage 6: Final Release-System Verification
|
||||
|
||||
### Goal
|
||||
|
||||
Review the implemented feature as one system and prove that code,
|
||||
documentation, shared validation, and CI converge on the same release model.
|
||||
|
||||
### Verification Work
|
||||
|
||||
1. Inspect all commits associated with Stages 1–5 and compare the result with
|
||||
`docs/roadmap/source-releases.md` and this plan.
|
||||
2. Run the shared candidate checker with synthetic version `v0.0.0`. This is a
|
||||
build identity only; do not create a note or tag for it.
|
||||
3. Independently run the repository-wide baseline checks if any are not already
|
||||
performed by the shared checker:
|
||||
|
||||
```sh
|
||||
go test ./...
|
||||
go vet ./...
|
||||
go build ./cmd/notarius
|
||||
```
|
||||
|
||||
4. Verify exact development and injected release output:
|
||||
- ordinary checkout: `notarius development`;
|
||||
- injected `v0.0.0`: `notarius v0.0.0`;
|
||||
- invalid linker override: nonzero exit, no false release identity.
|
||||
5. Confirm both maintained D&D configurations validate offline.
|
||||
6. Verify all added or changed local Markdown links and run
|
||||
`git diff --check`.
|
||||
7. Audit `.woodpecker/release.yml` and `docs/release.md` for agreement on tag
|
||||
form, note location/headings, Go image/version expectations, and shared
|
||||
checker use.
|
||||
8. Confirm the repository contains no generated release binary, distribution
|
||||
directory, checksum file, release credential, Windows target, release
|
||||
plugin, synthetic release note, or new tag.
|
||||
9. Review tests under the repository testing policy. Retain behavior-level
|
||||
coverage for the public version contract and important validation guards;
|
||||
remove redundant tests that merely duplicate the shared checker or CI text.
|
||||
10. Report any remaining divergence as a concrete finding. Fix only in-scope
|
||||
release-feature defects discovered during this verification; do not expand
|
||||
into packaged distribution or unrelated cleanup.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
- All feature-roadmap acceptance criteria are met except creation of the first
|
||||
real post-procedure release, which is intentionally a separate operator
|
||||
action.
|
||||
- Local validation and tag CI share one substantive source checker.
|
||||
- Version reporting, source installation, platform policy, documentation
|
||||
ownership, tag guards, and immutable failure handling are internally
|
||||
consistent.
|
||||
- The full test suite, vet, build, configuration validation, four-target cross-
|
||||
build matrix, Markdown link review, and whitespace checks pass.
|
||||
- The worktree contains no release side effects beyond the intended source,
|
||||
automation, and documentation changes.
|
||||
281
docs/roadmap/source-releases.md
Normal file
281
docs/roadmap/source-releases.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# Source-Only Releases
|
||||
|
||||
## Status
|
||||
|
||||
Proposed.
|
||||
|
||||
## Purpose
|
||||
|
||||
Define a repeatable, guarded release process for Notarius without taking on a
|
||||
binary-distribution system that its current operator audience does not need.
|
||||
The process should make an exact source revision, its compatibility impact,
|
||||
and its validation status easy to identify while keeping installation in the
|
||||
hands of technically capable operators and deployment automation.
|
||||
|
||||
The model is adapted from Weatherreporter's release procedure, but its target
|
||||
is deliberately narrower: an immutable source tag and checked-in release note
|
||||
are the release. Notarius does not publish executable archives or support
|
||||
Windows as part of this work.
|
||||
|
||||
## Release Model
|
||||
|
||||
Notarius releases come from commits on `main` and use stable semantic-version
|
||||
tags in the form `vMAJOR.MINOR.PATCH`. Prerelease tags are not part of the
|
||||
initial process.
|
||||
|
||||
Every release has one nonempty, version-matched note at
|
||||
`docs/releases/<tag>.md`. The note and every affected current-state document
|
||||
must be present in the tagged commit. The Git tag and checked-in note together
|
||||
are the durable release record; no separately editable release page is
|
||||
required.
|
||||
|
||||
Published tags are immutable. A maintainer must never move, reuse, or delete a
|
||||
published tag. If a published candidate is defective, the correction is made
|
||||
on `main` and released under a new patch version. An unpublished local tag may
|
||||
be deleted when candidate inspection finds a problem before any remote push.
|
||||
|
||||
Before `v1.0.0`, a minor release may intentionally change a documented CLI,
|
||||
configuration, durable artifact, integration, or operating contract when its
|
||||
release note explains the impact and required operator action. A patch release
|
||||
must not intentionally break those documented contracts within its minor
|
||||
line.
|
||||
|
||||
The existing `v0.1.0`, `v0.2.0`, and `v0.3.0` tags remain unchanged. They
|
||||
predate this procedure and do not need retrospective release notes. The first
|
||||
release made under this process establishes the release-note series.
|
||||
|
||||
## Source-Only Distribution
|
||||
|
||||
Notarius does not publish release binaries, archives, installers, container
|
||||
images, package-manager entries, checksum files, or signatures. A release tag
|
||||
is suitable for Go-native installation and for an operator-controlled build
|
||||
from an exact checkout.
|
||||
|
||||
The primary installation form is:
|
||||
|
||||
```sh
|
||||
GOWORK=off go install \
|
||||
gitea.maximumdirect.net/eric/notarius/cmd/notarius@vMAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
Operator documentation should also describe cloning the repository, checking
|
||||
out the tag in detached-head state, and building `./cmd/notarius` with the Go
|
||||
version declared by `go.mod`. Private-module authentication and `GOPRIVATE`
|
||||
configuration belong to the operator environment and must be documented by
|
||||
mechanism rather than with real credentials.
|
||||
|
||||
Consumers such as Narratio should pin the desired Notarius tag in provisioning
|
||||
or deployment configuration. They must continue to decide runtime
|
||||
compatibility from Notarius's published receipt and artifact schema contracts,
|
||||
not merely from the executable's product version.
|
||||
|
||||
Packaged binaries may be reconsidered if distribution demand, installation
|
||||
friction, or a broader user audience justifies their build, signing, retention,
|
||||
and platform-support costs. They are not a prerequisite for a disciplined
|
||||
release process.
|
||||
|
||||
## Platform Policy
|
||||
|
||||
Linux is the supported deployment platform. Release validation must run the
|
||||
test suite and the release build on Linux and must confirm that the command
|
||||
builds with `CGO_ENABLED=0` for Linux `amd64` and `arm64`.
|
||||
|
||||
macOS is a best-effort development and testing platform. Release validation
|
||||
should confirm that the command cross-compiles with `CGO_ENABLED=0` for Darwin
|
||||
`amd64` and `arm64`, but the project does not promise packaged artifacts or a
|
||||
separate runtime test environment for those targets.
|
||||
|
||||
Windows is unsupported. The release process must not require Windows builds,
|
||||
Windows-specific compatibility work, or Windows documentation. Platform-
|
||||
specific implementation may intentionally use Unix facilities when they are
|
||||
important to Notarius's filesystem safety and operational model. Any later
|
||||
decision to support Windows requires its own feature scope and validation
|
||||
policy.
|
||||
|
||||
## Version Reporting
|
||||
|
||||
Add a root `notarius --version` interface for deployment diagnostics. It
|
||||
prints exactly one line:
|
||||
|
||||
```text
|
||||
notarius vMAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
when the build has a valid release version, and:
|
||||
|
||||
```text
|
||||
notarius development
|
||||
```
|
||||
|
||||
when no release version is available.
|
||||
|
||||
The implementation must obtain the main-module version from Go build
|
||||
information so `go install ...@vMAJOR.MINOR.PATCH` reports the selected tag. It
|
||||
must also accept an optional link-time version override so controlled builds
|
||||
and release CI can identify an exact tag from a checkout. The override must be
|
||||
validated and must not silently turn arbitrary text into a release version.
|
||||
Ordinary unversioned checkout builds remain `development`; the release process
|
||||
must not modify a tracked source constant for each release.
|
||||
|
||||
Version reporting is an informational product interface. It does not replace
|
||||
receipt, configuration, prompt, or artifact schema versioning, and it must not
|
||||
be used as the sole downstream compatibility check.
|
||||
|
||||
## Release Notes
|
||||
|
||||
Each new `docs/releases/<tag>.md` document has this minimum structure:
|
||||
|
||||
```markdown
|
||||
# Notarius vMAJOR.MINOR.PATCH
|
||||
|
||||
This release ...
|
||||
|
||||
## Summary
|
||||
|
||||
## Compatibility
|
||||
|
||||
## Upgrade
|
||||
|
||||
## Changes
|
||||
```
|
||||
|
||||
The note should concisely explain the release's purpose, compatibility with the
|
||||
preceding release, operator actions, and material user-visible, operational,
|
||||
integration, and maintainer-visible changes. It should link to canonical
|
||||
current-state documentation for exact contracts rather than duplicating those
|
||||
contracts.
|
||||
|
||||
Release notes are durable historical summaries. They must not contain
|
||||
credentials, private infrastructure detail, sensitive campaign material, or
|
||||
claims that are not true of the tagged candidate. A release note does not
|
||||
excuse stale current-state documentation; affected canonical documents are
|
||||
updated in the same candidate.
|
||||
|
||||
## Candidate Validation
|
||||
|
||||
The release procedure must provide copyable POSIX-shell guards that validate
|
||||
the release version, release-note filename and heading, required note sections,
|
||||
repository state, and module hygiene. Validation must be run from the Notarius
|
||||
repository root with Go workspace behavior disabled.
|
||||
|
||||
At minimum, a candidate must pass:
|
||||
|
||||
- no tracked `go.work` or `go.work.sum`, no vendored tree, and no `replace`
|
||||
directive in `go.mod`;
|
||||
- `GOWORK=off go test -count=1 ./...`;
|
||||
- `GOWORK=off go test -race -count=1 ./...`;
|
||||
- `GOWORK=off go vet ./...`;
|
||||
- `GOWORK=off go build ./...`;
|
||||
- `GOWORK=off go mod tidy -diff`;
|
||||
- `gofmt` verification for every tracked Go file;
|
||||
- `git diff --check` and `git diff --cached --check`;
|
||||
- validation of both maintained D&D configuration examples with their selected
|
||||
pipeline;
|
||||
- Linux `amd64` and `arm64` static command builds;
|
||||
- best-effort Darwin `amd64` and `arm64` static command builds; and
|
||||
- a focused manual or automated check that every added or changed local
|
||||
Markdown link resolves.
|
||||
|
||||
The candidate review also checks for generated binaries, test output,
|
||||
credentials, temporary files, module replacements, vendored dependencies, and
|
||||
other unintended source-control content. Tests remain offline and do not call
|
||||
an LLM provider or require live credentials.
|
||||
|
||||
## Candidate Publication
|
||||
|
||||
The release procedure must guard the exact commit immediately before tagging.
|
||||
It requires:
|
||||
|
||||
- the current branch is `main`;
|
||||
- the worktree and index are clean;
|
||||
- the candidate commit has been pushed and exactly matches `origin/main`;
|
||||
- the matching release note exists in that commit;
|
||||
- no local or remote tag already uses the selected version; and
|
||||
- the substantive release checks have passed for that exact candidate.
|
||||
|
||||
The maintainer records the exact candidate commit, creates a lightweight tag
|
||||
bound explicitly to that commit, verifies the local tag target, and pushes only
|
||||
that tag ref. The procedure must not recommend `git push --tags`.
|
||||
|
||||
After publication, the maintainer verifies that the remote tag resolves to the
|
||||
guarded commit and that the release note can be read from the tagged tree. A
|
||||
fresh temporary checkout or `go install ...@<tag>` must build successfully, and
|
||||
the resulting command must report the expected version through `--version`.
|
||||
|
||||
## Validation-Only Release Automation
|
||||
|
||||
Add a tag-triggered Woodpecker pipeline that validates source releases without
|
||||
publishing artifacts. It should:
|
||||
|
||||
- accept only stable semantic-version tags;
|
||||
- require the version-matched release note;
|
||||
- run the same substantive module, test, race, vet, build, formatting, and
|
||||
whitespace checks as the documented local procedure;
|
||||
- validate the maintained configuration examples;
|
||||
- perform the supported and best-effort cross-build checks; and
|
||||
- verify a release-version build's `notarius --version` output on the CI host.
|
||||
|
||||
The pipeline must not upload binaries, create archives or checksums, create or
|
||||
edit a Gitea release object, or require a release API token. Local guards remain
|
||||
authoritative before tag publication because CI begins only after the tag is
|
||||
already remote.
|
||||
|
||||
If tag validation fails, preserve the published tag, fix the cause on `main`,
|
||||
select a new patch version, and repeat the full process. Do not weaken tag
|
||||
immutability merely because the release contains source rather than binaries.
|
||||
|
||||
## Documentation Ownership
|
||||
|
||||
In the target state:
|
||||
|
||||
- `docs/release.md` owns the maintainer release procedure, commands, ordering,
|
||||
publication checks, and failure recovery;
|
||||
- `docs/releases/` owns one historical summary per release made under the new
|
||||
process;
|
||||
- `docs/cli.md` owns the `--version` contract;
|
||||
- `README.md` owns the shortest source-installation example and links to the
|
||||
release procedure where useful;
|
||||
- `docs/development.md` routes release preparation, tagging, and verification
|
||||
work to `docs/release.md`;
|
||||
- `docs/policy/documentation.md` assigns canonical ownership to the release
|
||||
procedure and release notes;
|
||||
- `docs/policy/architecture.md` records Linux support, best-effort macOS
|
||||
development, unsupported Windows, and source-only distribution only if those
|
||||
are judged durable development invariants rather than release mechanics; and
|
||||
- `docs/operations.md` describes only installation or deployment consequences
|
||||
relevant to operators and links to canonical CLI and release contracts.
|
||||
|
||||
Current-state documentation must not describe the new release process,
|
||||
`--version`, or automated validation until the corresponding behavior exists.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- A maintainer can prepare, validate, tag, publish, and verify a source release
|
||||
by following `docs/release.md` without relying on undocumented knowledge.
|
||||
- Every new release has an immutable semantic-version tag and matching
|
||||
checked-in release note in the tagged commit.
|
||||
- The guarded candidate is clean, synchronized with `origin/main`, and passes
|
||||
the documented substantive checks before tagging.
|
||||
- Tag-triggered CI independently validates the published source and never
|
||||
publishes binary artifacts.
|
||||
- `go install` of a tagged version succeeds and `notarius --version` reports
|
||||
that version; ordinary unversioned builds report `development`.
|
||||
- Linux is the documented supported deployment platform, macOS has a
|
||||
best-effort development build check, and Windows is explicitly unsupported.
|
||||
- Downstream compatibility remains based on durable Notarius contracts rather
|
||||
than the product version alone.
|
||||
- Existing pre-procedure tags remain untouched and require no invented release
|
||||
history.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Publishing executable archives, installers, container images, checksums,
|
||||
signatures, or package-manager entries.
|
||||
- Supporting or cross-compiling for Windows.
|
||||
- Creating or maintaining a mutable Gitea release page.
|
||||
- Supporting prerelease tag syntax in the initial procedure.
|
||||
- Automating version selection, release-note authorship, commits, or tag
|
||||
creation.
|
||||
- Retrospectively creating release notes for `v0.1.0` through `v0.3.0`.
|
||||
- Treating a product version as a substitute for receipt, configuration,
|
||||
prompt, or artifact schema compatibility.
|
||||
Reference in New Issue
Block a user