android / Build + lint + test (push) Successful in 4m30s
android.yml and release.yml uploaded via actions/upload-artifact@v3, which
reports success while Gitea stores the result in a format its v4-only
artifact API will never serve back — 72 artifacts on this repo are on disk,
have valid DB rows, and are invisible to every retrieval path. Green jobs
producing nothing retrievable.
release.yml is a producer/consumer pair: android-release uploads
minstrel-apk and image-release downloads it to bundle into the container.
Swapping only the upload would have left download-artifact@v3 reading the
v1/v3 listing and finding nothing, so mirror the download side too —
bvandeusen/download-artifact, pull mirror of forgejo/download-artifact,
pinned at its v5 tag to match the upload pin's major.
Not actions/{upload,download}-artifact@v4: isGhes() throws on the hostname
before opening a connection, so no server-side change reaches it.
Upload steps also set if-no-files-found: error — image-release hard-depends
on minstrel-apk existing, so an empty upload must fail where it happens.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
96 lines
3.6 KiB
YAML
96 lines
3.6 KiB
YAML
name: android
|
|
|
|
# Native Android (Kotlin/Compose/Media3) — M8 rewrite, now the only client.
|
|
# This workflow is testing only — lint + detekt + unit tests on every push
|
|
# to dev/main, plus a debug APK artifact for main. The signed-release
|
|
# build + asset attach + image-bundling lives in release.yml under a
|
|
# `needs:` chain so the docker image cannot ship without the APK.
|
|
|
|
on:
|
|
push:
|
|
branches: [main, dev]
|
|
paths:
|
|
- 'android/**'
|
|
- '.gitea/workflows/android.yml'
|
|
|
|
# pull_request trigger intentionally omitted — see test-web.yml for
|
|
# the rationale (single-author repo, push covers PR-merge equivalent).
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
# Silences the JDK 22+ "restricted method in java.lang.System has been
|
|
# called" warning that Gradle 9.1's bundled native-platform jar trips
|
|
# at launch (System.load for native primitives). Affects the LAUNCHER
|
|
# JVM, not the daemon — that's why org.gradle.jvmargs in
|
|
# gradle.properties isn't enough. Future-compat: required opt-in once
|
|
# JDK 25 promotes the warning to an error.
|
|
JAVA_TOOL_OPTIONS: "--enable-native-access=ALL-UNNAMED"
|
|
|
|
jobs:
|
|
build:
|
|
name: Build + lint + test
|
|
# Using flutter-ci runner label because it's the only proven-working
|
|
# label with docker that can pull our container.image. Switch to
|
|
# android-ci once the operator registers that runner label.
|
|
runs-on: flutter-ci
|
|
container:
|
|
image: git.fabledsword.com/bvandeusen/ci-android:36
|
|
|
|
defaults:
|
|
run:
|
|
working-directory: android
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Cache Gradle dirs
|
|
# Resolved deps + Gradle distribution + Kotlin daemon caches.
|
|
# Saves ~3 min per CI run after the first warm-up.
|
|
uses: actions/cache@v4
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
~/.kotlin
|
|
key: gradle-${{ runner.os }}-${{ hashFiles('android/gradle/wrapper/gradle-wrapper.properties', 'android/gradle/libs.versions.toml', 'android/**/*.gradle.kts') }}
|
|
restore-keys: |
|
|
gradle-${{ runner.os }}-
|
|
|
|
- name: Make gradlew executable
|
|
run: chmod +x ./gradlew
|
|
|
|
- name: Gradle wrapper validation
|
|
run: ./gradlew --version
|
|
|
|
- name: ktlint
|
|
run: ./gradlew ktlintCheck
|
|
|
|
- name: detekt
|
|
run: ./gradlew detekt
|
|
|
|
- name: Unit tests
|
|
run: ./gradlew testDebugUnitTest
|
|
|
|
- name: Assemble debug
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
run: ./gradlew assembleDebug
|
|
|
|
- name: Upload debug APK
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
# Mirrored action, never actions/upload-artifact. @v4+ throws
|
|
# GHESNotSupportedError client-side on the hostname (no server setting
|
|
# reaches that check), and @v3 is worse — it reports success while Gitea
|
|
# serves artifacts back only through the v4 API, so the upload is stored
|
|
# and invisible to every retrieval path. @v3 is what left 72 unreachable
|
|
# artifacts on this repo. Pinned by SHA because the mirror auto-syncs;
|
|
# full URL because DEFAULT_ACTIONS_URL sends bare owner/repo to github.com.
|
|
# See Scribe issues 2255 / 2270.
|
|
uses: https://git.fabledsword.com/bvandeusen/upload-artifact@cb8afe72b42edc798abfb8fcb556cf660d894245
|
|
with:
|
|
name: minstrel-android-debug-${{ github.sha }}
|
|
path: android/app/build/outputs/apk/debug/app-debug.apk
|
|
if-no-files-found: error
|