Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
77ed44c
feat(ci): add apk and abb in release
angelacorte Mar 11, 2026
80350f5
feat(ci): add setup for gh and play store release
angelacorte Mar 11, 2026
9c3d2fc
build(fastlane): update release and deploy lanes for Android
angelacorte Mar 16, 2026
9ab4c92
chore(release): update assets to Android APK and remove docker commands
angelacorte Mar 16, 2026
e22f88d
ci: refactor build and deploy workflow to use workflow_call and seman…
angelacorte Mar 16, 2026
efe47c4
chore(deps): add ruby version file
angelacorte Mar 16, 2026
d526d42
chore: update Gemfile.lock for ruby version
angelacorte Mar 16, 2026
406ebcf
fix(ci): linter run invocation
angelacorte Mar 16, 2026
763802b
fix(ci): get env variables
angelacorte Mar 16, 2026
ece2ac7
fix(ci): add missing success job
angelacorte Mar 16, 2026
bc272eb
Merge branch 'main' into ci/release
angelacorte Mar 23, 2026
f5930d1
Merge branch 'main' into ci/release
DanySK Mar 24, 2026
90712f5
Merge branch 'main' into ci/release
DanySK Mar 25, 2026
c1def40
Merge branch 'main' into ci/release
DanySK Mar 26, 2026
e07ee42
Merge branch 'main' into ci/release
DanySK Mar 27, 2026
4f3498f
Merge branch 'main' into ci/release
DanySK Apr 2, 2026
726c334
Merge branch 'main' into ci/release
DanySK Apr 8, 2026
ffe0ba4
fix(ci): dispatcher workflow and ignore specific branches
angelacorte Apr 9, 2026
4fe16a4
chore: upadte gemfile lock for ci
angelacorte Apr 9, 2026
9d327ae
fix(ci): update artifact names in build-and-deploy.yml
angelacorte Apr 9, 2026
7f7005b
chore: add package.json and package-lock.json for dependencies
angelacorte Apr 9, 2026
2560ae8
Merge branch 'main' into ci/release
DanySK Apr 9, 2026
73e38c7
Merge branch 'main' into ci/release
DanySK Apr 10, 2026
4dac876
fix(ci): add step to extract Node version from package.json
angelacorte Apr 13, 2026
0411d37
chore: add node_modules to .gitignore
angelacorte Apr 13, 2026
1cd6408
fix(ci): update deployment track option in Fastfile and build-and-dep…
angelacorte Apr 13, 2026
acdf686
Merge branch 'main' into ci/release
DanySK Apr 13, 2026
36a98c7
Merge branch 'main' into ci/release
DanySK Apr 17, 2026
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
138 changes: 108 additions & 30 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,74 +1,152 @@

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: echo-app-apk
path: composeApp/build/outputs/apk/release/
- name: Find the version of Node from package.json
id: node-version
run: echo "version=$(jq -r .engines.node package.json)" >> $GITHUB_OUTPUT
- 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: echo-app-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 track:internal # default to internal deploy, change this when needed

success:
runs-on: ubuntu-latest
needs:
- build-android
- build-ios
- release
#- deploy-play-store
if: >-
always() && (
contains(join(needs.*.result, ','), 'failure')
Expand Down
31 changes: 28 additions & 3 deletions .github/workflows/dispatcher.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
name: CI/CD
on:
push:
# Disables the branch builds for some branches,
# the dispatcher for PRs should get triggered anyway
branches-ignore:
# Dependabot branch builds disabled as they do not access secrets
- 'dependabot/**'
- 'feat/**'
- 'fix/**'
paths-ignore:
- '.gitignore'
- '.mergify.yml'
Expand All @@ -14,15 +19,35 @@ on:
workflow_dispatch:

jobs:
inspect:
runs-on: ubuntu-latest
if: false
steps:
- run: |
echo 'github.event_name = ${{ github.event_name }}'
echo 'github.event.pull_request.head.repo.full_name = ${{ github.event.pull_request.head.repo.full_name }}'
echo 'github.repository = ${{ github.repository }}'
echo 'github.head_ref = ${{ github.head_ref }}'
dispatcher:
runs-on: ubuntu-latest
# This filter blocks all pull-request builds that also have a branch build.
# Called workflows inherit the event, so, internally the workflow can distinguish.
# If the event is not a pull request, then the build should run
# (it is either a branch push or a dispatched workflow).
# If the pull request comes from another repo, then the build should run.
# If the pull request is from a dependabot branch, it should run, as
# the dispatcher is disabled for dependabot branch builds.
if: >-
github.event_name != 'pull_request'
|| github.event.pull_request.head.repo.full_name != github.repository
|| startsWith(github.head_ref, 'refs/heads/dependabot/')
github.event_name == 'pull_request' ||
(github.event_name == 'push' && github.ref == 'refs/heads/master') ||
github.event_name == 'workflow_dispatch'
steps:
- run: 'true'
ci-cd:
permissions:
contents: write
issues: write
pull-requests: write
needs:
- dispatcher
uses: ./.github/workflows/build-and-deploy.yml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ captures
**/xcshareddata/WorkspaceSettings.xcsettings
fastlane/report.xml
upload-keystore.jks
/node_modules/
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"
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ CHECKSUMS
xcpretty-travis-formatter (1.0.1) sha256=aacc332f17cb7b2cba222994e2adc74223db88724fe76341483ad3098e232f93

RUBY VERSION
ruby 4.0.2
ruby 4.0.1

BUNDLED WITH
4.0.3
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
61 changes: 29 additions & 32 deletions fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,53 @@ 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
end
lane :deploy do |options|
target_track = options[:track] || 'internal' # ['internal', 'production', 'beta', 'alpha']

upload_to_play_store(
track: target_track,
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

Loading
Loading