Files
ReleaseKit/docs/consumers/delivery.md

196 lines
9.0 KiB
Markdown

# Deliver a tagged source release
Use `releasekit.Deliver` or the `deliver` command after a source tag exists.
Delivery status is separate from source publication: a delivery problem does
not move or remove the tag, and a retry can use the same immutable version.
The operation accepts historical lightweight and annotated tags, including a
detached checkout, when the checked-out `HEAD` identifies the selected tag
commit. It does not require the old remote `main` to match.
## CI preparation
Use `PrepareTaggedCheckout` when a disposable CI checkout must be verified
against the commit that triggered the job. It fetches only the selected tag
from the chosen remote (default `origin`), compares the peeled tag commit with
the expected commit, and checks out that commit detached. Fetch or checkout
conflicts are returned so the caller can replace or repair the workspace.
Cancellation is returned to the caller; the operation does not publish a tag
or hosted content.
```go
err := releasekit.PrepareTaggedCheckout(ctx, releasekit.TaggedCheckoutRequest{
RepositoryDir: repositoryDir,
Version: version,
ExpectedCommit: ciCommit,
})
if err != nil {
return err
}
```
For binary profiles, call `PrepareBuildDependencies(ctx, repositoryDir)` after
checkout preparation and before delivery. It runs `go mod download` with
workspace discovery disabled and the available compatible local Go toolchain.
The operation may use the network and updates the Go module cache while
preserving the caller's proxy, private-module, credential, and cache settings.
If checksums are missing, Go may update `go.sum`; see the
[Go Modules Reference](https://go.dev/ref/mod#go-mod-download). Cancellation
and command errors are returned. Page-only profiles do not need dependency
preparation.
## Command line
Add a Gitea destination to the profile:
```json
{
"product": "Example",
"delivery": {
"base_url": "https://gitea.example",
"owner": "example",
"repository": "example",
"token_env": "RELEASEKIT_GITEA_TOKEN"
}
}
```
Fetch and check out the immutable tag, then deliver it:
```sh
git checkout --detach v1.2.3
RELEASEKIT_GITEA_TOKEN="$GITEA_TOKEN" releasekit deliver v1.2.3
```
The CLI reads the named token variable only for `deliver`; its default name is
`RELEASEKIT_GITEA_TOKEN`. It verifies the local checkout and hosted tag before
creating or accepting a hosted release page. The full checked-in note is the
hosted body. A retry accepts an identical page and matching attachments, adds
only missing assets, and reports conflicts without replacing content.
With no build targets, delivery is page-only: no builder, version smoke check,
receipt, binary asset, or checksum manifest is involved. With selected targets,
one `deliver` invocation builds the tagged source through the facade into
temporary storage and delivers the result. To retain artifacts for a retry or
separate credentials between build and delivery, use two invocations:
```sh
releasekit build --output dist v1.2.3
RELEASEKIT_GITEA_TOKEN="$GITEA_TOKEN" releasekit deliver --assets dist v1.2.3
```
The build command does not need delivery credentials. The `--assets DIR`
directory must contain the private `.releasekit-build.json` receipt created by
`build`. ReleaseKit checks the receipt's repository, commit, version, resolved
build settings, and file hashes before making a remote request; caller-owned
files remain available for retries. Ordinary `deliver` does not download
application dependencies or change the checkout.
The result reports `complete`, `partial`, `conflict`, `unknown`, or
`not_attempted`, along with matching, uploaded, pending, conflicting, and
uncertain assets when known. These are disjoint current observations: an asset
appears in at most one category, and early failures may leave some declared
assets unreported. `Matching` means existing content matches; `Uploaded` means
an upload was confirmed during this invocation; `Pending` means known missing
work; `Conflicting` means different hosted content was found; `Uncertain` means
the remote state could not be resolved.
Fix local or preflight failures before retrying. For partial delivery, fix the
reported cause and retry the same version. Resolve an unknown remote outcome
before retrying. Investigate conflicts and use a new version if the source or
published content needs correction. If rebuilding could change bytes already
on the server, retain the original build output and retry with `--assets DIR`.
The command does not run candidate checks or publish tags.
## Go API
Pass the Gitea credential explicitly. Set `Build` to a `BuildSpec` to compile
selected targets as part of delivery. The facade verifies the local tag, clean
checkout, and committed release note before compiling. Managed output is stored
outside the checkout and removed when delivery returns. `Output` receives build
progress. With no build, or with an empty target set, delivery is page-only.
To deliver binaries built separately, set `Prebuilt` to the `BuildResult`.
ReleaseKit checks that it identifies the selected repository, tagged commit, and
version, that its source was verified clean and unchanged during compilation,
and that the current files still match their recorded digests. The files remain
caller-owned, so callers can retain the original bytes for retries and are
responsible for cleanup. With neither artifact source, an empty managed target
set, or an empty prebuilt result, delivery is page-only. Do not set both `Build`
and `Prebuilt` in one request.
```go
result, err := releasekit.Deliver(ctx, releasekit.DeliveryRequest{
RepositoryDir: "/work/example",
Product: "Example",
Version: "v1.2.3",
Destination: releasekit.GiteaDestination{
BaseURL: "https://gitea.example",
Owner: "example",
Repository: "example",
Token: token,
},
Build: &releasekit.BuildSpec{
MainPackage: "./cmd/example",
BinaryName: "example",
Targets: []releasekit.Target{{OS: "linux", Arch: "amd64"}},
},
})
if err != nil {
// Keep the returned state and any completed asset identities for recovery.
return err
}
fmt.Println(result.State, result.ReleaseURL)
```
See the [CLI contract](../cli.md), [configuration reference](../config.md),
and [Gitea integration guide](../integrations/gitea.md) for exact settings,
exit codes, and transport behavior.
## Woodpecker tag workflows
Use the maintained [tag-delivery workflow](../../examples/woodpecker/tag-delivery.yml)
in the consumer repository's `.woodpecker/` directory. Set `GO_IMAGE` to an
image with Go 1.25 or newer, Git, and a Go version compatible with the consumer
module. Replace `RELEASEKIT_VERSION` with an immutable ReleaseKit revision or
published version. The example selects the initial `v0.1.0` baseline; update
that pin when adopting a later release. Configure the Woodpecker repository secret
`releasekit_gitea_token`; the template maps it to `RELEASEKIT_GITEA_TOKEN` only
for the delivery step. The repository needs a `delivery` profile. Page-only and
binary behavior both use this template; the profile's build target list selects
whether binaries are built and delivered.
The command runs versioned source directly with `go run`, passing
`CI_WORKSPACE`, `CI_COMMIT_SHA`, and `CI_COMMIT_TAG` as command arguments.
`ci-deliver` fetches and verifies the event tag against its commit before
checking out the commit detached. It then loads the profile from that source,
validates the destination and token, and downloads application dependencies
only for profiles with build targets. The facade builds and delivers those
targets with the note page. Source-only profiles skip dependency downloads and
binary work. The workflow does not repeat checkout guards or maintain a
separate build/receipt/delivery sequence.
The normal Go module and build caches are sufficient. Cache mounts may be added
as deployment configuration when they help the runner; they are not needed by
the template. A locally retained executable can be installed with
`go install gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@PIN`, then run
with the same arguments:
```sh
releasekit ci-deliver --repo "$CI_WORKSPACE" --commit "$CI_COMMIT_SHA" "$CI_COMMIT_TAG"
```
Upgrade by changing the selected immutable
`RELEASEKIT_VERSION` (or the `@PIN` used by `go install`) and validating the
workflow against a tag fixture. The command and profile behavior are documented
in the [CLI contract](../cli.md) and [configuration reference](../config.md).
Woodpecker runs delivery after the tag event, independently from the source
publication result. Read its workflow status as delivery status: a delivery
failure does not undo source publication. A failed, partial, or uncertain run
can be inspected and retried against the same immutable tag and commit; do not
move the tag to make a retry pass. See
[Woodpecker's environment reference](https://woodpecker-ci.org/docs/usage/environment)
for runner-provided tag and commit variables and
[workflow syntax](https://woodpecker-ci.org/docs/usage/workflow-syntax) for tag
events, sequential steps, and the shared workspace.