test : retirer un import inutile signale par l'analyseur #32
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| # Se déclenche au push d'un tag `v*` (ex : `git tag v0.9.5 && git push origin v0.9.5`). | |
| # Build l'APK signé via les secrets GitHub, calcule SHA256, crée la release. | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| jobs: | |
| build-and-release: | |
| name: Build signed APK + GitHub Release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| permissions: | |
| contents: write # nécessaire pour créer la release | |
| steps: | |
| - name: Checkout app | |
| uses: actions/checkout@v6 | |
| with: | |
| path: notes_tech | |
| - name: Checkout files_tech_voice (path dependency) | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: gitubpatrice/files_tech_voice | |
| path: files_tech_voice | |
| - name: Checkout files_tech_core (path dependency) | |
| uses: actions/checkout@v6 | |
| with: | |
| repository: gitubpatrice/files_tech_core | |
| path: files_tech_core | |
| - name: Setup Java 17 | |
| uses: actions/setup-java@v5 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| - name: Setup Flutter | |
| uses: subosito/flutter-action@v2 | |
| with: | |
| channel: stable | |
| cache: true | |
| - name: Extract version from tag | |
| id: version | |
| run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT | |
| - name: Decode keystore | |
| env: | |
| KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} | |
| run: | | |
| echo "$KEYSTORE_BASE64" | base64 -d > notes_tech/android/notestech-release.jks | |
| ls -la notes_tech/android/notestech-release.jks | |
| - name: Create key.properties | |
| env: | |
| STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} | |
| KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} | |
| KEY_ALIAS: ${{ secrets.KEY_ALIAS }} | |
| run: | | |
| cat > notes_tech/android/key.properties << EOF | |
| storePassword=$STORE_PASSWORD | |
| keyPassword=$KEY_PASSWORD | |
| keyAlias=$KEY_ALIAS | |
| storeFile=notestech-release.jks | |
| EOF | |
| - name: Pub get | |
| working-directory: notes_tech | |
| run: flutter pub get | |
| # `--split-per-abi` : convention Files Tech, cf. le commentaire de | |
| # `android/app/build.gradle.kts` (les splits passent par la CLI, JAMAIS | |
| # par un bloc `splits.abi {}` qui entre en conflit avec `ndk.abiFilters`). | |
| # `--obfuscate` : le code Dart était livré en clair en release. | |
| # `--split-debug-info` est OBLIGATOIRE avec `--obfuscate` (les symboles | |
| # restent sur le runner, pas d'upload : l'app est 100 % offline et n'a | |
| # aucun reporting de crash à désobfusquer). | |
| - name: Build APKs release splits (signed) | |
| working-directory: notes_tech | |
| run: > | |
| flutter build apk --release --split-per-abi | |
| --obfuscate --split-debug-info=build/symbols | |
| # ⚠️ PAS d'APK universel, et ce n'est pas une économie de bande passante. | |
| # Les deux familles ont des versionCode INCOMPATIBLES : `--split-per-abi` | |
| # applique l'offset +1000×index de Flutter, l'universel garde le | |
| # versionCode brut du pubspec. Publier les deux tendait un piège à | |
| # l'utilisateur — la release lui conseillait l'universel « en cas de | |
| # doute », et Android refusait l'installation en downgrade s'il avait | |
| # déjà un split. Une seule famille, donc, et c'est celle des splits : | |
| # leur versionCode est toujours supérieur à celui d'un universel de | |
| # même version, la mise à jour depuis les releases ≤ v1.1.6 (universel | |
| # seul) passe donc sans rupture. La transition est à sens unique : | |
| # ne pas réintroduire d'universel plus tard. | |
| - name: Rename + SHA256 | |
| id: sha | |
| run: | | |
| set -euo pipefail | |
| V=${{ steps.version.outputs.VERSION }} | |
| OUT=notes_tech/build/app/outputs/flutter-apk | |
| # Convention Files Tech : `<app>-<abi>-<version>.apk` pour les splits, | |
| # `<app>-universel-<version>.apk` pour l'universel. | |
| # Tableau indexé (pas associatif) : l'ordre d'itération est garanti, | |
| # donc le bloc SHA de la release suit l'ordre de la liste ci-dessus. | |
| APKS=( | |
| "app-arm64-v8a-release.apk:notes-tech-arm64-v8a-$V.apk" | |
| "app-armeabi-v7a-release.apk:notes-tech-armeabi-v7a-$V.apk" | |
| "app-x86_64-release.apk:notes-tech-x86_64-$V.apk" | |
| ) | |
| BODY="" | |
| for ENTRY in "${APKS[@]}"; do | |
| SRC="$OUT/${ENTRY%%:*}" | |
| DEST="${ENTRY##*:}" | |
| cp "$SRC" "$DEST" | |
| SHA=$(sha256sum "$DEST" | awk '{print $1}') | |
| echo "APK signé : $DEST" | |
| echo "SHA-256 : $SHA" | |
| BODY="$BODY**\`$DEST\`**"$'\n'"\`\`\`"$'\n'"$SHA"$'\n'"\`\`\`"$'\n\n' | |
| done | |
| { | |
| echo "SHA_BLOCK<<SHA_EOF" | |
| echo "$BODY" | |
| echo "SHA_EOF" | |
| } >> $GITHUB_OUTPUT | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ github.ref_name }} | |
| name: ${{ github.ref_name }} | |
| generate_release_notes: true | |
| body: | | |
| ## Quel APK télécharger ? | |
| - **`arm64-v8a`** : la quasi-totalité des téléphones, dès 2016. | |
| **En cas de doute, c'est celui-là.** | |
| - **`armeabi-v7a`** : appareils 32 bits anciens, si l'arm64 est refusé. | |
| - **`x86_64`** : émulateurs. | |
| ## Vérification d'intégrité (SHA-256) | |
| ${{ steps.sha.outputs.SHA_BLOCK }} | |
| Vérifiez avec : | |
| ``` | |
| sha256sum <fichier>.apk | |
| ``` | |
| --- | |
| 🤖 Build automatique via GitHub Actions (commit `${{ github.sha }}`) | |
| files: | | |
| notes-tech-arm64-v8a-${{ steps.version.outputs.VERSION }}.apk | |
| notes-tech-armeabi-v7a-${{ steps.version.outputs.VERSION }}.apk | |
| notes-tech-x86_64-${{ steps.version.outputs.VERSION }}.apk | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| rm -f notes_tech/android/notestech-release.jks | |
| rm -f notes_tech/android/key.properties |