diff --git a/.github/workflows/desktop-bundled-release.yml b/.github/workflows/desktop-bundled-release.yml index 7617667d76..cceeb97dba 100644 --- a/.github/workflows/desktop-bundled-release.yml +++ b/.github/workflows/desktop-bundled-release.yml @@ -76,6 +76,11 @@ on: required: false type: boolean default: false + termux_upgrade_from_run: + description: 'Successful Termux run whose package must upgrade to this build' + required: false + type: string + default: '' upload_release: description: 'Upload artifacts to the R2 release bucket (staging + feeds)' required: false @@ -84,6 +89,7 @@ on: permissions: contents: write + actions: read packages: write id-token: write @@ -1022,6 +1028,30 @@ jobs: retention-days: 30 if-no-files-found: error + - name: Verify the previous Termux run + if: inputs.termux_upgrade_from_run != '' + env: + PREVIOUS_RUN: ${{ inputs.termux_upgrade_from_run }} + run: | + [[ "$PREVIOUS_RUN" =~ ^[0-9]+$ ]] + gh api "repos/$GITHUB_REPOSITORY/actions/runs/$PREVIOUS_RUN" > "$RUNNER_TEMP/termux-previous-run.json" + python3 - "$RUNNER_TEMP/termux-previous-run.json" <<'PY' + import json, subprocess, sys + run = json.load(open(sys.argv[1], encoding="utf-8")) + assert run["conclusion"] == "success", "previous run did not succeed" + assert run["path"] == ".github/workflows/desktop-bundled-release.yml", "wrong artifact producer" + subprocess.run(["git", "merge-base", "--is-ancestor", run["head_sha"], "origin/main"], check=True) + PY + - name: Download the previous Termux package + if: inputs.termux_upgrade_from_run != '' + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + github-token: ${{ github.token }} + run-id: ${{ inputs.termux_upgrade_from_run }} + pattern: hermes-bundled-termux-* + merge-multiple: true + path: termux-build/previous + - name: Write the APT signing key shell: bash env: @@ -1037,6 +1067,7 @@ jobs: shell: bash env: CHANNEL: ${{ steps.channel.outputs.channel }} + PREVIOUS_RUN: ${{ inputs.termux_upgrade_from_run }} # Passphrase-protected signing keys only; unset for bare keys. TERMUX_APT_GPG_PASSPHRASE: ${{ secrets.TERMUX_APT_GPG_PASSPHRASE }} run: | @@ -1058,6 +1089,16 @@ jobs: -v "$PWD/scripts/termux/check_apt.sh:/tmp/check-apt.sh:ro" \ -v "$PWD/scripts/termux/validate_installed.py:/tmp/validate_installed.py:ro" \ "termux/termux-docker@$digest" bash /tmp/check-apt.sh "hermes-$CHANNEL" "$version" + if [ -n "$PREVIOUS_RUN" ]; then + previous=(termux-build/previous/*.deb) + test "${#previous[@]}" -eq 1 + docker run --rm --platform linux/arm64 --user 1000:1000 --network none \ + -v "$PWD/termux-build/apt:/apt:ro" \ + -v "$PWD/${previous[0]}:/previous.deb:ro" \ + -v "$PWD/scripts/termux/check_apt.sh:/tmp/check-apt.sh:ro" \ + -v "$PWD/scripts/termux/validate_installed.py:/tmp/validate_installed.py:ro" \ + "termux/termux-docker@$digest" bash /tmp/check-apt.sh "hermes-$CHANNEL" "$version" + fi # --key-is-full is MANDATORY on every feed-dir upload: without it # r2-release.mjs re-prefixes the key into the tag archive diff --git a/scripts/termux/check_apt.sh b/scripts/termux/check_apt.sh index 41c3f6050d..5c501d449a 100755 --- a/scripts/termux/check_apt.sh +++ b/scripts/termux/check_apt.sh @@ -17,6 +17,9 @@ apt_options=( -o "DPkg::Options::=--force-not-root" -o "DPkg::Options::=--force-script-chrootless" ) +mkdir -p "$work/state" +printf 'user data survives package replacement\n' > "$work/state/sentinel" +export HERMES_HOME="$work/state" if [ -f /previous.deb ]; then dpkg --force-not-root --force-script-chrootless --install /previous.deb previous="$(dpkg-query -W -f='${Version}' hermes-agent)" @@ -26,6 +29,7 @@ apt-get "${apt_options[@]}" update apt-get "${apt_options[@]}" --yes install hermes-agent actual="$(dpkg-query -W -f='${Version}' hermes-agent)" [ "$actual" = "$expected" ] +[ "$(cat "$work/state/sentinel")" = 'user data survives package replacement' ] root="$PREFIX/lib/hermes-agent" export LD_LIBRARY_PATH="$root/tools/python$PREFIX/lib:$root/tools/node$PREFIX/lib:$root/tools/ffmpeg$PREFIX/lib:$root/runtime-libs/lib:$PREFIX/lib" export PYTHONPATH="$root/app"