Skip to content

Commit 726a0d7

Browse files
authored
release: adopt package.json semver as canonical version (#208)
1 parent bd43dcb commit 726a0d7

15 files changed

Lines changed: 377 additions & 192 deletions

.github/workflows/release-on-main.yml

Lines changed: 131 additions & 182 deletions
Large diffs are not rendered by default.

CONFIGURATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ Broker mode also emits best-effort context usage telemetry in inbox pull `meta`
174174

175175
### Release Updater / Rollback (CLI env overrides)
176176

177+
Baudbot release versioning is driven by the root `package.json.version`. Runtime and release metadata record both semver and git SHA, while on-disk release snapshots remain SHA-addressed. Semver tags are published manually via the **Release on main** GitHub Actions workflow.
178+
177179
These are **command-time overrides** for `baudbot update` / `baudbot rollback` (or the underlying scripts). They are not required in `~/.config/.env`.
178180

179181
| Variable | Description | Default |

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ See [SECURITY.md](SECURITY.md) for full threat model, trust boundaries, and know
171171
- [docs/linux-runtime.md](docs/linux-runtime.md) — Linux execution model, tools, and constraints
172172
- [docs/operations.md](docs/operations.md) — day-2 operations (start/stop/update/rollback/audit)
173173
- [docs/architecture.md](docs/architecture.md) — source/runtime/release architecture
174+
- [docs/releases.md](docs/releases.md) — semver policy and manual release workflow
174175
- [CONFIGURATION.md](CONFIGURATION.md) — full env var reference
175176
- [SECURITY.md](SECURITY.md) — deep security model and vulnerability reporting
176177
- [CONTRIBUTING.md](CONTRIBUTING.md) — contribution workflow

bin/baudbot

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ if [ -f "$RUNTIME_NODE_HELPER" ]; then
3535
source "$RUNTIME_NODE_HELPER"
3636
fi
3737

38+
JSON_COMMON_HELPER="$BAUDBOT_ROOT/bin/lib/json-common.sh"
39+
if [ -f "$JSON_COMMON_HELPER" ]; then
40+
# shellcheck source=bin/lib/json-common.sh
41+
source "$JSON_COMMON_HELPER"
42+
fi
43+
44+
VERSION_COMMON_HELPER="$BAUDBOT_ROOT/bin/lib/version-common.sh"
45+
if [ -f "$VERSION_COMMON_HELPER" ]; then
46+
# shellcheck source=bin/lib/version-common.sh
47+
source "$VERSION_COMMON_HELPER"
48+
fi
49+
3850
json_get_string_or_empty() {
3951
local file="$1"
4052
local key="$2"
@@ -63,6 +75,13 @@ else
6375
fi
6476

6577
version() {
78+
if [ -n "${VERSION_COMMON_HELPER:-}" ] && [ -f "$VERSION_COMMON_HELPER" ]; then
79+
bb_package_version_or_unknown "$BAUDBOT_ROOT"
80+
return 0
81+
fi
82+
83+
# Fallback for partially copied/degraded installations where the shared
84+
# version helper is missing but package.json is still present.
6685
local package_json="$BAUDBOT_ROOT/package.json"
6786
local pkg_version=""
6887

bin/deploy.sh

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ source "$SCRIPT_DIR/lib/json-common.sh"
2828
source "$SCRIPT_DIR/lib/deploy-common.sh"
2929
# shellcheck source=bin/lib/runtime-node.sh
3030
source "$SCRIPT_DIR/lib/runtime-node.sh"
31+
# shellcheck source=bin/lib/version-common.sh
32+
source "$SCRIPT_DIR/lib/version-common.sh"
3133
bb_enable_strict_mode
3234
bb_init_paths
3335

@@ -422,25 +424,39 @@ if [ "$DRY_RUN" -eq 0 ]; then
422424
GIT_SHA=""
423425
GIT_SHA_SHORT=""
424426
GIT_BRANCH=""
427+
RELEASE_VERSION=""
428+
RELEASE_TAG=""
425429

426430
if (cd "$BAUDBOT_SRC" && git rev-parse HEAD >/dev/null 2>&1); then
427431
GIT_SHA=$(cd "$BAUDBOT_SRC" && git rev-parse HEAD 2>/dev/null || echo "unknown")
428432
GIT_SHA_SHORT=$(cd "$BAUDBOT_SRC" && git rev-parse --short HEAD 2>/dev/null || echo "unknown")
429433
GIT_BRANCH=$(cd "$BAUDBOT_SRC" && git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
434+
RELEASE_VERSION="$(bb_package_version_or_unknown "$BAUDBOT_SRC")"
435+
if [ "$RELEASE_VERSION" != "unknown" ]; then
436+
RELEASE_TAG="$(bb_release_tag_for_version "$RELEASE_VERSION")"
437+
fi
430438
elif [ -f "$RELEASE_META_FILE" ]; then
431439
GIT_SHA="$(json_get_string_or_empty "$RELEASE_META_FILE" "sha")"
432440
GIT_SHA_SHORT="$(json_get_string_or_empty "$RELEASE_META_FILE" "short")"
433441
GIT_BRANCH="$(json_get_string_or_empty "$RELEASE_META_FILE" "branch")"
442+
RELEASE_VERSION="$(json_get_string_or_empty "$RELEASE_META_FILE" "version")"
443+
RELEASE_TAG="$(json_get_string_or_empty "$RELEASE_META_FILE" "tag")"
434444
fi
435445

436446
[ -n "$GIT_SHA" ] || GIT_SHA="unknown"
437447
[ -n "$GIT_SHA_SHORT" ] || GIT_SHA_SHORT="unknown"
438448
[ -n "$GIT_BRANCH" ] || GIT_BRANCH="unknown"
449+
[ -n "$RELEASE_VERSION" ] || RELEASE_VERSION="unknown"
450+
if [ -z "$RELEASE_TAG" ] && [ "$RELEASE_VERSION" != "unknown" ]; then
451+
RELEASE_TAG="$(bb_release_tag_for_version "$RELEASE_VERSION")"
452+
fi
439453
DEPLOY_TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
440454

441455
# Write version file via agent
442456
as_agent bash -c "cat > '$VERSION_FILE'" <<VEOF
443457
{
458+
"version": "$RELEASE_VERSION",
459+
"tag": "$RELEASE_TAG",
444460
"sha": "$GIT_SHA",
445461
"short": "$GIT_SHA_SHORT",
446462
"branch": "$GIT_BRANCH",
@@ -449,7 +465,7 @@ if [ "$DRY_RUN" -eq 0 ]; then
449465
}
450466
VEOF
451467
as_agent chmod 644 "$VERSION_FILE"
452-
log "✓ baudbot-version.json ($GIT_SHA_SHORT @ $GIT_BRANCH)"
468+
log "✓ baudbot-version.json ($RELEASE_VERSION, $GIT_SHA_SHORT @ $GIT_BRANCH)"
453469

454470
# Generate sha256 manifest of all deployed files (excluding node_modules)
455471
# Agent reads its own files to compute hashes

bin/lib/baudbot-runtime.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@ has_systemd() {
1313
print_deployed_version() {
1414
local agent_user="${BAUDBOT_AGENT_USER:-baudbot_agent}"
1515
local version_file="/home/$agent_user/.pi/agent/baudbot-version.json"
16+
local version=""
17+
local tag=""
1618
local short=""
1719
local sha=""
1820
local branch=""
1921
local deployed_at=""
2022
local line=""
2123

2224
if [ -r "$version_file" ]; then
25+
version="$(json_get_string_or_empty "$version_file" "version")"
26+
tag="$(json_get_string_or_empty "$version_file" "tag")"
2327
short="$(json_get_string_or_empty "$version_file" "short")"
2428
sha="$(json_get_string_or_empty "$version_file" "sha")"
2529
branch="$(json_get_string_or_empty "$version_file" "branch")"
@@ -28,21 +32,23 @@ print_deployed_version() {
2832
local version_json=""
2933
version_json="$(sudo -u "$agent_user" sh -c "cat '$version_file' 2>/dev/null" || true)"
3034
if [ -n "$version_json" ]; then
35+
version="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "version" 2>/dev/null || true)"
36+
tag="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "tag" 2>/dev/null || true)"
3137
short="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "short" 2>/dev/null || true)"
3238
sha="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "sha" 2>/dev/null || true)"
3339
branch="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "branch" 2>/dev/null || true)"
3440
deployed_at="$(printf '%s' "$version_json" | json_get_string_stdin_or_empty "deployed_at" 2>/dev/null || true)"
3541
fi
3642
fi
3743

38-
if [ -z "$short" ] && [ -z "$sha" ] && [ -z "$branch" ] && [ -z "$deployed_at" ]; then
44+
if [ -z "$version" ] && [ -z "$short" ] && [ -z "$sha" ] && [ -z "$branch" ] && [ -z "$deployed_at" ]; then
3945
local release_target=""
4046
local release_sha=""
4147

4248
release_target="$(readlink -f /opt/baudbot/current 2>/dev/null || true)"
4349
if printf '%s\n' "$release_target" | grep -Eq '/releases/[0-9a-f]{7,40}$'; then
4450
release_sha="${release_target##*/}"
45-
echo -e "${BOLD}deployed version:${RESET} ${release_sha:0:7} sha: $release_sha (from /opt/baudbot/current)"
51+
echo -e "${BOLD}deployed version:${RESET} unknown (${release_sha:0:7}) sha: $release_sha (from /opt/baudbot/current)"
4652
else
4753
echo -e "${BOLD}deployed version:${RESET} unavailable"
4854
fi
@@ -53,8 +59,10 @@ print_deployed_version() {
5359
short="${sha:0:7}"
5460
fi
5561

56-
line="${short:-unknown}"
57-
[ -n "$branch" ] && line="$line (branch: $branch)"
62+
line="${version:-unknown}"
63+
[ -n "$short" ] && line="$line ($short)"
64+
[ -n "$tag" ] && line="$line tag: $tag"
65+
[ -n "$branch" ] && line="$line branch: $branch"
5866
[ -n "$deployed_at" ] && line="$line deployed: $deployed_at"
5967
[ -n "$sha" ] && line="$line sha: $sha"
6068

bin/lib/release-runtime-common.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ bb_verify_deployed_release_sha() {
5959

6060
local version_file="$BAUDBOT_AGENT_HOME/.pi/agent/baudbot-version.json"
6161
local deployed_sha
62+
local deployed_version
6263

6364
deployed_sha="$(sudo -u "$BAUDBOT_AGENT_USER" sh -c "cat '$version_file' 2>/dev/null" | json_get_string_stdin "sha" 2>/dev/null || true)"
65+
deployed_version="$(sudo -u "$BAUDBOT_AGENT_USER" sh -c "cat '$version_file' 2>/dev/null" | json_get_string_stdin "version" 2>/dev/null || true)"
6466

6567
if [ -z "$deployed_sha" ]; then
6668
die "deployed version file missing or unreadable: $version_file"
@@ -71,6 +73,10 @@ bb_verify_deployed_release_sha() {
7173
fi
7274

7375
if [ -n "$verified_label" ]; then
74-
log "deployed version verified: $verified_label"
76+
if [ -n "$deployed_version" ]; then
77+
log "deployed version verified: $deployed_version ($verified_label)"
78+
else
79+
log "deployed version verified: $verified_label"
80+
fi
7581
fi
7682
}

bin/lib/version-common.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
# Shared version helpers for Baudbot shell scripts.
3+
# Prerequisite: callers must source bin/lib/json-common.sh before this file.
4+
5+
bb_package_json_path() {
6+
local root="${1:?repo root required}"
7+
echo "$root/package.json"
8+
}
9+
10+
bb_package_lock_json_path() {
11+
local root="${1:?repo root required}"
12+
echo "$root/package-lock.json"
13+
}
14+
15+
bb_package_version() {
16+
local root="${1:?repo root required}"
17+
local package_json=""
18+
19+
package_json="$(bb_package_json_path "$root")"
20+
[ -r "$package_json" ] || return 1
21+
if ! command -v json_get_string >/dev/null 2>&1; then
22+
echo "json_get_string unavailable; source bin/lib/json-common.sh before version-common.sh" >&2
23+
return 1
24+
fi
25+
26+
json_get_string "$package_json" "version"
27+
}
28+
29+
bb_package_version_or_unknown() {
30+
local root="${1:?repo root required}"
31+
bb_package_version "$root" 2>/dev/null || echo "unknown"
32+
}
33+
34+
bb_release_tag_for_version() {
35+
local version="${1:?version required}"
36+
echo "v$version"
37+
}

bin/lib/version-common.test.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
# Tests for bin/lib/version-common.sh
3+
4+
set -euo pipefail
5+
6+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7+
# shellcheck source=bin/lib/json-common.sh
8+
source "$SCRIPT_DIR/json-common.sh"
9+
# shellcheck source=bin/lib/version-common.sh
10+
source "$SCRIPT_DIR/version-common.sh"
11+
12+
TOTAL=0
13+
PASSED=0
14+
FAILED=0
15+
16+
run_test() {
17+
local name="$1"
18+
shift
19+
local out
20+
21+
TOTAL=$((TOTAL + 1))
22+
printf " %-45s " "$name"
23+
24+
out="$(mktemp /tmp/baudbot-version-common-test-output.XXXXXX)"
25+
if "$@" >"$out" 2>&1; then
26+
echo ""
27+
PASSED=$((PASSED + 1))
28+
else
29+
echo "✗ FAILED"
30+
tail -40 "$out" | sed 's/^/ /'
31+
FAILED=$((FAILED + 1))
32+
fi
33+
rm -f "$out"
34+
}
35+
36+
test_reads_package_version() {
37+
(
38+
set -euo pipefail
39+
local tmp
40+
tmp="$(mktemp -d /tmp/baudbot-version-common.XXXXXX)"
41+
trap 'rm -rf "$tmp"' EXIT
42+
43+
printf '{"version":"1.2.3"}\n' > "$tmp/package.json"
44+
[ "$(bb_package_version "$tmp")" = "1.2.3" ]
45+
)
46+
}
47+
48+
test_formats_release_tag() {
49+
(
50+
set -euo pipefail
51+
[ "$(bb_release_tag_for_version "2.3.4")" = "v2.3.4" ]
52+
)
53+
}
54+
55+
echo "=== version-common tests ==="
56+
echo ""
57+
58+
run_test "reads package.json version" test_reads_package_version
59+
run_test "formats release tag" test_formats_release_tag
60+
61+
echo ""
62+
echo "=== $PASSED/$TOTAL passed, $FAILED failed ==="
63+
64+
if [ "$FAILED" -gt 0 ]; then
65+
exit 1
66+
fi

bin/test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ run_shell_tests() {
106106
run "doctor lib helpers" bash bin/lib/doctor-common.test.sh
107107
run "update release flow" bash bin/update-release.test.sh
108108
run "rollback release" bash bin/rollback-release.test.sh
109+
run "version common" bash bin/lib/version-common.test.sh
109110
echo ""
110111
}
111112

0 commit comments

Comments
 (0)