Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

All notable changes to the Toolpath workspace are documented here.

## path-cli 0.5.0 + toolpath-cli 0.5.1
## path-cli 0.5.0 + toolpath-cli 0.5.1 + workspace re-alignment

### path-cli 0.5.0 (new crate name)

Expand All @@ -14,6 +14,10 @@ All notable changes to the Toolpath workspace are documented here.
- `toolpath-cli` is now a tiny shim crate whose only job is to make `cargo install toolpath-cli` keep working — it depends on `path-cli` and ships the same `path` binary. Existing users see no behavioral change on upgrade. The shim will be retired in a future release; pin to `path-cli` directly to avoid the eventual removal.
- The dev-only `gen_synthetic_path` helper is no longer shipped from this crate; it lives in `path-cli` only.

### toolpath-dot 0.1.3, toolpath-md 0.2.1, toolpath-git 0.1.4, toolpath-github 0.2.1 (publish re-alignment)

Patch bumps with no source changes. These four satellite crates were last released when `toolpath` was at 0.1.5, so their on-registry manifests still pin `toolpath = "0.1.5"`. Without these bumps, publishing any new crate (like `path-cli`) that depends on both `toolpath = "0.2.0"` and one of these four would drag two majors of `toolpath` into cargo's publish-time resolution and fail with E0308 type mismatches between `toolpath::types::Document` and `toolpath::v1::Document`. Each crate still uses `toolpath = { workspace = true }`, so the new published versions automatically pick up the workspace's current `toolpath = "0.2.0"` and the skew is closed.

## toolpath-claude 0.8.0 + toolpath-gemini 0.2.0 + toolpath-pi 0.2.0

### toolpath-claude 0.8.0
Expand Down
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ license = "Apache-2.0"
[workspace.dependencies]
toolpath = { version = "0.2.0", path = "crates/toolpath" }
toolpath-convo = { version = "0.7.0", path = "crates/toolpath-convo" }
toolpath-git = { version = "0.1.3", path = "crates/toolpath-git" }
toolpath-git = { version = "0.1.4", path = "crates/toolpath-git" }
toolpath-claude = { version = "0.8.0", path = "crates/toolpath-claude", default-features = false }
toolpath-gemini = { version = "0.2.0", path = "crates/toolpath-gemini", default-features = false }
toolpath-codex = { version = "0.1.0", path = "crates/toolpath-codex" }
toolpath-opencode = { version = "0.1.0", path = "crates/toolpath-opencode" }
toolpath-github = { version = "0.2.0", path = "crates/toolpath-github" }
toolpath-dot = { version = "0.1.2", path = "crates/toolpath-dot" }
toolpath-md = { version = "0.2.0", path = "crates/toolpath-md" }
toolpath-github = { version = "0.2.1", path = "crates/toolpath-github" }
toolpath-dot = { version = "0.1.3", path = "crates/toolpath-dot" }
toolpath-md = { version = "0.2.1", path = "crates/toolpath-md" }
toolpath-pi = { version = "0.2.0", path = "crates/toolpath-pi" }
path-cli = { version = "0.5.0", path = "crates/path-cli" }

Expand Down
2 changes: 1 addition & 1 deletion crates/toolpath-dot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "toolpath-dot"
version = "0.1.2"
version = "0.1.3"
edition.workspace = true
license.workspace = true
repository = "https://github.com/empathic/toolpath"
Expand Down
2 changes: 1 addition & 1 deletion crates/toolpath-git/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "toolpath-git"
version = "0.1.3"
version = "0.1.4"
edition.workspace = true
license.workspace = true
repository = "https://github.com/empathic/toolpath"
Expand Down
2 changes: 1 addition & 1 deletion crates/toolpath-github/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "toolpath-github"
version = "0.2.0"
version = "0.2.1"
edition.workspace = true
license.workspace = true
repository = "https://github.com/empathic/toolpath"
Expand Down
2 changes: 1 addition & 1 deletion crates/toolpath-md/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "toolpath-md"
version = "0.2.0"
version = "0.2.1"
edition.workspace = true
license.workspace = true
repository = "https://github.com/empathic/toolpath"
Expand Down
127 changes: 101 additions & 26 deletions scripts/release.sh
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail

# Publish all workspace crates to crates.io in dependency order.
# Verify (default) or publish (--execute) all workspace crates to crates.io
# in dependency order.
#
# Default mode is a dry run — it packages each crate, runs `cargo publish
# --dry-run` against the real crates.io view, and reports what *would*
# happen. Nothing is uploaded. This catches publish-time resolution issues
# (e.g. deps pinning incompatible major versions of a shared crate) that
# `cargo build/test --workspace` cannot see, because workspace builds use
# local path-deps while `cargo publish` resolves against the registry.
#
# Pass --execute to actually publish.
#
# Usage:
# scripts/release.sh # publish for real (prompts for confirmation)
# scripts/release.sh --dry-run # verify packaging without uploading
# scripts/release.sh --yes # skip confirmation prompt
# scripts/release.sh # dry-run (default; safe)
# scripts/release.sh --execute # publish for real (prompts)
# scripts/release.sh --execute --yes # publish for real, skip prompt
# scripts/release.sh --dry-run # alias for default (back-compat)
#
# Dependency order:
# 1. toolpath (no workspace deps)
Expand All @@ -25,29 +36,38 @@ set -euo pipefail

ALL_CRATES=(toolpath toolpath-convo toolpath-git toolpath-github toolpath-dot toolpath-md toolpath-claude toolpath-gemini toolpath-codex toolpath-opencode toolpath-pi path-cli toolpath-cli)

DRY_RUN=""
EXECUTE=0
AUTO_YES=""
for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN="--dry-run" ;;
--yes|-y) AUTO_YES=1 ;;
*) echo "unknown argument: $arg"; exit 1 ;;
--execute) EXECUTE=1 ;;
--dry-run) ;; # back-compat: dry-run is the default
--yes|-y) AUTO_YES=1 ;;
-h|--help)
sed -n '4,28p' "$0" | sed 's/^# \{0,1\}//'
exit 0
;;
*) echo "unknown argument: $arg"; echo "see --help"; exit 1 ;;
esac
done

if [[ -n "$DRY_RUN" ]]; then
echo "=== DRY RUN ==="
echo
if (( EXECUTE )); then
DRY_RUN=""
echo "=== mode: EXECUTE — will publish to crates.io ==="
else
DRY_RUN="--dry-run"
echo "=== mode: dry-run (pass --execute to publish for real) ==="
fi
echo

ALLOW_DIRTY=""
if [[ -n "$(git status --porcelain 2>/dev/null)" ]]; then
if [[ -n "$DRY_RUN" ]]; then
ALLOW_DIRTY="--allow-dirty"
else
if (( EXECUTE )); then
echo "error: working directory has uncommitted changes"
echo "commit or stash before publishing"
exit 1
else
ALLOW_DIRTY="--allow-dirty"
fi
fi

Expand Down Expand Up @@ -82,7 +102,7 @@ already_published() {
wait_for_index() {
local crate="$1"
local version="$2"
if [[ -n "$DRY_RUN" ]]; then
if ! (( EXECUTE )); then
return
fi
echo " waiting for $crate $version to appear on crates.io index..."
Expand All @@ -97,7 +117,7 @@ wait_for_index() {
}

# --- Survey: check what needs publishing ---
# Uses parallel indexed arrays instead of associative arrays (bash 3.2 compat)
# Uses parallel indexed arrays instead of associative arrays (bash 3.2 compat).

echo "=== surveying crates ==="

Expand All @@ -109,10 +129,7 @@ for i in "${!ALL_CRATES[@]}"; do
crate="${ALL_CRATES[$i]}"
version=$(get_version "$crate")
VERSIONS+=("$version")
if [[ -n "$DRY_RUN" ]]; then
STATUSES+=("publish")
TO_PUBLISH+=("$crate")
elif already_published "$crate" "$version"; then
if already_published "$crate" "$version"; then
STATUSES+=("skip")
else
STATUSES+=("publish")
Expand Down Expand Up @@ -141,9 +158,9 @@ for i in "${!ALL_CRATES[@]}"; do
done
echo

# --- Confirmation ---
# --- Confirmation (only when actually publishing) ---

if [[ -z "$DRY_RUN" && -z "$AUTO_YES" ]]; then
if (( EXECUTE )) && [[ -z "$AUTO_YES" ]]; then
read -rp "proceed? [y/N] " answer
if [[ "$answer" != "y" && "$answer" != "Y" ]]; then
echo "aborted."
Expand All @@ -152,15 +169,73 @@ if [[ -z "$DRY_RUN" && -z "$AUTO_YES" ]]; then
echo
fi

# --- Pre-flight: run tests and clippy ---
# --- Pre-flight: workspace tests and clippy ---

echo "=== pre-flight checks ==="
cargo test --workspace --quiet
cargo clippy --workspace --quiet -- -D warnings
cargo doc --workspace --no-deps --quiet
echo "all checks passed"
echo "workspace checks ok"
echo

# --- Pre-flight: per-crate publish dry-run ---
#
# Workspace `cargo build/test` resolve every dep through local path entries,
# bypassing crates.io entirely. `cargo publish --dry-run` resolves against
# the registry — exactly the view that matters at publish time. This loop
# catches issues like "satellite-crate-A on crates.io still pins old toolpath,
# while we depend directly on a newer toolpath" before any real upload.
#
# Failures classed as chicken-and-egg (the failing dep is itself in this
# release's TO_PUBLISH set, so it'll land on the registry mid-publish) are
# tolerated; everything else aborts.

echo "=== publish dry-runs ==="
PREFLIGHT_FAILED=()
for crate in "${TO_PUBLISH[@]}"; do
logfile=$(mktemp -t release-dryrun.XXXXXX)
rc=0
if [[ "$crate" == "toolpath-cli" ]]; then
(cd crates/toolpath-cli && cargo publish --dry-run $ALLOW_DIRTY) > "$logfile" 2>&1 || rc=$?
else
cargo publish --dry-run $ALLOW_DIRTY -p "$crate" > "$logfile" 2>&1 || rc=$?
fi
if (( rc == 0 )); then
echo " $crate: ok"
else
# Cargo phrases "dep not on registry yet" several ways depending on
# context. Try each known shape; whichever produces a match wins.
missing=$(sed -nE \
-e 's/.*no matching package named `([^`]+)`.*/\1/p' \
-e 's/.*failed to select a version for the requirement `([^ `]+).*/\1/p' \
-e 's/.*could not find `([^`]+)` in registry.*/\1/p' \
"$logfile" | head -1)
if [[ -n "$missing" ]] && printf '%s\n' "${TO_PUBLISH[@]}" | grep -qFx "$missing"; then
echo " $crate: deferred (depends on $missing being published in this run)"
else
echo " $crate: FAILED"
tail -40 "$logfile" | sed 's/^/ /'
PREFLIGHT_FAILED+=("$crate")
fi
fi
rm -f "$logfile"
done
if (( ${#PREFLIGHT_FAILED[@]} > 0 )); then
echo
echo "publish dry-run failed for: ${PREFLIGHT_FAILED[*]}"
echo "aborting before any real publishing happens."
exit 1
fi
echo "publish dry-runs ok"
echo

# In dry-run mode (the default), the dry-run pre-flight above is the whole
# point of the script. Stop here.
if ! (( EXECUTE )); then
echo "=== dry-run done — pass --execute to publish ==="
exit 0
fi

# --- Helpers to look up survey results ---

crate_index() {
Expand Down Expand Up @@ -201,9 +276,9 @@ publish() {
echo "--- publishing $crate $version ---"
if [[ "$crate" == "toolpath-cli" ]]; then
# Excluded from the workspace; publish from its own manifest.
(cd crates/toolpath-cli && cargo publish $DRY_RUN $ALLOW_DIRTY)
(cd crates/toolpath-cli && cargo publish $ALLOW_DIRTY)
else
cargo publish -p "$crate" $DRY_RUN $ALLOW_DIRTY
cargo publish -p "$crate" $ALLOW_DIRTY
fi
echo
}
Expand Down
8 changes: 4 additions & 4 deletions site/_data/crates.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
},
{
"name": "toolpath-git",
"version": "0.1.3",
"version": "0.1.4",
"description": "Derive from git repository history",
"docs": "https://docs.rs/toolpath-git",
"crate": "https://crates.io/crates/toolpath-git",
"role": "Reads git history via libgit2 and maps commits to Steps, branches to Paths. Single branch produces a Path; multiple branches produce a Graph."
},
{
"name": "toolpath-github",
"version": "0.2.0",
"version": "0.2.1",
"description": "Derive from GitHub pull requests",
"docs": "https://docs.rs/toolpath-github",
"crate": "https://crates.io/crates/toolpath-github",
Expand Down Expand Up @@ -73,15 +73,15 @@
},
{
"name": "toolpath-dot",
"version": "0.1.2",
"version": "0.1.3",
"description": "Graphviz DOT visualization",
"docs": "https://docs.rs/toolpath-dot",
"crate": "https://crates.io/crates/toolpath-dot",
"role": "Renders any Toolpath Document as a Graphviz diagram. Steps are color-coded by actor type, dead ends get red dashed borders, and the DAG structure is preserved visually."
},
{
"name": "toolpath-md",
"version": "0.2.0",
"version": "0.2.1",
"description": "Markdown rendering for LLM consumption",
"docs": "https://docs.rs/toolpath-md",
"crate": "https://crates.io/crates/toolpath-md",
Expand Down
Loading