diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2d476e9..770cc70 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -68,24 +68,25 @@ jobs: echo "prev=$PREV" >> "$GITHUB_OUTPUT" echo "Releasing ${GITHUB_REF_NAME} (version $(cat VERSION)); previous tag: ${PREV:-}" - - name: Build source tarball + - name: Build Tizen .wgt (unsigned in CI) + run: | + chmod +x tizen/build-wgt.sh + ( cd tizen && ./build-wgt.sh ) # no Tizen CLI on the runner => unsigned zip + cp tizen/ScreenTinker.wgt ScreenTinker.wgt + ls -la ScreenTinker.wgt + + - name: Build source tarball (bundles the .wgt; the signed apk is added by scripts/finalize-release.sh) run: | OUT="screentinker-${{ steps.ver.outputs.version }}.tar.gz" tar czf "$OUT" \ --exclude='node_modules' --exclude='.git' --exclude='.github' \ --exclude='*.db' --exclude='*.db-wal' --exclude='*.db-shm' --exclude='*.db.*' \ --exclude='server/uploads' --exclude='server/certs' --exclude='server/test' \ - --exclude='*.apk' --exclude='*.wgt' \ - server frontend scripts VERSION README.md LICENSE .env.example + --exclude='*.apk' \ + server frontend scripts VERSION README.md LICENSE .env.example ScreenTinker.wgt echo "TARBALL=$OUT" >> "$GITHUB_ENV" ls -la "$OUT" - - name: Build Tizen .wgt (unsigned in CI) - run: | - chmod +x tizen/build-wgt.sh - ( cd tizen && ./build-wgt.sh ) # no Tizen CLI on the runner => unsigned zip - ls -la tizen/ScreenTinker.wgt - - name: Generate release notes run: | PREV="${{ steps.ver.outputs.prev }}" @@ -101,12 +102,13 @@ jobs: fi echo echo "### Artifacts" - echo "- \`${TARBALL}\` - server + frontend source tarball (Node 20; see the README to run)." + echo "- \`${TARBALL}\` - bundle: server + frontend source + the Tizen .wgt (the signed Android APK is added at the root during release finalization)." echo "- \`ScreenTinker.wgt\` - Tizen TV web app, **unsigned - for inspection only**." echo " Sign it with your own Samsung certificate (Tizen Studio + a profile that includes" echo " your TV's DUID) to install, or - easiest - point a Tizen TV browser / URL Launcher" echo " at \`https:///player\` (no signing needed)." echo "- Docker image: \`ghcr.io/screentinker/screentinker:${{ steps.ver.outputs.version }}\` (also \`:latest\`)." + echo "- \`ScreenTinker.apk\` - signed Android player (attached during release finalization)." } > RELEASE_NOTES.md cat RELEASE_NOTES.md diff --git a/.gitignore b/.gitignore index f2631d4..4138c8f 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,8 @@ android/local.properties android/release-key.jks *.apk *.aab +*.wgt +*.tar.gz # IDE / Editor .claude/ diff --git a/scripts/finalize-release.sh b/scripts/finalize-release.sh new file mode 100755 index 0000000..eef0bce --- /dev/null +++ b/scripts/finalize-release.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Finalize a release with the artifacts that need the LOCAL signing keystore +# (which never goes into CI). After the release workflow has published the tag's +# GitHub Release (source tarball + unsigned .wgt + docker image), run this to: +# 1. build the SIGNED Android APK locally, +# 2. pull the CI-built unsigned .wgt back down from the release, +# 3. assemble a COMPLETE source tarball that bundles BOTH binaries +# (extract it and ScreenTinker.apk sits at the root, ready for /download/apk), +# 4. upload the APK + the complete tarball to the release (replacing the +# source-only tarball CI uploaded). +# +# KEYSTORE_PASSWORD=... KEY_PASSWORD=... scripts/finalize-release.sh +# +# Requires: Android SDK + the release keystore (android/release-key.jks), the +# Tizen .wgt already on the release, and an authenticated gh CLI. +set -euo pipefail +cd "$(dirname "$0")/.." +VERSION="$(cat VERSION)" +TAG="v$VERSION" +: "${KEYSTORE_PASSWORD:?set KEYSTORE_PASSWORD}" +: "${KEY_PASSWORD:?set KEY_PASSWORD}" + +cleanup() { rm -f ScreenTinker.apk ScreenTinker.wgt "screentinker-$VERSION.tar.gz"; } +trap cleanup EXIT + +echo "==> Building signed APK $VERSION" +( cd android && KEYSTORE_PASSWORD="$KEYSTORE_PASSWORD" KEY_PASSWORD="$KEY_PASSWORD" ./gradlew assembleRelease ) +cp android/app/build/outputs/apk/release/app-release.apk ScreenTinker.apk + +echo "==> Pulling the CI-built unsigned .wgt from release $TAG" +gh release download "$TAG" -p ScreenTinker.wgt --clobber + +echo "==> Assembling complete tarball (source + apk + wgt)" +OUT="screentinker-$VERSION.tar.gz" +tar czf "$OUT" \ + --exclude='node_modules' --exclude='.git' --exclude='.github' \ + --exclude='*.db' --exclude='*.db-wal' --exclude='*.db-shm' --exclude='*.db.*' \ + --exclude='server/uploads' --exclude='server/certs' --exclude='server/test' \ + server frontend scripts VERSION README.md LICENSE .env.example \ + ScreenTinker.apk ScreenTinker.wgt + +echo "==> Uploading APK + complete tarball to $TAG" +gh release upload "$TAG" "$OUT" ScreenTinker.apk --clobber + +echo "==> Done: $TAG now carries the standalone APK and a tarball bundling apk + wgt."