Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 105 additions & 30 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,74 +1,149 @@

name: CI/CD Process
on:
workflow_call:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true

jobs:
build-android:
name: Compile Android
runs-on: ubuntu-latest
build-ios:
name: Build iOS
runs-on: macos-latest
concurrency:
group: build-android-${{ github.workflow }}-${{ github.event.number || github.ref }}
group: ios-${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@v6.0.2

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v6
with:
allow-snapshots: false
min-wrapper-count: 1

- name: Set up JDK 17
uses: actions/setup-java@v5
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'
- name: Set up Ruby & Fastlane
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build iOS via Fastlane
run: bundle exec fastlane ios build

- name: Run ktlint
run: ./gradlew ktlintCheck

- name: Compile Android Kotlin
run: ./gradlew composeApp:compileDebugKotlinAndroid

build-ios:
name: Compile iOS
runs-on: macos-latest
build-android:
name: Compile Android
runs-on: ubuntu-latest
concurrency:
group: build-ios-${{ github.workflow }}-${{ github.event.number || github.ref }}
group: android-${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@v6.0.2

- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v5
with:
allow-snapshots: false
min-wrapper-count: 1
- name: Set up JDK 17
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
cache: 'gradle'

- name: Set up Ruby w/Fastlane
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Compile iOS Kotlin
run: ./gradlew composeApp:compileKotlinIosSimulatorArm64
- name: Run lint through Fastlane
run: bundle exec fastlane android lint
- name: Decode Keystore
env:
ENCODED_STRING: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
run: |
echo $ENCODED_STRING | base64 -di > composeApp/keystore.jks
- name: Build Android Release (APK & AAB) via Fastlane
run: bundle exec fastlane android release
env: # for gradle
KEYSTORE_FILE: "keystore.jks"
KEYSTORE_PASSWORD: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.ANDROID_KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.ANDROID_KEY_PASSWORD }}
- name: Upload Android APK artifact
uses: actions/upload-artifact@v4
with:
name: echo-app-apk
path: composeApp/build/outputs/apk/release/*.apk
- name: Upload Android AAB artifact
uses: actions/upload-artifact@v4
with:
name: echo-app-aab
path: composeApp/build/outputs/bundle/release/*.aab

release:
name: GitHub Release
runs-on: ubuntu-latest
needs:
- build-ios
- build-android
concurrency:
# Only one release job at a time per branch, as only master releases.
group: release-${{ github.event.number || github.ref }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download Android APK artifact
uses: actions/download-artifact@v4
with:
name: android-release-apk
path: composeApp/build/outputs/apk/release/
- name: Install Node
uses: actions/setup-node@v6.3.0
with:
node-version: ${{ steps.node-version.outputs.version }}
- name: Semantic Release
env:
GITHUB_TOKEN: ${{ secrets.DEPLOYMENT_TOKEN }}
run: |
npm install
npx semantic-release

###### remove comment when ready to deploy on play store
# deploy-play-store:
# name: Deploy to Play Store
# runs-on: ubuntu-latest
# needs: release
# if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
# steps:
# - name: Checkout repository
# uses: actions/checkout@v4
# - name: Download Android AAB artifact
# uses: actions/download-artifact@v4
# with:
# name: android-release-aab
# path: composeApp/build/outputs/bundle/release/
# - name: Set up Ruby & Fastlane for Play Store Deploy
# uses: ruby/setup-ruby@v1
# with:
# bundler-cache: true
# - name: Deploy to Google Play Store via Fastlane
# #env:
# # PLAY_STORE_JSON_KEY_DATA: ${{ secrets.PLAY_STORE_JSON_KEY }}
# run: bundle exec fastlane android deploy

success:
runs-on: ubuntu-latest
needs:
- build-android
- build-ios
- release
#- deploy-play-store
if: >-
always() && (
contains(join(needs.*.result, ','), 'failure')
Expand Down
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.0.1
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
source "https://rubygems.org"
ruby '4.0.2'
ruby file: '.ruby-version'
gem "fastlane"
22 changes: 20 additions & 2 deletions composeApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,20 @@ android {
applicationId = "it.unibo.collektive.echo"
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
versionCode = System.getenv("VERSION_CODE")?.toIntOrNull() ?: 1
versionName = System.getenv("VERSION_NAME") ?: "1.0"
}

signingConfigs {
create("release") {
val keystoreFilePath = System.getenv("KEYSTORE_FILE")
if (keystoreFilePath != null) {
storeFile = file(keystoreFilePath)
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_PASSWORD")
}
}
}

packaging {
Expand All @@ -95,6 +107,12 @@ android {
buildTypes {
release {
isMinifyEnabled = false
val keystoreFilePath = System.getenv("KEYSTORE_FILE")
signingConfig = if (keystoreFilePath != null) {
signingConfigs.getByName("release")
} else {
signingConfigs.getByName("debug")
}
}
}

Expand Down
58 changes: 27 additions & 31 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,52 @@ platform :android do
project_dir: "./"
)
end

lane :release do
# Builds the APK used for the GitHub Release
gradle(
task: "composeApp:assembleRelease",
project_dir: "./"
)
# Builds the Android App Bundle (AAB) used for the Play Store
gradle(
task: "composeApp:bundleRelease",
project_dir: "./"
)
end

lane :deploy do
# Uploads the generated AAB to Google Play Console
upload_to_play_store(
track: 'production', # ['internal', 'production', 'beta']
aab: 'composeApp/build/outputs/bundle/release/composeApp-release.aab',
json_key_data: ENV['PLAY_STORE_JSON_KEY_DATA']
)
end

end

platform :ios do

lane :build do
gradle(
task: "composeApp:linkDebugFrameworkIosArm64",
project_dir: "./"
)

end

lane :ios_release do
gradle(
task: "composeApp:linkReleaseFrameworkIosArm64",
project_dir: "./"
)
build_app(
project: './iosApp/iosApp.xcodeproj',
scheme: "iosApp",
configuration: "Release",
destination: "generic/platform=iOS"
)

end

lane :release do
gradle(
task: "composeApp:linkReleaseFrameworkIosArm64",
project_dir: "./"
)

build_app(
project: './iosApp/iosApp.xcodeproj',
scheme: 'iosApp',
configuration: 'Release',
destination: 'generic/platform=iOS',
allowProvisioningUpdates: true
)
end
lane :release do
gradle(
task: "composeApp:linkReleaseFrameworkIosArm64",
project_dir: "./"
)
build_app(
project: "./iosApp/iosApp.xcodeproj",
scheme: "iosApp",
configuration: "Release",
destination: "generic/platform=iOS",
allowProvisioningUpdates: true
)
end

end

6 changes: 2 additions & 4 deletions release.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ var prepareCmd = `
echo version=\${nextRelease.version} > gradle.properties
echo VERSION="\${nextRelease.version}" > .env
echo PROJECT_NAME=$(grep -Po 'rootProject\\s*\\.\\s*name\\s*=\\s*"\\K[\\w-]+(?=")' settings.gradle.kts) >> .env
docker compose build
`
var publishCmd = `
docker compose push
git add gradle.properties .env
git commit -m "chore(release): update gradle.properties .env versions to \${nextRelease.version} [skip ci]"
git push
Expand All @@ -18,9 +16,9 @@ config.plugins.push(
}],
["@semantic-release/github", {
"assets": [
{ "path": "charts.tar.zst" },
{ "path": "composeApp/build/outputs/apk/release/*.apk", "label": "Android Release APK" }
]
}],
"@semantic-release/git",
)
module.exports = config
module.exports = config
Loading