Skip to content

Commit

Permalink
Added|Changed: Add github_release_build workflow to attach APKs for…
Browse files Browse the repository at this point in the history
… GitHub release builds, and update `github_action_build` (previously `debug_build`) workflow and `app/build.gradle` to use semantic versioning for app version and add commit hash and `github` to APK file names

The `versionName` will now follow semantic version `2.0.0` spec in the format `major.minor.patch(-prerelease)(+buildmetadata)`. This will make versioning the prerelease and github debug builds versions easier and follow a spec. The @termux devs should make sure that when bumping `versionName` in `build.gradle` file and when creating a tag for new releases on github that they include the patch number as well, like `v0.1.0` instead of just `v0.1`. The `build.gradle` file and `attach_debug_apks_to_release` workflow will now validate the version as well and the build/attachment will fail if `versionName` does not follow the spec. https://semver.org/spec/v2.0.0.html

APKs released on github for debug build workflows and releases are now referred as `Github` releases as per termux/termux-app@7b10a35f and termux/termux-app@94e01d68, so APK filenames have been modified to include `github` in the filename. The APKs are still debuggable, so that tag remains too.

For github workflows the apk filename format will be `termux-boot_<current_version>+<last_commit_hash>.github.debug_<arch>.apk`, like `termux-boot_v0.1.0+xxxxxxxx.github.debug_arm64-v8a.apk` and for github releases it will be `termux-boot_<release_version>+github.debug_<arch>.apk`, like `termux-boot_v0.1.0+github.debug_arm64-v8a.apk`. The `last_commit_hash` will be the first `8` characters of the commit hash. The `<last_commit_hash>.github.debug` will act as `buildmetadata` and will not affect versioning precedence.

The dot `.` is used as tags separator instead of dash `-` for `github` release source and `debug` build type in the apk version tag to be consistent with semver build metadata tags. For example `github-debug` will now be `github.debug`. https://semver.org/#spec-item-10

For github workflows triggered by `push` and `pull_request` triggers, `<current_version>+<last_commit_hash>` will be used as new `versionName`, like `v0.1.0+xxxxxxxx`. This will make tracking which build a user is using easier and help in resolving issues as well.

The `app/build.gradle` now also supports following `TERMUX_BOOT_APP_BUILD__` scoped environmental variables.

- `TERMUX_BOOT_APP_BUILD__APP_VERSION_NAME` will be used as `versionName` if its set.
- `TERMUX_BOOT_APP_BUILD__APK_VERSION_TAG` will be used as `termux-boot_<TERMUX_BOOT_APP_BUILD__APK_VERSION_TAG>.apk` if its set.
  • Loading branch information
agnostic-apollo committed Apr 17, 2024
1 parent f26515e commit cd9d22a
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 29 deletions.
23 changes: 0 additions & 23 deletions .github/workflows/debug_build.yml

This file was deleted.

77 changes: 77 additions & 0 deletions .github/workflows/github_action_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: GitHub Action Build

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone repository
uses: actions/checkout@v4

- name: Build
shell: bash {0}
run: |
exit_on_error() { echo "$1"; exit 1; }
if [ -z "$JAVA_HOME_17_X64" ] || [ ! -f "$JAVA_HOME_17_X64/bin/javac" ] || [ ! -x "$JAVA_HOME_17_X64/bin/javac" ]; then
exit_on_error "jdk-17 binary not found at path '$JAVA_HOME_17_X64/bin/javac' or is not executable."
fi
echo "Setting vars"
if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then
GITHUB_SHA="${{ github.event.pull_request.head.sha }}" # Do not use last merge commit set in GITHUB_SHA
fi
# Set RELEASE_VERSION_NAME to "<CURRENT_VERSION_NAME>+<last_commit_hash>"
CURRENT_VERSION_NAME_REGEX='\s+versionName "([^"]+)"$'
CURRENT_VERSION_NAME="$(grep -m 1 -E "$CURRENT_VERSION_NAME_REGEX" ./app/build.gradle | sed -r "s/$CURRENT_VERSION_NAME_REGEX/\1/")"
RELEASE_VERSION_NAME="v$CURRENT_VERSION_NAME+${GITHUB_SHA:0:7}" # The "+" is necessary so that versioning precedence is not affected
if ! printf "%s" "${RELEASE_VERSION_NAME/v/}" | grep -qP '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'; then
exit_on_error "The release version '${RELEASE_VERSION_NAME/v/}' generated from current version '$CURRENT_VERSION_NAME' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html."
fi
APK_DIR_PATH="./app/build/outputs/apk/debug"
APK_VERSION_TAG="$RELEASE_VERSION_NAME.github.debug" # Note the ".", GITHUB_SHA will already have "+" before it
APK_BASENAME_PREFIX="termux-boot_$APK_VERSION_TAG"
# Used by upload step later
echo "APK_DIR_PATH=$APK_DIR_PATH" >> $GITHUB_ENV
echo "APK_VERSION_TAG=$APK_VERSION_TAG" >> $GITHUB_ENV
echo "APK_BASENAME_PREFIX=$APK_BASENAME_PREFIX" >> $GITHUB_ENV
echo "Building APK file for '$RELEASE_VERSION_NAME' release with '$APK_VERSION_TAG' tag"
export TERMUX_BOOT_APP_BUILD__APP_VERSION_NAME="${RELEASE_VERSION_NAME/v/}" # Used by app/build.gradle
export TERMUX_BOOT_APP_BUILD__APK_VERSION_TAG="$APK_VERSION_TAG" # Used by app/build.gradle
export GRADLE_OPTS="-Dorg.gradle.java.home=$JAVA_HOME_17_X64"
if ! ./gradlew assembleDebug; then
exit_on_error "Build failed for '$RELEASE_VERSION_NAME' release with '$APK_VERSION_TAG' tag."
fi
echo "Validating APK file"
if ! test -f "$APK_DIR_PATH/${APK_BASENAME_PREFIX}.apk"; then
files_found="$(ls "$APK_DIR_PATH")"
exit_on_error "Failed to find built APK file at '$APK_DIR_PATH/${APK_BASENAME_PREFIX}.apk'. Files found: "$'\n'"$files_found"
fi
echo "Generating checksums-sha256.txt file"
if ! (cd "$APK_DIR_PATH"; sha256sum "${APK_BASENAME_PREFIX}.apk" > checksums-sha256.txt); then
exit_on_error "Generate checksums-sha256.txt file failed for '$RELEASE_VERSION_NAME' release."
fi
echo "checksums-sha256.txt:"$'\n```\n'"$(cat "$APK_DIR_PATH/checksums-sha256.txt")"$'\n```'
- name: Upload files to action
uses: actions/upload-artifact@v4
with:
name: ${{ env.APK_BASENAME_PREFIX }}
path: |
${{ env.APK_DIR_PATH }}/${{ env.APK_BASENAME_PREFIX }}.apk
${{ env.APK_DIR_PATH }}/checksums-sha256.txt
${{ env.APK_DIR_PATH }}/output-metadata.json
69 changes: 69 additions & 0 deletions .github/workflows/github_release_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: GitHub Release Build

on:
release:
types:
- published

jobs:
build:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Clone repository
uses: actions/checkout@v4
with:
ref: ${{ env.GITHUB_REF }}

- name: Build and upload files to release
shell: bash {0}
run: |
exit_on_error() {
echo "$1"
echo "Deleting '$RELEASE_VERSION_NAME' release and '$GITHUB_REF' tag"
hub release delete "$RELEASE_VERSION_NAME"
git push --delete origin "$GITHUB_REF"
exit 1
}
if [ -z "$JAVA_HOME_17_X64" ] || [ ! -f "$JAVA_HOME_17_X64/bin/javac" ] || [ ! -x "$JAVA_HOME_17_X64/bin/javac" ]; then
exit_on_error "jdk-17 binary not found at path '$JAVA_HOME_17_X64/bin/javac' or is not executable."
fi
echo "Setting vars"
RELEASE_VERSION_NAME="${GITHUB_REF/refs\/tags\//}"
if ! printf "%s" "${RELEASE_VERSION_NAME/v/}" | grep -qP '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'; then
exit_on_error "The release version '${RELEASE_VERSION_NAME/v/}' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html."
fi
APK_DIR_PATH="./app/build/outputs/apk/debug"
APK_VERSION_TAG="$RELEASE_VERSION_NAME+github.debug"
APK_BASENAME_PREFIX="termux-boot_$APK_VERSION_TAG"
echo "Building APK file for '$RELEASE_VERSION_NAME' release with '$APK_VERSION_TAG' tag"
export TERMUX_BOOT_APP_BUILD__APK_VERSION_TAG="$APK_VERSION_TAG" # Used by app/build.gradle
export GRADLE_OPTS="-Dorg.gradle.java.home=$JAVA_HOME_17_X64"
if ! ./gradlew assembleDebug; then
exit_on_error "Build failed for '$RELEASE_VERSION_NAME' release with '$APK_VERSION_TAG' tag."
fi
echo "Validating APK file"
if ! test -f "$APK_DIR_PATH/${APK_BASENAME_PREFIX}.apk"; then
files_found="$(ls "$APK_DIR_PATH")"
exit_on_error "Failed to find built APK file at '$APK_DIR_PATH/${APK_BASENAME_PREFIX}.apk'. Files found: "$'\n'"$files_found"
fi
echo "Generating checksums-sha256.txt file"
if ! (cd "$APK_DIR_PATH"; sha256sum "${APK_BASENAME_PREFIX}.apk" > checksums-sha256.txt); then
exit_on_error "Generate checksums-sha256.txt file failed for '$RELEASE_VERSION_NAME' release."
fi
echo "checksums-sha256.txt:"$'\n```\n'"$(cat "$APK_DIR_PATH/checksums-sha256.txt")"$'\n```'
echo "Uploading files to release"
if ! gh release upload "$RELEASE_VERSION_NAME" \
"$APK_DIR_PATH/${APK_BASENAME_PREFIX}.apk" \
"$APK_DIR_PATH/checksums-sha256.txt" \
; then
exit_on_error "Upload files to release failed for '$RELEASE_VERSION_NAME' release."
fi
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Termux:Boot application can be obtained from [F-Droid](https://f-droid.org/en/pa

Additionally we provide per-commit debug builds for those who want to try
out the latest features or test their pull request. This build can be obtained
from one of the workflow runs listed on [Github Actions](https://github.com/termux/termux-boot/actions)
from one of the workflow runs listed on [Github Actions](https://github.com/termux/termux-boot/actions/workflows/github_action_build.yml?query=branch%3Amaster+event%3Apush)
page.

Signature keys of all offered builds are different. Before you switch the
Expand Down
32 changes: 27 additions & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ android {

compileSdk project.properties.compileSdkVersion.toInteger()

def appVersionName = System.getenv("TERMUX_BOOT_APP_BUILD__APP_VERSION_NAME") ?: ""
def apkVersionTag = System.getenv("TERMUX_BOOT_APP_BUILD__APK_VERSION_TAG") ?: ""

defaultConfig {
applicationId "com.termux.boot"
minSdk project.properties.minSdkVersion.toInteger()
targetSdk project.properties.targetSdkVersion.toInteger()
versionCode 7
versionName "0.7"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
versionName "0.7.0"

if (appVersionName) versionName = appVersionName
validateVersionName(versionName)
}

signingConfigs {
Expand Down Expand Up @@ -39,14 +44,31 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

applicationVariants.all { variant ->
variant.outputs.all { output ->
if (variant.buildType.name == "debug") {
outputFileName = new File("termux-boot_" + (apkVersionTag ? apkVersionTag : "debug") + ".apk")
} else if (variant.buildType.name == "release") {
outputFileName = new File("termux-boot_" + (apkVersionTag ? apkVersionTag : "release") + ".apk")
}
}
}
}

dependencies {
implementation "androidx.annotation:annotation:1.7.0"
}

task versionName {
doLast {
print android.defaultConfig.versionName
}
doLast {
print android.defaultConfig.versionName
}
}

def validateVersionName(String versionName) {
// https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
// ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
if (!java.util.regex.Pattern.matches("^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?\$", versionName))
throw new GradleException("The versionName '" + versionName + "' is not a valid version as per semantic version '2.0.0' spec in the format 'major.minor.patch(-prerelease)(+buildmetadata)'. https://semver.org/spec/v2.0.0.html.")
}

0 comments on commit cd9d22a

Please sign in to comment.