From c311c86c428de74bb76b5d2ab588f0e82e551bf3 Mon Sep 17 00:00:00 2001 From: souravanand001 Date: Wed, 1 Jul 2026 03:00:44 +0530 Subject: [PATCH] Added initial CI/CD build setup --- .github/workflows/ci-cd.yml | 89 +++++++++++++++++++++++++++++++++++++ app/build.gradle.kts | 31 +++++++++++-- 2 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/ci-cd.yml diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 0000000..6e62924 --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,89 @@ +name: CI/CD Pipeline + +on: + pull_request: + branches: + - main + push: + branches: + - main + - version_2.1 + +permissions: + contents: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: '17' + cache: 'gradle' + + - name: Make Gradlew Executable + run: chmod +x gradlew + + - name: Run Spotless Check + run: ./gradlew spotlessCheck + + - name: Run Unit Tests + run: ./gradlew testDebugUnitTest + + - name: Build Debug APK + if: github.event_name == 'pull_request' + run: ./gradlew assembleDebug + + # Decode Keystore - only runs on push events to main or version_2.1 + - name: Decode Keystore + if: github.event_name == 'push' + env: + KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }} + run: | + if [ -z "$KEYSTORE_BASE64" ]; then + echo "Error: KEYSTORE_BASE64 secret is not defined." + exit 1 + fi + echo "$KEYSTORE_BASE64" | base64 --decode > "${{ runner.temp }}/keystore.jks" + + # Build Release APK - only runs on push events to main or version_2.1 + - name: Build Release APK + if: github.event_name == 'push' + env: + KEYSTORE_FILE_PATH: ${{ runner.temp }}/keystore.jks + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }} + KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }} + run: | + if [ -z "$KEYSTORE_PASSWORD" ] || [ -z "$KEYSTORE_KEY_ALIAS" ] || [ -z "$KEYSTORE_KEY_PASSWORD" ]; then + echo "Error: Keystore signing secrets are missing." + exit 1 + fi + ./gradlew assembleRelease + + # Rename Release APK - only runs on push events to main or version_2.1 + - name: Rename Release APK with Version + if: github.event_name == 'push' + run: | + VERSION_NAME="2.1.${{ github.run_number }}" + mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/assistant-v${VERSION_NAME}.apk + echo "VERSION_NAME=${VERSION_NAME}" >> $GITHUB_ENV + + # Create GitHub Release - only runs on push events to main or version_2.1 + - name: Create GitHub Release and Upload APK + if: github.event_name == 'push' + uses: softprops/action-gh-release@v2 + with: + tag_name: v${{ env.VERSION_NAME }} + name: Release v${{ env.VERSION_NAME }} + draft: false + prerelease: ${{ github.ref_name != 'main' }} + files: app/build/outputs/apk/release/assistant-v${{ env.VERSION_NAME }}.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index cc4dd26..f8ef375 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,8 +16,9 @@ android { applicationId = "com.app.assistant" minSdk = 24 targetSdk = 35 - versionCode = 1 - versionName = "1.0" + val runNumber = System.getenv("GITHUB_RUN_NUMBER")?.toIntOrNull() ?: 0 + versionCode = 2 + runNumber + versionName = if (runNumber > 0) "2.1.$runNumber" else "2.1" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -46,6 +47,27 @@ android { ) } + val keystoreFilePath = System.getenv("KEYSTORE_FILE_PATH") + val keystorePassword = System.getenv("KEYSTORE_PASSWORD") + val keystoreKeyAlias = System.getenv("KEYSTORE_KEY_ALIAS") + val keystoreKeyPassword = System.getenv("KEYSTORE_KEY_PASSWORD") + + val hasSigningConfig = !keystoreFilePath.isNullOrEmpty() && + !keystorePassword.isNullOrEmpty() && + !keystoreKeyAlias.isNullOrEmpty() && + !keystoreKeyPassword.isNullOrEmpty() + + signingConfigs { + if (hasSigningConfig) { + create("release") { + storeFile = file(keystoreFilePath) + storePassword = keystorePassword + keyAlias = keystoreKeyAlias + keyPassword = keystoreKeyPassword + } + } + } + buildTypes { release { isMinifyEnabled = false @@ -53,8 +75,9 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) - // You might want to also define buildConfigFields for release - // if you have different keys for release builds, or if local.properties is not available in CI + if (hasSigningConfig) { + signingConfig = signingConfigs.getByName("release") + } } debug { // BuildConfigFields from defaultConfig are inherited.