From 79e2bd2f8344f9294a07c35e64343dde90ac9889 Mon Sep 17 00:00:00 2001 From: Robert M1 <50460704+githubrobbi@users.noreply.github.com> Date: Wed, 10 Jun 2026 14:10:39 -0700 Subject: [PATCH] docs(release): record publishable-set narrowing + R8 credential path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an R8-prep row to the 8.1 deviations log: cargo metadata proves the live publishable set is 2 crates (uffs-time, uffs-text), not the 12/13 cited in historical plan/baseline entries; documents the dependency- ordered bootstrap sequence (both leaves, order interchangeable) and the credential decision (CARGO_REGISTRY_TOKEN for first publish β€” trusted publishing requires the crate to already exist β€” then OIDC via the dormant R7 job and token revocation). Also refreshes the R7 dashboard row: the dormancy gate is the ENABLE_CRATES_IO_PUBLISH repo variable, not the original if:false. --- docs/architecture/release-automation-plan.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/architecture/release-automation-plan.md b/docs/architecture/release-automation-plan.md index d94dccf2b..99eee14e9 100644 --- a/docs/architecture/release-automation-plan.md +++ b/docs/architecture/release-automation-plan.md @@ -2055,7 +2055,7 @@ Single source of truth for phase progress. Mirror the format of | R4 | release-plz active (release PR mode) | 🟒 | `HEAD` | 2026-06-09 | (this PR) | Push trigger re-enabled after Polars 0.54.4 resolved the chrono conflict. Workflow now auto-triggers on every push to main, analyzes conventional commits, and opens release PRs when feat/fix/perf/security changes land. Added workflow_dispatch bridge to release.yml to handle GitHub's anti-loop policy (GITHUB_TOKEN-created tags don't trigger downstream workflows). First release through new flow will satisfy exit criterion. | | R5 | Retire bespoke tooling (incl. `scripts/ci/ci-pipeline.rs` thin wrapper per its `REMOVE-AFTER: v0.5.73` marker) | 🟒 | `HEAD` | 2026-06-09 | (this PR) | Re-applied now that Polars 0.54.4 on crates.io resolves the publishability blocker. Deleted: `build/update_all_versions.rs`, `scripts/ci/ci-pipeline.rs`, `.github/workflows/auto-tag-release.yml`, version-bump functions from `version.rs`, `STEP_VERSION_INCREMENT` from workflow. Updated: `justfile` recipes, `.gitignore` restored to blanket `build/`. Version bumps now handled entirely by release-plz when conventional commits land on `main`. | | R6 | crates.io metadata audit + dry-run CI | 🟒 | `cccf4f111` | 2026-05-07 | [#145](https://github.com/skyllc-ai/UltraFastFileSearch/pull/145) | Adds: `[package.metadata.docs.rs]` to all 12 publishable crates with appropriate `targets`/`default-target` per crate's platform surface; explicit `publish = false` to `crates/uffs-diag/Cargo.toml`; per-package `release = false` blocks for the 3 internal CI tools in `release-plz.toml`; `.github/workflows/crates-io-dry-run.yml` (advisory weekly + workflow_dispatch); `docs/publishing.md` DORMANT runbook. R6 step 6 (crate name reservations on crates.io) is intentionally **deferred** β€” those happen from a throwaway external workspace per plan Β§R6 step 6, not from this repo. | -| R7 | OIDC trusted publisher (dormant) | 🟑 | `HEAD` | 2026-06-09 | (this PR) | Scaffolding complete with `if: false` gate. Added `crates-io-publish` job with OIDC token permissions, environment protection, and placeholder steps. Dormant until R8 when trusted publishers are configured on crates.io and the job is enabled by flipping `if: false` β†’ `if: github.repository_owner == 'skyllc-ai'`. | +| R7 | OIDC trusted publisher (dormant) | 🟑 | `HEAD` | 2026-06-09 | (this PR) | Scaffolding complete. Added `crates-io-publish` job with OIDC token permissions, environment protection, and placeholder steps. Originally gated `if: false`; replaced with a repo-variable gate (`if: vars.ENABLE_CRATES_IO_PUBLISH == 'true'`) after actionlint flagged the constant-false expression. Dormant until after the R8 bootstrap: trusted publishers can only be configured on crates.io for crates that already exist, so the first publish of each crate uses a maintainer `CARGO_REGISTRY_TOKEN`; then configure trusted publishers and set the repo variable (see `R8 prep` deviation row, 2026-06-10). | | R8 | First publish dress rehearsal (`uffs-time` only) | ⬜ | | | | **External state change** β€” one crate goes live on crates.io | | R9 | Live publishing (full workspace) | ⬜ | | | | **DEFERRED** β€” explicit maintainer decision, separate plan | @@ -2084,6 +2084,7 @@ Mirror the format of | R6 β†’ R8 publishability resolution (Path A) | 2026-05-08 | Resolution of the prior `R6 β†’ R8 publishability` deviation row. Probed option (b) of the original row's resolution column ("aligning chrono with crates.io polars expectations") and found it infeasible. Probe details: dropped the polars `git/rev` pin in `crates/uffs-polars/Cargo.toml` and switched to `polars = "=0.53.0"` from crates.io. Workspace `chrono` pinned to `=0.4.41` to satisfy crates.io polars-arrow 0.53.0's `<=0.4.41` constraint. `cargo update` succeeded. But `cargo build --workspace` then hard-failed in two independent places: (1) `polars-arrow-0.53.0/src/bitmap/bitmask.rs:2` β€” `use std::simd::{LaneCount, SupportedLaneCount, …}` against current nightly (`nightly-2026-05-08`) reports "no `LaneCount` in `simd`" because the upstream `std::simd` API has moved post-0.53.0-release; (2) `polars-ops-0.53.0/src/chunked_array/strings/case.rs:79` β€” `use core::unicode::{Case_Ignorable, Cased}` reports "no `Cased` in `unicode`" and "function `Case_Ignorable` is private" against the same nightly. Both code paths are gated by `polars/nightly`, but `polars/nightly` is also pulled transitively through `polars-stream`/`polars-lazy`/`polars-expr`/`polars-plan` even when the top-level `nightly` feature is disabled in our config. Conclusion: the in-workspace polars `git/rev` pin (`1e9a63b9...`) was NOT opportunistic. It carries upstream nightly-API patches that the published 0.53.0 release lacks, and dropping it breaks the build. Path B-i abandoned. | The git-rev / published-version skew is fundamental: the same crate version (`0.53.0`) ships TWO different sets of source contents. The git rev's `polars-arrow` declares `chrono ^0.4.42`; the published `polars-arrow 0.53.0` declares `chrono <=0.4.41` β€” no chrono version satisfies both. The git rev is necessary for the workspace to build on current nightly, so it cannot be dropped. An older nightly pin would also break unrelated workspace deps (Tokio/`std::simd`/`tracing` API drift over the same window), so a Path C ("regress nightly") was rejected without probing. | Executed option (a) of the original row. Added `publish = false` to the 8 polars-tainted crates' Cargo.toml: `uffs-polars`, `uffs-mft`, `uffs-format`, `uffs-core`, `uffs-daemon`, `uffs-client`, `uffs-mcp`, `uffs-cli` (the user's table called out 6; the actual chain is 8 because `uffs-client` inherits polars via `uffs-format β†’ uffs-mft β†’ uffs-polars`, and `uffs-mcp` via `uffs-client β†’ …`). Replaced the corresponding `[[package]]` blocks in `release-plz.toml` from `changelog_path = "CHANGELOG.md"` to `release = false` so release-plz skips them entirely (no version bump computation, no `cargo package` step). The 4 polars-free crates (`uffs-time`, `uffs-text`, `uffs-security`, `uffs-broker`) remain release-eligible with their original `changelog_path` entries. Retired the `just polars` recipe (PR-internal β€” replaced with a deprecation stub in `just/test.just` that points users at `cargo update -p polars` plus a chrono-pin compat checklist) since bumping the rev now risks pulling in MORE nightly-API drift faster than upstream polars publishes patches. Removed the `just polars` line from `just/help.just`. | R6 PARTIALLY RESOLVED β€” the publishability invariant is now scoped to 4 of 12 crates. R7 (OIDC scaffolding) unaffected β€” the dormancy gate doesn't care which crates are publishable. R8 dress rehearsal still feasible on its originally-chosen leaf target (`uffs-time` is polars-free). R9 (full publish) DEFERRED until polars upstream publishes a release containing the nightly-API patches our `git/rev` carries (track via `crates-io-dry-run.yml` weekly). When that release ships: (1) flip the 8 Γ— `publish = false` to unset (or remove the line), (2) flip the 8 Γ— `release = false` back to `changelog_path = "CHANGELOG.md"` in `release-plz.toml`, (3) drop the `git/rev` pin in `uffs-polars/Cargo.toml` in favor of the new published version, (4) re-evaluate the workspace `chrono = "=0.4.41"` pin (likely loosen if polars-arrow relaxes its upper bound), (5) restore the `just polars` recipe (or replace with a `just bump-polars` that takes a version arg). `crates-io-dry-run.yml`'s ADVISORY mode comments at lines 19-39 and 245-251 reference the original deviation by old framing β€” those will be refreshed in the same future PR that re-enables the polars subtree. | | R6 β†’ R8 publishability resolution (crates.io polars 0.54) | 2026-06-09 | Final resolution of the `R6 β†’ R8 publishability` / `…resolution (Path A)` rows. Polars published `0.54.4` to crates.io (edition 2024, 2026-06-04) carrying the nightly-`std::simd` / `core::unicode` patches that the abandoned Path B-i probe found missing in published `0.53.0`, and its `polars-arrow` now accepts modern `chrono` (workspace resolves `chrono 0.4.45`). Dropped the `git`+`rev` pin in `crates/uffs-polars/Cargo.toml` β†’ plain `polars = "0.54.4"` from crates.io. Handled the 0.54 breaking changes: feature `new_streaming` β†’ `streaming`; `LazyFrame::with_new_streaming` β†’ `with_streaming`; `&ChunkedArray` no longer implements `IntoIterator` (replaced `.into_iter()` with `.iter()` at ~25 call sites in `uffs-core`/`uffs-diag`). Retired the track-upstream-main machinery: `update_polars_git()` + `STEP_UPDATE_POLARS` (`scripts/ci-pipeline`), the `just polars` HEAD-bump recipe (now a crates.io SemVer bump), and the `pola-rs/polars` `deny.toml` `allow-git` entry (zero git sources remain). `cargo check --workspace --all-targets` + `cargo clippy --workspace --all-targets` both clean. | The original blocker was the git-rev / published-version skew on `0.53.0` (git `polars-arrow` wanted `chrono ^0.4.42`, registry wanted `<=0.4.41`; and registry `0.53.0` was un-buildable on current nightly). A published `0.54.x` that both builds on nightly and accepts modern chrono removes the need for any git source, collapsing the divergence to zero. | `uffs-polars` now packages as a plain registry dependency, so `cargo package -p uffs-polars` is no longer blocked by the chrono clash. **Unblocks R5/R6/R8**: release-plz reactivation + the crates.io dry-run / `uffs-time` dress rehearsal can proceed without the polars publishability caveat. No release-workflow flips made in this change β€” gate-lift recorded here for the next release-automation pass. | | R5 re-application (post-Polars) | 2026-06-09 | R5 originally landed via PR #153 on 2026-05-08 but was rolled back same-day when the chrono conflict in `cargo package --workspace` forced release-plz deferral to `workflow_dispatch`-only (PR #157). With Polars 0.54.4 now on crates.io (see prior row), the publishability blocker is resolved and R5 can safely re-land. | The Polars git-rev / crates.io skew was the only remaining blocker preventing `cargo package` from succeeding. Once Polars 0.54.4 arrived with nightly-compatible code and modern chrono support, the path to R5 was cleared. | Re-applied R5: deleted `build/update_all_versions.rs`, `.github/workflows/auto-tag-release.yml`, `scripts/ci/ci-pipeline.rs`, version-bump functions from `version.rs`, and `STEP_VERSION_INCREMENT`. Updated justfile recipes and `.gitignore`. Dashboard R5 flips from πŸ”΄ ROLLBACK to 🟒. | R5 now 🟒. Bespoke version tooling is retired; release-plz owns all version bumps. This is the final state β€” no further rollback expected. | +| R8 prep β€” publishable set narrowed (12 β†’ 2) + credential path | 2026-06-10 | Pre-publish audit for R8 found the "12/13 publishable crates" figure used throughout this plan and `release-automation-baseline.md` (R0/R3.5/R6 entries) is no longer the live state. `cargo metadata --no-deps` (authoritative, resolves workspace inheritance) shows exactly **2** members with `publish = ANY`: `uffs-time` and `uffs-text`. All 17 others resolve to `publish = []` (false) β€” `uffs-broker`, `uffs-broker-protocol`, and `uffs-security` were flipped back to `publish.workspace = true` (= false) during the publishability deep-dive (name-squat reservations / internal-only; see `docs/refactor/crates-io-publishability-deep-dive.md` Β§7.3–7.5), and the root-manifest comment lagged behind (corrected in PR [#385](https://github.com/skyllc-ai/UltraFastFileSearch/pull/385)). | The strategic publish scrub happened incrementally across the deep-dive without a single "recount" pass; historical plan/baseline entries are point-in-time records and stay unedited per append-only discipline β€” this row is the correction of record. | **Publish sequence for R8/R9 (dependency-ordered):** both publishable crates are dependency-free leaves with zero internal deps, so the bootstrap is simply (1) `cargo publish -p uffs-time`, (2) `cargo publish -p uffs-text` (order interchangeable); dry-runs verified green for both, names available on crates.io. No other crate can join the set without first flipping its never-publish internal deps (`uffs-polars`/`uffs-security`/`uffs-format` β†’ blocking `uffs-mft` β†’ blocking `uffs-client`/`uffs-mcp`/`uffs-cli`) β€” a deliberate architecture decision, not a gap. **Credential path:** crates.io Trusted Publishing is configured per-crate in the crate's settings page and therefore requires the crate to already exist β€” no pending-publisher flow exists β€” so the **first** publish of each crate must use a maintainer `CARGO_REGISTRY_TOKEN` (manual `cargo publish` or repo secret); after bootstrap, configure the trusted publisher for both crates and flip the dormant R7 OIDC job (`vars.ENABLE_CRATES_IO_PUBLISH`), then revoke the token. | R8's dress-rehearsal target (`uffs-time` only) is unchanged and now fully unblocked. R9 "full workspace" should be re-read as "the publishable set" (currently 2 crates). | ## 9. Cross-references