feat(cmd): release v1.10.0 — shallow clone guard and --check preflight
- refuse to release when the clone is shallow and no previous release tag is found: tags beyond the fetch depth would silently restart versioning at X.Y.0; --allow-shallow bypasses the guard for a true first release - new --check preflight validates the release environment without releasing: branch resolution + pattern, working tree, tag discovery, shallow clone, remote origin URL parse (same parse the push performs), push auth method, version files, release target — all problems reported at once, non-zero exit on failure - .releaser.gitlab-ci.yml gains an optional .releaser:check MR-pipeline job; CI examples now set GIT_DEPTH: 0 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,13 @@ title: Changelog
|
||||
weight: 50
|
||||
---
|
||||
|
||||
## v1.10.0 — 2026-07-16
|
||||
|
||||
### Added
|
||||
|
||||
- **`--check` preflight** — validates branch, working tree, shallow clone, remote URL, push auth, version files, and release target without releasing; reports all problems at once, non-zero exit on failure
|
||||
- **Shallow clone detection** — refuses to release when the clone is shallow and no previous tag is found (tags may be beyond the fetch depth); `--allow-shallow` bypasses the guard for a genuine first release
|
||||
|
||||
## v1.9.0 — 2026-07-16
|
||||
|
||||
### Added
|
||||
|
||||
@@ -29,6 +29,7 @@ release:
|
||||
- if: $CI_COMMIT_BRANCH =~ /^release\/.+$/
|
||||
variables:
|
||||
GITLAB_TOKEN: $RELEASE_TOKEN
|
||||
GIT_DEPTH: 0 # full history — shallow clones hide previous release tags
|
||||
script:
|
||||
- releaser
|
||||
artifacts:
|
||||
@@ -93,6 +94,32 @@ jobs:
|
||||
`fetch-depth: 0` is required. A shallow clone (`--depth 1`) hides the previous tag, causing `releaser` to treat every commit as the first release.
|
||||
{{< /hint >}}
|
||||
|
||||
## Preflight checks
|
||||
|
||||
`releaser --check` validates the release environment without releasing anything: branch resolution and pattern match, working tree state, shallow clone, remote URL parseability (the same parse the push performs — it catches shell-quoting accidents in `set-url` lines), which push auth would be used, configured version files, and the release target. All problems are reported at once, and the exit code is non-zero if any check fails.
|
||||
|
||||
Note the split with `--dry-run`: dry-run answers *"what version would be released?"* (it analyzes commits and computes the bump); `--check` answers *"will the release plumbing work?"* (everything dry-run never touches). Run `--check` in merge-request pipelines to catch broken CI configuration before it blocks a real release:
|
||||
|
||||
```yaml
|
||||
release:check:
|
||||
stage: test
|
||||
image: registry.example.com/releaser:latest
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
variables:
|
||||
GIT_DEPTH: 0
|
||||
script:
|
||||
- releaser --check --branch "release/0.0" # any pattern-matching name works for validation
|
||||
```
|
||||
|
||||
## Shallow clones
|
||||
|
||||
GitLab CI checks out a shallow clone by default (`GIT_DEPTH: 20`), and shallow clones hide any release tag beyond the fetch depth — tag discovery would silently restart versioning at `X.Y.0`. `releaser` detects this: when the clone is shallow **and** no previous release tag is found, it refuses to release and asks for full history.
|
||||
|
||||
Fix it by fetching full history (`GIT_DEPTH: 0` in GitLab CI, `fetch-depth: 0` in GitHub Actions, or `git fetch --unshallow`). If the project genuinely has no release tag yet, pass `--allow-shallow` to release anyway.
|
||||
|
||||
A shallow clone whose history does include the latest release tag is fine — the version calculation is unaffected, and `releaser` proceeds normally.
|
||||
|
||||
## Detached HEAD
|
||||
|
||||
CI runners check out a commit SHA, leaving the repository in detached HEAD state. `releaser` detects this and falls back to the branch name from the CI environment, in order:
|
||||
|
||||
@@ -35,6 +35,7 @@ releaser --verbose --dry-run
|
||||
| Flag | Default | Description |
|
||||
|------|---------|-------------|
|
||||
| `--dry-run` | false | Print next version and exit without making any changes |
|
||||
| `--check` | false | Preflight: validate branch, working tree, remote URL, push auth, version files, and release target without releasing |
|
||||
| `--branch <name>` | auto-detected | Override branch name (detached HEAD falls back to `CI_COMMIT_BRANCH`, `CI_COMMIT_REF_NAME`, `GITHUB_REF_NAME`) |
|
||||
| `--branch-pattern <regex>` | `^(?:.*/)?release/(\d+)\.(\d+)$` | Override branch pattern (two capture groups: major, minor) |
|
||||
| `--tag-prefix <prefix>` | `""` | Prefix for version tags (e.g. `v` → `v1.2.3`) |
|
||||
@@ -43,6 +44,7 @@ releaser --verbose --dry-run
|
||||
| `--pyproject <path>` | — | Override `python.pyproject_toml` from config |
|
||||
| `--changelog-file <path>` | `CHANGELOG.md` | Path to changelog file |
|
||||
| `--release-env-file <path>` | `release.env` | Path for dotenv artifact; pass `""` to disable |
|
||||
| `--allow-shallow` | false | Proceed in a shallow clone even when no previous release tag is found |
|
||||
| `--no-commit` | false | Update version files but stop before committing |
|
||||
| `--no-push` | false | Commit and tag locally, skip push and release |
|
||||
| `--no-release` | false | Push branch and tag but skip release creation |
|
||||
|
||||
Reference in New Issue
Block a user