From 29616b1cf715915ba45abb895935d868788b6056 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Thu, 2 Jan 2025 11:46:41 +0530 Subject: [PATCH 1/9] Fixed: Reproducible Builds. * To generate the APK for a specific date, set the "RELEASE_DATE" environment variable in the format `YYYY-MM-DD`. The APK will be generated for the specified date. If the variable is not set, the APK will be generated for the current date. --- buildSrc/src/main/kotlin/VersionCodeGenerator.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt index 269b31198..aa5355415 100644 --- a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt +++ b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt @@ -23,9 +23,18 @@ fun String.getVersionCode(): Int { // the date when the automatic version code generation started val lastDate = LocalDate.of(2024, 7, 17) + // Get the current date. If the "RELEASE_DATE" environment variable is set(in YYYY-MM-DD format). + // it uses the specified date to generate the APK version code. + // Otherwise, it generates the version code based on the current date. + // See https://github.com/kiwix/kiwix-android/issues/4120 for more details. + val currentDate = if (!System.getenv("RELEASE_DATE").isNullOrEmpty()) { + LocalDate.parse(System.getenv("RELEASE_DATE")) + } else { + LocalDate.now() + } // Calculate the number of days between the lastDate and today's date. // This gives us the total number of days since the last version code was set. - val daysDifference = ChronoUnit.DAYS.between(lastDate, LocalDate.now()).toInt() + val daysDifference = ChronoUnit.DAYS.between(lastDate, currentDate).toInt() // Base version code. This is the version code of the last release uploaded to the Play Store. // We use this as the starting point for generating new version codes automatically. From caa45c5f5153ba23e7ddd6798e1a0e09fd560b34 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Thu, 2 Jan 2025 18:02:09 +0530 Subject: [PATCH 2/9] Renamed the environment variable to `KIWIX_ANDROID_RELEASE_DATE`. * Made `LAST_DATE` and `BASE_VERSION_CODE` constants, as these values are crucial for our app and should not be changed. We have marked them as constants and added comments to ensure they remain unchanged. --- .../src/main/kotlin/VersionCodeGenerator.kt | 41 +++++++++++-------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt index aa5355415..392bb5b14 100644 --- a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt +++ b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt @@ -1,6 +1,3 @@ -import java.time.LocalDate -import java.time.temporal.ChronoUnit - /* * Kiwix Android * Copyright (c) 2024 Kiwix @@ -19,29 +16,37 @@ import java.time.temporal.ChronoUnit * */ -fun String.getVersionCode(): Int { - // the date when the automatic version code generation started - val lastDate = LocalDate.of(2024, 7, 17) +import java.time.LocalDate +import java.time.temporal.ChronoUnit - // Get the current date. If the "RELEASE_DATE" environment variable is set(in YYYY-MM-DD format). - // it uses the specified date to generate the APK version code. +/** + * The date when the automatic version code generation started. + */ +val LAST_DATE: LocalDate = LocalDate.of(2024, 7, 17) + +/** + * Base version code. This is the version code of the last release uploaded to the Play Store. + * We use this as the starting point for generating new version codes automatically. + */ +const val BASE_VERSION_CODE = 231101 + +fun String.getVersionCode(): Int { + // Get the current date. If the "KIWIX_ANDROID_RELEASE_DATE" environment + // variable is set(in YYYY-MM-DD format). + // It uses the specified date to generate the APK version code. // Otherwise, it generates the version code based on the current date. // See https://github.com/kiwix/kiwix-android/issues/4120 for more details. - val currentDate = if (!System.getenv("RELEASE_DATE").isNullOrEmpty()) { - LocalDate.parse(System.getenv("RELEASE_DATE")) + val currentDate = if (!System.getenv("KIWIX_ANDROID_RELEASE_DATE").isNullOrEmpty()) { + LocalDate.parse(System.getenv("KIWIX_ANDROID_RELEASE_DATE")) } else { LocalDate.now() } - // Calculate the number of days between the lastDate and today's date. + // Calculate the number of days between the LAST_DATE and today's date. // This gives us the total number of days since the last version code was set. - val daysDifference = ChronoUnit.DAYS.between(lastDate, currentDate).toInt() - - // Base version code. This is the version code of the last release uploaded to the Play Store. - // We use this as the starting point for generating new version codes automatically. - val baseVersionCode = 231101 + val daysDifference = ChronoUnit.DAYS.between(LAST_DATE, currentDate).toInt() // Generate and return the new version code. - // The new version code is calculated by adding the number of days since lastDate + // The new version code is calculated by adding the number of days since LAST_DATE // to the base version code. This creates a unique version code for each day. - return baseVersionCode + daysDifference + return BASE_VERSION_CODE + daysDifference } From ae7988f112aee7ac541877b15e149272e23818c1 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Fri, 3 Jan 2025 11:23:40 +0530 Subject: [PATCH 3/9] Refactored `testing_release` CD workflow to generate and publish the application on the Play Store based on a specified date, using a new tag format `internal_testing_v*` where `*` is replaced by the date, which is extracted and set as an environment variable to generate the app bundle for that date, defaulting to the current date if no date is provided, and uploading the generated app bundle to the Play Store. --- .github/workflows/testing_release.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/testing_release.yml b/.github/workflows/testing_release.yml index 393370a4a..f68656fd2 100644 --- a/.github/workflows/testing_release.yml +++ b/.github/workflows/testing_release.yml @@ -7,6 +7,7 @@ on: push: tags: - 'internal_testing' # internal_testing Tag + - 'internal_testing_v*' # Dynamic date tag for internal testing jobs: publish: @@ -29,10 +30,21 @@ jobs: echo "$KEYSTORE" | base64 -d > kiwix-android.keystore echo "$PLAYSTORE_JSON" > playstore.json + - name: Retrieve date from TAG + id: extract_date + run: | + if [[ "${GITHUB_REF}" =~ internal_testing_v([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then + RELEASE_DATE="${BASH_REMATCH[1]}" + else + RELEASE_DATE="" + fi + echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + - name: Publish bundle in internal testing on Google Play env: KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} + KIWIX_ANDROID_RELEASE_DATE: ${{ env.KIWIX_ANDROID_RELEASE_DATE }} run: | ./gradlew publishPlayStoreBundle --scan From a371ae6d67e6078107184336c7558760371b24e7 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Fri, 3 Jan 2025 12:20:57 +0530 Subject: [PATCH 4/9] We refactored our `dummy_bundle.yml` workflow to generate the dummy bundle and APKs based on a specified date, using a new tag format `dummy_bundle_and_apk_v*`, where `*` is replaced by the date in `YYYY_MM_DD`. This date is extracted and set as an environment variable to generate the app bundle and APK for that date, defaulting to the current date if no date is provided. * Now, our `dummy_bundle.yml` will generate both the app bundle and APKs, so if we need the APK for a specified date, we can easily retrieve it. * Added comments in both workflows to understand the flow of the workflows. --- .github/workflows/dummy_bundle.yml | 50 -------------- .github/workflows/dummy_bundle_and_apk.yml | 76 ++++++++++++++++++++++ .github/workflows/testing_release.yml | 8 ++- 3 files changed, 83 insertions(+), 51 deletions(-) delete mode 100644 .github/workflows/dummy_bundle.yml create mode 100644 .github/workflows/dummy_bundle_and_apk.yml diff --git a/.github/workflows/dummy_bundle.yml b/.github/workflows/dummy_bundle.yml deleted file mode 100644 index bd946537c..000000000 --- a/.github/workflows/dummy_bundle.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: Generate dummy bundle - -# The workflow will trigger when the `dummy_bundle` tag is pushed. -on: - push: - tags: - - 'dummy_bundle' # dummy_bundle Tag - -jobs: - publish_dummy_bundle: - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: 17 - distribution: temurin - - - name: Preparing signing material - env: - KEYSTORE: ${{ secrets.keystore }} - run: | - echo "$KEYSTORE" | base64 -d > kiwix-android.keystore - - - name: Generate dummy Bundle - env: - KEY_ALIAS: ${{ secrets.KEY_ALIAS }} - KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} - KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} - run: | - ./gradlew bundlePlayStore --scan - - - - name: Get Bundle name and path - id: bundle-path - run: | - BUNDLE_PATH="app/build/outputs/bundle/playStore/kiwix-playStore.aab" - BUNDLE_NAME="PlayStoreDummyBundle.aab" - echo "bundle_path=$BUNDLE_PATH" >> $GITHUB_ENV - echo "bundle_name=$BUNDLE_NAME" >> $GITHUB_ENV - - - name: Upload Bundle as an artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ env.bundle_name }} - path: ${{ env.bundle_path }} - diff --git a/.github/workflows/dummy_bundle_and_apk.yml b/.github/workflows/dummy_bundle_and_apk.yml new file mode 100644 index 000000000..d43215f37 --- /dev/null +++ b/.github/workflows/dummy_bundle_and_apk.yml @@ -0,0 +1,76 @@ +name: Generate dummy bundle and APK + +# This workflow will trigger when the 'dummy_bundle_and_apk' or 'dummy_bundle_and_apk_v*' tag is pushed. +# In 'dummy_bundle_and_apk_v*', '*' is a dynamic date pushed in the tag. +# The date format should be YYYY-MM-DD (e.g., 2024-12-18). +on: + push: + tags: + - 'dummy_bundle_and_apk' # dummy_bundle_and_apk Tag. + - 'dummy_bundle_and_apk_v*' # Trigger for generating dummy bundle and APKs with dynamic date. + +jobs: + publish_dummy_bundle_and_apk: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + + - name: Preparing signing material + env: + KEYSTORE: ${{ secrets.keystore }} + run: | + echo "$KEYSTORE" | base64 -d > kiwix-android.keystore + + - name: Retrieve date from TAG + id: extract_date + run: | + # Check if the tag matches the pattern 'dummy_bundle_and_apk_vYYYY-MM-DD'. + # If the date is found in the tag, it will be extracted and set as the RELEASE_DATE. + # If no date is found or the tag does not match, an empty string will be set for RELEASE_DATE, + # and Android will generate the APK and app bundle for the current date. + if [[ "${GITHUB_REF}" =~ dummy_bundle_and_apk_v([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then + RELEASE_DATE="${BASH_REMATCH[1]}" + else + RELEASE_DATE="" + fi + echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + + - name: Generate dummy Bundle and APKs + env: + KEY_ALIAS: ${{ secrets.KEY_ALIAS }} + KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} + KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} + KIWIX_ANDROID_RELEASE_DATE: ${{ env.KIWIX_ANDROID_RELEASE_DATE }} + run: | + ./gradlew bundlePlayStore assembleRelease --scan + + + - name: Get Bundle and APKs name and path + id: get-bundle-and-apk-paths + run: | + BUNDLE_PATH="app/build/outputs/bundle/playStore/kiwix-playStore.aab" + BUNDLE_NAME="PlayStoreDummyBundle.aab" + echo "bundle_path=$BUNDLE_PATH" >> $GITHUB_ENV + echo "bundle_name=$BUNDLE_NAME" >> $GITHUB_ENV + APK_DIR="app/build/outputs/apk/release/" + echo "apk_dir=$APK_DIR" >> $GITHUB_ENV + + - name: Upload Bundle as an artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ env.bundle_name }} + path: ${{ env.bundle_path }} + + - name: Upload All Release APKs as artifacts + uses: actions/upload-artifact@v4 + with: + name: ReleaseApks + path: ${{ env.apk_dir }}*.apk + diff --git a/.github/workflows/testing_release.yml b/.github/workflows/testing_release.yml index f68656fd2..6a894fc37 100644 --- a/.github/workflows/testing_release.yml +++ b/.github/workflows/testing_release.yml @@ -1,6 +1,8 @@ name: Publish App to Play Store -# Trigger the workflow on a schedule (every Monday at 12:00 UTC) +# This workflow is triggered on a schedule or when specific tags are pushed. +# It runs every Monday at 12:00 UTC and also when the 'internal_testing' or 'internal_testing_v*' tag is pushed. +# In 'internal_testing_v*', '*' represents a dynamic date (e.g., 2024-12-18). on: schedule: - cron: '0 12 * * 1' # Runs every Monday at 12:00 @@ -33,6 +35,10 @@ jobs: - name: Retrieve date from TAG id: extract_date run: | + # Check if the tag matches the pattern 'internal_testing_vYYYY-MM-DD'. + # If the date is found in the tag, it will be extracted and set as the RELEASE_DATE. + # If no date is found or the tag does not match, an empty string will be set for RELEASE_DATE. + # Android will use the current date for the APK generation. if [[ "${GITHUB_REF}" =~ internal_testing_v([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then RELEASE_DATE="${BASH_REMATCH[1]}" else From 40285a7cfd16b4487b3d31e0f139010d45ec0026 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Fri, 3 Jan 2025 14:44:16 +0530 Subject: [PATCH 5/9] Documented this new feature in the README.md file so that this feature can be easily used. --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index de89d170c..b06610c61 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,19 @@ want to build the `app` module in the `debug` configuration. If you are interested in our custom apps, they have their own repo [kiwix-android-custom](https://github.com/kiwix/kiwix-android-custom). +## Release + +We have implemented an [automatic version code generation](https://github.com/kiwix/kiwix-android/blob/main/buildSrc/src/main/kotlin/VersionCodeGenerator.kt) system based on the current date. +This ensures that every new build is generated with a unique version code daily. +If you need to generate an APK or app bundle for a specific date, you can do so by creating and pushing one of the following tags: + +- `internal_testing_vYYYY-MM-DD`: If you want to publish the app bundle for a specific date on play store, create a tag e.g. `internal_testing_v2024-12-18` and push it. + This will automatically trigger the [testing_release](https://github.com/kiwix/kiwix-android/blob/main/.github/workflows/testing_release.yml) workflow, which generates the app bundle + and publishes the application to the internal testing track on the play store. +- `dummy_bundle_and_apk_vYYYY-MM-DD`: If you need a bundle or APK for specific date, create a tag e.g. `dummy_bundle_and_apk_v2024-12-18` and push it, it will automatically triggered + the [dummy_bundle_and_apk](https://github.com/kiwix/kiwix-android/blob/main/.github/workflows/dummy_bundle_and_apk.yml) workflow, which creates the app bundle and APK for specific date. + The generated files can be found in the triggered workflow. + ## Libraries Used - [Libkiwix](https://github.com/kiwix/java-libkiwix) - Kotlin/Java binding for the core Kiwix From ce830093f951acd8d4ce6e95aea56d4437e89af9 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Fri, 3 Jan 2025 17:26:42 +0530 Subject: [PATCH 6/9] Made the `LAST_DATE` const so that it can not be changed. --- buildSrc/src/main/kotlin/VersionCodeGenerator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt index 392bb5b14..c962a9d47 100644 --- a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt +++ b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt @@ -22,7 +22,7 @@ import java.time.temporal.ChronoUnit /** * The date when the automatic version code generation started. */ -val LAST_DATE: LocalDate = LocalDate.of(2024, 7, 17) +const val LAST_DATE = "2024-07-17" /** * Base version code. This is the version code of the last release uploaded to the Play Store. @@ -43,7 +43,7 @@ fun String.getVersionCode(): Int { } // Calculate the number of days between the LAST_DATE and today's date. // This gives us the total number of days since the last version code was set. - val daysDifference = ChronoUnit.DAYS.between(LAST_DATE, currentDate).toInt() + val daysDifference = ChronoUnit.DAYS.between(LocalDate.parse(LAST_DATE), currentDate).toInt() // Generate and return the new version code. // The new version code is calculated by adding the number of days since LAST_DATE From 66f3d4d7cdb35957a4cd94c0ade45cf8217f209b Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Sat, 4 Jan 2025 12:24:26 +0530 Subject: [PATCH 7/9] Refactored all CD pipelines to generate APKs and app bundles based on the relevant git revision. * The date is extracted from the specified git revision and set in the `KIWIX_ANDROID_RELEASE_DATE` environment variable, and the version code is generated for that date. * This feature has been added to the Release section in the README file. --- .github/workflows/dummy_bundle_and_apk.yml | 21 ++++++++------------- .github/workflows/release.yml | 14 ++++++++++++++ .github/workflows/testing_release.yml | 20 ++++++++------------ README.md | 14 ++++---------- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/.github/workflows/dummy_bundle_and_apk.yml b/.github/workflows/dummy_bundle_and_apk.yml index d43215f37..4a43c47f8 100644 --- a/.github/workflows/dummy_bundle_and_apk.yml +++ b/.github/workflows/dummy_bundle_and_apk.yml @@ -1,13 +1,10 @@ name: Generate dummy bundle and APK -# This workflow will trigger when the 'dummy_bundle_and_apk' or 'dummy_bundle_and_apk_v*' tag is pushed. -# In 'dummy_bundle_and_apk_v*', '*' is a dynamic date pushed in the tag. -# The date format should be YYYY-MM-DD (e.g., 2024-12-18). +# This workflow will trigger when the 'dummy_bundle_and_apk' is pushed. on: push: tags: - 'dummy_bundle_and_apk' # dummy_bundle_and_apk Tag. - - 'dummy_bundle_and_apk_v*' # Trigger for generating dummy bundle and APKs with dynamic date. jobs: publish_dummy_bundle_and_apk: @@ -28,19 +25,17 @@ jobs: run: | echo "$KEYSTORE" | base64 -d > kiwix-android.keystore - - name: Retrieve date from TAG - id: extract_date + - name: Retrieve date from git revision + id: git_date run: | - # Check if the tag matches the pattern 'dummy_bundle_and_apk_vYYYY-MM-DD'. - # If the date is found in the tag, it will be extracted and set as the RELEASE_DATE. - # If no date is found or the tag does not match, an empty string will be set for RELEASE_DATE, - # and Android will generate the APK and app bundle for the current date. - if [[ "${GITHUB_REF}" =~ dummy_bundle_and_apk_v([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then - RELEASE_DATE="${BASH_REMATCH[1]}" + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") + if [ "$DATE" = "NoCommits" ]; then + RELEASE_DATE="" else - RELEASE_DATE="" + RELEASE_DATE="$DATE" fi echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + shell: bash - name: Generate dummy Bundle and APKs env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0c2e8304..f540ce8d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,18 @@ jobs: - name: Set tag variable run: echo "TAG=$(echo ${GITHUB_REF:10})" >> $GITHUB_ENV + - name: Retrieve date from git revision + id: git_date + run: | + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") + if [ "$DATE" = "NoCommits" ]; then + RELEASE_DATE="" + else + RELEASE_DATE="$DATE" + fi + echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + shell: bash + - name: Retrieve secrets to files env: KEYSTORE: ${{ secrets.keystore }} @@ -37,6 +49,7 @@ jobs: KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} UNIVERSAL_RELEASE_APK: app/build/outputs/apk/standalone/*universal*.apk ARCHIVE_NAME: kiwix-${{ github.event.release.tag_name }}.apk + KIWIX_ANDROID_RELEASE_DATE: ${{ env.KIWIX_ANDROID_RELEASE_DATE }} run: | ./gradlew assembleStandalone cp ${UNIVERSAL_RELEASE_APK} ${ARCHIVE_NAME} @@ -64,6 +77,7 @@ jobs: KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} PLAYSTORE_JSON: ${{ secrets.PLAYSTORE_JSON }} + KIWIX_ANDROID_RELEASE_DATE: ${{ env.KIWIX_ANDROID_RELEASE_DATE }} run: | echo "$PLAYSTORE_JSON" > playstore.json ./gradlew publishPlayStoreBundle --scan diff --git a/.github/workflows/testing_release.yml b/.github/workflows/testing_release.yml index 6a894fc37..de0590758 100644 --- a/.github/workflows/testing_release.yml +++ b/.github/workflows/testing_release.yml @@ -1,15 +1,13 @@ name: Publish App to Play Store # This workflow is triggered on a schedule or when specific tags are pushed. -# It runs every Monday at 12:00 UTC and also when the 'internal_testing' or 'internal_testing_v*' tag is pushed. -# In 'internal_testing_v*', '*' represents a dynamic date (e.g., 2024-12-18). +# It runs every Monday at 12:00 UTC and also when the 'internal_testing' tag is pushed. on: schedule: - cron: '0 12 * * 1' # Runs every Monday at 12:00 push: tags: - 'internal_testing' # internal_testing Tag - - 'internal_testing_v*' # Dynamic date tag for internal testing jobs: publish: @@ -32,19 +30,17 @@ jobs: echo "$KEYSTORE" | base64 -d > kiwix-android.keystore echo "$PLAYSTORE_JSON" > playstore.json - - name: Retrieve date from TAG - id: extract_date + - name: Retrieve date from git revision + id: git_date run: | - # Check if the tag matches the pattern 'internal_testing_vYYYY-MM-DD'. - # If the date is found in the tag, it will be extracted and set as the RELEASE_DATE. - # If no date is found or the tag does not match, an empty string will be set for RELEASE_DATE. - # Android will use the current date for the APK generation. - if [[ "${GITHUB_REF}" =~ internal_testing_v([0-9]{4}-[0-9]{2}-[0-9]{2}) ]]; then - RELEASE_DATE="${BASH_REMATCH[1]}" + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") + if [ "$DATE" = "NoCommits" ]; then + RELEASE_DATE="" else - RELEASE_DATE="" + RELEASE_DATE="$DATE" fi echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + shell: bash - name: Publish bundle in internal testing on Google Play env: diff --git a/README.md b/README.md index b06610c61..c88da6ac7 100644 --- a/README.md +++ b/README.md @@ -101,16 +101,10 @@ are interested in our custom apps, they have their own repo ## Release -We have implemented an [automatic version code generation](https://github.com/kiwix/kiwix-android/blob/main/buildSrc/src/main/kotlin/VersionCodeGenerator.kt) system based on the current date. -This ensures that every new build is generated with a unique version code daily. -If you need to generate an APK or app bundle for a specific date, you can do so by creating and pushing one of the following tags: - -- `internal_testing_vYYYY-MM-DD`: If you want to publish the app bundle for a specific date on play store, create a tag e.g. `internal_testing_v2024-12-18` and push it. - This will automatically trigger the [testing_release](https://github.com/kiwix/kiwix-android/blob/main/.github/workflows/testing_release.yml) workflow, which generates the app bundle - and publishes the application to the internal testing track on the play store. -- `dummy_bundle_and_apk_vYYYY-MM-DD`: If you need a bundle or APK for specific date, create a tag e.g. `dummy_bundle_and_apk_v2024-12-18` and push it, it will automatically triggered - the [dummy_bundle_and_apk](https://github.com/kiwix/kiwix-android/blob/main/.github/workflows/dummy_bundle_and_apk.yml) workflow, which creates the app bundle and APK for specific date. - The generated files can be found in the triggered workflow. +We have an [automatic version code generation](https://github.com/kiwix/kiwix-android/blob/main/buildSrc/src/main/kotlin/VersionCodeGenerator.kt) system based on the current date. However, you +can override this by setting the environment variable `KIWIX_ANDROID_RELEASE_DATE` to a specific +date in the `YYYY-MM-DD` format. This will use the provided date for the version code calculation +instead of the current date. ## Libraries Used From befd7d389ada16cfaa6af3cba05bbe2615b78dbd Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Sat, 4 Jan 2025 16:24:47 +0530 Subject: [PATCH 8/9] The testing_release job is skipped, if the application is being uploaded with the same version as the previously uploaded one, and Play Store gives the error for same version code. This prevents the CD pipeline from failing due to this error, while for all other errors, the workflow will fail as expected. --- .github/workflows/testing_release.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/testing_release.yml b/.github/workflows/testing_release.yml index de0590758..93792a106 100644 --- a/.github/workflows/testing_release.yml +++ b/.github/workflows/testing_release.yml @@ -49,4 +49,16 @@ jobs: KEY_STORE_PASSWORD: ${{ secrets.KEY_STORE_PASSWORD }} KIWIX_ANDROID_RELEASE_DATE: ${{ env.KIWIX_ANDROID_RELEASE_DATE }} run: | - ./gradlew publishPlayStoreBundle --scan + OUTPUT=$(./gradlew publishPlayStoreBundle --scan 2>&1) + echo "$OUTPUT" > gradle_output.log + if echo "$OUTPUT" | grep -q "BUILD SUCCESSFUL"; then + echo "$OUTPUT" + exit 0 + fi + + if echo "$OUTPUT" | grep -q "Try another version code."; then + echo "Upload skipped because very same version. $OUTPUT" + exit 0 + fi + echo "$OUTPUT" + exit 1 From 0ec90f06b043874e587c87b5de07f531f74e096a Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Mon, 6 Jan 2025 13:17:16 +0530 Subject: [PATCH 9/9] Added logs to check whether the environment variable is set, for debugging purposes. * Improved the ID of the "Retrieve date from git revision" job. * Removed unnecessary conditions from the workflow. --- .github/workflows/dummy_bundle_and_apk.yml | 11 +++-------- .github/workflows/release.yml | 11 +++-------- .github/workflows/testing_release.yml | 11 +++-------- buildSrc/src/main/kotlin/VersionCodeGenerator.kt | 8 ++++++-- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/.github/workflows/dummy_bundle_and_apk.yml b/.github/workflows/dummy_bundle_and_apk.yml index 4a43c47f8..00736d16c 100644 --- a/.github/workflows/dummy_bundle_and_apk.yml +++ b/.github/workflows/dummy_bundle_and_apk.yml @@ -26,15 +26,10 @@ jobs: echo "$KEYSTORE" | base64 -d > kiwix-android.keystore - name: Retrieve date from git revision - id: git_date + id: git_head_revision_date run: | - DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") - if [ "$DATE" = "NoCommits" ]; then - RELEASE_DATE="" - else - RELEASE_DATE="$DATE" - fi - echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d) + echo "KIWIX_ANDROID_RELEASE_DATE=$DATE" >> $GITHUB_ENV shell: bash - name: Generate dummy Bundle and APKs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f540ce8d2..342e9b7dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,15 +22,10 @@ jobs: run: echo "TAG=$(echo ${GITHUB_REF:10})" >> $GITHUB_ENV - name: Retrieve date from git revision - id: git_date + id: git_head_revision_date run: | - DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") - if [ "$DATE" = "NoCommits" ]; then - RELEASE_DATE="" - else - RELEASE_DATE="$DATE" - fi - echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d) + echo "KIWIX_ANDROID_RELEASE_DATE=$DATE" >> $GITHUB_ENV shell: bash - name: Retrieve secrets to files diff --git a/.github/workflows/testing_release.yml b/.github/workflows/testing_release.yml index 93792a106..d9a8362cb 100644 --- a/.github/workflows/testing_release.yml +++ b/.github/workflows/testing_release.yml @@ -31,15 +31,10 @@ jobs: echo "$PLAYSTORE_JSON" > playstore.json - name: Retrieve date from git revision - id: git_date + id: git_head_revision_date run: | - DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d || echo "NoCommits") - if [ "$DATE" = "NoCommits" ]; then - RELEASE_DATE="" - else - RELEASE_DATE="$DATE" - fi - echo "KIWIX_ANDROID_RELEASE_DATE=$RELEASE_DATE" >> $GITHUB_ENV + DATE=$(git log -1 --format=%cd --date=format:%Y-%m-%d) + echo "KIWIX_ANDROID_RELEASE_DATE=$DATE" >> $GITHUB_ENV shell: bash - name: Publish bundle in internal testing on Google Play diff --git a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt index c962a9d47..a61cf3e1e 100644 --- a/buildSrc/src/main/kotlin/VersionCodeGenerator.kt +++ b/buildSrc/src/main/kotlin/VersionCodeGenerator.kt @@ -37,9 +37,13 @@ fun String.getVersionCode(): Int { // Otherwise, it generates the version code based on the current date. // See https://github.com/kiwix/kiwix-android/issues/4120 for more details. val currentDate = if (!System.getenv("KIWIX_ANDROID_RELEASE_DATE").isNullOrEmpty()) { - LocalDate.parse(System.getenv("KIWIX_ANDROID_RELEASE_DATE")) + LocalDate.parse(System.getenv("KIWIX_ANDROID_RELEASE_DATE")).also { + println("Environment variable found. Using date: $it for version code generation.") + } } else { - LocalDate.now() + LocalDate.now().also { + println("No environment variable found. Using current date: $it for version code generation.") + } } // Calculate the number of days between the LAST_DATE and today's date. // This gives us the total number of days since the last version code was set.