282 lines
12 KiB
Markdown
282 lines
12 KiB
Markdown
# 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.
|