From 7da76687872401a2c110151dc57ed77a936b383d Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 2 Sep 2026 19:23:42 +0200 Subject: [PATCH] fix(release): write package.json and pyproject.toml versions correctly The single-quoted bash string passed to sed -i prevented FRONT_VERSION from being interpolated, so the file content was being silently rewritten to the literal text "${FRONT_VERSION}". Likewise the double-quoted sed for pyproject.toml would silently do nothing if the [project] section was absent while still printing a misleading 'updated' success line. Replace both with python: json.load/dump for package.json (so the JSON remains well-formed and 2-space-indented), and a regex section-aware edit for pyproject.toml that exits non-zero with a warning if no `version = "..."` line is found, so the success message only prints when something actually changed. --- Docker/release.sh | 77 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/Docker/release.sh b/Docker/release.sh index 3f1347c..4834c8b 100644 --- a/Docker/release.sh +++ b/Docker/release.sh @@ -85,7 +85,20 @@ echo "Version file updated → ${VERSION_FILE}" FRONT_VERSION="${NEW_TAG#v}" FRONT_PKG="${SCRIPT_DIR}/../package.json" if [[ -f "${FRONT_PKG}" ]]; then - sed -i "s/\"version\": \"[^\"]*\"/\"version\": \"${FRONT_VERSION}\"/" "${FRONT_PKG}" + # Use a python one-liner for portable, safe JSON editing. The previous + # `sed -i` used single-quoted bash strings, which prevented + # ${FRONT_VERSION} from being interpolated and silently rewrote the file + # to the literal string "${FRONT_VERSION}". + python3 - "$FRONT_PKG" "$FRONT_VERSION" <<'PY' +import json, sys +path, new_version = sys.argv[1], sys.argv[2] +with open(path, encoding="utf-8") as fh: + data = json.load(fh) +data["version"] = new_version +with open(path, "w", encoding="utf-8") as fh: + json.dump(data, fh, indent=2) + fh.write("\n") +PY echo "package.json version updated → ${FRONT_VERSION}" else echo "Warning: package.json not found, skipping package.json version sync" >&2 @@ -94,13 +107,63 @@ fi # Keep root pyproject.toml in sync. BACKEND_PYPROJECT="${SCRIPT_DIR}/../pyproject.toml" if [[ -f "${BACKEND_PYPROJECT}" ]]; then - # Update version under [project] section if present - if grep -q '^\[project\]' "${BACKEND_PYPROJECT}"; then - sed -i "/^\[project\]/,/^\[/ s/^version = \".*\"/version = \"${FRONT_VERSION}\"/" "${BACKEND_PYPROJECT}" - else - sed -i "s/^version = \".*\"/version = \"${FRONT_VERSION}\"/" "${BACKEND_PYPROJECT}" + # Use python instead of sed: the previous `sed -i` used double-quoted + # patterns whose `&` and `\` characters would have to be escaped, and + # more importantly it could silently do nothing if the [project] section + # was missing. python reads/writes the file as a string, preserving + # the existing format, and reports whether anything changed. + if FRONT_VERSION="$FRONT_VERSION" BACKEND_PYPROJECT="$BACKEND_PYPROJECT" python3 <<'PY' +import os, re, sys + +path = os.environ["BACKEND_PYPROJECT"] +new_version = os.environ["FRONT_VERSION"] +with open(path, encoding="utf-8") as fh: + text = fh.read() + +# If there is a [project] table, update only the `version = "..."` line +# inside it; otherwise update the first top-level `version = "..."` line. +project_match = re.search(r"^\[project\]\s*$", text, re.MULTILINE) +if project_match: + start = project_match.end() + end = re.search(r"^\[", text[start:], re.MULTILINE) + section_end = start + end.start() if end else len(text) + section = text[start:section_end] + new_section, n = re.subn( + r'^version = ".*"$', + f'version = "{new_version}"', + section, + count=1, + flags=re.MULTILINE, + ) + if n == 0: + print( + f"Warning: no `version = ...` line found under [project] in {path}", + file=sys.stderr, + ) + sys.exit(2) + text = text[:start] + new_section + text[section_end:] +else: + new_text, n = re.subn( + r'^version = ".*"$', + f'version = "{new_version}"', + text, + count=1, + flags=re.MULTILINE, + ) + if n == 0: + print( + f"Warning: no `version = ...` line found in {path}", + file=sys.stderr, + ) + sys.exit(2) + text = new_text + +with open(path, "w", encoding="utf-8") as fh: + fh.write(text) +PY + then + echo "pyproject.toml version updated → ${FRONT_VERSION}" fi - echo "pyproject.toml version updated → ${FRONT_VERSION}" else echo "Warning: pyproject.toml not found, skipping pyproject.toml version sync" >&2 fi