Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
123 changes: 79 additions & 44 deletions .github/workflows/pre-release.yml
Original file line number Diff line number Diff line change
@@ -1,56 +1,91 @@
name: Pre-Release Build

on:
workflow_dispatch:
workflow_dispatch: # Allows manual triggering of the workflow
push:
branches-ignore: [ "master" ]
tags: [ "*-pre-release" ]
pull_request:
branches-ignore: [ "master" ]

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
contents: write # Needed for creating a GitHub Release
steps:
- name: Extract tag name
if: startsWith(github.ref, 'refs/tags/')
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Set up environment variables
run: |
echo "GPR_USER=${{ github.actor }}" >> $GITHUB_ENV
echo "GPR_KEY=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_BASE64=${{ secrets.KEYSTORE_BASE64 }}" >> $GITHUB_ENV
echo "BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- uses: actions/checkout@v4
- name: set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build

- name: Archive APK
uses: actions/upload-artifact@v4
with:
name: app-release.apk
path: app/build/outputs/apk/release/app-release.apk

- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
if: startsWith(github.ref, 'refs/tags/')
with:
name: ${{ github.ref_name }}
prerelease: true
generateReleaseNotes: true
artifacts: app/build/outputs/apk/release/app-release.apk, app/manifest.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Extract tag name
# This step only runs if the workflow was triggered by a tag push.
if: startsWith(github.ref, 'refs/tags/')
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV

- name: Set up environment variables
# These environment variables are set for the entire job.
run: |
echo "GPR_USER=${{ github.actor }}" >> $GITHUB_ENV
echo "GPR_KEY=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_BASE64=${{ secrets.KEYSTORE_BASE64 }}" >> $GITHUB_ENV
echo "BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV

- uses: actions/checkout@v4
# This action checks out the code.
# If triggered by a tag, it checks out the exact commit the tag points to.
# If triggered by a branch push, it checks out that branch.

# NEW STEP: Check if the tagged commit is already on the master branch
- name: Check if tagged commit is on master branch
id: check_master_tag
# This step only runs if the workflow was triggered by a tag push.
if: startsWith(github.ref, 'refs/tags/')
run: |
# Fetch all remote branches to ensure 'git branch --contains' has full context
# This is crucial for accurately checking if the commit is on origin/master.
git fetch origin --prune

# Check if the commit pointed to by the tag (${{ github.sha }}) is contained within 'origin/master'.
# If 'origin/master' contains the commit, it means the tagged code is already part of the master branch's history.
if git branch -r --contains ${{ github.sha }} | grep -q "origin/master"; then
echo "IS_ON_MASTER=true" >> $GITHUB_ENV
echo "Tagged commit ${{ github.sha }} IS on origin/master. A release will NOT be created."
else
echo "IS_ON_MASTER=false" >> $GITHUB_ENV
echo "Tagged commit ${{ github.sha }} is NOT on origin/master. A release WILL be created."
fi
# This environment variable (IS_ON_MASTER) will be used in the 'Create Release' step's condition.

- name: set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: ./gradlew build -PpreReleaseVersion=${{ env.RELEASE_VERSION }}

- name: Archive APK
uses: actions/upload-artifact@v4
with:
name: app-release.apk
path: app/build/outputs/apk/release/app-release.apk

- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
# IMPORTANT: The release will now ONLY be created if:
# 1. The workflow was triggered by a tag (startsWith(github.ref, 'refs/tags/'))
# 2. AND the commit pointed to by that tag is NOT already on the 'master' branch (env.IS_ON_MASTER == 'false').
if: startsWith(github.ref, 'refs/tags/') && env.IS_ON_MASTER == 'false'
with:
name: ${{ github.ref_name }}
prerelease: true
generateReleaseNotes: true
artifacts: app/build/outputs/apk/release/app-release.apk, app/manifest.json, config_screen.png, config_screen2.png, example1.png, example2.png, example3.png, example4.png
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4 changes: 2 additions & 2 deletions .github/workflows/release-comments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ jobs:
comment-on-fixed:
runs-on: ubuntu-latest
permissions:
pull-requests: write
issues: write
pull-requests: write
issues: write
steps:
- uses: actions/checkout@v4
with:
Expand Down
78 changes: 39 additions & 39 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,45 @@ jobs:
permissions:
contents: write
steps:
- name: Extract tag name
if: startsWith(github.ref, 'refs/tags/')
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Set up environment variables
run: |
echo "GPR_USER=${{ github.actor }}" >> $GITHUB_ENV
echo "GPR_KEY=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_BASE64=${{ secrets.KEYSTORE_BASE64 }}" >> $GITHUB_ENV
echo "BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- uses: actions/checkout@v4
- name: set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle
- name: Extract tag name
if: startsWith(github.ref, 'refs/tags/')
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Set up environment variables
run: |
echo "GPR_USER=${{ github.actor }}" >> $GITHUB_ENV
echo "GPR_KEY=${{ secrets.GITHUB_TOKEN }}" >> $GITHUB_ENV
echo "KEY_ALIAS=${{ secrets.KEY_ALIAS }}" >> $GITHUB_ENV
echo "KEY_PASSWORD=${{ secrets.KEY_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> $GITHUB_ENV
echo "KEYSTORE_BASE64=${{ secrets.KEYSTORE_BASE64 }}" >> $GITHUB_ENV
echo "BUILD_NUMBER=${{ github.run_number }}" >> $GITHUB_ENV
- uses: actions/checkout@v4
- name: set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: gradle

- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build

- name: Archive APK
uses: actions/upload-artifact@v4
with:
name: app-release.apk
path: app/build/outputs/apk/release/app-release.apk
- name: Archive APK
uses: actions/upload-artifact@v4
with:
name: app-release.apk
path: app/build/outputs/apk/release/app-release.apk

- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
if: startsWith(github.ref, 'refs/tags/')
with:
name: ${{ github.ref_name }}
prerelease: false
generateReleaseNotes: true
artifacts: app/build/outputs/apk/release/app-release.apk, app/manifest.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Release
id: create_release
uses: ncipollo/release-action@v1
if: startsWith(github.ref, 'refs/tags/')
with:
name: ${{ github.ref_name }}
prerelease: false
generateReleaseNotes: true
artifacts: app/build/outputs/apk/release/app-release.apk, app/manifest.json, config_screen.png, config_screen2.png, example1.png, example2.png, example3.png, example4.png
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107 changes: 71 additions & 36 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import groovy.json.JsonBuilder
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
Expand All @@ -13,6 +14,20 @@ kotlin {
}
}

val projectName = "karoo-ext-template"
val screenshotBaseNames = listOf(
"example1.png"
)
val projectLabel = "Karoo Extension Template"
val projectDescription = "Karoo Extension template"
val projectDeveloper = "currand"

kotlin {
compilerOptions {
jvmTarget = JvmTarget.fromTarget("17")
}
}

android {
namespace = "com.currand60.karooexttemplate"
compileSdk = 36
Expand Down Expand Up @@ -61,35 +76,73 @@ dependencies {
implementation(libs.bundles.androidx.lifeycle)
implementation(libs.androidx.activity.compose)
implementation(libs.bundles.compose.ui)
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.datastore.preferences)
implementation(libs.androidx.glance.appwidget)
implementation(libs.androidx.glance.preview)
implementation(libs.androidx.glance.appwidget.preview)
implementation(libs.androidx.navigation.runtime.android)
implementation(libs.javax.inject)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.debug)
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)
implementation(libs.androidx.material.icons.extended)
}

tasks.register("generateManifest") {
description = "Generates manifest.json with current version information"
group = "build"

// Retrieve the preReleaseVersion property at configuration time.
// This makes it a declared input to the task.
val preReleaseVersion = project.providers.gradleProperty("preReleaseVersion")
.getOrElse("")

// Declare the preReleaseVersion as an input property for Gradle's up-to-date checks.
// If this value doesn't change, the task won't re-run.
inputs.property("preReleaseVersion", preReleaseVersion)
val manifestOutputFile = layout.projectDirectory.file("manifest.json")
outputs.file(manifestOutputFile).withPropertyName("manifestFile")

// The task action, equivalent to the @TaskAction method in the class-based approach.
doLast {
val manifestFile = file("$projectDir/manifest.json")
val androidExtension = project.extensions.getByName("android") as com.android.build.gradle.AppExtension
val defaultConfig = androidExtension.defaultConfig

val manifestFile = manifestOutputFile.asFile

// Use the 'preReleaseVersion' value obtained at configuration time
val currentPreReleaseVersion = preReleaseVersion.takeIf { it.isNotBlank() }
println("Debug: preReleaseVersion from task input: $currentPreReleaseVersion")

val releasePathComponent = if (currentPreReleaseVersion != null) {
"download/$currentPreReleaseVersion" // e.g., "download/v0.4.2-pre-release"
} else {
"latest/download" // Default for stable releases or local builds
}

val baseUrl = "https://github.com/$projectDeveloper/$projectName/releases/$releasePathComponent"
val apkFileName = "app-release.apk"

val screenshotUrls = screenshotBaseNames.map { "$baseUrl/$it" }

// Construct the manifest as a Map
val manifest = mapOf(
"label" to "Karoo Template",
"packageName" to android.namespace,
"latestApkUrl" to "https://github.com/currand/karoo-ext-template/releases/latest/download/app-release.apk",
"latestVersion" to android.defaultConfig.versionName,
"latestVersionCode" to android.defaultConfig.versionCode,
"developer" to "currand",
"description" to "Template Karoo Extension",
// "screenshotUrls" to listOf(
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/example1.png",
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/example2.png",
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/example3.png",
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/example4.png",
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/config_screen.png",
// "https://github.com/currand/karoo-colorspeed/releases/latest/download/config_screen2.png"
// ),
"label" to projectLabel,
"packageName" to androidExtension.namespace,
"latestApkUrl" to "$baseUrl/$apkFileName",
"latestVersion" to defaultConfig.versionName,
"latestVersionCode" to defaultConfig.versionCode,
"developer" to projectDeveloper,
"description" to projectDescription,
"screenshotUrls" to screenshotUrls
)

val gson = groovy.json.JsonBuilder(manifest).toPrettyString()
// Use groovy.json.JsonBuilder to serialize the Map to a pretty-printed JSON string
val gson = JsonBuilder(manifest).toPrettyString()
manifestFile.writeText(gson)
println("Generated manifest.json with version ${android.defaultConfig.versionName} (${android.defaultConfig.versionCode})")
println("Generated manifest.json with download path: $releasePathComponent at ${manifestFile.absolutePath}")
}
}

Expand All @@ -101,22 +154,4 @@ java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}

dependencies {
implementation(libs.hammerhead.karoo.ext)
implementation(libs.androidx.core.ktx)
implementation(libs.bundles.androidx.lifeycle)
implementation(libs.androidx.activity.compose)
implementation(libs.bundles.compose.ui)
implementation(libs.androidx.datastore.preferences)
implementation(libs.androidx.glance.appwidget)
implementation(libs.androidx.glance.preview)
implementation(libs.androidx.glance.appwidget.preview)
implementation(libs.androidx.navigation.runtime.android)
implementation(libs.javax.inject)
implementation(libs.timber)
implementation(libs.kotlinx.coroutines.debug)
implementation(libs.koin.android)
implementation(libs.koin.androidx.compose)
}
Loading