Read delivery tokens from files and check selected paths before release

This commit is contained in:
2026-11-01 15:39:36 +00:00
parent 6650b639e1
commit 792bfc4eca
17 changed files with 361 additions and 23 deletions

View File

@@ -174,8 +174,9 @@ Deliver a tagged source release to Gitea:
go run ./cmd/releasekit deliver [--repo DIR] [--config FILE] [--assets DIR] VERSION
```
`deliver` requires a `delivery` profile object and its configured token
environment variable, which defaults to `RELEASEKIT_GITEA_TOKEN`. It verifies
`deliver` requires a `delivery` profile object and a token loaded from its
configured environment variable or token file. Credential selection and errors
are defined in the [configuration reference](config.md). It verifies
the local tag, clean tagged checkout, hosted tag, and committed release note,
then creates or finds the release page and reports delivery state separately
from source publication. Historical lightweight tags and detached checkouts

View File

@@ -16,7 +16,7 @@ The current profile fields are:
| `checks` | No | Ordered additional child commands, each with an argument vector and optional environment map. |
| `validation` | No | Optional shared checks selected by ReleaseKit. |
| `build` | No | Optional main package, binary name, and selected `GOOS/GOARCH` target strings. |
| `delivery` | No | Optional Gitea `base_url`, `owner`, `repository`, and `token_env` settings for tagged-source delivery. |
| `delivery` | No | Optional Gitea `base_url`, `owner`, `repository`, `token_env`, and `token_file` settings for tagged-source delivery. |
`module_dir` names the selected module's physical location in the repository;
ReleaseKit reads its declared import path from that module's own `go.mod`. The
@@ -141,12 +141,32 @@ symlink size is the committed link text. Gitlinks have no measured size. Only
the captured candidate is checked, one offending file is reported at a time,
and historical or aggregate repository size is not measured.
`validation.untracked_files` is an optional list of literal repository-relative
file paths that must be absent from the captured commit. It runs after the Go
checks and before other file checks, using the `untracked-files` identity and
reporting selected committed paths. Omission, `null`, or `[]` disables it.
Paths use slash separators and ordinary relative normalization and must stay
within the repository. They are checked against the whole captured repository,
independently of the selected module and `shared_files`. The check reads path
metadata only; it does not read token contents, follow symlink targets, require
local files to exist, or inspect Git history. Existing clean-index/worktree
requirements still apply to candidate operations. An ignore rule alone does
not remove a previously committed file from the candidate.
The `delivery` object contains `base_url`, `owner`, `repository`, and optional
`token_env`. Its values are required when running `deliver`, but credentials are
not required for `check`, `publish`, or `build`. `token_env` names the
environment variable containing the Gitea token; it defaults to
`RELEASEKIT_GITEA_TOKEN`. The CLI reads this variable only for `deliver` and
passes its value explicitly to the library operation.
`token_env` and `token_file`. `token_env` names the environment variable
containing the Gitea token and defaults to `RELEASEKIT_GITEA_TOKEN`. A nonblank
environment value takes precedence. When it is unset or blank, `token_file`
selects a plain token-containing file; relative paths resolve from the Git
repository root, and absolute paths are used as supplied. The CLI trims leading
and trailing whitespace from file contents. An unreadable or blank file, or
the absence of both credential sources, returns status 2. Omission of
`token_file` retains environment-only loading.
Credential loading runs only for `deliver` and `ci-deliver`. `check`, `publish`,
and `build` do not read the token file or require a token. The CLI passes the
resolved value explicitly to the library operation. Selecting a token file and
selecting the optional untracked-file validator are independent settings.
`expected_push_url`, when nonempty, is compared exactly with Git's resolved
effective push URL during `publish`, before candidate validation. It applies

View File

@@ -98,6 +98,13 @@ The `Candidate` supplies both `RepositoryDir` and `ModuleDir`, plus the declared
module-local product checks. ReleaseKit calls `AdditionalChecks` once after
shared validation when supplied.
For local token files, set `Validation.UntrackedFiles` to the repository-relative
paths that should stay out of the committed candidate, such as
`[]string{".releasekit/gitea-token"}`. Failures use `untracked-files` and carry the
selected committed paths in `ValidationError.Findings`. This selection is
independent of module and shared-file inputs; see [GoDoc](../../check.go) for
the API contract and the [configuration reference](../config.md) for CLI use.
`ValidationSpec.SharedFiles` adds committed, repository-relative files to
ReleaseKit's optional file checks without enabling any checks. A nil slice
selects the optional defaults `COPYRIGHT`, `LICENSE`, and

View File

@@ -77,11 +77,36 @@ 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
The CLI resolves the token for delivery using the configured environment
variable or token file. 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.
For local delivery, save a Gitea personal access token in a git-ignored file such
as `.releasekit/gitea-token` and configure:
```json
{
"product": "Example",
"validation": {
"untracked_files": [".releasekit/gitea-token"]
},
"delivery": {
"base_url": "https://gitea.example",
"owner": "example",
"repository": "example",
"token_file": ".releasekit/gitea-token"
}
}
```
Add `.releasekit/` to the consumer's ignore rules and use owner-only file
permissions for the saved token. Then run `releasekit deliver v1.2.3` from the
tagged checkout. CI can continue supplying the environment token. See the
[configuration reference](../config.md) for precedence, path resolution, and the
optional candidate check. The validator checks the selected committed paths;
it does not scan for secrets in other files or past commits.
For nested modules, the note comes from that module's committed
`docs/releases/<version>.md`, and the hosted page is keyed by its complete tag.

View File

@@ -59,6 +59,10 @@ workspace-file check using the same candidate inventory. Resolved module bodies
are parsed once per blob object ID; only owned filesystem-replacement targets
and line numbers remain cached. Each declaration path receives findings from
that summary in its own path context.
The optional untracked-file check uses the captured tree's full path lookup
before the other file checks. It normalizes the explicitly selected
repository-relative names and reports matching entries through `untracked-files`
without loading their blobs. Candidate-tree cleanup covers this failure path.
The optional file-size check applies normalized literal file/directory
exclusions with path-boundary matching, then requests local Git sizes for the
remaining selected blobs. Sizes include symlink link-text bytes; gitlinks are

View File

@@ -14,6 +14,15 @@ succeeded. CI and consumer installation are not completion checks.
## Prepare a candidate
For local hosted-page delivery, save a Gitea personal access token in
`.releasekit/gitea-token` with owner-only file permissions. The file contains
only the token. ReleaseKit's profile selects this file as a fallback to
`RELEASEKIT_GITEA_TOKEN`; `.releasekit/` is already ignored. Its optional
`validation.untracked_files` selection checks that this path is absent from the
committed candidate. Source publication requires no delivery token. The
[configuration reference](config.md) owns credential selection and validator
semantics.
Use a clean clone on `main`. The chosen build toolchain is Go 1.26.10. Make that
local installation the active `go` command for preparation, building the release
executable, and candidate validation:
@@ -150,7 +159,15 @@ git checkout --detach "vX.Y.Z"
GOTOOLCHAIN=local go mod download
mkdir -p .releasekit/bin
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go build -o .releasekit/bin/releasekit ./cmd/releasekit
RELEASEKIT_GITEA_TOKEN="$GITEA_TOKEN" .releasekit/bin/releasekit deliver "vX.Y.Z"
.releasekit/bin/releasekit deliver "vX.Y.Z"
```
For an older tag whose CLI predates `token_file`, supply the token through its
environment variable when retrying that tagged tool:
```sh
RELEASEKIT_GITEA_TOKEN="$(cat .releasekit/gitea-token)" \
.releasekit/bin/releasekit deliver "vX.Y.Z"
```
The root ignore file excludes `.releasekit/`. Delivery uses the committed note