Skip to content

Commit bff8dda

Browse files
timbortnikclaude
andcommitted
Add CI release workflow with signed builds
Configure Gradle to read signing credentials from environment variables. Add GitHub Actions workflow that builds signed APK/AAB on tag push, using secrets from the production environment. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b4d9f7b commit bff8dda

2 files changed

Lines changed: 86 additions & 7 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
environment: production
16+
17+
steps:
18+
- uses: actions/checkout@v6
19+
20+
- name: Setup Flutter
21+
uses: subosito/flutter-action@v2
22+
with:
23+
channel: 'stable'
24+
cache: true
25+
26+
- name: Install dependencies
27+
run: flutter pub get
28+
29+
- name: Analyze code
30+
run: flutter analyze
31+
32+
- name: Run tests
33+
run: flutter test
34+
35+
- name: Decode keystore
36+
run: echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > $RUNNER_TEMP/keystore.jks
37+
38+
- name: Build APK
39+
env:
40+
KEYSTORE_PATH: ${{ runner.temp }}/keystore.jks
41+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
42+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
43+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
44+
run: flutter build apk --release
45+
46+
- name: Build App Bundle
47+
env:
48+
KEYSTORE_PATH: ${{ runner.temp }}/keystore.jks
49+
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
50+
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
51+
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
52+
run: flutter build appbundle --release
53+
54+
- name: Upload APK artifact
55+
uses: actions/upload-artifact@v4
56+
with:
57+
name: release-apk
58+
path: build/app/outputs/flutter-apk/app-release.apk
59+
60+
- name: Upload App Bundle artifact
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: release-aab
64+
path: build/app/outputs/bundle/release/app-release.aab
65+
66+
- name: Create GitHub Release
67+
if: startsWith(github.ref, 'refs/tags/')
68+
uses: softprops/action-gh-release@v2
69+
with:
70+
files: |
71+
build/app/outputs/flutter-apk/app-release.apk
72+
build/app/outputs/bundle/release/app-release.aab
73+
generate_release_notes: true

‎android/app/build.gradle.kts‎

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,29 @@ android {
2222
}
2323

2424
defaultConfig {
25-
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
2625
applicationId = "org.bortnik.meteogram"
27-
// You can update the following values to match your application needs.
28-
// For more information, see: https://flutter.dev/to/review-gradle-config.
2926
minSdk = flutter.minSdkVersion
3027
targetSdk = flutter.targetSdkVersion
3128
versionCode = flutter.versionCode
3229
versionName = flutter.versionName
3330
}
3431

32+
signingConfigs {
33+
val keystorePath = System.getenv("KEYSTORE_PATH")
34+
if (keystorePath != null) {
35+
create("release") {
36+
storeFile = file(keystorePath)
37+
storePassword = System.getenv("KEYSTORE_PASSWORD")
38+
keyAlias = System.getenv("KEY_ALIAS")
39+
keyPassword = System.getenv("KEY_PASSWORD")
40+
}
41+
}
42+
}
43+
3544
buildTypes {
3645
release {
37-
// TODO: Add your own signing config for the release build.
38-
// Signing with the debug keys for now, so `flutter run --release` works.
39-
signingConfig = signingConfigs.getByName("debug")
46+
signingConfig = signingConfigs.findByName("release")
4047

41-
// Enable code shrinking, obfuscation, and optimization
4248
isMinifyEnabled = true
4349
isShrinkResources = true
4450
proguardFiles(

0 commit comments

Comments
 (0)