199 lines
11 KiB
Markdown
199 lines
11 KiB
Markdown
# Release tooling simplification
|
|
|
|
Status: target design finalized for the release-tooling sprint; implementation
|
|
has not started. All four generic file checks, registered-tool execution,
|
|
page-only hosted delivery, and protection of the supplied token path are selected.
|
|
The [implementation plan](implementation.md) owns stage order, tasks, validation,
|
|
and completion evidence. Current release behavior stays with its canonical owners
|
|
until implementation updates them.
|
|
|
|
## Purpose and authority
|
|
|
|
Reduce CommandKit's release infrastructure to declarative module profiles,
|
|
a small launcher, and focused tests of CommandKit-owned wiring. Delegate
|
|
reusable candidate validation and publication mechanics to ReleaseKit while
|
|
retaining CommandKit's domain-specific checks in their existing owners. Add
|
|
hosted Gitea release pages as a separate local delivery operation after source
|
|
publication.
|
|
|
|
The [agent policy](../policy/agents.md),
|
|
[release policy](../policy/release.md#candidate-validation), and
|
|
[testing policy](../policy/testing.md#upstream-integration-testing-ownership)
|
|
govern implementation. The [release procedure](../release.md) continues to own
|
|
the current workflow until implementation updates it.
|
|
|
|
## Targeted end state
|
|
|
|
### Ownership
|
|
|
|
CommandKit retains module selectors, product identities, profile locations,
|
|
the authoritative endpoint selection, release order, release-note meaning,
|
|
compatibility decisions, and attribution accuracy. Its existing public API,
|
|
CLI, integration-adaptation, and consumer-example tests remain local and run
|
|
through the owning module's suite. No parallel release-only domain suite is
|
|
needed unless a concrete CommandKit requirement is otherwise unprotected.
|
|
|
|
ReleaseKit supplies the standard offline candidate suite, selected generic file
|
|
checks, candidate/note and publication guards, tag creation and publication,
|
|
hosted delivery, outcome reporting, and recovery. CommandKit's launcher delegates
|
|
those operations. Existing source-release completion and immutability rules
|
|
continue to apply. Hosted pages are the added delivery channel; binary
|
|
deliverables and platform support commitments remain unchanged.
|
|
|
|
### Profiles
|
|
|
|
Select these existing ReleaseKit options in each profile:
|
|
|
|
| Selection | Intended protection |
|
|
| --- | --- |
|
|
| `validation.go_format: true` | Detect unformatted committed Go source. |
|
|
| `validation.markdown: {}` | Detect broken local Markdown destinations and supported heading fragments. |
|
|
| `validation.module_distribution.workspace_files: true` | Detect committed development workspace files in selected inputs. |
|
|
| `validation.module_distribution.local_replacements: true` | Detect filesystem replacements in selected committed module declarations. |
|
|
|
|
Also select
|
|
`validation.forbidden_files: [".releasekit/gitea-token"]` in all three profiles.
|
|
This delegates protection of the supplied credential path to ReleaseKit's
|
|
existing check. The path is repository-relative and the check applies across
|
|
the captured repository even for an integration release. It does not read token
|
|
contents, scan other paths, or inspect Git history.
|
|
|
|
Retain the explicit shared-file lists and use ReleaseKit's existing input scope.
|
|
The root profile does not run every nested module's suite. File checks inspect
|
|
committed inputs and do not replace formatting worktree changes or reviewing
|
|
documentation meaning, attribution, and external links. Markdown keeps its
|
|
default treatment of outside-checkout destinations; no stricter boundary mode
|
|
is proposed.
|
|
|
|
The pinned [ReleaseKit configuration reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/config.md)
|
|
owns exact scope and behavior, including nested-module boundaries and vendored
|
|
inputs. Do not expand an option's scope into a general repository prohibition.
|
|
Race testing, full vet, compilation matrices, size limits, and additional
|
|
forbidden-file paths are not selected by this roadmap. They can be considered
|
|
separately for demonstrated needs.
|
|
|
|
### Launcher and recovery
|
|
|
|
Use the root module's registered `go tool releasekit` through `exec`, keeping
|
|
the current selector interface and publication argument mapping.
|
|
Retain host normalization, workspace-off execution, the local toolchain, and
|
|
read-only module metadata. Preserve other effective Go settings while arranging
|
|
read-only selection.
|
|
The implementation plan specifies the wrapper interface and invocation details.
|
|
|
|
Go's cache supplies executable storage; the launcher creates no persistent
|
|
binary directory. `/.releasekit/` remains ignored for the credential file, with
|
|
an explanatory comment. Recovery instructions use the registered tool or the
|
|
entry point printed for the saved attempt, preserving ReleaseKit's distinction
|
|
between publication outcome and record-storage errors.
|
|
|
|
Share module selection and host-safe tool invocation between publication,
|
|
delivery, and recovery where applicable. Delivery selects the same module
|
|
profile as publication; recovery uses its recorded attempt rather than inferring
|
|
identity from a current profile. Keep the existing publication interface and
|
|
provide an explicit delivery invocation without automatically chaining the two
|
|
operations. Keep one selector mapping and shared invocation plumbing.
|
|
|
|
A pending upstream request concerns host-safe consumer launcher examples and
|
|
regression coverage. It is not a dependency of this work: v0.8.0 already supports
|
|
registered tools. Keep host normalization locally because the reviewed
|
|
`go tool` invocation inherited foreign `GOOS`/`GOARCH` values and failed to run.
|
|
Do not switch tool-version selection from the root module to each integration
|
|
merely to match the upstream multi-module example.
|
|
|
|
### Hosted Gitea release pages
|
|
|
|
Configure this delivery selection in each module profile:
|
|
|
|
| Field | Selected value |
|
|
| --- | --- |
|
|
| `delivery.forge` | `gitea` |
|
|
| `delivery.base_url` | `https://forge.maximumdirect.net` |
|
|
| `delivery.owner` | `base-layer` |
|
|
| `delivery.repository` | `commandkit` |
|
|
| `delivery.token_file` | `.releasekit/gitea-token` |
|
|
|
|
Preserve the profiles' distinct product identities and physical module
|
|
directories. All pages belong to the same Gitea repository and are keyed by
|
|
the complete tag: `vX.Y.Z` for core, `integrations/ckconfig/vX.Y.Z` for ckconfig,
|
|
and `integrations/ckprompt/vX.Y.Z` for ckprompt. Pass the selected profile and
|
|
semantic version to `deliver`; ReleaseKit derives the complete module tag.
|
|
|
|
With no build targets, delivery is page-only. ReleaseKit uses the complete
|
|
checked-in module release note, including its licensing footer, as the hosted
|
|
body. No binary assets, receipts, or checksum manifests are added. Use current
|
|
forge URLs and the full module tag for future notes' immutable source and
|
|
licensing links. Existing published tags and notes remain unchanged.
|
|
|
|
After source publication succeeds, explicitly invoke delivery from a clean
|
|
checkout whose `HEAD` identifies that published tag's commit. For later retries,
|
|
use the original tagged source and its recorded module files. Report the source
|
|
publication outcome and hosted-delivery outcome separately, including the hosted
|
|
URL on success. A delivery failure leaves the source release complete; repair
|
|
delivery without republishing or moving its tag.
|
|
|
|
Delivery performs its own read-only credential preflight, without rerunning
|
|
candidate validation or publishing a tag. Hosted-service availability and the
|
|
Gitea token do not become source-publication gates. A nonblank
|
|
`RELEASEKIT_GITEA_TOKEN` environment value takes precedence over the configured
|
|
file. The file path resolves from the repository root for all three modules.
|
|
|
|
ReleaseKit accepts matching hosted content and reports conflicting content
|
|
without overwriting it. Resolve uncertain hosted writes before retrying the
|
|
same immutable version. The pinned
|
|
[delivery guide](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/consumers/delivery.md)
|
|
owns exact delivery behavior and recovery. Start with tags containing the new
|
|
delivery configuration; historical page backfilling remains a separate decision.
|
|
This local workflow needs no CI delivery job or additional secret distribution.
|
|
|
|
### Focused local tests
|
|
|
|
Replace the release-test scaffolding with a small controlled Go-command boundary
|
|
that invokes the actual launcher. Cover:
|
|
|
|
- Selector-to-profile/module routing for core, ckconfig, and ckprompt, including
|
|
consistency with the checked-in profiles' intended module and product.
|
|
- Invalid argument handling before tool invocation.
|
|
- Invocation from another directory and paths containing spaces.
|
|
- Host normalization and workspace/toolchain/read-only settings.
|
|
- Publication and delivery argument, output-stream, and child exit-status
|
|
forwarding, with the selected module profile reaching the delivery operation.
|
|
- Profile wiring for the shared Gitea destination, token path, and its selected
|
|
committed-path protection; assertions do not read the credential file.
|
|
|
|
Exercise module routing separately from exit statuses rather than multiplying
|
|
every combination. Assert behavior and meaningful selections, not helper
|
|
implementation details or exact usage prose.
|
|
|
|
The resulting local suite omits the disposable publication exercise, generic
|
|
tag inspection, assertion-helper self-tests, and custom build-call log/parser.
|
|
Upstream publication and delivery coverage owns those generic behaviors. No
|
|
replacement publication engine or exported test-helper API is needed. There is
|
|
no line-count target for the replacement tests.
|
|
|
|
## Selected choices and rationale
|
|
|
|
All four generic file checks are selected as release-time checks, in addition
|
|
to the agreed forbidden token path. Formatting and local-link validation automate
|
|
existing contributor review work. Workspace-file and filesystem-replacement
|
|
checks address accidental inclusion of development metadata that a successful
|
|
local test run can overlook. This adds specific release checks; it does not
|
|
make every optional ReleaseKit validator mandatory or prohibit development
|
|
workspaces and replacements outside the selected committed candidate inputs.
|
|
Selecting only formatting and Markdown would change less release behavior, but
|
|
would leave these distribution mistakes to manual review. The selected upstream
|
|
checks avoid a second local implementation.
|
|
|
|
Host-normalized registered-tool execution is selected because the root module
|
|
already registers ReleaseKit and Go caches the executable. Retaining a persistent
|
|
native executable would provide a recovery entry point independent of a later
|
|
Go-driver invocation, but would retain executable-storage and bootstrap test
|
|
maintenance. Recovery instead uses the registered tool or ReleaseKit's reported
|
|
entry point. The credential directory remains ignored under either approach.
|
|
|
|
The implementation plan records the existing integration dependency-version
|
|
mismatch separately from validation of the current source. This infrastructure
|
|
sprint does not publish releases or select new library dependency versions.
|
|
Historical hosted-page backfilling and CI delivery remain separate future
|
|
choices, not prerequisites for the selected local page-only workflow.
|