6.0 KiB
Multi-module release example
This example maps selectors and complete event tags to a physical Go module directory and a repository-root profile. The library derives the release tag from the selected module declaration and physical location; the table only selects the corresponding profile and checkout directory.
Copy the contents of this directory into a consumer repository root, keeping the listed module directories and profile paths at those locations, then run the launcher from that checkout.
The sample modules declare Go 1.26.0, matching the current ReleaseKit consumer minimum.
Select the release tool
The module files are setup skeletons. Set RELEASEKIT_TOOL_VERSION to a released
ReleaseKit version containing module-release support, then register that tool in
each consumer module before running the launcher or workflow:
: "${RELEASEKIT_TOOL_VERSION:?Select a ReleaseKit release with module-release support}"
for module_dir in . integrations/ckconfig integrations/core/v2; do
go -C "$module_dir" get -tool "gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@${RELEASEKIT_TOOL_VERSION}"
go -C "$module_dir" mod tidy
done
Review and commit the generated tool, dependency, and checksum declarations. The adoption guide owns tool registration and coordinated tool/workflow upgrades. The v0.4.0 release note describes module-release support and migration from earlier versions.
Module mapping and publication
release-modules.tsv is literal tab-separated text with four columns:
- Local selector.
- Shell pattern matched against a complete event tag.
- Repository-relative physical module directory (
.means the root module). - Repository-relative profile path.
The checked-in patterns are v[01].*, integrations/ckconfig/v*, and
integrations/core/v2.*. The helper passes pattern text to the shell's case
matcher without eval. A tag must match exactly one row; missing and ambiguous
matches are configuration errors. Module and profile paths may contain spaces.
The core-v2 row places the Go module physically under integrations/core/v2
and declares a /v2 module path. ReleaseKit derives the versioned tag under
integrations/core, while the table retains the full physical path.
Before running candidate checks offline, prepare each module's dependencies in its own directory:
go -C . mod download
go -C integrations/ckconfig mod download
go -C integrations/core/v2 mod download
Commit each generated go.sum with its module files. The binary delivery
profile prepares application dependencies in the tagged module before building;
the committed sums keep that prepared checkout clean for delivery verification.
Then select a module and semantic version with the shared launcher:
./release.sh root v1.2.3
./release.sh ckconfig v1.2.3
./release.sh core-v2 v2.1.0
The launcher copies the selected module's go.mod and go.sum to temporary
alternate module files outside the checkout, resolves ReleaseKit from that
module's local dependency selection, and builds the tool there. It invokes
publish with the repository profile and --expected-module so the library
can verify that the profile agrees with the selected table row. The temporary
files and tool are removed on exit. As with any publish invocation, commit the
selected module's release note and prepare its repository before publishing.
If an integration depends on a sibling release, publish the dependency first, then publish the integration with the version that consumes it. For example, publish the core release before an integration that requires that release. This declaration does not infer dependency order or rerun the standard suite.
The maintained Woodpecker example uses the same map and
selector for root, ckconfig, and major-version tags. It verifies and detaches
the literal event tag before selecting the module, copies that module's metadata
outside the checkout, and builds the ReleaseKit version selected there. It then
uses ci-deliver --prepared with the mapped profile and expected physical module.
The core-v2 profile demonstrates binary delivery; the other profiles are
page-only. Before enabling the workflow, configure each selected profile's
delivery destination and add the Woodpecker repository secret
releasekit_gitea_token; the workflow exposes it as
RELEASEKIT_GITEA_TOKEN only in the delivery step.
Retries use the selected tag's module files and matching workflow. Tags whose tool predates this interface use their corresponding historical workflow.
Local source verification
For verification before a compatible release is published, copy this example
into a disposable consumer checkout. Set RELEASEKIT_SOURCE to the absolute
path of a prepared ReleaseKit checkout, then select its source in those fixture
modules:
: "${RELEASEKIT_SOURCE:?Set the absolute ReleaseKit checkout path}"
for module_dir in . integrations/ckconfig integrations/core/v2; do
go -C "$module_dir" mod edit \
-require=gitea.maximumdirect.net/eric/ReleaseKit@v0.0.0 \
-replace="gitea.maximumdirect.net/eric/ReleaseKit=$RELEASEKIT_SOURCE" \
-tool=gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit
GOTOOLCHAIN=local GOWORK=off go -C "$module_dir" mod tidy
done
Here v0.0.0 is a fixture placeholder resolved by the local replacement.
Keep these declarations in the disposable checkout. Add representative product
source and each selected product's module-local release note, then commit the
fixture and run the source-selected tool without publishing:
go tool releasekit check --config releasekit-root.json v1.2.3
go -C integrations/ckconfig tool releasekit check --config releasekit-ckconfig.json v1.2.3
go -C integrations/core/v2 tool releasekit check --config releasekit-core-v2.json v2.1.0
These commands use the repository-root profile paths even when invoked from a
child module. The core profile also verifies the native binary and injected
version. Prepared dependencies allow this verification with GOPROXY=off and
GOSUMDB=off.