mirror of
https://github.com/HendrikRauh/inventree-app.git
synced 2026-02-04 05:43:18 +00:00
Refactor Android CI workflow to use Nix actions and improve translation file collection
Some checks failed
Android / build (push) Failing after 6m11s
Some checks failed
Android / build (push) Failing after 6m11s
This commit is contained in:
parent
49bc90c00c
commit
f0f2d8aea4
3 changed files with 172 additions and 22 deletions
50
.github/actions/nix-devshell/action.yml
vendored
Normal file
50
.github/actions/nix-devshell/action.yml
vendored
Normal file
|
|
@ -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 }}"
|
||||
102
.github/workflows/android.yaml
vendored
102
.github/workflows/android.yaml
vendored
|
|
@ -11,28 +11,88 @@ 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" "${GITHUB_WORKSPACE}/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: Debug Gradle signing
|
||||
uses: ./.github/actions/nix-devshell
|
||||
with:
|
||||
commands: |
|
||||
echo "=== root key.properties ==="
|
||||
sed -n '1,200p' key.properties | sed -E 's/^(storePassword|keyPassword)=.*/\1=***/' || true
|
||||
echo "=== android/key.properties ==="
|
||||
sed -n '1,200p' android/key.properties | sed -E 's/^(storePassword|keyPassword)=.*/\1=***/' || true
|
||||
echo "=== run gradle printSigning ==="
|
||||
cd android
|
||||
./gradlew :app:printSigning --no-daemon --console=plain
|
||||
|
||||
- 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
|
||||
|
|
|
|||
|
|
@ -23,11 +23,37 @@ 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))
|
||||
}
|
||||
|
||||
// Temporary debug task: prints which keystore file Gradle sees and whether the storeFile exists (does NOT print secrets)
|
||||
task printSigning {
|
||||
doLast {
|
||||
println "keystorePropertiesFile = ${keystorePropertiesFile} (abs: ${keystorePropertiesFile?.absolutePath})"
|
||||
println "keystoreProperties keys = " + keystoreProperties.keySet().toString()
|
||||
def rawStore = keystoreProperties['storeFile'] ? keystoreProperties['storeFile'].toString().trim() : null
|
||||
println "raw storeFile (trimmed) = " + (rawStore ?: 'null')
|
||||
if (rawStore) {
|
||||
def f = file(rawStore)
|
||||
println "storeFile interpreted as file(...) = " + f.absolutePath + " exists = " + f.exists()
|
||||
def f2 = new File(keystorePropertiesFile.parentFile, rawStore)
|
||||
println "storeFile interpreted relative to keystorePropertiesFile = " + f2.absolutePath + " exists = " + f2.exists()
|
||||
def f3 = new File(rootProject.projectDir, rawStore)
|
||||
println "storeFile interpreted relative to rootProject = " + f3.absolutePath + " exists = " + f3.exists()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
android {
|
||||
namespace "inventree.inventree_app"
|
||||
compileSdkVersion 35
|
||||
|
|
@ -68,7 +94,21 @@ android {
|
|||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||
// Resolve storeFile robustly: trim, then prefer absolute path; if not found, try relative to keystore properties file
|
||||
def rawStoreFile = keystoreProperties['storeFile'] ? keystoreProperties['storeFile'].toString().trim() : null
|
||||
def resolvedStoreFile = null
|
||||
if (rawStoreFile) {
|
||||
def candidate = file(rawStoreFile)
|
||||
if (!candidate.exists()) {
|
||||
// try relative to the keystore properties file directory
|
||||
def parentCandidate = new File(keystorePropertiesFile.parentFile, rawStoreFile)
|
||||
if (parentCandidate.exists()) {
|
||||
candidate = parentCandidate
|
||||
}
|
||||
}
|
||||
resolvedStoreFile = candidate.exists() ? candidate : null
|
||||
}
|
||||
storeFile resolvedStoreFile
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue