From 3d396b1a66bfafc509472cd74a3f8029def3d432 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Tue, 3 Nov 2026 15:26:02 +0000 Subject: [PATCH] Plan hosted Gitea release delivery --- docs/roadmap/release-simplification.md | 151 ++++++++++++++++++++----- 1 file changed, 121 insertions(+), 30 deletions(-) diff --git a/docs/roadmap/release-simplification.md b/docs/roadmap/release-simplification.md index 6e72bef..5cbfdc9 100644 --- a/docs/roadmap/release-simplification.md +++ b/docs/roadmap/release-simplification.md @@ -1,16 +1,19 @@ # Release tooling simplification -Status: proposed implementation roadmap. No implementation has started. -The recommendations in Open Decisions remain unselected. This document records -the intended simplification and the work to reach it; it does not add release -requirements or change public contracts by itself. +Status: implementation roadmap; no implementation has started. Local page-only +Gitea delivery and protection of the supplied token path are selected for +implementation. The recommendations in Open Decisions remain unselected. +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. +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 @@ -30,7 +33,7 @@ Baseline: CommandKit commit `a74fcb20041cbccde93f9b9a1e3b24cb8dd131e7`. [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. + 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. @@ -45,6 +48,12 @@ Baseline: CommandKit commit `a74fcb20041cbccde93f9b9a1e3b24cb8dd131e7`. 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 @@ -63,10 +72,10 @@ 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, -outcome reporting, and recovery. CommandKit's launcher does not repeat those -operations. Existing release completion and immutability rules continue to -apply; this work adds no publication channel, binary deliverable, or platform -support commitment. +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 @@ -79,8 +88,15 @@ 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.local_replacements: true` | Detect filesystem replacements in selected committed module declarations. | +Separately from OD-1, 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 validate every nested module. File checks inspect +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 @@ -89,9 +105,9 @@ 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 forbidden-file -lists are not selected by this roadmap. They can be considered separately for -demonstrated needs. +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 @@ -103,11 +119,20 @@ silently replacing them while arranging read-only selection. Go 1.26.8's `go tool` does not accept `-mod=readonly` directly; use its supported Go settings mechanism and verify the intended behavior. -Remove explicit executable storage and the dedicated ignore entry when the -launcher no longer creates that storage. Update recovery instructions to use -the registered tool or the entry point printed for the saved attempt. Preserve +Remove explicit executable storage when the launcher no longer creates it. +Retain `/.releasekit/` in `.gitignore` for the credential file, and update its +comment to describe that purpose. Update recovery instructions to use the +registered tool or the entry point printed for the saved attempt. Preserve 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. Choose a small wrapper arrangement during implementation rather +than adding a coordination framework or duplicating selector tables. + 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 @@ -115,6 +140,51 @@ registered tools. Keep host normalization locally because the reviewed 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 @@ -125,7 +195,10 @@ that invokes the actual launcher. Cover: - Invalid argument handling before tool invocation. - Invocation from another directory and paths containing spaces. - Host normalization and workspace/toolchain/read-only settings. -- Publication argument, output-stream, and child exit-status forwarding. +- 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 @@ -134,21 +207,24 @@ implementation details or exact usage prose. Remove the disposable publication exercise and its Git fixtures, synthetic notes, markers, tag inspection, and environment-isolation helpers when no longer used. Remove assertion-helper self-tests and the custom build-call log/parser -with their obsolete consumers. Trust upstream publication-engine coverage; +with their obsolete consumers. Trust upstream publication and delivery coverage; do not move a duplicate suite into a different local package or export a new test-helper API. There is no line-count target for the replacement tests. ## Work from baseline to target -### 1. Select profile checks +### 1. Configure validation and hosted delivery - [ ] Resolve OD-1 and record the chosen scope here. - [ ] Update the three profiles for the selected options while preserving their module identities, endpoint, and shared-file selections. +- [ ] Add the agreed delivery destination and forbidden token path to each + profile. Preserve the ignored token file and the directory ignore rule. - [ ] Run the selected checks against each module's committed candidate inputs. Review findings against existing contracts; fix relevant defects without introducing broad exclusions or unrelated remediation by default. -- [ ] Update the release procedure's selected-check description in the same unit. +- [ ] 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 @@ -157,11 +233,14 @@ test-helper API. There is no line-count target for the replacement tests. - [ ] Remove `scripts/release_integration_test.go`, assertion-helper self-tests, and unused build/publisher scaffolding after reviewing their coverage ownership. - [ ] If registered-tool execution is selected, remove executable-storage setup - and the dedicated `.releasekit/` ignore entry. Do not delete user-local files - as part of the refactor. -- [ ] Update recovery commands and remove obsolete opt-in publication-exercise - instructions from the release and development guides with the corresponding - behavior change. + 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 @@ -177,12 +256,21 @@ test-helper API. There is no line-count target for the replacement tests. 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. +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 @@ -199,6 +287,8 @@ 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 @@ -213,9 +303,10 @@ restriction. Do not compensate by writing equivalent local validators. **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 storage-specific test machinery and documentation. Preserve -read-only metadata selection and test the effective environment before replacing -the current bootstrap. +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