Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
08ab226
refactor: Extract KMP change detection into reusable action
matejsemancik Aug 29, 2025
d7c5605
fix(github-actions): Improve cache key generation for build artifacts
matejsemancik Aug 29, 2025
5014fbf
feat: Add Android CI/CD GitHub Actions
matejsemancik Aug 29, 2025
45d716e
fix: Correctly set `bundle_file` output in Android build action
matejsemancik Aug 29, 2025
ac059ea
refactor(android): Use composite actions for setup and checks
matejsemancik Aug 29, 2025
c39680a
fix: Correct relative paths for GitHub Actions
matejsemancik Aug 29, 2025
b4fbbe1
chore: Update Android cloud check workflow to use remote actions
matejsemancik Aug 29, 2025
1a51dcd
fix(github-actions): Update DANGER_GITHUB_API_TOKEN to use `github.to…
matejsemancik Aug 29, 2025
46e07d9
chore: Add TODO comments to Android cloud check workflow for branch r…
matejsemancik Aug 29, 2025
d4c2c92
chore(github-actions): Update Android release workflow to use composi…
matejsemancik Aug 29, 2025
40d10b0
feat(android-ci): Add Android nightly build workflow
matejsemancik Aug 29, 2025
eef69ce
ci: Cache latest build commit SHA in nightly workflow
matejsemancik Aug 29, 2025
744db85
ci: Save latest build commit SHA to file
matejsemancik Aug 29, 2025
5abbf1b
refactor(ci): Streamline Android Firebase App Distribution workflow
matejsemancik Sep 23, 2025
b9fe6ac
refactor(ci): Extract baseline profile generation into reusable action
matejsemancik Sep 23, 2025
2799ad8
docs(README): add new Android workflows
matejsemancik Sep 23, 2025
eae0553
refactor(ci): Pass build number, version name and signing secrets as …
matejsemancik Sep 24, 2025
cd6d43a
refactor(ci): Update Android workflows to use `feature/android-refact…
matejsemancik Sep 24, 2025
500471e
Revert "refactor(ci): Pass build number, version name and signing sec…
matejsemancik Sep 24, 2025
745798f
Merge branch 'main' into feature/android-refactor
matejsemancik Sep 25, 2025
68b32ea
Merge branch 'main' into feature/android-refactor
matejsemancik Sep 25, 2025
4416651
refactor(ci): Add reusable iOS KMP build action and update TestFlight…
matejsemancik Sep 25, 2025
9a14525
refactor(ci): Add optional setup toggles for Java, Ruby, and Gradle i…
matejsemancik Sep 25, 2025
accc38d
Disable Ruby setup for ios-kmp-selfhosted-build.yml
matejsemancik Sep 25, 2025
b58ec4b
feat(ci): Add KMP combined nightly build workflow
matejsemancik Sep 25, 2025
be8c542
docs: Enhance workflow documentation with dependency diagram
matejsemancik Sep 25, 2025
8c3eb70
Revert "docs: Enhance workflow documentation with dependency diagram"
matejsemancik Sep 25, 2025
2bfabf3
docs: Update README with new workflows and fixes
matejsemancik Sep 25, 2025
be120f1
refactor(ci): Simplify and streamline inputs in KMP nightly build wor…
matejsemancik Sep 25, 2025
3fc2a7a
refactor(ci): Remove default value for `build_flavor` in KMP nightly …
matejsemancik Sep 26, 2025
0445f18
refactor(ci): Specify `bash` shell for all action steps in `android-g…
matejsemancik Sep 26, 2025
5fe051f
fix(ci): Update action reference in `kmp-cloud-detect-changes.yml`
matejsemancik Sep 26, 2025
86634e0
refactor(ci): Update action references to `main` across workflows
matejsemancik Sep 26, 2025
e4927f8
refactor(ci): Update iOS build action references to `ios-kmp-build`
matejsemancik Sep 26, 2025
e46f173
refactor(ci): Remove unused `SIGNING_KEYSTORE_PATH` input from Androi…
matejsemancik Sep 26, 2025
38c493a
refactor(ci): Standardize input variable casing in `kmp-combined-nigh…
matejsemancik Sep 26, 2025
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
90 changes: 90 additions & 0 deletions .github/actions/android-build-firebase/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Enterprise build
description: Builds and uploads app to Firebase App Distribution.

inputs:
## Required Inputs
test_gradle_task:
description: "A Gradle task(s) for executing unit tests, for example `testReleaseUnitTest` or `testDevEnterpriseUnitTest`"
required: true
package_gradle_task:
description: "A Gradle task for packaging universal APK, eg. 'packageEnterpriseUniversalApk'"
required: true
upload_gradle_task:
description: "A Gradle task for uploading APK, for example `appDistributionUploadEnterprise`"
required: true
app_distribution_groups:
description: "Comma-separated list of Firebase App Distribution group IDs"
required: true
app_distribution_service_account:
required: true
description: "JSON key of service account with permissions to upload build to Firebase App Distribution"

## Optional Inputs
version_name:
description: "Version name. Example: '1.X.X-snapshot'"
required: false
build_number_offset:
description: "Build number offset. This number will be added to GITHUB_RUN_NUMBER and can be used to make corrections to build numbers."
required: false
default: 0
release_notes:
description: "Release notes for this build"
required: false
default: ${{ github.event.head_commit.message }}
kmp_flavor:
description: "KMP Build flavor. This is optional and only required by KMP projects and can be ignored on pure Android projects"
required: false
default: 'test'
secret_properties_file:
description: "A path to file that will be populated with contents of 'SECRET_PROPERTIES' secret. This file can be picked up by Secrets Gradle plugin to embed secrets into BuildConfig."
required: false
default: 'secrets.properties'
secret_properties:
required: false
description: "Custom string that contains key-value properties as secrets. Contents of this secret will be placed into file specified by 'SECRET_PROPERTIES_FILE' input."

runs:
using: "composite"
steps:
- name: Prepare Environment
shell: bash
run: |
{
echo "ANDROID_BUILD_NUMBER=$((GITHUB_RUN_NUMBER + ${{ inputs.build_number_offset}} ))";
echo "KMP_FLAVOR=${{ inputs.kmp_flavor }}"
} >> "$GITHUB_ENV"

# Set ANDROID_VERSION_NAME only if VERSION_NAME is provided
if [[ -n "${{ inputs.version_name }}" ]]; then
echo "ANDROID_VERSION_NAME=${{ inputs.version_name }}" >> "$GITHUB_ENV"
fi

echo '${{ inputs.secret_properties }}' > ${{ inputs.secret_properties_file }}
- name: Run Unit tests
shell: bash
run: ./gradlew --continue ${{ inputs.test_gradle_task }}
- name: Build universal APK
id: build_apk
shell: bash
run: |
./gradlew ${{ inputs.package_gradle_task }} -P buildkonfig.flavor="$KMP_FLAVOR"
APK_FILE=$(find . -name '*.apk' | grep -v -e '.*intermediate' -e '.*baseline')
echo "universal_apk_file=$APK_FILE" >> "$GITHUB_OUTPUT"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: universal_apk
path: ${{ steps.build_apk.outputs.universal_apk_file }}
- name: Upload APK to Firebase App Distribution
shell: bash
run: |
echo '${{ inputs.app_distribution_service_account }}' > "firebase_credentials.json"

./gradlew ${{ inputs.upload_gradle_task }} \
--serviceCredentialsFile="firebase_credentials.json" \
--groups="${{ inputs.app_distribution_groups }}" \
--artifactType="APK" \
--artifactPath="${{ steps.build_apk.outputs.universal_apk_file }}" \
--releaseNotes='${{ inputs.release_notes }}'

rm firebase_credentials.json
99 changes: 99 additions & 0 deletions .github/actions/android-build-googlePlay/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Release build
description: Builds and uploads app to Google Play.

inputs:
## Required Inputs
bundle_gradle_task:
description: "A Gradle task for assembling app bundle, for example `bundleRelease`"
required: true
version_name:
description: "Version name. Example: '1.0.0'"
required: true
signing_keystore_password:
description: "Password to provided keystore"
required: true
signing_key_alias:
description: "Alias of the signing key in the provided keystore"
required: true
signing_key_password:
description: "Password to the key in the provided keystore"
required: true
google_play_application_id:
description: "Google Play applicationId"
required: true
google_play_whatsnew_dir:
description: "Path to directory with changelog files according to documentation in https://github.com/r0adkll/upload-google-play"
required: true
google_play_publish_service_account:
required: true
description: "JSON key of service account with permissions to upload build to Google Play"

## Optional Inputs
changes_not_sent_for_review:
description: 'A changesNotSentForReview Google Play flag. Enable when last google review failed, disable when last review was successful.'
required: false
default: false
build_number_offset:
description: "Build number offset. This number will be added to GITHUB_RUN_NUMBER and can be used to make corrections to build numbers."
required: false
default: 0
kmp_flavor:
description: "KMP Build flavor. This is optional and only required by KMP projects and can be ignored on pure Android projects"
required: false
default: 'prod'
secret_properties_file:
description: "A path to file that will be populated with contents of 'SECRET_PROPERTIES' secret. This file can be picked up by Secrets Gradle plugin to embed secrets into BuildConfig."
required: false
default: 'secrets.properties'
secret_properties:
required: false
description: "Custom string that contains key-value properties as secrets. Contents of this secret will be placed into file specified by 'SECRET_PROPERTIES_FILE' input."

runs:
using: "composite"
steps:
- name: Prepare Environment
shell: bash
run: |
{
echo "ANDROID_BUILD_NUMBER=$((GITHUB_RUN_NUMBER + ${{ inputs.build_number_offset}} ))";
echo "ANDROID_VERSION_NAME=${{ inputs.version_name }}";
echo "KMP_FLAVOR=${{ inputs.kmp_flavor }}"
} >> "$GITHUB_ENV"

echo '${{ inputs.secret_properties }}' > ${{ inputs.secret_properties_file }}
- name: Generate Artifacts (AAB)
id: build_aab
shell: bash
env:
ANDROID_KEYSTORE_PASSWORD: ${{ inputs.signing_keystore_password }}
ANDROID_KEY_ALIAS: ${{ inputs.signing_key_alias }}
ANDROID_KEY_PASSWORD: ${{ inputs.signing_key_password }}
run: |
./gradlew ${{ inputs.bundle_gradle_task }} -P buildkonfig.flavor="$KMP_FLAVOR"
BUNDLE_FILE=$(find . -name '*.aab' | grep -v -e '.*intermediate' -e '.*baseline')
MAPPING_FILE=$(find . -name mapping.txt)

echo "bundle_file=$BUNDLE_FILE" >> "$GITHUB_OUTPUT"
echo "mapping_file=$MAPPING_FILE" >> "$GITHUB_OUTPUT"
- name: Upload AAB artifact
uses: actions/upload-artifact@v4
with:
name: release_bundle
path: ${{ steps.build_aab.outputs.bundle_file }}
- name: Upload Mapping file artifact
uses: actions/upload-artifact@v4
with:
name: mapping_file
path: ${{ steps.build_aab.outputs.mapping_file }}
- name: Upload to Google Play
uses: r0adkll/[email protected]
with:
serviceAccountJsonPlainText: ${{ inputs.google_play_publish_service_account }}
packageName: ${{ inputs.google_play_application_id }}
releaseFiles: ${{ steps.build_aab.outputs.bundle_file }}
track: internal
status: draft
whatsNewDirectory: ${{ inputs.google_play_whatsnew_dir }}
mappingFile: ${{ steps.build_aab.outputs.mapping_file }}
changesNotSentForReview: ${{ toJSON(inputs.changes_not_sent_for_review) }}
30 changes: 30 additions & 0 deletions .github/actions/android-check/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Android Check
description: Runs lint checks and unit tests.

inputs:
# Required inputs
lint_gradle_task:
description: "A Gradle task(s) for executing lint check, for example `lintCheck lintRelease`"
required: true
test_gradle_task:
description: "A Gradle task(s) for executing unit tests, for example `testReleaseUnitTest` or `testDevEnterpriseUnitTest`"
required: true

runs:
using: "composite"
steps:
- name: Run Lint Check
shell: bash
run: ./gradlew --continue ${{ inputs.lint_gradle_task }}
- name: Run Unit Tests
shell: bash
run: ./gradlew --continue ${{ inputs.test_gradle_task }}
- name: Danger action
uses: MeilCli/danger-action@v2
continue-on-error: true
with:
plugins_file: 'Gemfile'
danger_file: 'Dangerfile'
danger_id: 'danger-pr'
env:
DANGER_GITHUB_API_TOKEN: ${{ github.token }}
56 changes: 56 additions & 0 deletions .github/actions/android-generate-baseline-profiles/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Generate Baseline Profiles
description: Generates baseline profiles and creates a PR with the changes

inputs:
# Required inputs
generate_gradle_task:
description: "A Gradle task for generating baseline profiles, for example `generateBaselineProfile`"
required: true
signing_keystore_password:
description: "Password to provided keystore"
required: true
signing_key_alias:
description: "Alias of the signing key in the provided keystore"
required: true
signing_key_password:
description: "Password to the key in the provided keystore"
required: true
secret_properties_file:
description: "A path to file that will be populated with contents of 'SECRET_PROPERTIES' secret. This file can be picked up by Secrets Gradle plugin to embed secrets into BuildConfig."
required: false
default: 'secrets.properties'
secret_properties:
required: false
description: "Custom string that contains key-value properties as secrets. Contents of this secret will be placed into file specified by 'SECRET_PROPERTIES_FILE' input."

runs:
using: "composite"
steps:
- name: Enable KVM group perms
shell: bash
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
ls /dev/kvm
- name: Prepare Environment
shell: bash
run: |
echo '${{ inputs.secret_properties }}' > ${{ inputs.secret_properties_file }}
- name: Generate profiles
env:
ANDROID_KEYSTORE_PASSWORD: ${{ inputs.signing_keystore_password }}
ANDROID_KEY_ALIAS: ${{ inputs.signing_key_alias }}
ANDROID_KEY_PASSWORD: ${{ inputs.signing_key_password }}
shell: bash
run: ./gradlew ${{ inputs.generate_gradle_task }}
-Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true
-Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
commit-message: 'Generate baseline profiles'
branch: 'feature/generate-baseline-profiles'
title: 'Generate baseline profiles'
body: ''

54 changes: 54 additions & 0 deletions .github/actions/android-setup-environment/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Set up Android environment
description: Sets up Java, Gradle and Ruby and other preconditions for CI runs at Futured Android workflows.

inputs:
# Java
java:
description: "Whether to set up Java"
required: false
default: 'true'
java_version:
description: "Java version to use, eg. '17'."
required: false
default: '17'
java_distribution:
description: "Java distribution to use, eg 'zulu'."
required: false
default: 'zulu'
# Ruby
ruby:
description: "Whether to set up Ruby"
required: false
default: 'true'
ruby_version:
description: "Ruby version."
required: false
default: '3.4'
# Gradle
gradle:
description: "Whether to set up Gradle"
required: false
default: 'true'
gradle_cache_encryption_key:
description: "Configuration cache encryption key. Leave empty if you don't need cache."
required: false

runs:
using: "composite"
steps:
- name: Setup Ruby
if: ${{ inputs.ruby == 'true' }}
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ inputs.ruby_version }}
- name: Setup Java
if: ${{ inputs.java == 'true' }}
uses: actions/setup-java@v4
with:
java-version: ${{ inputs.java_version }}
distribution: ${{ inputs.java_distribution }}
- name: Setup Gradle
if: ${{ inputs.gradle == 'true' }}
uses: gradle/actions/setup-gradle@v4
with:
cache-encryption-key: ${{ inputs.gradle_cache_encryption_key }}
Loading