From 050cd7b876a373539e3dedea405b6d0c9d036c55 Mon Sep 17 00:00:00 2001 From: HendrikRauh <114620133+HendrikRauh@users.noreply.github.com> Date: Mon, 26 Jan 2026 17:40:54 +0100 Subject: [PATCH] Refactor Android CI workflow to use Nix actions and improve translation file collection --- .github/actions/nix-devshell/action.yml | 50 ++++++++++++++ .github/workflows/android.yaml | 90 +++++++++++++++++++------ android/app/build.gradle | 9 ++- 3 files changed, 127 insertions(+), 22 deletions(-) create mode 100644 .github/actions/nix-devshell/action.yml diff --git a/.github/actions/nix-devshell/action.yml b/.github/actions/nix-devshell/action.yml new file mode 100644 index 0000000..d0f47b1 --- /dev/null +++ b/.github/actions/nix-devshell/action.yml @@ -0,0 +1,50 @@ +name: "nix-devshell" +description: + "Set up Nix, prebuild the devshell and run commands inside the devshell." +inputs: + prebuild: + description: + "Whether to prebuild the devshell (nix develop --command true)." + required: false + default: "false" + commands: + description: + "Commands to run inside the devshell (executed with bash -lc)." + required: false + default: "" + +runs: + using: "composite" + steps: + - name: Install Nix (idempotent) + shell: bash + run: | + set -euo pipefail + if ! command -v nix >/dev/null 2>&1; then + curl -L https://nixos.org/nix/install | sh -s -- --no-daemon + fi + # source the nix profile if present + if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then + . "$HOME/.nix-profile/etc/profile.d/nix.sh" + fi + nix --version + + - name: Prebuild devshell + if: ${{ inputs.prebuild == 'true' }} + shell: bash + run: | + set -euo pipefail + if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then + . "$HOME/.nix-profile/etc/profile.d/nix.sh" + fi + nix --extra-experimental-features 'nix-command flakes' develop --command true + + - name: Run commands in devshell + if: ${{ inputs.commands != '' }} + shell: bash + run: | + set -euo pipefail + if [ -f "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then + . "$HOME/.nix-profile/etc/profile.d/nix.sh" + fi + nix --extra-experimental-features 'nix-command flakes' develop --command bash -lc "${{ inputs.commands }}" diff --git a/.github/workflows/android.yaml b/.github/workflows/android.yaml index 67afa0c..236a380 100644 --- a/.github/workflows/android.yaml +++ b/.github/workflows/android.yaml @@ -11,28 +11,76 @@ jobs: runs-on: ubuntu-latest steps: - - name: Install Nix (for nix usage) - run: | - set -euo pipefail - curl -L https://nixos.org/nix/install | sh -s -- --no-daemon - . "$HOME/.nix-profile/etc/profile.d/nix.sh" - nix --version - - name: Checkout code uses: actions/checkout@v6 - - name: Collect Translation Files - run: | - set -euo pipefail - . "$HOME/.nix-profile/etc/profile.d/nix.sh" - nix --version - cd lib/l10n - nix --extra-experimental-features 'nix-command flakes' develop --command python3 collect_translations.py - cd ../.. + - name: Prepare Nix devshell + uses: ./.github/actions/nix-devshell + with: + prebuild: "true" - - name: Build Debug APK - run: | - set -euo pipefail - . "$HOME/.nix-profile/etc/profile.d/nix.sh" - nix --version - nix --extra-experimental-features 'nix-command flakes' develop --command flutter build apk --debug + - name: Collect Translation Files + uses: ./.github/actions/nix-devshell + with: + commands: | + cd lib/l10n + python3 collect_translations.py + + # - name: Build Debug APK + # uses: ./.github/actions/nix-devshell + # with: + # commands: | + # flutter build apk --debug --target-platform android-arm64 + + # - name: Upload APK artifact + # uses: actions/upload-artifact@v4 + # with: + # name: app-debug-apk + # path: build/app/outputs/flutter-apk/*.apk + # # retention-days: 90 + + - name: Setup Release Keystore + uses: ./.github/actions/nix-devshell + with: + commands: | + # Write keystore into android/app and key.properties into android/ + echo "$RELEASE_KEYSTORE_BASE64" | base64 -d > android/app/inventree-release-key.jks + chmod 600 android/app/inventree-release-key.jks + + # Write key.properties inside android/ (user preferred) + printf "storePassword=%s\nkeyPassword=%s\nkeyAlias=%s\nstoreFile=%s\n" \ + "$STORE_PASSWORD" "$KEY_PASSWORD" "$KEY_ALIAS" "android/app/inventree-release-key.jks" \ + > android/key.properties + + # Also write a repo-root shim with an absolute path for Gradle to consume reliably + printf "storePassword=%s\nkeyPassword=%s\nkeyAlias=%s\nstoreFile=%s\n" \ + "$STORE_PASSWORD" "$KEY_PASSWORD" "$KEY_ALIAS" "${GITHUB_WORKSPACE}/android/app/inventree-release-key.jks" \ + > key.properties + + # Debug: show only non-secret info so logs aren't masked; confirm storeFile entries and JKS presence + echo "=== root storeFile ===" + grep '^storeFile=' key.properties || true + echo "=== android storeFile ===" + grep '^storeFile=' android/key.properties || true + echo "=== android/app listing ===" + ls -la android/app | sed -n '1,200p' + echo "=== key.properties files ===" + ls -la key.properties android/key.properties || true + env: + RELEASE_KEYSTORE_BASE64: ${{ secrets.INVENTREE_RELEASE_KEY_BASE64 }} + STORE_PASSWORD: ${{ secrets.INVENTREE_STORE_PASSWORD }} + KEY_PASSWORD: ${{ secrets.INVENTREE_KEY_PASSWORD }} + KEY_ALIAS: ${{ secrets.INVENTREE_KEY_ALIAS }} + + - name: Build Release APK + uses: ./.github/actions/nix-devshell + with: + commands: | + flutter build apk --release --no-tree-shake-icons + + - name: Upload Release APK artifact + uses: actions/upload-artifact@v4 + with: + name: app-release-apk + path: build/app/outputs/flutter-apk/*.apk + # retention-days: 90 diff --git a/android/app/build.gradle b/android/app/build.gradle index d133d64..9abef89 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -23,10 +23,17 @@ if (flutterVersionName == null) { } def keystoreProperties = new Properties() +// Prefer root key.properties, but fall back to android/key.properties if present (CI may place it there) def keystorePropertiesFile = rootProject.file('key.properties') +if (!keystorePropertiesFile.exists()) { + def alt = rootProject.file('android/key.properties') + if (alt.exists()) { + keystorePropertiesFile = alt + } +} if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) -} +} android { namespace "inventree.inventree_app"