name: Android
# The Android live wallpaper in droid/. Adapted from Ova's workflow.
#
# Kept in .github/workflows beside package.yml: Forgejo reads
# .forgejo/workflows *instead of* .github/workflows when it exists, so
# putting this there would quietly switch the deb/rpm builds off.
on:
push:
branches: [master]
paths:
- 'droid/**'
# The app packages the desktop wallpaper's shader.
- 'moire/shaders/**'
- '.github/workflows/android.yml'
# A newer push supersedes this run: on a branch or PR the run in
# progress is cancelled; on master it finishes, and only a run still
# waiting is replaced.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
jobs:
# Builds, signs, and publishes the APK to this repository's own F-Droid
# registry.
#
# Needs two secrets, and skips cleanly without them:
#
# ANDROID_KEYSTORE base64 of the release keystore (.jks)
# ANDROID_KEYSTORE_PASS its password
#
# Generate one once, and keep it: the signing certificate is what
# Android checks on every update, so losing it means every install
# has to be uninstalled and redone by hand.
#
# keytool -genkeypair -v -keystore release.jks -alias moire \
# -keyalg RSA -keysize 4096 -validity 10000 \
# -dname "CN=neiam moire, O=neiam, C=US"
# base64 -w0 release.jks
android:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Resolve the forge URL
env:
CI_FORGE_URL: ${{ vars.CI_FORGE_URL }}
run: |
set -euo pipefail
forge_url=${CI_FORGE_URL:-${GITHUB_SERVER_URL:-}}
if [ -z "$forge_url" ]; then
echo "No forge URL available." >&2
exit 1
fi
echo "FORGE_URL=$forge_url" >> "$GITHUB_ENV"
# A secret can't be read in a job-level `if`, so the gate is a
# step output that everything after checks.
- name: Unpack the signing keystore
id: keystore
env:
KEYSTORE: ${{ secrets.ANDROID_KEYSTORE }}
KEYSTORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASS }}
run: |
set -euo pipefail
if [ -z "${KEYSTORE:-}" ] || [ -z "${KEYSTORE_PASS:-}" ]; then
echo "No ANDROID_KEYSTORE / ANDROID_KEYSTORE_PASS set — skipping."
echo "An unsigned or debug-signed APK is worse than none: the"
echo "debug key is shared by every developer, so publishing one"
echo "would let anyone ship an 'update' to it."
echo "skip=true" >> "$GITHUB_OUTPUT"
exit 0
fi
umask 077
printf '%s' "$KEYSTORE" | base64 -d > release.jks
printf '%s' "$KEYSTORE_PASS" > keystore.pass
echo "skip=false" >> "$GITHUB_OUTPUT"
# The context is the repository root, not droid/: the build takes
# the shader from moire/shaders. droid/Dockerfile.dockerignore keeps
# the rest of the repository, stand-in images and all, out of it.
- name: Build and sign the APK
if: steps.keystore.outputs.skip != 'true'
env:
RUN_NUMBER: ${{ github.run_number }}
run: |
set -euo pipefail
# One stamp for the whole run, computed here rather than
# inside Gradle, so every artifact a run produces agrees on
# its version even if the build is retried a step at a time.
stamp=$(date -u +%s)
echo "version: 0.1.0-dev-$stamp (versionCode $RUN_NUMBER)"
docker buildx build \
--target android-export \
--build-arg GITHUB_RUN_NUMBER="$RUN_NUMBER" \
--build-arg SOURCE_DATE_EPOCH="$stamp" \
--secret id=keystore,src=./release.jks \
--secret id=keystore_password,src=./keystore.pass \
--output type=local,dest=./apk \
--file droid/Dockerfile .
# The keystore is gone before anything else runs, so a later step
# or a failure mid-job can't leave it on a persistent runner.
- name: Shred the keystore
if: always()
run: shred -u release.jks keystore.pass 2>/dev/null || rm -f release.jks keystore.pass
- name: Publish to the F-Droid repository
if: steps.keystore.outputs.skip != 'true'
env:
REPOSITORY: ${{ github.repository }}
TOKEN: ${{ github.token }}
run: |
set -euo pipefail
curl --fail-with-body -sS \
-u "gitgud-actions:$TOKEN" \
-H "Content-Type: application/vnd.android.package-archive" \
--data-binary "@apk/app-release.apk" \
"$FORGE_URL/pkg/fdroid/$REPOSITORY/upload"
echo
- name: How to install it
if: steps.keystore.outputs.skip != 'true'
env:
OWNER: ${{ github.repository_owner }}
run: |
set -euo pipefail
fingerprint=$(curl -fsSL "$FORGE_URL/pkg/_keys/fdroid/$OWNER")
cat <<EOF
Add this repository in F-Droid (Settings -> Repositories -> +):
$FORGE_URL/pkg/fdroid/$OWNER/_all?fingerprint=$fingerprint
One entry covers every Android app $OWNER publishes, Ova
included. The fingerprint pins the index signing certificate;
F-Droid refuses an index signed by anything else.
EOF
neiam
/neiam-devices
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
5.3 KiB · text
History
0e2fadf