forked from openMF/mifos-mobile-github-actions
-
Notifications
You must be signed in to change notification settings - Fork 0
480 lines (419 loc) · 16.4 KB
/
multi-platform-build-and-publish.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# GitHub Actions Workflow for Multi-Platform Application Deployment
#
# OVERVIEW:
# This workflow supports building and publishing applications across multiple platforms:
# - Android (APK/AAB)
# - iOS (IPA)
# - Desktop (EXE, MSI, DMG, DEB)
# - Web (GitHub Pages)
#
# PREREQUISITES:
# 1. Ensure your project is configured with:
# - Gradle build system
# - Fastlane for deployment automation
# - Separate modules/package names for each platform
#
# REQUIRED SECRETS:
# Configure the following secrets in GitHub repository settings:
#
# Android-related secrets:
# - original_keystore_file: Base64 encoded Android release keystore
# - original_keystore_file_password: Keystore password
# - original_keystore_alias: Keystore alias
# - original_keystore_alias_password: Keystore alias password
# - upload_keystore_file: Base64 encoded Android upload keystore
# - upload_keystore_file_password: Upload keystore password
# - upload_keystore_alias: Upload keystore alias
# - upload_keystore_alias_password: Upload keystore alias password
#
# Google and Firebase credentials:
# - google_services: Google Services configuration JSON
# - playstore_creds: Play Store service account credentials
# - firebase_creds: Firebase distribution credentials
# - token: GitHub token for repository access
#
# Apple-related secrets:
# - notarization_apple_id: Apple ID for macOS app notarization
# - notarization_password: Notarization password
# - notarization_team_id: Apple developer team ID
#
# Windows signing secrets:
# - windows_signing_key: Windows app signing key
# - windows_signing_password: Windows app signing password
# - windows_signing_certificate: Windows app signing certificate
#
# macOS signing secrets:
# - macos_signing_key: macOS app signing key
# - macos_signing_password: macOS app signing password
# - macos_signing_certificate: macOS app signing certificate
#
# Linux signing secrets:
# - linux_signing_key: Linux app signing key
# - linux_signing_password: Linux app signing password
# - linux_signing_certificate: Linux app signing certificate
# WORKFLOW INPUTS:
# - release_type: 'internal' (default) or 'beta'
# - target_branch: Branch to use for release (default: 'dev')
# - android_package_name: Name of Android module
# - ios_package_name: Name of iOS module
# - desktop_package_name: Name of desktop module
# - web_package_name: Name of web module
# - build_ios: Enable/disable iOS build
# - publish_ios: Enable/disable iOS App Store publishing
# - tester_groups: Firebase tester group for distribution
# USAGE:
# 1. Ensure all required secrets are configured
# 2. Customize package names in workflow inputs
# 3. Toggle platform-specific publishing flags
# 4. Trigger workflow manually or via GitHub Actions UI
# NOTES:
# - Some TODO sections exist for future implementation
# - Requires Fastlane and specific project structure
# - Assumes Kotlin Multiplatform or similar cross-platform setup
name: Multi-Platform App Build and Publish
on:
workflow_call:
inputs:
release_type:
type: string
default: 'internal'
description: Release Type
target_branch:
type: string
default: 'dev'
description: 'Target branch for release'
android_package_name:
description: 'Name of the Android project module'
type: string
required: true
ios_package_name:
description: 'Name of the iOS project module'
type: string
required: true
desktop_package_name:
description: 'Name of the Desktop project module'
type: string
required: true
web_package_name:
description: 'Name of the Web project module'
type: string
required: true
build_ios:
type: boolean
default: false
description: Build iOS App
# Toggle for iOS App Store publishing
publish_ios:
type: boolean
default: false
description: Publish iOS App On App Store
tester_groups:
type: string
description: 'Firebase Tester Group'
required: true
secrets:
# Android-related secrets
original_keystore_file:
description: 'Base64 encoded Android release keystore'
required: false
original_keystore_file_password:
description: 'Keystore password'
required: false
original_keystore_alias:
description: 'Keystore alias'
required: false
original_keystore_alias_password:
description: 'Keystore alias password'
required: false
upload_keystore_file:
description: 'Base64 encoded Android upload keystore'
required: false
upload_keystore_file_password:
description: 'Upload keystore password'
required: false
upload_keystore_alias:
description: 'Upload keystore alias'
required: false
upload_keystore_alias_password:
description: 'Upload keystore alias password'
required: false
# Google and Firebase credentials
google_services:
description: 'Google Services configuration JSON'
required: false
playstore_creds:
description: 'Play Store service account credentials'
required: false
firebase_creds:
description: 'Firebase distribution credentials'
required: false
token:
description: 'Github Token'
required: false
# Apple-related secrets
notarization_apple_id:
description: 'Apple ID for macOS app notarization'
required: false
notarization_password:
description: 'Notarization password'
required: false
notarization_team_id:
description: 'Apple developer team ID'
required: false
# Desktop signing secrets
windows_signing_key:
description: 'Windows app signing key'
required: false
windows_signing_password:
description: 'Windows app signing password'
required: false
windows_signing_certificate:
description: 'Windows app signing certificate'
required: false
macos_signing_key:
description: 'macOS app signing key'
required: false
macos_signing_password:
description: 'macOS app signing password'
required: false
macos_signing_certificate:
description: 'macOS app signing certificate'
required: false
linux_signing_key:
description: 'Linux app signing key'
required: false
linux_signing_password:
description: 'Linux app signing password'
required: false
linux_signing_certificate:
description: 'Linux app signing certificate'
required: false
permissions:
contents: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Publish Android app on Firebase App Distribution
publish_android_on_firebase:
name: Deploy Android App On Firebase
runs-on: macos-latest
steps:
# Check out caller repository
- name: Checkout Caller Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Publish Android App on Firebase
uses: openMF/[email protected]
with:
android_package_name: ${{ inputs.android_package_name }}
keystore_file: ${{ secrets.original_keystore_file }}
keystore_password: ${{ secrets.original_keystore_file_password }}
keystore_alias: ${{ secrets.original_keystore_alias }}
keystore_alias_password: ${{ secrets.original_keystore_alias_password }}
google_services: ${{ secrets.google_services }}
firebase_creds: ${{ secrets.firebase_creds }}
tester_groups: ${{ inputs.tester_groups }}
# Publish Android app on Play Store
publish_android_on_playstore:
name: Publish Android App On Play Store
runs-on: macos-latest
steps:
# Check out caller repository
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Promote Android App to Beta or Internal
uses: openMF/[email protected]
with:
release_type: ${{ inputs.release_type }}
android_package_name: ${{ inputs.android_package_name }}
google_services: ${{ secrets.google_services }}
playstore_creds: ${{ secrets.playstore_creds }}
keystore_file: ${{ secrets.upload_keystore_file }}
keystore_password: ${{ secrets.upload_keystore_file_password }}
keystore_alias: ${{ secrets.upload_keystore_alias }}
keystore_alias_password: ${{ secrets.upload_keystore_alias_password }}
# Firebase Distribution Job for iOS
publish_ios_app_to_firebase:
name: Publish iOS App On Firebase
runs-on: macos-latest
permissions:
contents: write
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Deploy iOS App to Firebase
if: inputs.build_ios
uses: openMF/[email protected]
continue-on-error: true
with:
ios_package_name: ${{ inputs.ios_package_name }}
firebase_creds: ${{ secrets.firebase_creds }}
tester_groups: ${{ inputs.tester_groups }}
# App Store Publishing Job
publish_ios_app_to_app_center:
name: Publish iOS App On App Center
if: inputs.publish_ios
runs-on: macos-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Git Status
run: git status
# TODO: Implement App Store publishing
# Desktop Publishing Job
publish_desktop:
name: Publish Desktop App
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: openMF/[email protected]
with:
desktop_package_name: ${{ inputs.desktop_package_name }}
windows_signing_key: ${{ secrets.windows_signing_key }}
windows_signing_password: ${{ secrets.windows_signing_password }}
windows_signing_certificate: ${{ secrets.windows_signing_certificate }}
macos_signing_key: ${{ secrets.macos_signing_key }}
macos_signing_password: ${{ secrets.macos_signing_password }}
macos_signing_certificate: ${{ secrets.macos_signing_certificate }}
linux_signing_key: ${{ secrets.linux_signing_key }}
linux_signing_password: ${{ secrets.linux_signing_password }}
linux_signing_certificate: ${{ secrets.linux_signing_certificate }}
# Web Publishing Job
publish_web:
name: Publish Web App
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
permissions:
id-token: write
pages: write
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Publish KMP Web App To GitHub Pages
uses: openMF/[email protected]
id: deployment
with:
web_package_name: ${{ inputs.web_package_name }}
# Creates GitHub release with all built artifacts
github_release:
name: Create Github Release
needs: [ publish_android_on_firebase, publish_ios_app_to_firebase, publish_desktop, publish_web ]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Generate Release Number
- name: Generate Release Number
id: rel_number
shell: bash
run: |
set +e # Disable exit on error to handle task non-existence
./gradlew versionFile
VERSIONFILE_EXIT_CODE=$?
set -e # Re-enable exit on error
# Check if version file exists after attempting to generate it
if [ -f "version.txt" ]; then
echo "Using version from versionFile"
VERSION=$(cat version.txt)
# Count commits to generate version code
VERSION_CODE=$(($(git rev-list --count HEAD) * 10))
echo "Version from file: ${VERSION}"
echo "Version Code: ${VERSION_CODE}"
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "version-code=${VERSION_CODE}" >> $GITHUB_OUTPUT
exit 0
fi
# Fallback to Git-based version generation
# Get the latest tag or use 1.0.0 as default
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v1.0.0")
# Remove 'v' prefix if present
LATEST_TAG=${LATEST_TAG#v}
# Count commits since the last tag
COMMITS_SINCE_TAG=$(git rev-list ${LATEST_TAG}..HEAD --count)
# Extract major, minor, patch from the latest tag
IFS='.' read -r MAJOR MINOR PATCH <<< "${LATEST_TAG}"
# Increment patch version and add commits as build number
NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
# Calculate version code (can be adjusted based on your versioning needs)
VERSION_CODE=$(($(git rev-list --count HEAD) * 10))
echo "Version: ${NEW_VERSION}"
echo "Version Code: ${VERSION_CODE}"
echo "version=${NEW_VERSION}" >> $GITHUB_OUTPUT
- name: Generate Release Notes
uses: actions/github-script@v7
id: release-notes
with:
github-token: ${{ secrets.token }}
script: |
try {
// Get latest release tag
const latestRelease = await github.rest.repos.getLatestRelease({
owner: context.repo.owner,
repo: context.repo.repo,
});
const previousTag = latestRelease.data.tag_name;
// Generate release notes
const params = {
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: '${{ steps.rel_number.outputs.version }}',
target_commitish: '${{ inputs.target_branch }}'
};
const { data } = await github.rest.repos.generateReleaseNotes(params);
const changelog = data.body.replaceAll('`', '\'').replaceAll('"', '\'');
// Write changelog files
const fs = require('fs');
fs.writeFileSync('changelogGithub', changelog);
// Generate beta changelog
const { execSync } = require('child_process');
execSync('git log --format="* %s" HEAD^..HEAD > changelogBeta');
return changelog;
} catch (error) {
console.error('Error generating release notes:', error);
return '';
}
# Get all build artifacts
- name: Download All Artifacts
uses: actions/download-artifact@v4
with:
path: ./all-artifacts
# Debug: Show downloaded files
- name: Display structure of downloaded files
run: ls -R ./all-artifacts
#Creates a ZIP archive of the web app build using PowerShell.
- name: Archive Web Build
shell: pwsh
# Executes the Compress-Archive command to create the ZIP archive.
run: |
Compress-Archive -Path './all-artifacts/web-app/*' -DestinationPath './all-artifacts/${{ inputs.web_package_name }}.zip'
# Create GitHub pre-release with all artifacts
- name: Create Github Pre-Release
uses: softprops/[email protected]
with:
tag_name: ${{ steps.rel_number.outputs.version }}
body_path: ./changelogGithub
draft: false
prerelease: true
files: |
./all-artifacts/android-app/${{ inputs.android_package_name }}/build/outputs/apk/demo/release/*.apk
./all-artifacts/android-app/${{ inputs.android_package_name }}/build/outputs/apk/prod/release/*.apk
./all-artifacts/desktop-app-macos-latest/${{ inputs.desktop_package_name }}/build/compose/binaries/main-release/dmg/*.dmg
./all-artifacts/desktop-app-ubuntu-latest/${{ inputs.desktop_package_name }}/build/compose/binaries/main-release/deb/*.deb
./all-artifacts/desktop-app-windows-latest/${{ inputs.desktop_package_name }}/build/compose/binaries/main-release/exe/*.exe
./all-artifacts/desktop-app-windows-latest/${{ inputs.desktop_package_name }}/build/compose/binaries/main-release/msi/*.msi
./all-artifacts/${{ inputs.web_package_name }}.zip