Skip to content

bump-version.sh silently skips package.json when versions drift (package.json stuck at 0.29.16 since v0.29.17) #375

@jpelaez-23blocks

Description

@jpelaez-23blocks

Summary

scripts/bump-version.sh silently no-ops on package.json whenever its current version doesn't match version.json. Because the helper that updates auxiliary files uses a grep -q pre-check, the script gives a "✓ Updated N files" success report while skipping package.json entirely. Every bump since the initial drift has compounded the gap.

Current state on main (a0ede7e)

File Version
version.json 0.35.31
package.json 0.29.16

PM2's process list shows 0.29.16 because PM2 reads version from package.json at process start. The drift is real, not a display artifact.

$ grep '"version"' package.json | head -1
  "version": "0.29.16",
$ cat version.json | grep version
  "version": "0.35.31",

package.json's version field has not been updated since commit df6a2fc (v0.29.17, Apr 2026). The last 15+ release tags (0.30.x → 0.35.31) ship with package.json frozen.

Root cause

scripts/bump-version.sh lines 100–113:

update_file() {
    local file="$1"
    local pattern="$2"
    local replacement="$3"
    local description="$4"

    if [ -f "$file" ]; then
        if grep -q "$pattern" "$file" 2>/dev/null; then     # ← silently skips on miss
            _sed_inplace "$file" "s|$pattern|$replacement|g"
            echo -e "  ${GREEN}${NC} $description"
            FILES_UPDATED=$((FILES_UPDATED + 1))
        fi
    fi
}

Called for package.json at lines 125–128 with pattern = "\"version\": \"$CURRENT_VERSION\"". CURRENT_VERSION is read from version.json. If package.json has already drifted, the grep -q fails, the sed never runs, and no warning is printed. The success report (Updated N files) still claims success.

A botched rebase around v0.29.17/0.29.18 set the initial drift; every bump since has silently preserved it.

Why it matters

  • npm/yarn/PM2/Docker introspection all read package.json — they report stale versions.
  • Anyone running npm publish or building OCI images tags artifacts with the wrong version.
  • Operators following the documented Pull/Build/Restart workflow have no signal that package.json is broken — the script reports success.

CLAUDE.md explicitly documents package.json as one of the files the script "updates ALL version references across":

This script updates ALL version references across the codebase:

  • version.json (source of truth)
  • package.json

So behavior diverges from documented contract.

Suggested fix

For canonical version sources that must track version.json regardless of drift (package.json at minimum), force-replace using a regex matching any current version, and log the previous value so drift is visible:

force_set_version() {
    local file="$1"
    local pattern="$2"        # extended regex matching any current version
    local replacement="$3"    # literal replacement
    local description="$4"

    if [ -f "$file" ] && grep -Eq "$pattern" "$file" 2>/dev/null; then
        local old; old=$(grep -Eo "$pattern" "$file" | head -1)
        _sed_inplace "$file" -E "s|$pattern|$replacement|g"
        if [ "$old" != "$replacement" ]; then
            echo -e "  ${GREEN}${NC} $description ${YELLOW}(was: $old)${NC}"
        else
            echo -e "  ${GREEN}${NC} $description"
        fi
        FILES_UPDATED=$((FILES_UPDATED + 1))
    fi
}

# Replace the package.json call with:
force_set_version "$PROJECT_ROOT/package.json" \
    '"version": "[0-9]+\.[0-9]+\.[0-9]+"' \
    "\"version\": \"$NEW_VERSION\"" \
    "package.json"

Optional hardening: at the top of the script, read package.json's version and warn loudly when it disagrees with version.json before bumping. That way drift never compounds silently again.

Also bump package.json directly in the same fix PR to 0.35.31 (or whatever current is at merge) so the next bump starts from a synced baseline.

Repro

git clone https://github.com/23blocks-OS/ai-maestro.git
cd ai-maestro
./scripts/bump-version.sh patch     # reports success
grep '"version"' package.json       # still 0.29.16, untouched

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions