ci: publish a test APK as a pre-release for outside testers
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 29m49s
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 57s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 9m25s
Traceability Validation / Check Requirement Traces (push) Successful in 17s
🏗️ Build and Test JellyTau / Android Compile Check (push) Failing after 51s
🏗️ Build and Test JellyTau / Run Tests (push) Successful in 29m49s
🏗️ Build and Test JellyTau / Supply Chain (push) Successful in 57s
Publish Documentation / Build & publish docs to gitea-pages (push) Successful in 9m25s
Traceability Validation / Check Requirement Traces (push) Successful in 17s
🏗️ Build and Test JellyTau / Android Compile Check (push) Failing after 51s
Gitea artifacts need an account with read access to download, which makes them useless for handing a build to someone outside the project -- the actual reason a test APK gets built in the first place. An optional publish input attaches the APK to a pre-release instead, whose assets are a plain public URL on a public repo. No merge to master, no MR, no version tag, and the tester needs no account. Safe from a feature branch on two counts. The tag is test-<branch> rather than v*, and only v* triggers build-release.yml, so nothing else reacts to it. And it cannot reach existing users: the desktop updater reads a static latest.json from the updater branch, not the release list. Re-dispatching the same branch replaces the APK on the existing pre-release rather than accumulating one release per attempt.
This commit is contained in:
@@ -15,6 +15,11 @@ name: '📱 Test APK'
|
|||||||
# Both variants install as com.dtourolle.jellytau.debug ("JellyTau Debug"),
|
# Both variants install as com.dtourolle.jellytau.debug ("JellyTau Debug"),
|
||||||
# side by side with a real install and with their own data directory. Neither
|
# side by side with a real install and with their own data directory. Neither
|
||||||
# needs the release signing key.
|
# needs the release signing key.
|
||||||
|
#
|
||||||
|
# Getting the APK to somebody else: Gitea artifacts need an account with read
|
||||||
|
# access to download, so `publish: true` also attaches the APK to a pre-release
|
||||||
|
# whose assets are a plain public URL. That is the only way an outside tester
|
||||||
|
# gets the file without being given an account.
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -41,6 +46,11 @@ on:
|
|||||||
- aarch64
|
- aarch64
|
||||||
- armv7
|
- armv7
|
||||||
- x86_64
|
- x86_64
|
||||||
|
publish:
|
||||||
|
description: 'Also publish as a pre-release, for testers with no Gitea account'
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
type: boolean
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
# One test build at a time; a newer dispatch supersedes an in-flight one.
|
# One test build at a time; a newer dispatch supersedes an in-flight one.
|
||||||
@@ -171,6 +181,83 @@ jobs:
|
|||||||
|
|
||||||
ls -lah dist/test-apk/
|
ls -lah dist/test-apk/
|
||||||
|
|
||||||
|
# Deliberately NOT tagged `v*`: that pattern triggers build-release.yml,
|
||||||
|
# which would run the whole three-platform release matrix and publish a
|
||||||
|
# real release off a feature branch. The tag here is derived from the
|
||||||
|
# branch name and carries no version, so nothing else reacts to it.
|
||||||
|
#
|
||||||
|
# This also cannot reach existing users. The desktop updater reads a
|
||||||
|
# static latest.json from the `updater` branch, not the release list, so a
|
||||||
|
# pre-release published here is invisible to anyone without the link.
|
||||||
|
- name: Publish as a pre-release
|
||||||
|
if: ${{ inputs.publish }}
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
AUTO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
command -v jq >/dev/null || { echo "❌ jq is required on the runner"; exit 1; }
|
||||||
|
API="${GITHUB_SERVER_URL}/api/v1"
|
||||||
|
REPO="${GITHUB_REPOSITORY}"
|
||||||
|
TOKEN="${GITEA_TOKEN:-$AUTO_TOKEN}"
|
||||||
|
BRANCH="${GITHUB_REF#refs/heads/}"
|
||||||
|
TAG="test-$(echo "$BRANCH" | tr '/' '-')"
|
||||||
|
|
||||||
|
# printf, not a heredoc: inside a YAML block scalar every line is
|
||||||
|
# indented, and a heredoc terminator has to sit at column 0.
|
||||||
|
BODY=$(printf '%s\n' \
|
||||||
|
"Test build of \`$BRANCH\` at \`${GITHUB_SHA::8}\` — **not a release**." \
|
||||||
|
"" \
|
||||||
|
"Installs as **JellyTau Debug** (\`com.dtourolle.jellytau.debug\`), alongside a" \
|
||||||
|
"normal install and with its own separate data. Uninstalling it does not touch" \
|
||||||
|
"the real app." \
|
||||||
|
"" \
|
||||||
|
"Variant: \`${{ inputs.variant }}\` · ABI: \`${{ inputs.abi }}\`" \
|
||||||
|
"" \
|
||||||
|
"Android will warn about installing from an unknown source; that is expected" \
|
||||||
|
"for a build signed with a debug key rather than the store key.")
|
||||||
|
|
||||||
|
PAYLOAD=$(jq -n \
|
||||||
|
--arg tag "$TAG" \
|
||||||
|
--arg name "Test build: $BRANCH" \
|
||||||
|
--arg body "$BODY" \
|
||||||
|
--arg target "$GITHUB_SHA" \
|
||||||
|
'{tag_name:$tag, target_commitish:$target, name:$name, body:$body, draft:false, prerelease:true}')
|
||||||
|
|
||||||
|
HTTP=$(curl -sS -o resp.json -w '%{http_code}' -X POST "$API/repos/$REPO/releases" \
|
||||||
|
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" -d "$PAYLOAD")
|
||||||
|
|
||||||
|
if [ "$HTTP" = "201" ]; then
|
||||||
|
RELEASE_ID=$(jq -r '.id' resp.json)
|
||||||
|
elif [ "$HTTP" = "409" ]; then
|
||||||
|
# Re-dispatching for the same branch replaces the previous APK rather
|
||||||
|
# than accumulating one release per attempt.
|
||||||
|
echo "ℹ️ Pre-release $TAG exists; reusing it"
|
||||||
|
RELEASE_ID=$(curl -fsS "$API/repos/$REPO/releases/tags/$TAG" \
|
||||||
|
-H "Authorization: token $TOKEN" | jq -r '.id')
|
||||||
|
for id in $(curl -fsS "$API/repos/$REPO/releases/$RELEASE_ID/assets" \
|
||||||
|
-H "Authorization: token $TOKEN" | jq -r '.[].id'); do
|
||||||
|
curl -fsS -X DELETE "$API/repos/$REPO/releases/$RELEASE_ID/assets/$id" \
|
||||||
|
-H "Authorization: token $TOKEN" >/dev/null
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "❌ Failed to create pre-release (HTTP $HTTP):"; cat resp.json; exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in dist/test-apk/*.apk; do
|
||||||
|
echo "⬆️ $(basename "$f")"
|
||||||
|
curl -fsS -X POST \
|
||||||
|
"$API/repos/$REPO/releases/$RELEASE_ID/assets?name=$(basename "$f")" \
|
||||||
|
-H "Authorization: token $TOKEN" -F "attachment=@$f" >/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
{
|
||||||
|
echo ""
|
||||||
|
echo "**Published:** ${GITHUB_SERVER_URL}/${REPO}/releases/tag/${TAG}"
|
||||||
|
echo ""
|
||||||
|
echo "Public link — no Gitea account needed. Delete the release when testing is done."
|
||||||
|
} >> "$GITHUB_STEP_SUMMARY"
|
||||||
|
|
||||||
- name: Upload APK
|
- name: Upload APK
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -110,6 +110,25 @@ two other projects, so building on every feature-branch commit would starve
|
|||||||
them. The APK lands as the `jellytau-test-apk` artifact (7-day retention), named
|
them. The APK lands as the `jellytau-test-apk` artifact (7-day retention), named
|
||||||
for the branch and short SHA, with its size and SHA256 in the run summary.
|
for the branch and short SHA, with its size and SHA256 in the run summary.
|
||||||
|
|
||||||
|
#### Sending a build to an outside tester
|
||||||
|
|
||||||
|
Gitea **artifacts require an account** with read access to download, so an
|
||||||
|
artifact is no use to someone outside the project. Tick **`publish`** on the
|
||||||
|
dispatch and the APK is also attached to a **pre-release**, whose assets are a
|
||||||
|
plain public URL on a public repo — no account, no MR, no merge to `master`.
|
||||||
|
|
||||||
|
Two things make that safe to do from a feature branch:
|
||||||
|
|
||||||
|
- The tag is `test-<branch>`, **not** `v*`. Only `v*` triggers
|
||||||
|
`build-release.yml`, so nothing else reacts to it.
|
||||||
|
- It cannot reach existing users. The desktop updater reads a static
|
||||||
|
`latest.json` from the `updater` branch, not the release list, so a
|
||||||
|
pre-release published this way is invisible to anyone without the link.
|
||||||
|
|
||||||
|
Re-dispatching for the same branch replaces the APK on the existing
|
||||||
|
pre-release rather than piling up one release per attempt. Delete the release
|
||||||
|
when testing is over.
|
||||||
|
|
||||||
### Key Files
|
### Key Files
|
||||||
|
|
||||||
Player-related Kotlin files:
|
Player-related Kotlin files:
|
||||||
|
|||||||
Reference in New Issue
Block a user