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 / Android Compile Check (push) Waiting to run
🏗️ 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 / Run Tests (push) Successful in 29m49s
🏗️ Build and Test JellyTau / Android Compile Check (push) Waiting to run
🏗️ 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
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"),
|
||||
# side by side with a real install and with their own data directory. Neither
|
||||
# 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:
|
||||
workflow_dispatch:
|
||||
@@ -41,6 +46,11 @@ on:
|
||||
- aarch64
|
||||
- armv7
|
||||
- x86_64
|
||||
publish:
|
||||
description: 'Also publish as a pre-release, for testers with no Gitea account'
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
concurrency:
|
||||
# One test build at a time; a newer dispatch supersedes an in-flight one.
|
||||
@@ -171,6 +181,83 @@ jobs:
|
||||
|
||||
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
|
||||
uses: actions/upload-artifact@v3
|
||||
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
|
||||
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
|
||||
|
||||
Player-related Kotlin files:
|
||||
|
||||
Reference in New Issue
Block a user