Finalize release tooling implementation plan
This commit is contained in:
328
docs/roadmap/implementation.md
Normal file
328
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
# Release tooling implementation plan
|
||||||
|
|
||||||
|
Status: ready for the implementation sprint; Stages 1–6 are pending.
|
||||||
|
|
||||||
|
Follow the stages in integer order. This is one end-to-end sprint: intermediate
|
||||||
|
stages may temporarily leave scripts, tests, and documentation inconsistent.
|
||||||
|
Do not add compatibility scaffolding or repeat complete suites merely to make
|
||||||
|
each intermediate stage independently releasable. Follow the local commit
|
||||||
|
policy for completed, validated units; stage boundaries do not require commits.
|
||||||
|
|
||||||
|
The [feature roadmap](release-simplification.md) owns the target and selected
|
||||||
|
choices. Read [development guidance](../development.md), the
|
||||||
|
[agent policy](../policy/agents.md), [testing policy](../policy/testing.md),
|
||||||
|
[documentation policy](../policy/documentation.md), and the applicable
|
||||||
|
[release policy](../policy/release.md) before implementation. Use codebase-memory
|
||||||
|
tools for code discovery as instructed by `AGENTS.md`.
|
||||||
|
|
||||||
|
## Baseline and fixed decisions
|
||||||
|
|
||||||
|
Planning baseline: `3d396b1a66bfafc509472cd74a3f8029def3d432`. At that revision:
|
||||||
|
|
||||||
|
- `go.mod` registers ReleaseKit v0.8.0. The root module owns the selected tool
|
||||||
|
version even when releasing an integration. Keep that dependency selection,
|
||||||
|
all library module paths and versions, and Go minimums unchanged.
|
||||||
|
- Three JSON profiles select core, ckconfig, and ckprompt. Their only file
|
||||||
|
selection is the explicit root shared-file list; hosted delivery is absent.
|
||||||
|
- `scripts/release` is a 49-line native-build launcher. The 506-line
|
||||||
|
`scripts/release_test.go` and 399-line `scripts/release_integration_test.go`
|
||||||
|
contain the test scaffolding being replaced.
|
||||||
|
- `.releasekit/gitea-token` is a maintainer-supplied ignored credential file.
|
||||||
|
Its contents are not input to implementation or tests. Preserve the file and
|
||||||
|
directory ignore rule. Do not add the credential to fixtures, logs, or commits.
|
||||||
|
- Both integrations declare core v0.2.0, while their current source requires
|
||||||
|
newer APIs. Workspace-off Go 1.26.8 tests fail at baseline with missing
|
||||||
|
`commandkit.CompletionHint`, `Explanation`, and other symbols. This is an
|
||||||
|
existing release-readiness issue, not a reason to change dependency versions
|
||||||
|
or weaken validation in this sprint. Stage 5 distinguishes this limitation
|
||||||
|
from verification of the current source and selected file checks.
|
||||||
|
|
||||||
|
The former open decisions are resolved for this plan: select all four proposed
|
||||||
|
generic file checks and use host-normalized registered-tool execution. Add the
|
||||||
|
agreed forbidden token path and local page-only Gitea delivery. Keep ordinary
|
||||||
|
source publication and hosted delivery separate. No binary delivery, CI job,
|
||||||
|
library API change, dependency upgrade, or production publication is part of
|
||||||
|
this sprint. No implementation-blocking design question remains.
|
||||||
|
|
||||||
|
## Stage 1: Configure the three release profiles
|
||||||
|
|
||||||
|
Edit `releasekit.json`, `integrations/ckconfig/releasekit.json`, and
|
||||||
|
`integrations/ckprompt/releasekit.json`.
|
||||||
|
|
||||||
|
1. Preserve each profile's `product`, `module_dir`, `remote`,
|
||||||
|
`expected_push_url`, and explicit `validation.shared_files`. The endpoint
|
||||||
|
remains `ssh://git@forge.maximumdirect.net:22222/base-layer/commandkit.git`.
|
||||||
|
2. Add `validation.go_format: true`, `validation.markdown: {}`, and
|
||||||
|
`validation.module_distribution` with `workspace_files` and
|
||||||
|
`local_replacements` both true.
|
||||||
|
3. Add `validation.forbidden_files` containing only
|
||||||
|
`.releasekit/gitea-token`. This is a literal repository-relative selection
|
||||||
|
applying to the captured repository, including integration releases.
|
||||||
|
4. Add `delivery` with `forge: "gitea"`,
|
||||||
|
`base_url: "https://forge.maximumdirect.net"`, `owner: "base-layer"`,
|
||||||
|
`repository: "commandkit"`, and `token_file: ".releasekit/gitea-token"`.
|
||||||
|
Leave `token_env` omitted, preserving ReleaseKit's default environment
|
||||||
|
override. Add no build targets or additional validators.
|
||||||
|
5. Retain `/.releasekit/` in `.gitignore`; revise its comment from executable
|
||||||
|
storage to local ReleaseKit credentials. Do not remove existing local files.
|
||||||
|
|
||||||
|
Check that all three files parse as JSON. Use the pinned
|
||||||
|
[configuration reference](https://forge.maximumdirect.net/base-layer/releasekit/src/commit/23203f235cc414c4ffe0fd3941030eb0c9f9943f/docs/config.md)
|
||||||
|
for field semantics. Root file checks stop at independent module boundaries;
|
||||||
|
the forbidden-path check has its separately documented repository scope.
|
||||||
|
Do not create custom validators, broader forbidden lists, or blanket exclusions.
|
||||||
|
|
||||||
|
**Stage result:** the intended checks and delivery destination are represented
|
||||||
|
entirely by the existing upstream profile schema.
|
||||||
|
|
||||||
|
## Stage 2: Centralize tool invocation and module routing
|
||||||
|
|
||||||
|
Create executable POSIX-shell `scripts/releasekit` as the shared entry point.
|
||||||
|
Keep executable `scripts/release` as the existing publication convenience entry
|
||||||
|
point. No shell library, module-map file, generated script, or JSON parser is
|
||||||
|
needed in the launcher.
|
||||||
|
|
||||||
|
The shared entry point has these forms:
|
||||||
|
|
||||||
|
| Invocation | Handling |
|
||||||
|
| --- | --- |
|
||||||
|
| `./scripts/releasekit MODULE publish [ARGS...]` | Select module defaults and invoke upstream `publish`. |
|
||||||
|
| `./scripts/releasekit MODULE check [ARGS...]` | Select module defaults and invoke upstream `check`. |
|
||||||
|
| `./scripts/releasekit MODULE deliver [ARGS...]` | Select module defaults and invoke upstream `deliver`. |
|
||||||
|
| `./scripts/releasekit version [ARGS...]` | Forward without module/profile inference. |
|
||||||
|
| `./scripts/releasekit publication-attempts [ARGS...]` | Forward without module/profile inference. |
|
||||||
|
| `./scripts/releasekit reconcile [ARGS...]` | Forward without module/profile inference. |
|
||||||
|
|
||||||
|
`ARGS` are ordinary upstream arguments, including the version where required;
|
||||||
|
forward them as separate quoted arguments, without shell evaluation. This
|
||||||
|
wrapper covers the selected maintainer workflow; it does not reimplement the
|
||||||
|
ReleaseKit parser. Let upstream validate versions, flags, records, and candidate
|
||||||
|
state. Reject a missing selector/operation or unsupported wrapper form with
|
||||||
|
usage on stderr and status 2 before running Go. Preserve meaningful argv
|
||||||
|
boundaries; exact usage prose is not a compatibility target.
|
||||||
|
|
||||||
|
Implement the only selector mapping in `scripts/releasekit`:
|
||||||
|
|
||||||
|
| Selector | Module directory | Profile | Product for profile-wiring tests |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `core` | `.` | `releasekit.json` | `CommandKit` |
|
||||||
|
| `ckconfig` | `integrations/ckconfig` | `integrations/ckconfig/releasekit.json` | `CommandKit ckconfig` |
|
||||||
|
| `ckprompt` | `integrations/ckprompt` | `integrations/ckprompt/releasekit.json` | `CommandKit ckprompt` |
|
||||||
|
|
||||||
|
Implementation details:
|
||||||
|
|
||||||
|
1. Resolve the repository root from the script location using quoted POSIX
|
||||||
|
shell operations safe with spaces and inherited `CDPATH`; change there.
|
||||||
|
2. Set `GOWORK=off` and `GOTOOLCHAIN=local` before querying Go. Resolve native
|
||||||
|
`GOHOSTOS` and `GOHOSTARCH` through the selected `go`, then export them as
|
||||||
|
`GOOS` and `GOARCH` for tool execution. Do not inherit a cross-build target.
|
||||||
|
3. Read the effective flags with `go env GOFLAGS`. Append `-mod=readonly` to
|
||||||
|
that string and export it as `GOFLAGS`, preserving the other effective
|
||||||
|
flags. Appending gives read-only selection precedence over an inherited
|
||||||
|
`-mod` setting. Do not parse or evaluate the string in the shell. Go 1.26.8
|
||||||
|
does not accept `go tool -mod=readonly`; do not use that unsupported form.
|
||||||
|
4. For module operations, prepend `OPERATION --repo ROOT --config ABS_PROFILE`.
|
||||||
|
For `publish` only, also prepend `--expected-module MODULE_DIR`. Neither
|
||||||
|
ordinary `check` nor `deliver` accepts that publication flag. Append the
|
||||||
|
supplied upstream arguments unchanged; upstream owns its flag semantics.
|
||||||
|
5. For the three raw forms, forward the command and supplied arguments without
|
||||||
|
adding profile, module, or publication flags. The working directory is the
|
||||||
|
repository root. Relative record paths therefore resolve there; document
|
||||||
|
absolute record paths in examples for clarity, without prohibiting relative
|
||||||
|
ones. Recovery identity comes from the selected saved record.
|
||||||
|
6. Finish through `exec go tool go.maximumdirect.net/releasekit/cmd/releasekit`.
|
||||||
|
Preserve the child's output streams and exit status. Do not create or build
|
||||||
|
an executable in `.releasekit/bin/`, preflight Gitea, or chain delivery after
|
||||||
|
publication.
|
||||||
|
|
||||||
|
Reduce `scripts/release` to checking its existing two-argument shape, then
|
||||||
|
executing the sibling helper with `MODULE publish VERSION`. Delegate selector
|
||||||
|
validation to that helper, avoiding a second mapping. Keep
|
||||||
|
`./scripts/release MODULE VERSION` usable from outside the repository.
|
||||||
|
|
||||||
|
**Stage result:** all selected operations share root-tool execution and one
|
||||||
|
module mapping; publication and delivery remain explicitly separate commands.
|
||||||
|
|
||||||
|
## Stage 3: Replace release-test scaffolding with focused wiring tests
|
||||||
|
|
||||||
|
Rewrite `scripts/release_test.go` around the actual scripts and a small fake Go
|
||||||
|
executable at the subprocess boundary. Remove
|
||||||
|
`scripts/release_integration_test.go` and helpers with no remaining users.
|
||||||
|
|
||||||
|
Use temporary directories, including a repository path with spaces and an
|
||||||
|
outside invocation directory. Copy the scripts and actual profiles into the
|
||||||
|
fixture. The fake Go needs only to answer the queried `go env` values and to
|
||||||
|
record the tool invocation, selected environment values, and controlled output
|
||||||
|
and status. Simple argument recording suffices: remove `goCall`, its bespoke
|
||||||
|
record parser, native-build assertions, and tests of assertion helpers. Do not
|
||||||
|
retain a fake build stage, fake publisher executable, Git repository fixture,
|
||||||
|
tag inspector, suite marker, or release-note generator.
|
||||||
|
|
||||||
|
Cover these behaviors with compact cases:
|
||||||
|
|
||||||
|
- Check the selector table against the copied profiles' module/product and the
|
||||||
|
selected destination, forbidden token path, shared files, and validation
|
||||||
|
selections. This checks CommandKit's choices, not upstream parsing semantics.
|
||||||
|
- Exercise each selector with `publish`, `check`, and `deliver`. Verify absolute
|
||||||
|
repository/profile arguments, publication-only `--expected-module`, and
|
||||||
|
unchanged forwarding of supplied upstream arguments.
|
||||||
|
- Exercise the legacy publication entry point and raw recovery/version forms.
|
||||||
|
Verify recovery receives the explicit record/options without inferred module
|
||||||
|
identity or a profile argument.
|
||||||
|
- Use foreign target values, workspace/toolchain overrides, and effective
|
||||||
|
`GOFLAGS` containing an unrelated flag and `-mod=mod`. The recorded tool
|
||||||
|
environment must select the host, disable workspace discovery, use the local
|
||||||
|
toolchain, preserve the unrelated flag, and give read-only mode precedence.
|
||||||
|
Assert effective settings rather than an incidental count/order of queries.
|
||||||
|
- Exercise statuses 0, 1, 2, and 3 on a representative operation, stdout/stderr
|
||||||
|
forwarding, and a nonzero legacy-publication result. Do not multiply all
|
||||||
|
module/operation combinations by all exit statuses.
|
||||||
|
- Exercise malformed wrapper invocations and confirm no Go command ran. Leave
|
||||||
|
invalid semantic-version and upstream-flag classification to ReleaseKit.
|
||||||
|
|
||||||
|
Use no credential file, authenticated request, or external service. Keep existing
|
||||||
|
domain package and maintained-consumer tests unchanged. Run the focused scripts
|
||||||
|
suite during development as needed; Stage 5 owns final complete validation.
|
||||||
|
|
||||||
|
**Stage result:** local tests protect CommandKit routing and invocation behavior;
|
||||||
|
upstream tests own publication, credential handling, and hosted reconciliation.
|
||||||
|
|
||||||
|
## Stage 4: Align current documentation with the implemented workflow
|
||||||
|
|
||||||
|
Update `docs/release.md`, the CommandKit-specific scope in
|
||||||
|
`docs/policy/release.md`, and release-tooling guidance in `docs/development.md`.
|
||||||
|
Keep adopted general policy text and provenance intact. Change current owners
|
||||||
|
with the implementation; the feature roadmap supplies the design rationale.
|
||||||
|
|
||||||
|
Document these concrete invocation examples, using placeholders rather than
|
||||||
|
selecting a new release version:
|
||||||
|
|
||||||
|
- Publish: `./scripts/release core vX.Y.Z`, with corresponding integration
|
||||||
|
selectors. Keep the existing core-then-ckconfig-then-ckprompt order.
|
||||||
|
- Diagnose: `./scripts/releasekit core check vX.Y.Z`; optional, never a required
|
||||||
|
step before publication repeats validation.
|
||||||
|
- Deliver: `./scripts/releasekit core deliver vX.Y.Z`, or either integration
|
||||||
|
selector with its own semantic version. The profile derives the full tag.
|
||||||
|
- Discover/reconcile: `./scripts/releasekit publication-attempts` and
|
||||||
|
`./scripts/releasekit reconcile --record /absolute/path/to/attempt.json`.
|
||||||
|
- Inspect the tool: `./scripts/releasekit version`.
|
||||||
|
|
||||||
|
Include the clean tagged-checkout prerequisite for delivery, later retries from
|
||||||
|
the original tagged source, the page-only body and module-specific full tags,
|
||||||
|
environment-token precedence over the repository-relative token file, and
|
||||||
|
retention of the ignored credential directory. Explain that successful source
|
||||||
|
publication completes the source release, while hosted delivery has a separate
|
||||||
|
outcome and URL. Credentials and Gitea availability do not gate publication.
|
||||||
|
Refer to upstream delivery and recovery contracts rather than duplicating an
|
||||||
|
HTTP implementation or a second status model.
|
||||||
|
|
||||||
|
Remove native executable-storage commands and the retired
|
||||||
|
`COMMANDKIT_RELEASE_INTEGRATION` exercise instructions. Explain that selected
|
||||||
|
upstream file checks inspect committed inputs, cover modules independently,
|
||||||
|
and do not replace domain review. Document future licensing footer URLs using
|
||||||
|
`https://forge.maximumdirect.net/base-layer/commandkit/src/tag/FULL_TAG/` plus
|
||||||
|
the correct repository-relative module file path. Keep existing published notes
|
||||||
|
and tags unchanged; add no speculative release note or historical backfill.
|
||||||
|
No CI workflow, provider call, runtime API, or attribution update is required.
|
||||||
|
|
||||||
|
Search affected documentation for stale `.releasekit/bin/` and retired test
|
||||||
|
references. Keep the credential-path references. Where baseline documentation
|
||||||
|
mentions a deleted source file, use its inline path and baseline revision
|
||||||
|
instead of leaving a broken local hyperlink. Keep stage tracking in this plan,
|
||||||
|
not in the feature roadmap.
|
||||||
|
|
||||||
|
**Stage result:** the maintainer runbook describes the actual wrapper commands,
|
||||||
|
selected checks, separate outcomes, and recovery without obsolete scaffolding.
|
||||||
|
|
||||||
|
## Stage 5: Verify the final source and record validation boundaries
|
||||||
|
|
||||||
|
Use Go 1.26.8 on `PATH`, `GOTOOLCHAIN=local`, and prepared dependency caches.
|
||||||
|
Reuse checks for unchanged final content instead of repeating them for each
|
||||||
|
stage. Preserve the existing ignored `go.work` (currently declaring Go 1.26.10);
|
||||||
|
use an external temporary Go 1.26.8 workspace when testing current source.
|
||||||
|
|
||||||
|
Perform the following one-time migration checks; add no persistent validation
|
||||||
|
script or new recurring publication gate:
|
||||||
|
|
||||||
|
1. Check shell syntax and executable modes for both scripts, parse the profiles,
|
||||||
|
review documentation links/fragments, and run `git diff --check`. Verify only
|
||||||
|
the intended files changed and the token remains ignored and untracked.
|
||||||
|
2. Exercise the real helper's `version` with foreign `GOOS`/`GOARCH`, an inherited
|
||||||
|
workspace, and an unrelated effective Go flag. Confirm ReleaseKit v0.8.0 runs
|
||||||
|
natively without changing module files. In a disposable module copy, remove
|
||||||
|
required tool checksum metadata and use inherited `-mod=mod`; confirm the
|
||||||
|
helper fails instead of repairing metadata. Do not alter the real sum files.
|
||||||
|
3. Review and stage only the intended sprint changes, including new files, for
|
||||||
|
verification. Obtain the staged tree with `git write-tree` and archive that
|
||||||
|
tree into a disposable directory; do not archive `HEAD` and accidentally
|
||||||
|
test the old implementation. Initialize and commit that snapshot in a new
|
||||||
|
local Git repository on `main`, with no copied tag refs or publication
|
||||||
|
remote. This verifies intended content before committing it in CommandKit.
|
||||||
|
Do not include ignored files, unrelated staged work, or real credentials.
|
||||||
|
Existing notes can label these local-only diagnostics: core `v0.3.0`,
|
||||||
|
integrations `v0.1.0`. No tag is created or reused in an authoritative
|
||||||
|
repository.
|
||||||
|
4. Build the pinned ReleaseKit executable once into temporary storage, using
|
||||||
|
the selected root module and read-only metadata. Run ordinary upstream
|
||||||
|
`check` on the snapshot's core profile with workspace discovery off. This
|
||||||
|
runs the root suite, including the new scripts tests, and all selected file
|
||||||
|
checks. Temporary native storage here is diagnostic setup, not launcher code.
|
||||||
|
5. For the integrations, create an external temporary workspace containing all
|
||||||
|
three snapshot modules. ReleaseKit v0.8.0 intentionally forces `GOWORK=off`
|
||||||
|
for its child suites, so exporting a workspace or alternate module-file flag
|
||||||
|
on the outer command cannot redirect those suites. For this diagnostic only,
|
||||||
|
put a temporary `go` shim on the executable's `PATH`: forward all invocations
|
||||||
|
to the absolute real Go binary, but for `go test` set `GOWORK` to that temporary
|
||||||
|
workspace before executing the real command. Do not skip tests or alter their
|
||||||
|
remaining arguments. Run upstream `check` for both integration profiles.
|
||||||
|
Real package suites then exercise current source; upstream file checks still
|
||||||
|
inspect unchanged committed inputs, including ordinary `go.mod` files. This
|
||||||
|
procedure was verified during planning and needs no committed helper.
|
||||||
|
6. Record workspace-backed integration results separately from independent
|
||||||
|
release-readiness evidence. The baseline standalone failures listed above
|
||||||
|
must remain visible. If needed, compare workspace-off tests with baseline to
|
||||||
|
distinguish new failures. Do not claim the shimmed diagnostic proves that
|
||||||
|
published dependencies are aligned, and do not add the shim to ordinary
|
||||||
|
`check`, `publish`, or the default test suite. Dependency/version alignment
|
||||||
|
and preparation of real integration candidates remain separate release work.
|
||||||
|
|
||||||
|
Planning evidence: the four generic file checks passed for the baseline core;
|
||||||
|
all five selected file checks passed for both baseline integration snapshots
|
||||||
|
using their real workspace-backed suites. The corresponding workspace-off
|
||||||
|
integration suites failed with the known missing-core-symbol errors. Repeat
|
||||||
|
the relevant diagnostics for the final sprint content, not merely the baseline.
|
||||||
|
Investigate new failures without turning the baseline limitation into a false
|
||||||
|
green result or disabling an agreed validator.
|
||||||
|
|
||||||
|
Do not invoke `publish`, `deliver`, or `ci-deliver` against a real destination
|
||||||
|
for verification. Configuration and forwarding are the local responsibility;
|
||||||
|
ReleaseKit owns authenticated preflight, hosted writes, and content matching.
|
||||||
|
|
||||||
|
**Stage result:** the changed infrastructure, real current-source suites, and
|
||||||
|
selected committed-file checks are verified, with independent integration
|
||||||
|
release-readiness limits accurately reported.
|
||||||
|
|
||||||
|
## Stage 6: Review, document completion, and commit
|
||||||
|
|
||||||
|
Review the complete diff against the feature roadmap. Confirm that all three
|
||||||
|
profiles have the selected options and destination; one shared launcher owns
|
||||||
|
module routing; the old publication exercise and unused helpers are gone;
|
||||||
|
domain tests remain; documentation uses the new invocation and separate
|
||||||
|
outcomes; and `/.releasekit/` still protects the local token directory.
|
||||||
|
|
||||||
|
Record stages completed and final validation results in this document, including
|
||||||
|
the dependency-version limitation. Do not retire these roadmap documents during
|
||||||
|
this sprint: retain the target and completion evidence for review, then apply
|
||||||
|
the normal roadmap lifecycle during later release preparation. No new release
|
||||||
|
version or source/hosted publication is required to finish this implementation.
|
||||||
|
|
||||||
|
Follow the local commit policy, review staged changes, and commit the intended
|
||||||
|
implementation units with short plain-English messages. Report the commit IDs,
|
||||||
|
remaining work, and verification limits. Preserve unrelated changes and private
|
||||||
|
files; do not force a clean worktree by deleting or including them. With only
|
||||||
|
the planned sprint changes present, the resulting tracked worktree should be
|
||||||
|
clean. Intermediate failures do not justify leaving the final selected scope
|
||||||
|
partially implemented.
|
||||||
|
|
||||||
|
**Stage result:** a reviewable, committed implementation of the selected target
|
||||||
|
with accurate validation evidence and no production publication.
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
# Release tooling simplification
|
# Release tooling simplification
|
||||||
|
|
||||||
Status: implementation roadmap; no implementation has started. Local page-only
|
Status: target design finalized for the release-tooling sprint; implementation
|
||||||
Gitea delivery and protection of the supplied token path are selected for
|
has not started. All four generic file checks, registered-tool execution,
|
||||||
implementation. The recommendations in Open Decisions remain unselected.
|
page-only hosted delivery, and protection of the supplied token path are selected.
|
||||||
Current release behavior stays with its canonical owners until implementation
|
The [implementation plan](implementation.md) owns stage order, tasks, validation,
|
||||||
updates them.
|
and completion evidence. Current release behavior stays with its canonical owners
|
||||||
|
until implementation updates them.
|
||||||
|
|
||||||
## Purpose and authority
|
## Purpose and authority
|
||||||
|
|
||||||
@@ -21,44 +22,6 @@ The [agent policy](../policy/agents.md),
|
|||||||
govern implementation. The [release procedure](../release.md) continues to own
|
govern implementation. The [release procedure](../release.md) continues to own
|
||||||
the current workflow until implementation updates it.
|
the current workflow until implementation updates it.
|
||||||
|
|
||||||
## Current baseline
|
|
||||||
|
|
||||||
Baseline: CommandKit commit `a74fcb20041cbccde93f9b9a1e3b24cb8dd131e7`.
|
|
||||||
|
|
||||||
- The root [module](../../go.mod) selects
|
|
||||||
`go.maximumdirect.net/releasekit v0.8.0` as a Go tool. The release toolchain
|
|
||||||
remains Go 1.26.8, and the consumer minimum remains Go 1.26.0.
|
|
||||||
- [Core](../../releasekit.json),
|
|
||||||
[ckconfig](../../integrations/ckconfig/releasekit.json), and
|
|
||||||
[ckprompt](../../integrations/ckprompt/releasekit.json) have separate profiles.
|
|
||||||
They select their physical module directories, the current SSH endpoint, and
|
|
||||||
an explicit repository-root shared-file list. They enable no optional file
|
|
||||||
checks or additional product checks, and configure no hosted delivery.
|
|
||||||
- The 49-line [launcher](../../scripts/release) maps the three selectors, changes
|
|
||||||
to the repository root, builds the root-selected tool into ignored
|
|
||||||
`.releasekit/bin/` storage for the host, and delegates publication to ReleaseKit.
|
|
||||||
- [Launcher tests](../../scripts/release_test.go) occupy 506 lines, including
|
|
||||||
custom command recording, fake build/publisher processes, and tests of the
|
|
||||||
assertion helpers themselves.
|
|
||||||
- The 399-line [publication exercise](../../scripts/release_integration_test.go)
|
|
||||||
creates disposable Git repositories, release notes, and suite markers. It
|
|
||||||
checks tag structure, exact remote objects, suite counts, nested tag prefixes,
|
|
||||||
and endpoint rejection in addition to exercising CommandKit's launcher.
|
|
||||||
- CommandKit's API, CLI, integration, and maintained consumer behavior is tested
|
|
||||||
in the owning package suites. There is no separate CommandKit-specific
|
|
||||||
candidate-validation implementation to replace or preserve.
|
|
||||||
|
|
||||||
After the baseline review, the maintainer supplied the local credential file
|
|
||||||
`.releasekit/gitea-token`. Its contents were not read. The file was confirmed
|
|
||||||
ignored, untracked, and mode `0600`; authentication was not tested. The existing
|
|
||||||
directory ignore rule now serves credential storage as well as executable
|
|
||||||
storage and remains needed after executable-storage removal.
|
|
||||||
|
|
||||||
During review, a temporary core profile enabled all four proposed file checks
|
|
||||||
below. ReleaseKit's local `check` accepted the committed core candidate with
|
|
||||||
Go 1.26.8. This was diagnostic evidence only: no profiles changed, no publication
|
|
||||||
occurred, and equivalent integration-module checks remain outstanding.
|
|
||||||
|
|
||||||
## Targeted end state
|
## Targeted end state
|
||||||
|
|
||||||
### Ownership
|
### Ownership
|
||||||
@@ -79,7 +42,7 @@ deliverables and platform support commitments remain unchanged.
|
|||||||
|
|
||||||
### Profiles
|
### Profiles
|
||||||
|
|
||||||
Subject to OD-1, select these existing ReleaseKit options in each profile:
|
Select these existing ReleaseKit options in each profile:
|
||||||
|
|
||||||
| Selection | Intended protection |
|
| Selection | Intended protection |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -88,7 +51,7 @@ Subject to OD-1, select these existing ReleaseKit options in each profile:
|
|||||||
| `validation.module_distribution.workspace_files: true` | Detect committed development workspace files in selected inputs. |
|
| `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. |
|
| `validation.module_distribution.local_replacements: true` | Detect filesystem replacements in selected committed module declarations. |
|
||||||
|
|
||||||
Separately from OD-1, select
|
Also select
|
||||||
`validation.forbidden_files: [".releasekit/gitea-token"]` in all three profiles.
|
`validation.forbidden_files: [".releasekit/gitea-token"]` in all three profiles.
|
||||||
This delegates protection of the supplied credential path to ReleaseKit's
|
This delegates protection of the supplied credential path to ReleaseKit's
|
||||||
existing check. The path is repository-relative and the check applies across
|
existing check. The path is repository-relative and the check applies across
|
||||||
@@ -111,27 +74,25 @@ separately for demonstrated needs.
|
|||||||
|
|
||||||
### Launcher and recovery
|
### Launcher and recovery
|
||||||
|
|
||||||
Subject to OD-2, use the root module's registered `go tool releasekit` through
|
Use the root module's registered `go tool releasekit` through `exec`, keeping
|
||||||
`exec`, keeping the current selector interface and publication argument mapping.
|
the current selector interface and publication argument mapping.
|
||||||
Retain host normalization, workspace-off execution, the local toolchain, and
|
Retain host normalization, workspace-off execution, the local toolchain, and
|
||||||
read-only module metadata. Preserve other effective Go settings rather than
|
read-only module metadata. Preserve other effective Go settings while arranging
|
||||||
silently replacing them while arranging read-only selection. Go 1.26.8's
|
read-only selection.
|
||||||
`go tool` does not accept `-mod=readonly` directly; use its supported Go settings
|
The implementation plan specifies the wrapper interface and invocation details.
|
||||||
mechanism and verify the intended behavior.
|
|
||||||
|
|
||||||
Remove explicit executable storage when the launcher no longer creates it.
|
Go's cache supplies executable storage; the launcher creates no persistent
|
||||||
Retain `/.releasekit/` in `.gitignore` for the credential file, and update its
|
binary directory. `/.releasekit/` remains ignored for the credential file, with
|
||||||
comment to describe that purpose. Update recovery instructions to use the
|
an explanatory comment. Recovery instructions use the registered tool or the
|
||||||
registered tool or the entry point printed for the saved attempt. Preserve
|
entry point printed for the saved attempt, preserving ReleaseKit's distinction
|
||||||
ReleaseKit's distinction between publication outcome and record-storage errors.
|
between publication outcome and record-storage errors.
|
||||||
|
|
||||||
Share module selection and host-safe tool invocation between publication,
|
Share module selection and host-safe tool invocation between publication,
|
||||||
delivery, and recovery where applicable. Delivery selects the same module
|
delivery, and recovery where applicable. Delivery selects the same module
|
||||||
profile as publication; recovery uses its recorded attempt rather than inferring
|
profile as publication; recovery uses its recorded attempt rather than inferring
|
||||||
identity from a current profile. Keep the existing publication interface and
|
identity from a current profile. Keep the existing publication interface and
|
||||||
provide an explicit delivery invocation without automatically chaining the two
|
provide an explicit delivery invocation without automatically chaining the two
|
||||||
operations. Choose a small wrapper arrangement during implementation rather
|
operations. Keep one selector mapping and shared invocation plumbing.
|
||||||
than adding a coordination framework or duplicating selector tables.
|
|
||||||
|
|
||||||
A pending upstream request concerns host-safe consumer launcher examples and
|
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
|
regression coverage. It is not a dependency of this work: v0.8.0 already supports
|
||||||
@@ -204,115 +165,34 @@ Exercise module routing separately from exit statuses rather than multiplying
|
|||||||
every combination. Assert behavior and meaningful selections, not helper
|
every combination. Assert behavior and meaningful selections, not helper
|
||||||
implementation details or exact usage prose.
|
implementation details or exact usage prose.
|
||||||
|
|
||||||
Remove the disposable publication exercise and its Git fixtures, synthetic
|
The resulting local suite omits the disposable publication exercise, generic
|
||||||
notes, markers, tag inspection, and environment-isolation helpers when no longer
|
tag inspection, assertion-helper self-tests, and custom build-call log/parser.
|
||||||
used. Remove assertion-helper self-tests and the custom build-call log/parser
|
Upstream publication and delivery coverage owns those generic behaviors. No
|
||||||
with their obsolete consumers. Trust upstream publication and delivery coverage;
|
replacement publication engine or exported test-helper API is needed. There is
|
||||||
do not move a duplicate suite into a different local package or export a new
|
no line-count target for the replacement tests.
|
||||||
test-helper API. There is no line-count target for the replacement tests.
|
|
||||||
|
|
||||||
## Work from baseline to target
|
## Selected choices and rationale
|
||||||
|
|
||||||
### 1. Configure validation and hosted delivery
|
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.
|
||||||
|
|
||||||
- [ ] Resolve OD-1 and record the chosen scope here.
|
Host-normalized registered-tool execution is selected because the root module
|
||||||
- [ ] Update the three profiles for the selected options while preserving their
|
already registers ReleaseKit and Go caches the executable. Retaining a persistent
|
||||||
module identities, endpoint, and shared-file selections.
|
native executable would provide a recovery entry point independent of a later
|
||||||
- [ ] Add the agreed delivery destination and forbidden token path to each
|
Go-driver invocation, but would retain executable-storage and bootstrap test
|
||||||
profile. Preserve the ignored token file and the directory ignore rule.
|
maintenance. Recovery instead uses the registered tool or ReleaseKit's reported
|
||||||
- [ ] Run the selected checks against each module's committed candidate inputs.
|
entry point. The credential directory remains ignored under either approach.
|
||||||
Review findings against existing contracts; fix relevant defects without
|
|
||||||
introducing broad exclusions or unrelated remediation by default.
|
|
||||||
- [ ] Update the release policy's delivery scope and the release procedure's
|
|
||||||
selected-check and hosted-delivery descriptions with the profile changes.
|
|
||||||
|
|
||||||
### 2. Simplify the launcher and its tests
|
The implementation plan records the existing integration dependency-version
|
||||||
|
mismatch separately from validation of the current source. This infrastructure
|
||||||
- [ ] Resolve OD-2 and implement the selected invocation path.
|
sprint does not publish releases or select new library dependency versions.
|
||||||
- [ ] Add or adapt focused wiring tests before deleting the coverage they replace.
|
Historical hosted-page backfilling and CI delivery remain separate future
|
||||||
- [ ] Remove `scripts/release_integration_test.go`, assertion-helper self-tests,
|
choices, not prerequisites for the selected local page-only workflow.
|
||||||
and unused build/publisher scaffolding after reviewing their coverage ownership.
|
|
||||||
- [ ] If registered-tool execution is selected, remove executable-storage setup
|
|
||||||
while retaining `/.releasekit/` for credentials and updating its comment.
|
|
||||||
Do not delete user-local files as part of the refactor.
|
|
||||||
- [ ] Expose explicit module-aware delivery using shared invocation plumbing.
|
|
||||||
Keep publication and delivery independently invocable and retryable.
|
|
||||||
- [ ] Update recovery commands, delivery prerequisites and retry instructions,
|
|
||||||
and token environment/file precedence. Remove obsolete opt-in publication
|
|
||||||
exercise instructions from the release and development guides with the
|
|
||||||
corresponding behavior change.
|
|
||||||
|
|
||||||
### 3. Validate and finish
|
|
||||||
|
|
||||||
- [ ] Validate with Go 1.26.8 and prepared dependencies. Exercise the real
|
|
||||||
registered tool's host execution and read-only behavior once where the local
|
|
||||||
wiring tests use a controlled process; use nonpublishing operations.
|
|
||||||
- [ ] Run the owning module suites and selected ReleaseKit checks against the
|
|
||||||
final candidates. ReleaseKit `check` already runs the selected module's suite;
|
|
||||||
avoid repeating the same successful suite solely for another checklist item.
|
|
||||||
- [ ] Distinguish workspace behavior evidence from each module's independent
|
|
||||||
dependency graph. For disposable committed-candidate checks, use matching
|
|
||||||
notes and existing module metadata; do not invent future dependency versions
|
|
||||||
or checksums to make validation pass.
|
|
||||||
- [ ] Review the documentation, local links, and final diff. Confirm that
|
|
||||||
domain-specific package tests remain and that removed helpers have no users.
|
|
||||||
Check future-note guidance for module-specific full tags and immutable forge
|
|
||||||
links; do not rewrite published notes to adopt the new workflow.
|
|
||||||
- [ ] Verify delivery profile routing and operation forwarding with controlled
|
|
||||||
processes. Rely on upstream tests for Gitea authentication, HTTP writes, and
|
|
||||||
content reconciliation rather than adding a duplicate local delivery engine
|
|
||||||
suite. No real token or hosted writes are needed for these migration checks.
|
|
||||||
- [ ] Record validation results and completed work here. Retire the completed
|
|
||||||
roadmap through the usual documentation lifecycle when appropriate.
|
|
||||||
|
|
||||||
These are migration tasks, not additional permanent release gates. Verification
|
|
||||||
needs no production tag push or hosted delivery. Ordinary releases continue to
|
|
||||||
use one publication command, with no required preliminary `check` run, followed
|
|
||||||
by a separate hosted-delivery operation. Confirmed source publication remains
|
|
||||||
the source-release completion point; hosted-delivery failure is reported and
|
|
||||||
handled separately.
|
|
||||||
|
|
||||||
## Open Decisions
|
|
||||||
|
|
||||||
### OD-1: Which optional checks become release gates?
|
|
||||||
|
|
||||||
**Recommendation:** Select all four options in the profiles table. Formatting
|
|
||||||
and local link checks automate existing contributor review work. The two module
|
|
||||||
distribution checks address accidental inclusion of development-only metadata
|
|
||||||
that a successful local test run can overlook. Reusing upstream mechanisms keeps
|
|
||||||
this protection declarative and avoids maintaining local checker code.
|
|
||||||
|
|
||||||
This is a deliberate addition to release-time validation, not merely deletion
|
|
||||||
of duplicate code. The observed core pass does not establish every module's
|
|
||||||
compatibility with the selected input scope. Resolve integration findings and
|
|
||||||
the applicability of vendored or fixture inputs before treating the selection
|
|
||||||
as adopted. Record the chosen release scope in the release procedure.
|
|
||||||
The specific forbidden token path and page-only delivery are already selected
|
|
||||||
for implementation and are not part of this open decision.
|
|
||||||
|
|
||||||
**Viable alternative:** Select formatting and Markdown now and defer the module
|
|
||||||
distribution checks. This automates familiar review work with less change to
|
|
||||||
accepted release contents, and preserves flexibility for legitimate committed
|
|
||||||
module fixtures. It leaves accidental workspace files or filesystem replacements
|
|
||||||
to ordinary review. Choose this alternative if the broader distribution checks
|
|
||||||
would reject justified inputs or their added protection does not warrant the
|
|
||||||
restriction. Do not compensate by writing equivalent local validators.
|
|
||||||
|
|
||||||
### OD-2: Registered tool or persistent native executable?
|
|
||||||
|
|
||||||
**Recommendation:** Use host-normalized `go tool releasekit`. The tool is already
|
|
||||||
registered in the root module, the Go cache supplies the executable, and the
|
|
||||||
launcher can forward its exit status without managing `.releasekit/bin/`.
|
|
||||||
This also removes executable-storage test machinery and documentation, while
|
|
||||||
the directory ignore rule remains for the token. Preserve read-only metadata
|
|
||||||
selection and test the effective environment before replacing the current
|
|
||||||
bootstrap.
|
|
||||||
|
|
||||||
**Viable alternative:** Retain the current native build and persistent executable
|
|
||||||
while simplifying profiles and tests. It is already proven to handle inherited
|
|
||||||
cross-build targets, accepts an explicit build-time read-only flag, and provides
|
|
||||||
a durable recovery entry point independent of a later Go-driver invocation.
|
|
||||||
It retains storage, bootstrap, and recovery-documentation maintenance, so it
|
|
||||||
removes less local infrastructure. Prefer it only if verification identifies a
|
|
||||||
meaningful recovery or tool-resolution need that the registered-tool path does
|
|
||||||
not meet; the pending upstream example change alone is not such a blocker.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user