Skip to content
This repository was archived by the owner on Apr 11, 2026. It is now read-only.

Commit e292d22

Browse files
z23ccclaude
andcommitted
chore: add bump-version.sh to sync all 4 version files at once
Eliminates the error-prone 4-file manual edit dance. Provides three modes: bump (scripts/bump-version.sh 0.1.27), check (--check exits 1 on drift), and show (no args). Updates flowctl-cli/Cargo.toml, .claude-plugin/flowctl-version, .claude-plugin/plugin.json, and .claude-plugin/marketplace.json in a single atomic command. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 176317e commit e292d22

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

scripts/bump-version.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env bash
2+
# bump-version.sh — single-command version bump across all 4 canonical files.
3+
#
4+
# Usage:
5+
# scripts/bump-version.sh 0.1.27 # bump to 0.1.27
6+
# scripts/bump-version.sh --check # verify all files agree
7+
# scripts/bump-version.sh # print current version
8+
#
9+
# Touches:
10+
# 1. flowctl/crates/flowctl-cli/Cargo.toml (bare semver)
11+
# 2. .claude-plugin/flowctl-version (v-prefixed)
12+
# 3. .claude-plugin/plugin.json (bare semver)
13+
# 4. .claude-plugin/marketplace.json (bare semver × 3)
14+
#
15+
# After running: commit + tag v<version> + push to trigger GitHub Release.
16+
17+
set -euo pipefail
18+
19+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
20+
cd "$ROOT"
21+
22+
CARGO="flowctl/crates/flowctl-cli/Cargo.toml"
23+
PIN=".claude-plugin/flowctl-version"
24+
PLUGIN=".claude-plugin/plugin.json"
25+
MARKET=".claude-plugin/marketplace.json"
26+
27+
# ── Read current versions ───────────────────────────────────────────
28+
current_cargo() { awk -F'"' '/^version = /{print $2; exit}' "$CARGO"; }
29+
current_pin() { tr -d ' \t\n\r' < "$PIN" | sed 's/^v//'; }
30+
current_plugin() { python3 -c 'import json,sys;print(json.load(open(sys.argv[1]))["version"])' "$PLUGIN"; }
31+
current_market() { python3 -c 'import json,sys;d=json.load(open(sys.argv[1]));print(d["version"])' "$MARKET"; }
32+
33+
print_current() {
34+
printf "%-50s %s\n" "$CARGO" "$(current_cargo)"
35+
printf "%-50s %s\n" "$PIN" "v$(current_pin)"
36+
printf "%-50s %s\n" "$PLUGIN" "$(current_plugin)"
37+
printf "%-50s %s\n" "$MARKET" "$(current_market)"
38+
}
39+
40+
# ── Check mode ──────────────────────────────────────────────────────
41+
if [ "${1:-}" = "--check" ]; then
42+
c="$(current_cargo)"; p="$(current_pin)"; pl="$(current_plugin)"; m="$(current_market)"
43+
if [ "$c" = "$p" ] && [ "$p" = "$pl" ] && [ "$pl" = "$m" ]; then
44+
echo "✓ all files agree on v$c"
45+
exit 0
46+
fi
47+
echo "✗ version drift detected:" >&2
48+
print_current >&2
49+
exit 1
50+
fi
51+
52+
# ── No args: just show ──────────────────────────────────────────────
53+
if [ $# -eq 0 ]; then
54+
print_current
55+
exit 0
56+
fi
57+
58+
# ── Bump mode ───────────────────────────────────────────────────────
59+
NEW="$1"
60+
NEW="${NEW#v}" # strip leading v if present
61+
62+
# Validate semver-ish (X.Y.Z, optionally with prerelease)
63+
if ! printf '%s' "$NEW" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.-]+)?$'; then
64+
echo "error: invalid version '$NEW' (expected X.Y.Z)" >&2
65+
exit 1
66+
fi
67+
68+
echo "bumping → v$NEW"
69+
70+
# 1. Cargo.toml — target the flowctl-cli package line only
71+
# (line starts with `version = "` near the top)
72+
python3 - "$CARGO" "$NEW" <<'PY'
73+
import re, sys
74+
path, new = sys.argv[1], sys.argv[2]
75+
src = open(path).read()
76+
# Match first `version = "..."` line (package version, not deps)
77+
src = re.sub(r'(?m)^version\s*=\s*"[^"]+"', f'version = "{new}"', src, count=1)
78+
open(path, 'w').write(src)
79+
PY
80+
81+
# 2. flowctl-version — v-prefixed
82+
printf 'v%s\n' "$NEW" > "$PIN"
83+
84+
# 3. plugin.json — update "version" field at top level
85+
python3 - "$PLUGIN" "$NEW" <<'PY'
86+
import json, sys
87+
path, new = sys.argv[1], sys.argv[2]
88+
with open(path) as f:
89+
data = json.load(f)
90+
data["version"] = new
91+
with open(path, 'w') as f:
92+
json.dump(data, f, indent=2, ensure_ascii=False)
93+
f.write('\n')
94+
PY
95+
96+
# 4. marketplace.json — update all 3 version fields
97+
python3 - "$MARKET" "$NEW" <<'PY'
98+
import json, sys
99+
path, new = sys.argv[1], sys.argv[2]
100+
with open(path) as f:
101+
data = json.load(f)
102+
data["version"] = new
103+
data["metadata"]["version"] = new
104+
for plugin in data.get("plugins", []):
105+
plugin["version"] = new
106+
with open(path, 'w') as f:
107+
json.dump(data, f, indent=2, ensure_ascii=False)
108+
f.write('\n')
109+
PY
110+
111+
echo ""
112+
echo "updated files:"
113+
print_current
114+
echo ""
115+
echo "next steps:"
116+
echo " cd flowctl && cargo build --release -p flowctl-cli # updates Cargo.lock"
117+
echo " git add -u && git commit -m \"chore: bump to v$NEW\""
118+
echo " git tag v$NEW && git push && git push --tags"

0 commit comments

Comments
 (0)