Release version management: single VERSION file as source of truth
- VERSION at repo root (0.1.2); bump it to cut a release - App: generated AppVersion.kt (config-cache-safe Gradle task with VERSION as declared input) shown in Settings; sent to the gateway via X-Iris-App-Version header on the SSE open - Gateway: reports its own version in hello.ack server_caps.app_version (read from the repo-root VERSION via the plugin symlink); stores the app's version in the device registry caps (merge, not overwrite, so an old app reconnecting without the header doesn't wipe it) - Settings: app + gateway version rows, mismatch hint, and a best-effort Gitea latest-release check (ReleaseCheck) with an 'update available' hint - Release workflow: reads VERSION from the repo (no manual input), with a guard against an empty file - Docs: frames.schema.json + 04-wire-protocol.md updated for app_version
This commit is contained in:
1 parent
f3f1b37221
commit
fb980d12b4
17 files changed
+422
-37
No files matched your search
+48
-20
@@ -100,11 +100,13 @@ jobs:
|
||||
|
||||
## 3. NEW FILE: `.gitea/workflows/release.yml`
|
||||
|
||||
Manual trigger: **repo → Actions → Release → Run workflow**, enter a
|
||||
`version` (e.g. `0.2.0`) and a `changelog`. It runs the same tests as CI,
|
||||
builds a signed Android APK + AAB and the Linux desktop packages (jpackage,
|
||||
JRE bundled), then creates the Gitea release `v<version>` with all artifacts
|
||||
as download attachments.
|
||||
The release version is the repo-root **`VERSION` file** (single source of
|
||||
truth — "everything from here on out is vX.Y.Z" = bump `VERSION` and
|
||||
commit). Manual trigger: **repo → Actions → Release → Run workflow**,
|
||||
optionally with a `changelog`. It runs the same tests as CI, builds a signed
|
||||
Android APK + AAB and the Linux desktop packages (jpackage, JRE bundled),
|
||||
then creates the Gitea release `v<VERSION>` with all artifacts as download
|
||||
attachments.
|
||||
|
||||
Note: builds + release creation happen in ONE job because Gitea/act_runner
|
||||
does not implement the GitHub artifacts API (`upload-artifact@v4+` fails
|
||||
@@ -116,12 +118,10 @@ name: Release
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Release version (e.g. 0.2.0)"
|
||||
required: true
|
||||
type: string
|
||||
# The release version comes from the repo-root VERSION file (the single
|
||||
# source of truth) — bump it in a commit, then dispatch this workflow.
|
||||
changelog:
|
||||
description: "Release notes (markdown, shown on the release page)"
|
||||
description: "Release notes (markdown, shown on the release page). Single-line field — use literal \\n for line breaks."
|
||||
required: false
|
||||
type: string
|
||||
|
||||
@@ -246,7 +246,8 @@ jobs:
|
||||
|
||||
- name: Build APK + AAB
|
||||
run: |
|
||||
VERSION=$(jq -r '.inputs.version' "$GITHUB_EVENT_PATH")
|
||||
VERSION=$(cat "$GITHUB_WORKSPACE/VERSION")
|
||||
[ -n "$VERSION" ] || { echo "::error::VERSION file is missing or empty"; exit 1; }
|
||||
cd app
|
||||
if [ -n "$ANDROID_KEYSTORE_FILE" ]; then
|
||||
# APK for direct sideloading, AAB for Play Store uploads.
|
||||
@@ -268,7 +269,8 @@ jobs:
|
||||
# for it (jpackage picks the native type: msi on Windows, dmg on macOS).
|
||||
- name: Build desktop app-image + deb
|
||||
run: |
|
||||
VERSION=$(jq -r '.inputs.version' "$GITHUB_EVENT_PATH")
|
||||
VERSION=$(cat "$GITHUB_WORKSPACE/VERSION")
|
||||
[ -n "$VERSION" ] || { echo "::error::VERSION file is missing or empty"; exit 1; }
|
||||
cd app
|
||||
# Self-contained app image (JRE bundled via jlink).
|
||||
./gradlew :desktopApp:jpackage -PappVersion="$VERSION"
|
||||
@@ -290,20 +292,39 @@ jobs:
|
||||
SERVER="${GITEA_SERVER_URL:-$GITHUB_SERVER_URL}"
|
||||
REPO="${GITEA_REPOSITORY:-$GITHUB_REPOSITORY}"
|
||||
TOKEN="${RELEASE_TOKEN:-$GITHUB_TOKEN}"
|
||||
VERSION=$(jq -r '.inputs.version' "$GITHUB_EVENT_PATH")
|
||||
CHANGELOG=$(jq -r '.inputs.changelog // ""' "$GITHUB_EVENT_PATH")
|
||||
VERSION=$(cat "$GITHUB_WORKSPACE/VERSION")
|
||||
# The dispatch input is a single-line field; turn literal \n into real newlines.
|
||||
CHANGELOG=$(jq -r '.inputs.changelog // ""' "$GITHUB_EVENT_PATH" | sed 's/\\n/\n/g')
|
||||
TAG="v$VERSION"
|
||||
API="$SERVER/api/v1/repos/$REPO"
|
||||
AUTH="Authorization: token $TOKEN"
|
||||
|
||||
# Re-run safety: drop a previous release (and its tag) for this version.
|
||||
OLD_ID=$(curl -sf -H "$AUTH" "$API/releases/tags/$TAG" | jq -r '.id // empty')
|
||||
# curl wrapper: on HTTP >= 400, print the response body (Gitea's error
|
||||
# message) before failing — plain `curl -f` hides it (exit 22).
|
||||
api() {
|
||||
local code body
|
||||
body=$(mktemp)
|
||||
code=$(curl -s -o "$body" -w '%{http_code}' "$@") || { cat "$body"; rm -f "$body"; return 1; }
|
||||
if [ "${code:0:1}" != "2" ]; then
|
||||
echo "API error $code: $(cat "$body")" >&2
|
||||
rm -f "$body"
|
||||
return 1
|
||||
fi
|
||||
cat "$body"
|
||||
rm -f "$body"
|
||||
}
|
||||
|
||||
# Re-run safety: drop a previous release AND its tag for this version.
|
||||
# (Gitea's DELETE /releases/:id does NOT remove the tag; a leftover tag
|
||||
# makes the POST below fail with 409.)
|
||||
OLD_ID=$(api -H "$AUTH" "$API/releases/tags/$TAG" | jq -r '.id // empty') || true
|
||||
if [ -n "$OLD_ID" ]; then
|
||||
curl -sf -X DELETE -H "$AUTH" "$API/releases/$OLD_ID" > /dev/null
|
||||
api -X DELETE -H "$AUTH" "$API/releases/$OLD_ID" > /dev/null
|
||||
fi
|
||||
api -X DELETE -H "$AUTH" "$API/tags/$TAG" > /dev/null || true
|
||||
|
||||
# Gitea creates the tag at the default branch HEAD automatically.
|
||||
RELEASE_ID=$(curl -sf -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
||||
RELEASE_ID=$(api -X POST -H "$AUTH" -H "Content-Type: application/json" \
|
||||
"$API/releases" \
|
||||
-d "$(jq -n --arg tag "$TAG" --arg title "Iris $VERSION" --arg body "$CHANGELOG" \
|
||||
'{tag_name:$tag, title:$title, body:$body}')" \
|
||||
@@ -313,15 +334,22 @@ jobs:
|
||||
for f in "$GITHUB_WORKSPACE"/iris-android-v* "$GITHUB_WORKSPACE"/iris-desktop-*; do
|
||||
[ -f "$f" ] || continue
|
||||
echo "Uploading $(basename "$f")"
|
||||
curl -sf -X POST -H "$AUTH" -F "attachment=@$f" \
|
||||
"$API/releases/$RELEASE_ID/attachments" > /dev/null
|
||||
# Forgejo-style API: release assets live under /assets, not /attachments.
|
||||
api -X POST -H "$AUTH" -F "attachment=@$f" \
|
||||
"$API/releases/$RELEASE_ID/assets" > /dev/null
|
||||
done
|
||||
echo "Done: $SERVER/$REPO/releases/tag/$TAG"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. EDITS to existing Gradle files
|
||||
|
||||
> **Note (versioning):** the `versionName` / `appVersion` lines shown below
|
||||
> have since been changed to read the repo-root **`VERSION` file** (single
|
||||
> source of truth; `-PappVersion` still overrides in CI). See
|
||||
> `.gitea/workflows/release.yml` and `gateway-plugin/version.py`.
|
||||
|
||||
### 4a. `app/androidApp/build.gradle.kts`
|
||||
|
||||
**Change 1** — in `defaultConfig`, replace:
|
||||
|
||||
Reference in new issue
Block a user