mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-13 22:03:13 -06:00
The published API reference (frontend/api-docs.html renders docs/openapi.yaml through Redoc) said version 1.9.0 while 1.9.25 was shipping. bump-version.sh updates VERSION, server/package.json, android versionName/versionCode and tizen/config.xml — the spec was simply never added to it, so it had been frozen since the public API landed and integrators were reading a version identity that no longer existed. Spec changes: - info.version -> 1.9.25. - Device gains its two network addresses, which are easy to confuse and are now described so they cannot be: ip_address is the PUBLIC/WAN address the server observed on connect (X-Forwarded-For aware, normally shared by every device at a site), local_ip is the device's OWN LAN address as reported by the player, which is the one that reaches a panel on site. local_ip is new; both were returned by GET /devices and neither was documented. - Device gains its flattened latest-telemetry block (wifi_ssid, wifi_rssi, battery, storage, ram, cpu_usage, uptime_seconds) — all returned already, none documented, all nullable because a web player does not report what Android does. - wifi_ssid's "permission" value is called out as a sentinel, not a network name: Android 10+ withholds the SSID without a location permission ScreenTinker only requests if an operator opts in. An integrator who does not know that renders "permission" to an end user as their Wi-Fi name. Drift prevention, because a wrong version number is silent and nobody re-reads one they trust: - bump-version.sh now writes the spec version too, anchored to info.version (operation- and schema-level version keys are indented deeper and untouched; openapi: 3.1.0 is unaffected). - Three contract tests: the spec version tracks package.json, the two addresses stay documented and distinct, and the SSID sentinel stays explained. No new endpoints — audited every public router's routes against the spec and all are documented. 830 server tests + the 5 contract tests green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
100 lines
5.5 KiB
Bash
Executable file
100 lines
5.5 KiB
Bash
Executable file
#!/bin/bash
|
|
# Bump the ScreenTinker version across every source of truth in one commit + tag.
|
|
#
|
|
# scripts/bump-version.sh major|minor|patch|X.Y.Z
|
|
#
|
|
# Updates (and commits together): VERSION (root, the value the server reads at
|
|
# runtime), server/package.json + package-lock.json, android versionName
|
|
# (+versionCode by 1), tizen/config.xml widget version. Then creates an annotated
|
|
# tag vX.Y.Z. Does NOT push - prints the push command, so a release fires
|
|
# deliberately (pushing the tag is what triggers the release workflow).
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
# Require a clean tree so the version commit can't sweep up unrelated changes.
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo "ERROR: working tree is dirty - commit or stash before bumping." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Pre-push fast-forward guard. This script creates an annotated tag locally; if
|
|
# origin/main has advanced past the commit we're bumping from, `git push origin main`
|
|
# is rejected as a non-fast-forward - and if the tag gets pushed anyway it fires the
|
|
# release workflow from a commit that isn't even on main (the beta9 divergence
|
|
# incident). Catch the divergence HERE, before the tag exists, so nothing can fire.
|
|
# Best-effort: when the fetch can't run (offline), warn and proceed rather than block
|
|
# a local bump - the push itself is still the backstop.
|
|
if git fetch --quiet origin main 2>/dev/null; then
|
|
if ! git merge-base --is-ancestor FETCH_HEAD HEAD; then
|
|
echo "ERROR: origin/main ($(git rev-parse --short FETCH_HEAD)) has commits not in your" >&2
|
|
echo " HEAD ($(git rev-parse --short HEAD)) - 'git push origin main' would be rejected." >&2
|
|
echo " Merge origin/main into your branch first, then re-run the bump." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "WARNING: could not fetch origin/main - skipping the fast-forward check (offline?)." >&2
|
|
echo " Confirm 'git push origin main' will fast-forward before pushing the tag." >&2
|
|
fi
|
|
|
|
CURRENT="$(cat VERSION)"
|
|
IFS=. read -r MAJ MIN PAT <<< "$CURRENT"
|
|
|
|
case "${1:-}" in
|
|
major) NEW="$((MAJ + 1)).0.0" ;;
|
|
minor) NEW="${MAJ}.$((MIN + 1)).0" ;;
|
|
patch) NEW="${MAJ}.${MIN}.$((PAT + 1))" ;;
|
|
[0-9]*.[0-9]*.[0-9]*) NEW="$1" ;;
|
|
*) echo "usage: $0 major|minor|patch|X.Y.Z (current: $CURRENT)" >&2; exit 1 ;;
|
|
esac
|
|
echo "Bumping $CURRENT -> $NEW"
|
|
|
|
# 1) VERSION (source of truth)
|
|
printf '%s\n' "$NEW" > VERSION
|
|
|
|
# 2) server/package.json version + lockfile (only the top-level "version" key;
|
|
# dependency entries are "name": "^x.y.z" and won't match "version": "x.y.z").
|
|
# The [^"]* tail also matches a pre-release CURRENT value (e.g. 1.9.1-beta1) so a
|
|
# beta1->beta2 bump replaces it instead of silently no-op'ing (issue: stale package.json).
|
|
sed -i -E "s/(\"version\"[[:space:]]*:[[:space:]]*)\"[0-9]+\.[0-9]+\.[0-9]+[^\"]*\"/\1\"$NEW\"/" server/package.json
|
|
( cd server && npm install --package-lock-only >/dev/null )
|
|
|
|
# 3) android versionName + versionCode (+1). Since #168 both are env-overridable, so the
|
|
# build.gradle.kts values live as FALLBACK literals inside `?: "…"` at the end of each line
|
|
# (versionName = getenv(...) ?: prop ?: "1.9.4"; versionCode = (getenv(...) ?: … ?: "44").toInt()).
|
|
# Target that trailing `?: "literal"` (the LAST quoted token on the line) rather than the old
|
|
# `versionName = "X"` / `versionCode = N` forms, which no longer exist. [0-9][^"]* matches a
|
|
# pre-release current value too (e.g. 1.9.1-beta1) so beta1->beta2 replaces it.
|
|
sed -i -E "s/(versionName.*\?:[[:space:]]*)\"[0-9][^\"]*\"/\1\"$NEW\"/" android/app/build.gradle.kts
|
|
CODE="$(grep -E 'versionCode' android/app/build.gradle.kts | grep -oE '\?:[[:space:]]*\"[0-9]+\"' | grep -oE '[0-9]+' | tail -1)"
|
|
sed -i -E "s/(versionCode.*\?:[[:space:]]*)\"[0-9]+\"/\1\"$((CODE + 1))\"/" android/app/build.gradle.kts
|
|
|
|
# 4) tizen widget version. Skip the <?xml ...?> declaration line - its
|
|
# version="1.0" is the XML FORMAT version, not the app version, and it also
|
|
# has a leading space before version= so the guard below would otherwise hit
|
|
# it (issue #77). The leading-space guard still excludes tizen:application
|
|
# required_version="..." (that's "...d_version", no preceding space).
|
|
# #80: Tizen requires a strictly-numeric x.y.z widget version, so a pre-release
|
|
# suffix (e.g. 1.9.0-rc1) is invalid and the .wgt fails to sign/install. Strip
|
|
# the suffix for config.xml only - the full VERSION (with -rc1/-beta.N) still
|
|
# drives the server/Android/package.json version.
|
|
NUMERIC="${NEW%%-*}"
|
|
sed -i -E "/^<\?xml/! s/([[:space:]]version=\")[0-9][^\"]*(\")/\1${NUMERIC}\2/" tizen/config.xml
|
|
|
|
# 5) public API spec version. This is the number Redoc prints at the top of the published
|
|
# API reference (frontend/api-docs.html renders docs/openapi.yaml directly), so leaving it
|
|
# behind means customers read a version that has not existed for months — it had drifted to
|
|
# 1.9.0 while shipping 1.9.25 precisely because this step did not exist. Anchored to the
|
|
# two-space ` version:` under `info:`; operation-level and schema-level keys are indented
|
|
# deeper and are not touched. As with Tizen, use the numeric form: the spec version is a
|
|
# published API identity, not a build label.
|
|
sed -i -E "0,/^ version:/s/^( version:[[:space:]]*).*/\1${NUMERIC}/" docs/openapi.yaml
|
|
|
|
# 6) commit + annotated tag (no push)
|
|
git add VERSION server/package.json server/package-lock.json android/app/build.gradle.kts tizen/config.xml docs/openapi.yaml
|
|
git commit -q -m "chore(release): v$NEW"
|
|
git tag -a "v$NEW" -m "ScreenTinker v$NEW"
|
|
|
|
echo
|
|
echo "Committed + tagged v$NEW (nothing pushed). To release:"
|
|
echo " git push origin main && git push origin v$NEW"
|