mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
docs(skill): unwrap prose lines and add semver.org references (#4918)
Remove hard line wrapping from rustfs-release-publish prose (one logical line per sentence/paragraph, soft wrap for display) and link SemVer 2.0.0 spec including spec item 11 for prerelease precedence.
This commit is contained in:
@@ -4,9 +4,7 @@ description: "End-to-end RustFS release pipeline: cut a preview tag first, verif
|
|||||||
---
|
---
|
||||||
# RustFS Release Publish (preview-validated pipeline)
|
# RustFS Release Publish (preview-validated pipeline)
|
||||||
|
|
||||||
This skill orchestrates a full release. It wraps `rustfs-release-version-bump`
|
This skill orchestrates a full release. It wraps `rustfs-release-version-bump` (which only edits version files and opens the PR) with a mandatory preview-tag validation loop before the final tag is published.
|
||||||
(which only edits version files and opens the PR) with a mandatory
|
|
||||||
preview-tag validation loop before the final tag is published.
|
|
||||||
|
|
||||||
Pipeline shape:
|
Pipeline shape:
|
||||||
|
|
||||||
@@ -21,62 +19,33 @@ bump to <target>-preview.N -> merge -> tag preview -> CI green
|
|||||||
## Required inputs
|
## Required inputs
|
||||||
|
|
||||||
- Final target version, for example `1.0.0-beta.10`.
|
- Final target version, for example `1.0.0-beta.10`.
|
||||||
- Preview iteration `N` (default: next unused `-preview.N` for that target;
|
- Preview iteration `N` (default: next unused `-preview.N` for that target; check with `git tag -l '<target>-preview.*'` after `git fetch --tags`).
|
||||||
check with `git tag -l '<target>-preview.*'` after `git fetch --tags`).
|
|
||||||
|
|
||||||
If the target version is missing or ambiguous, stop and ask before doing
|
If the target version is missing or ambiguous, stop and ask before doing anything (see the semver gate below).
|
||||||
anything (see the semver gate below).
|
|
||||||
|
|
||||||
## Semver gate — confirm the target version before touching anything
|
## Semver gate — confirm the target version before touching anything
|
||||||
|
|
||||||
Versions follow SemVer 2.0.0. Precedence reminder:
|
Versions follow [SemVer 2.0.0](https://semver.org/). Precedence reminder:
|
||||||
|
|
||||||
```
|
```
|
||||||
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0 < 1.0.1 < 1.1.0 < 2.0.0
|
1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0 < 1.0.1 < 1.1.0 < 2.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
Numeric prerelease identifiers compare numerically (`beta.9 < beta.10`),
|
Numeric prerelease identifiers compare numerically (`beta.9 < beta.10`), not lexically — see [semver.org spec item 11](https://semver.org/#spec-item-11). Preview tags (`<target>-preview.N`) are internal validation tags layered on top of the target's prerelease channel — they are never themselves a deliverable version.
|
||||||
not lexically. Preview tags (`<target>-preview.N`) are internal validation
|
|
||||||
tags layered on top of the target's prerelease channel — they are never
|
|
||||||
themselves a deliverable version.
|
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
|
|
||||||
- A request like "发个版" / "release the next version" without an exact
|
- A request like "发个版" / "release the next version" without an exact version string is ALWAYS ambiguous. Derive the current latest tag (`git tag --sort=-v:refname | head`), then ask the user to choose via AskUserQuestion with concrete candidates, e.g. from `1.0.0-beta.10`: next prerelease `1.0.0-beta.11`, promote to `1.0.0-rc.1`, promote to stable `1.0.0`. Never guess between these — they have very different meanings (channel promotion vs. iteration) and different CI classification consequences.
|
||||||
version string is ALWAYS ambiguous. Derive the current latest tag
|
- After a stable `X.Y.Z` exists, the next version must state which component bumps: patch `X.Y.(Z+1)` for fixes only, minor `X.(Y+1).0` for backward-compatible features, major `(X+1).0.0` for breaking changes. If the user names a bump type but not a number, compute it from the latest stable tag and echo the exact resulting version back for confirmation.
|
||||||
(`git tag --sort=-v:refname | head`), then ask the user to choose via
|
- Echo the final confirmed version string verbatim in your first status report; every later phase must use exactly that string. If at any point the user's wording and the confirmed version diverge, stop and re-confirm.
|
||||||
AskUserQuestion with concrete candidates, e.g. from `1.0.0-beta.10`:
|
|
||||||
next prerelease `1.0.0-beta.11`, promote to `1.0.0-rc.1`, promote to
|
|
||||||
stable `1.0.0`. Never guess between these — they have very different
|
|
||||||
meanings (channel promotion vs. iteration) and different CI
|
|
||||||
classification consequences.
|
|
||||||
- After a stable `X.Y.Z` exists, the next version must state which
|
|
||||||
component bumps: patch `X.Y.(Z+1)` for fixes only, minor `X.(Y+1).0`
|
|
||||||
for backward-compatible features, major `(X+1).0.0` for breaking
|
|
||||||
changes. If the user names a bump type but not a number, compute it
|
|
||||||
from the latest stable tag and echo the exact resulting version back
|
|
||||||
for confirmation.
|
|
||||||
- Echo the final confirmed version string verbatim in your first status
|
|
||||||
report; every later phase must use exactly that string. If at any point
|
|
||||||
the user's wording and the confirmed version diverge, stop and re-confirm.
|
|
||||||
|
|
||||||
## Hard rules
|
## Hard rules
|
||||||
|
|
||||||
- **Prerelease classification is substring-based.** `build.yml` marks a tag
|
- **Prerelease classification is substring-based.** `build.yml` marks a tag as prerelease only if its name contains `alpha`, `beta`, or `rc`. A preview of a prerelease target (`1.0.0-beta.10-preview.3`) contains `beta` and is safe. For a **stable** target (e.g. `1.1.0`), NEVER tag `1.1.0-preview.N` — it would be treated as a stable release and overwrite `latest.json` as stable. Use `1.1.0-rc.N` as the preview tag instead.
|
||||||
as prerelease only if its name contains `alpha`, `beta`, or `rc`. A preview
|
|
||||||
of a prerelease target (`1.0.0-beta.10-preview.3`) contains `beta` and is
|
|
||||||
safe. For a **stable** target (e.g. `1.1.0`), NEVER tag `1.1.0-preview.N` —
|
|
||||||
it would be treated as a stable release and overwrite `latest.json` as
|
|
||||||
stable. Use `1.1.0-rc.N` as the preview tag instead.
|
|
||||||
- Tags have no `v` prefix. Always annotated: `git tag -a <tag> -m "Release <tag>"`.
|
- Tags have no `v` prefix. Always annotated: `git tag -a <tag> -m "Release <tag>"`.
|
||||||
- The final tag MUST point at a commit whose ancestry is exactly
|
- The final tag MUST point at a commit whose ancestry is exactly `validated preview hash + final version-bump commit(s)`. Never tag current `main` HEAD: commits merged after the preview was validated are unvalidated.
|
||||||
`validated preview hash + final version-bump commit(s)`. Never tag current
|
- Phases run in order; a failure in any phase blocks everything after it. After the fix lands on main, restart from Phase 1 with `N+1` — do not resume mid-pipeline against a stale hash.
|
||||||
`main` HEAD: commits merged after the preview was validated are unvalidated.
|
- User-facing status updates in Chinese; commits, PR titles/bodies, and tag messages in English. No hard-wrapping in commit messages, PR bodies, or documentation prose — one logical line per sentence/paragraph, let soft wrap handle display.
|
||||||
- Phases run in order; a failure in any phase blocks everything after it.
|
|
||||||
After the fix lands on main, restart from Phase 1 with `N+1` — do not
|
|
||||||
resume mid-pipeline against a stale hash.
|
|
||||||
- User-facing status updates in Chinese; commits, PR titles/bodies, and tag
|
|
||||||
messages in English. No hard-wrapping in commit messages or PR bodies.
|
|
||||||
|
|
||||||
## Phase 0 — Preflight
|
## Phase 0 — Preflight
|
||||||
|
|
||||||
@@ -86,8 +55,7 @@ Rules:
|
|||||||
|
|
||||||
## Phase 1 — Preview version bump
|
## Phase 1 — Preview version bump
|
||||||
|
|
||||||
- Invoke the `rustfs-release-version-bump` skill with version
|
- Invoke the `rustfs-release-version-bump` skill with version `<target>-preview.N`, full GitHub flow (commit/push/PR).
|
||||||
`<target>-preview.N`, full GitHub flow (commit/push/PR).
|
|
||||||
- Get the PR merged into main. Record the resulting main commit:
|
- Get the PR merged into main. Record the resulting main commit:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -95,8 +63,7 @@ git fetch origin main
|
|||||||
PREVIEW_HASH=$(git rev-parse origin/main) # must contain the bump PR
|
PREVIEW_HASH=$(git rev-parse origin/main) # must contain the bump PR
|
||||||
```
|
```
|
||||||
|
|
||||||
`PREVIEW_HASH` is the single source of truth for the rest of the pipeline —
|
`PREVIEW_HASH` is the single source of truth for the rest of the pipeline — report it to the user and reuse it verbatim in Phases 2 and 6.
|
||||||
report it to the user and reuse it verbatim in Phases 2 and 6.
|
|
||||||
|
|
||||||
## Phase 2 — Publish the preview tag
|
## Phase 2 — Publish the preview tag
|
||||||
|
|
||||||
@@ -105,25 +72,16 @@ git tag -a "<target>-preview.N" -m "Release <target>-preview.N" "$PREVIEW_HASH"
|
|||||||
git push origin "<target>-preview.N"
|
git push origin "<target>-preview.N"
|
||||||
```
|
```
|
||||||
|
|
||||||
Pushing the tag triggers `.github/workflows/build.yml` ("Build and Release");
|
Pushing the tag triggers `.github/workflows/build.yml` ("Build and Release"); `docker.yml` chains off it via `workflow_run`.
|
||||||
`docker.yml` chains off it via `workflow_run`.
|
|
||||||
|
|
||||||
## Phase 3 — CI and artifact verification
|
## Phase 3 — CI and artifact verification
|
||||||
|
|
||||||
- Watch the tag build:
|
- Watch the tag build: `gh run list --workflow build.yml --limit 5` then `gh run watch <run-id>`. Every matrix target must succeed (linux x86_64/aarch64 × musl/gnu, macos-aarch64, windows-x86_64) plus the release and latest.json jobs.
|
||||||
`gh run list --workflow build.yml --limit 5` then `gh run watch <run-id>`.
|
- Verify the GitHub release: `gh release view "<target>-preview.N" --json isPrerelease,assets`
|
||||||
Every matrix target must succeed (linux x86_64/aarch64 × musl/gnu,
|
|
||||||
macos-aarch64, windows-x86_64) plus the release and latest.json jobs.
|
|
||||||
- Verify the GitHub release:
|
|
||||||
`gh release view "<target>-preview.N" --json isPrerelease,assets`
|
|
||||||
- `isPrerelease` must be `true`.
|
- `isPrerelease` must be `true`.
|
||||||
- Assets must include all 6 platform zips in both versioned
|
- Assets must include all 6 platform zips in both versioned (`rustfs-<platform>-v<tag>.zip`) and `-latest` forms, plus `SHA256SUMS`, `SHA512SUMS`, `rustfs-<tag>.sbom.cdx.json`, `rustfs-<tag>.provenance.json`.
|
||||||
(`rustfs-<platform>-v<tag>.zip`) and `-latest` forms, plus `SHA256SUMS`,
|
- Verify the chained Docker run succeeded: `gh run list --workflow docker.yml --limit 3`.
|
||||||
`SHA512SUMS`, `rustfs-<tag>.sbom.cdx.json`, `rustfs-<tag>.provenance.json`.
|
- Checksum spot-check for the platform you will run locally: download the zip and `SHA256SUMS`, verify with `shasum -a 256 -c` (grep to one line).
|
||||||
- Verify the chained Docker run succeeded:
|
|
||||||
`gh run list --workflow docker.yml --limit 3`.
|
|
||||||
- Checksum spot-check for the platform you will run locally: download the
|
|
||||||
zip and `SHA256SUMS`, verify with `shasum -a 256 -c` (grep to one line).
|
|
||||||
|
|
||||||
## Phase 4 — Run the artifact locally, verify the console
|
## Phase 4 — Run the artifact locally, verify the console
|
||||||
|
|
||||||
@@ -142,22 +100,15 @@ Defaults: S3 endpoint `:9000`, embedded console `:9001`.
|
|||||||
Checks (all must pass):
|
Checks (all must pass):
|
||||||
|
|
||||||
- `curl -fsS http://localhost:9000/health/ready` returns ready.
|
- `curl -fsS http://localhost:9000/health/ready` returns ready.
|
||||||
- Startup log shows the embedded console being served (this was the
|
- Startup log shows the embedded console being served (this was the regression that `fix(release): require embedded console assets` guards).
|
||||||
regression that `fix(release): require embedded console assets` guards).
|
- Open `http://localhost:9001` in the browser: login with `rustfsadmin`/`rustfsadmin`; dashboard renders without JS console errors; create a bucket, upload a file, download it back (byte-identical), delete the object and bucket. Keep the server running for Phase 5.
|
||||||
- Open `http://localhost:9001` in the browser: login with
|
|
||||||
`rustfsadmin`/`rustfsadmin`; dashboard renders without JS console errors;
|
|
||||||
create a bucket, upload a file, download it back (byte-identical), delete
|
|
||||||
the object and bucket. Keep the server running for Phase 5.
|
|
||||||
|
|
||||||
## Phase 5 — Validate with the latest rc client
|
## Phase 5 — Validate with the latest rc client
|
||||||
|
|
||||||
`rc` is the RustFS CLI client from <https://github.com/rustfs/cli>.
|
`rc` is the RustFS CLI client from <https://github.com/rustfs/cli>.
|
||||||
|
|
||||||
- Ensure the latest release is installed: compare `rc --version` against
|
- Ensure the latest release is installed: compare `rc --version` against `gh api repos/rustfs/cli/releases/latest --jq .tag_name`; update via `brew upgrade rustfs/tap/rc` (or download the release binary).
|
||||||
`gh api repos/rustfs/cli/releases/latest --jq .tag_name`; update via
|
- Point it at the preview server and run the command matrix, recording PASS/FAIL per command:
|
||||||
`brew upgrade rustfs/tap/rc` (or download the release binary).
|
|
||||||
- Point it at the preview server and run the command matrix, recording
|
|
||||||
PASS/FAIL per command:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rc alias set preview http://localhost:9000 rustfsadmin rustfsadmin
|
rc alias set preview http://localhost:9000 rustfsadmin rustfsadmin
|
||||||
@@ -178,8 +129,7 @@ rc admin user remove preview/ relcheckuser
|
|||||||
rc alias remove preview
|
rc alias remove preview
|
||||||
```
|
```
|
||||||
|
|
||||||
- Any FAIL blocks the release. Afterwards stop the server and delete the
|
- Any FAIL blocks the release. Afterwards stop the server and delete the scratch data directory.
|
||||||
scratch data directory.
|
|
||||||
|
|
||||||
## Phase 6 — Final version bump from the validated hash
|
## Phase 6 — Final version bump from the validated hash
|
||||||
|
|
||||||
@@ -187,11 +137,8 @@ rc alias remove preview
|
|||||||
git checkout -b release/<target> "$PREVIEW_HASH" # NOT origin/main
|
git checkout -b release/<target> "$PREVIEW_HASH" # NOT origin/main
|
||||||
```
|
```
|
||||||
|
|
||||||
- Invoke `rustfs-release-version-bump` with the final `<target>` on this
|
- Invoke `rustfs-release-version-bump` with the final `<target>` on this branch (commit/push/PR). Its verification gate (`make pre-commit` etc.) must pass; the PR's CI must be green before proceeding.
|
||||||
branch (commit/push/PR). Its verification gate (`make pre-commit` etc.)
|
- Do not rebase this branch onto main and do not merge main into it — that would reintroduce unvalidated commits under the final tag.
|
||||||
must pass; the PR's CI must be green before proceeding.
|
|
||||||
- Do not rebase this branch onto main and do not merge main into it —
|
|
||||||
that would reintroduce unvalidated commits under the final tag.
|
|
||||||
|
|
||||||
## Phase 7 — Publish the final tag
|
## Phase 7 — Publish the final tag
|
||||||
|
|
||||||
@@ -202,17 +149,13 @@ git tag -a "<target>" -m "Release <target>" "$FINAL_HASH"
|
|||||||
git push origin "<target>"
|
git push origin "<target>"
|
||||||
```
|
```
|
||||||
|
|
||||||
- Re-run the Phase 3 verification against the final tag (for a stable
|
- Re-run the Phase 3 verification against the final tag (for a stable target, `isPrerelease` must now be `false`).
|
||||||
target, `isPrerelease` must now be `false`).
|
- Merge the bump PR into main afterwards so main records the version. With squash-merge, main's copy of the bump differs from the tagged commit — that is expected and fine.
|
||||||
- Merge the bump PR into main afterwards so main records the version. With
|
|
||||||
squash-merge, main's copy of the bump differs from the tagged commit —
|
|
||||||
that is expected and fine.
|
|
||||||
|
|
||||||
## Output contract
|
## Output contract
|
||||||
|
|
||||||
Always report:
|
Always report:
|
||||||
|
|
||||||
- Target version, preview tag(s) used, `PREVIEW_HASH`, `FINAL_HASH`.
|
- Target version, preview tag(s) used, `PREVIEW_HASH`, `FINAL_HASH`.
|
||||||
- Per-phase result (PASS/FAIL/BLOCKED) with key evidence: CI run URLs,
|
- Per-phase result (PASS/FAIL/BLOCKED) with key evidence: CI run URLs, release URLs, console check results, the rc command matrix.
|
||||||
release URLs, console check results, the rc command matrix.
|
|
||||||
- Any deviation from this pipeline and why the user approved it.
|
- Any deviation from this pipeline and why the user approved it.
|
||||||
|
|||||||
Reference in New Issue
Block a user