diff --git a/.github/workflows/AGENTS.md b/.github/workflows/AGENTS.md index 49cba15..50d129c 100644 --- a/.github/workflows/AGENTS.md +++ b/.github/workflows/AGENTS.md @@ -13,6 +13,10 @@ - `x86_64-apple-darwin` - `aarch64-apple-darwin` - `x86_64-pc-windows-msvc` +- Use only supported runner labels; avoid deprecated/unsupported macOS labels (for example `macos-13` if unavailable in project settings). +- Smoke-test binaries only on native runner/target pairs. +- Do not execute cross-built `linux-aarch64` artifacts on `ubuntu-latest` x86 runners; this must be skipped (exec format mismatch). +- When `x86_64-apple-darwin` is built on Apple Silicon runners, skip smoke execution unless a native Intel runner is configured. - Keep binary naming stable in packaged archives: - Unix: `clawdentity` - Windows: `clawdentity.exe` @@ -27,9 +31,10 @@ - Keep release uploads idempotent (`overwrite_files` / clobber-safe behavior) so reruns replace assets cleanly. ## Rust Crate Publish Rules -- Resolve next version from crates.io and bump both crate manifests consistently: +- Resolve next version from crates metadata using `cargo info` and bump both crate manifests consistently: - `crates/clawdentity-core/Cargo.toml` - `crates/clawdentity-cli/Cargo.toml` +- Do not call crates.io API endpoints directly from release automation; use Cargo registry/index access paths. - Keep `clawdentity-cli` dependency on `clawdentity-core` version-locked to the same release version before publish. - Publish order is strict: - first `clawdentity-core` diff --git a/.github/workflows/publish-rust.yml b/.github/workflows/publish-rust.yml index d040fd2..4fcbca8 100644 --- a/.github/workflows/publish-rust.yml +++ b/.github/workflows/publish-rust.yml @@ -47,6 +47,9 @@ jobs: with: fetch-depth: 0 + - name: Set up Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Validate required secrets env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} @@ -60,15 +63,24 @@ jobs: set -euo pipefail RELEASE_TYPE="${{ inputs.release_type }}" - STATUS_CODE="$(curl -sS -o /tmp/core-crate.json -w '%{http_code}' https://crates.io/api/v1/crates/clawdentity-core)" - if [[ "${STATUS_CODE}" == "200" ]]; then - CURRENT_VERSION="$(jq -r '.crate.max_version // empty' /tmp/core-crate.json)" - elif [[ "${STATUS_CODE}" == "404" ]]; then - CURRENT_VERSION="0.0.0" + if CARGO_TERM_COLOR=never cargo info clawdentity-core --registry crates-io >/tmp/core-info.out 2>/tmp/core-info.err; then + CURRENT_VERSION="$( + sed -E 's/\x1B\[[0-9;]*[mK]//g' /tmp/core-info.out \ + | awk -F': ' '/^version: / {print $2; exit}' + )" + if [[ -z "${CURRENT_VERSION}" ]]; then + echo "Unable to parse version from cargo info output." + cat /tmp/core-info.out + exit 1 + fi else - echo "Failed to resolve current version from crates.io (status: ${STATUS_CODE})" - cat /tmp/core-crate.json - exit 1 + if grep -Fq 'could not find `clawdentity-core`' /tmp/core-info.err; then + CURRENT_VERSION="0.0.0" + else + echo "Failed to resolve current version from crates.io registry index." + cat /tmp/core-info.err + exit 1 + fi fi if [[ ! "${CURRENT_VERSION}" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then @@ -121,15 +133,18 @@ jobs: NEXT_VERSION="${{ steps.version.outputs.next_version }}" for CRATE in clawdentity-core clawdentity-cli; do - STATUS_CODE="$(curl -s -o /dev/null -w '%{http_code}' "https://crates.io/api/v1/crates/${CRATE}/${NEXT_VERSION}")" - if [[ "${STATUS_CODE}" == "200" ]]; then + if CARGO_TERM_COLOR=never cargo info "${CRATE}@${NEXT_VERSION}" --registry crates-io >/tmp/"${CRATE}".out 2>/tmp/"${CRATE}".err; then echo "${CRATE} ${NEXT_VERSION} already exists on crates.io" exit 1 fi - if [[ "${STATUS_CODE}" != "404" ]]; then - echo "Unexpected crates.io status for ${CRATE} ${NEXT_VERSION}: ${STATUS_CODE}" - exit 1 + + if grep -Fq "could not find \`${CRATE}@${NEXT_VERSION}\`" /tmp/"${CRATE}".err; then + continue fi + + echo "Unexpected error while checking ${CRATE}@${NEXT_VERSION}." + cat /tmp/"${CRATE}".err + exit 1 done publish: @@ -218,12 +233,17 @@ jobs: SLEEP_SECONDS=10 for ((i = 1; i <= ATTEMPTS; i++)); do - STATUS_CODE="$(curl -s -o /dev/null -w '%{http_code}' "https://crates.io/api/v1/crates/clawdentity-core/${VERSION}")" - if [[ "${STATUS_CODE}" == "200" ]]; then + if CARGO_TERM_COLOR=never cargo info "clawdentity-core@${VERSION}" --registry crates-io >/tmp/core-propagation.out 2>/tmp/core-propagation.err; then echo "clawdentity-core ${VERSION} is available on crates.io" exit 0 fi + if ! grep -Fq "could not find \`clawdentity-core@${VERSION}\`" /tmp/core-propagation.err; then + echo "Unexpected error while waiting for clawdentity-core ${VERSION}." + cat /tmp/core-propagation.err + exit 1 + fi + echo "Waiting for clawdentity-core ${VERSION} propagation (${i}/${ATTEMPTS})" sleep "${SLEEP_SECONDS}" done @@ -248,26 +268,31 @@ jobs: target: x86_64-unknown-linux-gnu archive_ext: tar.gz use_cross: "false" + smoke_test: "true" - os: ubuntu-latest platform: linux-aarch64 target: aarch64-unknown-linux-gnu archive_ext: tar.gz use_cross: "true" - - os: macos-13 + smoke_test: "false" + - os: macos-14 platform: macos-x86_64 target: x86_64-apple-darwin archive_ext: tar.gz use_cross: "false" + smoke_test: "false" - os: macos-14 platform: macos-aarch64 target: aarch64-apple-darwin archive_ext: tar.gz use_cross: "false" + smoke_test: "true" - os: windows-latest platform: windows-x86_64 target: x86_64-pc-windows-msvc archive_ext: zip use_cross: "false" + smoke_test: "true" steps: - name: Checkout release tag uses: actions/checkout@v4 @@ -304,8 +329,9 @@ jobs: --target "${{ matrix.target }}" fi + # only execute smoke tests when runner architecture matches target architecture - name: Smoke test binary (Unix) - if: runner.os != 'Windows' + if: runner.os != 'Windows' && matrix.smoke_test == 'true' shell: bash run: | set -euo pipefail @@ -313,7 +339,7 @@ jobs: "${BIN}" --version - name: Smoke test binary (Windows) - if: runner.os == 'Windows' + if: runner.os == 'Windows' && matrix.smoke_test == 'true' shell: pwsh run: | $bin = "crates/target/${{ matrix.target }}/release/clawdentity-cli.exe" diff --git a/AGENTS.md b/AGENTS.md index 02624e2..6f3af76 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -82,7 +82,7 @@ Use `docs/` as system of record: ## 7) Release Automation - Keep Rust release automation in `.github/workflows/publish-rust.yml` as the single canonical path for version bump + crates.io publish + tag creation + binary release. -- Rust crate publish flow must derive next version from crates.io and keep `clawdentity-core` / `clawdentity-cli` versions aligned. +- Rust crate publish flow must derive the next version from crates metadata via `cargo info`, avoid direct crates.io API endpoint calls, verify the new `rust/vX.Y.Z` tag does not yet exist, and keep `clawdentity-core` / `clawdentity-cli` versions aligned. - Rust crate publish order is strict: publish `clawdentity-core` before `clawdentity-cli`. - Rust binary builds must use the same `rust/vX.Y.Z` tag created by the crate publish flow. - Rust binary releases must publish cross-platform assets for Windows x64, Linux x64/aarch64, and macOS x64/aarch64. diff --git a/apps/openclaw-skill/skill/AGENTS.md b/apps/openclaw-skill/skill/AGENTS.md index 78c2b80..ead4475 100644 --- a/apps/openclaw-skill/skill/AGENTS.md +++ b/apps/openclaw-skill/skill/AGENTS.md @@ -17,6 +17,12 @@ - `clawdentity skill install ...` - Keep onboarding invite prefix explicit: `clw_inv_...`. - Do not document manual registry/proxy host changes unless explicitly needed for a recovery scenario. +- Keep CLI install guidance deterministic and fallback-safe: + - primary path: `rustup` + `cargo install --locked clawdentity-cli` + - optional deterministic pin: `cargo install --locked --version clawdentity-cli` + - secondary path: direct GitHub release asset URLs with explicit platform naming (`linux-aarch64`, `linux-x86_64`, `macos-*`, `windows-x86_64`) + - treat `https://clawdentity.com/install.sh` as best-effort only; never as the only documented path + - avoid hardcoding specific release numbers in docs; use `` placeholders unless a user explicitly asks for a pinned version ## Sync Rules - When `skill/SKILL.md` or `skill/references/*` changes, regenerate and sync CLI bundle: diff --git a/apps/openclaw-skill/skill/SKILL.md b/apps/openclaw-skill/skill/SKILL.md index 23d822b..c672e63 100644 --- a/apps/openclaw-skill/skill/SKILL.md +++ b/apps/openclaw-skill/skill/SKILL.md @@ -37,19 +37,53 @@ Do not instruct deprecated command groups that are not present in the Rust CLI: This skill assumes the Rust CLI executable (`clawdentity`) is already available on `PATH`. If it is missing, install it first. -Preferred release binary flow: -- Linux/macOS: - - Download `clawdentity--linux-x86_64.tar.gz`, `clawdentity--linux-aarch64.tar.gz`, `clawdentity--macos-x86_64.tar.gz`, or `clawdentity--macos-aarch64.tar.gz` - - Extract and place `clawdentity` in a `PATH` directory -- Windows: - - Download `clawdentity--windows-x86_64.zip` - - Extract and place `clawdentity.exe` in a `PATH` directory +Use this install order: + +1. Rust + crates.io (recommended) + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +source "$HOME/.cargo/env" +cargo install --locked clawdentity-cli +clawdentity --version +``` + +Optional deterministic pin: + +```bash +cargo install --locked --version clawdentity-cli +``` + +2. Prebuilt release binary (if Rust toolchain is unavailable) +- Release URL pattern: + - `https://github.com/vrknetha/clawdentity/releases/download/rust/v/clawdentity--.tar.gz` + - `https://github.com/vrknetha/clawdentity/releases/download/rust/v/clawdentity--windows-x86_64.zip` +- Linux/macOS platforms: + - `linux-x86_64` + - `linux-aarch64` + - `macos-x86_64` + - `macos-aarch64` + +Linux `aarch64` example (`0.1.1`): + +```bash +version="" +asset="clawdentity-${version}-linux-aarch64.tar.gz" +url="https://github.com/vrknetha/clawdentity/releases/download/rust/v${version}/${asset}" + +mkdir -p "$HOME/bin" /tmp/clawdentity-bin +curl -fL "$url" -o "/tmp/${asset}" +tar -xzf "/tmp/${asset}" -C /tmp/clawdentity-bin +install -m 0755 /tmp/clawdentity-bin/clawdentity "$HOME/bin/clawdentity" +export PATH="$HOME/bin:$PATH" +clawdentity --version +``` PowerShell example (Windows download/install via `irm`): ```powershell -$tag = "rust/vX.Y.Z" -$version = "X.Y.Z" +$version = "" +$tag = "rust/v$version" $asset = "clawdentity-$version-windows-x86_64.zip" $url = "https://github.com/vrknetha/clawdentity/releases/download/$tag/$asset" @@ -59,11 +93,9 @@ New-Item -ItemType Directory -Force -Path "$HOME\\bin" | Out-Null Move-Item ".\\clawdentity-bin\\clawdentity.exe" "$HOME\\bin\\clawdentity.exe" -Force ``` -Cargo fallback (if prebuilt binary is unavailable): - -```bash -cargo install --locked clawdentity-cli -``` +3. Optional installer shortcut (best effort) +- `https://clawdentity.com/install.sh` +- If this returns CDN/proxy errors (for example HTTP 522), do not block onboarding. Use option 1 or 2 above. ## Tool Execution Contract (Agent) diff --git a/crates/clawdentity-cli/Cargo.toml b/crates/clawdentity-cli/Cargo.toml index bb44ac7..849dd7b 100644 --- a/crates/clawdentity-cli/Cargo.toml +++ b/crates/clawdentity-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawdentity-cli" -version = "0.1.0" +version = "0.1.1" edition.workspace = true license.workspace = true repository.workspace = true @@ -10,7 +10,7 @@ readme = "../../README.md" [dependencies] anyhow.workspace = true clap.workspace = true -clawdentity-core = { version = "0.1.0", path = "../clawdentity-core" } +clawdentity-core = { version = "0.1.1", path = "../clawdentity-core" } reqwest = { version = "0.12.24", default-features = false, features = ["json", "rustls-tls"] } serde_json.workspace = true tokio = { version = "1.49.0", features = ["macros", "rt-multi-thread", "signal"] } diff --git a/crates/clawdentity-core/Cargo.toml b/crates/clawdentity-core/Cargo.toml index e47e7fb..fb53c8a 100644 --- a/crates/clawdentity-core/Cargo.toml +++ b/crates/clawdentity-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clawdentity-core" -version = "0.1.0" +version = "0.1.1" edition.workspace = true license.workspace = true repository.workspace = true diff --git a/docs/HARNESS_ACTION_PLAN.md b/docs/HARNESS_ACTION_PLAN.md index 7692d9f..4b85973 100644 --- a/docs/HARNESS_ACTION_PLAN.md +++ b/docs/HARNESS_ACTION_PLAN.md @@ -159,6 +159,7 @@ tmux new-session -d -s codex-fix -c ../clawdentity-wt-fix/crates 4. **Next week:** Phase 4 (agent-to-agent review) 5. **Next week:** Phase 5 (garbage collection crons) 6. **Ongoing:** Phase 6 (parallel worktrees as needed) +7. **Release practice:** Keep `.github/workflows/publish-rust.yml` as the single source for Rust release automation, derive versions using `cargo info` metadata (not direct crates.io API calls), and verify duplicate tag creation before publishing. ## Success Metrics