Files
FitnessDroid/.gitea/workflows/release.yaml
claude 923f58420d
Some checks failed
release / build-release (push) Failing after 13m22s
CI: vägra bygga APK på arm64/Pi5 — spärr först i jobbet
Bygget ska bara gå på brasse-linux01 (label linux-amd64). Om jobbet ändå
hamnar på en arm64-runner avbryts det direkt, innan gradle startar, så att
Pi5:n inte OOM:ar och tar ner alla tjänster.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFvSx1pF9pymyEuK7MFkEG
2026-09-06 12:57:42 +02:00

180 lines
8.5 KiB
YAML

name: release
# På varje push till main: bygg signerad release-APK och lägg den på en
# rullande "latest"-release på släppsidan i Gitea.
#
# Byggs ALLTID på brasse-linux01 (label linux-amd64) — Pi5:n OOM:ar på
# APK-bygget, och Gitea saknar runner-prioritet så delade labels gav slumpen.
# Är huvuddatorn av köas jobbet tills runnern är tillbaka. Första steget
# vägrar dessutom köra på arm64 (2026-09-06), som skydd om labels ändras.
# På arm64 används en statiskt byggd aapt2 (lzhiyong/android-sdk-tools) —
# Googles aapt2 finns bara för linux x86_64. Resten av Android-bygget är
# JVM-baserat och arkitekturoberoende.
on:
push:
branches: [main]
workflow_dispatch: {}
env:
CMDLINE_TOOLS_URL: https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
AAPT2_ARM64_URL: https://github.com/lzhiyong/android-sdk-tools/releases/download/35.0.2/android-sdk-tools-static-aarch64.zip
jobs:
build-release:
runs-on: linux-amd64
steps:
# Säkerhetsspärr: APK-bygget får ALDRIG köra på Pi5:n (OOM ⇒ hela servern
# nere). Om jobbet ändå hamnar på en arm64-runner (t.ex. om Pi-runnern
# fått labeln linux-amd64) avbryts det här, innan något tungt startat.
- name: Vägra bygga på arm64/Pi5
run: |
if [ "$(uname -m)" != "x86_64" ]; then
echo "::error::Fel runner ($(uname -m), $(hostname)). APK-bygget ska köras på brasse-linux01 (label linux-amd64). Avbryter för att inte ta ner Pi5:n."
exit 1
fi
echo "Runner OK: $(uname -m) på $(hostname)"
- name: Checkout
uses: actions/checkout@v4
- name: Skriv signeringsnyckel från secrets
run: |
set -e
if [ -z "${{ secrets.KEYSTORE_B64 }}" ] || [ -z "${{ secrets.KEYSTORE_PASSWORD }}" ]; then
echo "Secrets KEYSTORE_B64 och KEYSTORE_PASSWORD saknas."
echo "Lägg till dem under repo-inställningar -> Actions -> Secrets:"
echo " KEYSTORE_B64 = base64 -w0 signing/fitnessdroid.jks"
echo " KEYSTORE_PASSWORD = storePassword ur signing/keystore.properties"
exit 1
fi
mkdir -p signing
echo "${{ secrets.KEYSTORE_B64 }}" | base64 -d > signing/fitnessdroid.jks
{
echo "storeFile=fitnessdroid.jks"
echo "storePassword=${{ secrets.KEYSTORE_PASSWORD }}"
echo "keyAlias=fitnessdroid"
echo "keyPassword=${{ secrets.KEYSTORE_PASSWORD }}"
} > signing/keystore.properties
- name: Cache gradle
uses: actions/cache@v4
continue-on-error: true
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: gradle-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties', 'gradle/libs.versions.toml') }}
restore-keys: gradle-
- name: Installera JDK 17 + Android SDK
run: |
set -e
echo "== apt: JDK 17 + verktyg =="
sudo apt-get update -qq
sudo apt-get install -y -qq openjdk-17-jdk-headless wget unzip jq curl
export ANDROID_HOME=$HOME/android-sdk
mkdir -p "$ANDROID_HOME/cmdline-tools"
echo "== hämtar cmdline-tools =="
wget -nv "$CMDLINE_TOOLS_URL" -O /tmp/cmdline-tools.zip
unzip -q /tmp/cmdline-tools.zip -d "$ANDROID_HOME/cmdline-tools"
mv "$ANDROID_HOME/cmdline-tools/cmdline-tools" "$ANDROID_HOME/cmdline-tools/latest"
echo "== accepterar licenser =="
# (yes || true): yes dör med SIGPIPE när sdkmanager stänger röret,
# och jobbet kör med pipefail — utan skyddet faller steget på exit 141.
(yes || true) | "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null
echo "== installerar platform-35 + build-tools =="
"$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" "platforms;android-35" "build-tools;34.0.0" > /dev/null
if [ "$(uname -m)" = "aarch64" ]; then
echo "== arm64: statisk aapt2 (Googles är x86_64-only) =="
mkdir -p "$HOME/ci-tools"
wget -nv "$AAPT2_ARM64_URL" -O /tmp/sdk-tools-arm64.zip
unzip -qo /tmp/sdk-tools-arm64.zip -d "$HOME/ci-tools"
chmod +x "$HOME/ci-tools/build-tools/aapt2"
echo "AAPT2_BIN=$HOME/ci-tools/build-tools/aapt2" >> "$GITHUB_ENV"
else
echo "== x86_64: Googles aapt2 ur build-tools =="
echo "AAPT2_BIN=$ANDROID_HOME/build-tools/34.0.0/aapt2" >> "$GITHUB_ENV"
fi
echo "ANDROID_HOME=$ANDROID_HOME" >> "$GITHUB_ENV"
echo "== SDK-setup klar =="
- name: Bygg signerad release-APK
run: |
set -e
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
if [ "$(uname -m)" = "aarch64" ]; then
# Snäll mot Pi5:n — begränsad parallellism + arm64-aapt2
nice -n 10 ./gradlew --no-daemon --console=plain \
-Dorg.gradle.workers.max=2 \
-Pandroid.aapt2FromMavenOverride="$AAPT2_BIN" \
:app:assembleRelease
else
./gradlew --no-daemon --console=plain :app:assembleRelease
fi
mkdir -p build
cp app/build/outputs/apk/release/app-release.apk build/FitnessDroid.apk
(cd build && sha256sum FitnessDroid.apk > checksums.txt && ls -la)
# version.json för appens inbyggda uppdateringskoll
VN=$("$AAPT2_BIN" dump badging build/FitnessDroid.apk \
| sed -n "s/.*versionName='\([^']*\)'.*/\1/p" | head -1)
SHA=$(cut -d' ' -f1 build/checksums.txt)
jq -n \
--argjson code "${{ github.run_number }}" \
--arg name "$VN" \
--arg sha "$SHA" \
--arg url "https://gitea.brasse-pc.eu/${{ github.repository }}/releases/download/latest/FitnessDroid.apk" \
'{versionCode:$code, versionName:$name, sha256:$sha, apkUrl:$url}' \
> build/version.json
cat build/version.json
- name: Skapa/uppdatera latest-release + ladda upp APK
env:
REPO: ${{ github.repository }}
TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
# gitea-d finns bara på Pi5:ns dockernät; annars publika URL:en
if curl -s -m 3 "http://gitea-d:3000/api/v1/version" -o /dev/null 2>/dev/null; then
API="http://gitea-d:3000/api/v1"
else
API="https://gitea.brasse-pc.eu/api/v1"
fi
echo "API: $API"
TAG="latest"
BASE="https://gitea.brasse-pc.eu/$REPO/releases/download/$TAG"
BODY=$(cat <<EOF
Rullande bygge från senaste main. Commit: ${{ github.sha }}. Byggnummer: ${{ github.run_number }}.
## Installera på telefonen
1. Öppna denna sida i telefonens webbläsare och ladda ner **FitnessDroid.apk**
(eller direktlänk: $BASE/FitnessDroid.apk)
2. Öppna den nedladdade filen och tillåt installation från okänd källa om telefonen frågar.
3. Appen uppdaterar befintlig installation — inget behöver avinstalleras (samma signeringsnyckel).
Kräver Android 12 eller nyare.
EOF
)
rid=$(curl -s -X POST "$API/repos/$REPO/releases" \
-H "Authorization: token $TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --arg tag "$TAG" --arg body "$BODY" '{tag_name:$tag,name:$tag,body:$body}')" | jq -r '.id // empty')
if [ -z "$rid" ]; then
rid=$(curl -s "$API/repos/$REPO/releases/tags/$TAG" \
-H "Authorization: token $TOKEN" | jq -r '.id')
curl -s -X PATCH "$API/repos/$REPO/releases/$rid" \
-H "Authorization: token $TOKEN" -H 'Content-Type: application/json' \
-d "$(jq -n --arg body "$BODY" '{body:$body}')" -o /dev/null
fi
echo "release id: $rid"
for f in FitnessDroid.apk checksums.txt version.json; do
aid=$(curl -s "$API/repos/$REPO/releases/$rid/assets" \
-H "Authorization: token $TOKEN" | jq -r ".[] | select(.name==\"$f\") | .id")
if [ -n "$aid" ] && [ "$aid" != "null" ]; then
curl -s -X DELETE "$API/repos/$REPO/releases/$rid/assets/$aid" \
-H "Authorization: token $TOKEN" -o /dev/null
fi
curl -s -X POST "$API/repos/$REPO/releases/$rid/assets?name=$f" \
-H "Authorization: token $TOKEN" \
-F "attachment=@build/$f" -o /dev/null -w " $f -> HTTP %{http_code}\n"
done