diff --git a/.github/release-allowed-signers b/.github/release-allowed-signers new file mode 100644 index 00000000..500e102b --- /dev/null +++ b/.github/release-allowed-signers @@ -0,0 +1 @@ +steipete@gmail.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII9XsaCcr8TInPnHcuTVfvXXcsoUFrOE7menfbEIHFW9 steipete@gmail.com diff --git a/.github/workflows/release-unified.yml b/.github/workflows/release-unified.yml index 520e6a14..4fa0f7d4 100644 --- a/.github/workflows/release-unified.yml +++ b/.github/workflows/release-unified.yml @@ -35,6 +35,7 @@ jobs: nfpm: auto build-runner: macos stable-identifier: org.openclaw.gitcrawl + require-signed-tag: true darwin-universal: disabled ci-check-events: '["push","pull_request"]' secrets: diff --git a/CHANGELOG.md b/CHANGELOG.md index 31bd98c7..a8cea9f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,17 @@ ## Unreleased -- Update CrawlKit to v0.17.3 so SQLite lock waits honor context deadlines, with SQLite 3.54.1 and the matching runtime dependency. -- Keep the cloud snapshot privacy regression compatible with SQLite 3.53 and 3.54 by explicitly preserving nested JSON arrays across subqueries. +## 0.17.0 - 2026-10-23 + +**Highlights:** Smaller portable-store updates with split archives, inspectable cluster-candidate generations, and SQLite reliability fixes. -- Update the pinned TruffleHog secret-scanning action to v3.99.3. Thanks @dependabot. -- Request `synchronous=FULL` on every SQLite connection and, on macOS, `fullfsync` for commits and checkpoints. Go test binaries skip the macOS full flush. -- Let the native code producer publish from a captured upstream commit when core progress is fresh, even while provider coverage is incomplete. Retries and coverage are not changed. - Add `portable export --compression split`, which publishes the uncompressed portable database as verified 32 MiB parts so Git stores each new generation as a small delta instead of a new 68 MB gzip blob. Refresh, init, status and recovery read split stores; older readers refuse them and keep their last good mirror. After advancing to a split generation, strict refresh geometrically repacks recent objects so subscribers also keep each generation as a delta, skipping a loose backlog of more than 512 objects. Raw and gzip stores are still never repacked. - Record every accepted native cluster run's complete computed partition as an immutable, run-scoped `gitcrawl.cluster-candidates.v3` generation, with observed overlaps to durable groups, and select it atomically. Quarantined candidates are visible in this domain without changing durable IDs or their history. Add `cluster-candidates` (also in the native reader) and `--rollback`. +- Let the native code producer publish from a captured upstream commit when core progress is fresh, even while provider coverage is incomplete. Retries and coverage are not changed. +- Request `synchronous=FULL` on every SQLite connection and, on macOS, `fullfsync` for commits and checkpoints. Go test binaries skip the macOS full flush. +- Update CrawlKit to v0.17.3 so SQLite lock waits honor context deadlines, with SQLite 3.54.1 and the matching runtime dependency. +- Keep the cloud snapshot privacy regression compatible with SQLite 3.53 and 3.54 by explicitly preserving nested JSON arrays across subqueries. +- Update the pinned TruffleHog secret-scanning action to v3.99.3. Thanks @dependabot. ## 0.16.0 - 2026-10-20 diff --git a/docs/releasing.md b/docs/releasing.md index a7d68739..636962d3 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -5,7 +5,7 @@ permalink: /releasing/ # Releasing Gitcrawl -`.github/workflows/release-unified.yml` is the only official release path. It calls `openclaw/release-workflows@v1` from protected `main`, creates and owns the immutable annotated version tag, preserves Gitcrawl's six thin platform archives and `checksums.txt`, signs and notarizes both macOS binaries as `org.openclaw.gitcrawl`, verifies the complete asset inventory independently on arm64 and Intel macOS, and waits for `openclaw/homebrew-tap` to update successfully. +`.github/workflows/release-unified.yml` is the only official release path. It calls `openclaw/release-workflows@v1` from protected `main`, verifies the immutable fleet-signed annotated version tag, preserves Gitcrawl's six thin platform archives and `checksums.txt`, signs and notarizes both macOS binaries as `org.openclaw.gitcrawl`, verifies the complete asset inventory independently on arm64 and Intel macOS, and waits for `openclaw/homebrew-tap` to update successfully. The public compatibility contract remains: @@ -21,13 +21,23 @@ Official builds run on macOS. CI uses the Apple Silicon `xcode-27` runner, with ## Release -Prepare a dated changelog section, land it on protected `main`, and dispatch the workflow: +Prepare a dated changelog section while retaining an empty `Unreleased` section, land it on protected `main`, and require green CI at that exact commit. First dispatch a dry run and require it to pass: ```sh -gh workflow run release-unified.yml --repo openclaw/gitcrawl -f version=X.Y.Z +gh workflow run release-unified.yml --repo openclaw/gitcrawl --ref main -f version=X.Y.Z -f dry_run=true ``` -The first run freezes the exact protected `main` head with an immutable annotated tag. Retries reuse that tag and target commit. Tagging, signing, notarization, and Homebrew delivery use only GitHub Actions and repository or organization secrets; maintainers need no local release credentials. +After the dry run, sign an annotated `vX.Y.Z` tag at that verified commit using only the fleet release SSH key. Verify it against `.github/release-allowed-signers` before pushing; never move or replace an existing tag: + +```sh +set -e +git -c gpg.format=ssh -c user.signingkey=/secure/path/to/fleet-release-key tag -s vX.Y.Z VERIFIED_COMMIT -m "Release vX.Y.Z" +git -c gpg.format=ssh -c gpg.ssh.allowedSignersFile=.github/release-allowed-signers verify-tag vX.Y.Z +git push origin vX.Y.Z +gh workflow run release-unified.yml --repo openclaw/gitcrawl --ref main -f version=X.Y.Z -f dry_run=false +``` + +The live workflow verifies the tag signature and freezes that exact tagged commit. Retries reuse the same tag and target commit. Artifact signing, notarization, and Homebrew delivery use only GitHub Actions and repository or organization secrets; local artifact publishing remains disabled. The release is complete only when the GitHub Release contains the full asset set, both native macOS verification jobs pass, and the Homebrew handoff is green. diff --git a/scripts/test-release.sh b/scripts/test-release.sh index 15c3d93b..382dd5c2 100755 --- a/scripts/test-release.sh +++ b/scripts/test-release.sh @@ -238,14 +238,11 @@ grep -F 'checksum-filename: checksums.txt' "$release_workflow" >/dev/null grep -F 'archive-files: '\''["CHANGELOG.md","LICENSE","README.md"]'\''' "$release_workflow" >/dev/null grep -F 'stable-identifier: org.openclaw.gitcrawl' "$release_workflow" >/dev/null grep -F 'darwin-universal: disabled' "$release_workflow" >/dev/null -if grep -F 'require-signed-tag:' "$release_workflow" >/dev/null; then - echo "unified release must own the annotated tag" >&2 - exit 1 -fi -if [[ -e "$ROOT/.github/release-allowed-signers" ]]; then - echo "unified release must not require a local tag-signing allowlist" >&2 - exit 1 -fi +grep -F 'require-signed-tag: true' "$release_workflow" >/dev/null +signers="$ROOT/.github/release-allowed-signers" +[[ -s "$signers" && ! -L "$signers" ]] +ssh-keygen -lf <(cut -d ' ' -f 2- "$signers") | + grep -F 'SHA256:WmI9lVtd7F2c5XyRHbZVO3yYYJzwsSNzcZQMPT147HI' >/dev/null if grep -R -F 'NOTARYTOOL_KEYCHAIN_PROFILE' "$ROOT/.github/workflows" >/dev/null; then echo "notary profile must not be configured in GitHub Actions" >&2 exit 1