diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..cef017a --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,26 @@ +name: Build Example + +on: [ push, workflow_dispatch ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + # Checkout repository + - name: Checkout + uses: actions/checkout@v4.1.1 + + # Setup JDK environment + - name: Set up JDK + uses: actions/setup-java@v4.3.0 + with: + distribution: 'zulu' + java-version: '17' + + # Run the Gradle Build task + - name: Build Kts Example App + run: ./gradlew clean :examplekts:assemble + + # Run the Gradle Build task + - name: Build Groovy Example App + run: ./gradlew clean :examplegroovy:assemble diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 17ef04b..5c1b543 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,4 +1,4 @@ -name: Publish Plugin to Portal +name: Publish to Maven Central on: push: @@ -9,13 +9,16 @@ on: jobs: publish: runs-on: ubuntu-latest - env: - GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PLUGIN_PORTAL_PUBLISH_KEY }} - GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PLUGIN_PORTAL_PUBLISH_SECRET }} steps: - - name: Checkout Repo - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v1 + with: + java-version: '17' - name: Grant permission to execute run: chmod +x gradlew - - name: Publish on Plugin Portal - run: ./gradlew --project-dir preset setupPluginUploadFromEnvironment publishPlugins -PgithubRefName=${{ github.ref_name }} + - name: Upload + run: | + echo "${{secrets.MAVEN_SIGNING_KEY_ARMOR_ASC}}" > ./signingkey.asc + gpg --quiet --output $GITHUB_WORKSPACE/signingkey.gpg --dearmor ./signingkey.asc + ./gradlew :alpaka:plugin:publishAndReleaseToMavenCentral -Psigning.secretKeyRingFile=$GITHUB_WORKSPACE/signingkey.gpg -Psigning.password='${{secrets.MAVEN_SIGNING_KEY_PASSPHRASE}}' -Psigning.keyId=${{secrets.MAVEN_SIGNING_KEY_ID}} -PmavenCentralUsername=${{secrets.MAVEN_CENTRAL_USERNAME}} -PmavenCentralPassword=${{secrets.MAVEN_CENTRAL_PASSWORD}} -PgithubRefName=${{ github.ref_name }} diff --git a/.github/workflows/release_artifactory.yml b/.github/workflows/release_artifactory.yml deleted file mode 100644 index 9dc407e..0000000 --- a/.github/workflows/release_artifactory.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Publish to Artifactory - -on: - push: - tags: - - 'v[0-9]+.[0-9]+.[0-9]+' - -jobs: - publish: - uses: UbiqueInnovation/actions-android/.github/workflows/android_gradle_task.yml@v1.6.4 - with: - task: 'clean :alpaka:artifactoryPublish' - concurrencyGroup: ${{ github.workflow }}-${{ github.ref }} - gradleArgs: '-PgithubRefName=${{ github.ref_name }}' - secrets: - UB_ARTIFACTORY_URL: ${{ secrets.UB_ARTIFACTORY_URL }} - UB_ARTIFACTORY_REPO_ANDROID: ${{ secrets.UB_ARTIFACTORY_REPO_ANDROID }} - UB_ARTIFACTORY_USER: ${{ secrets.UB_ARTIFACTORY_USER }} - UB_ARTIFACTORY_PASSWORD: ${{ secrets.UB_ARTIFACTORY_PASSWORD }} - self_hosted_cache_access_key: ${{ secrets.self_hosted_cache_access_key }} - self_hosted_cache_secret_key: ${{ secrets.self_hosted_cache_secret_key }} \ No newline at end of file diff --git a/README.md b/README.md index e52edea..9c274d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # Alpaka Gradle Plugin -This plugin configures an Android project for build and upload to the Ubique Alpaka backend. +[![Build](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/actions/workflows/build.yml/badge.svg)](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/actions/workflows/build.yml) +[![Release](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/actions/workflows/publish.yml/badge.svg)](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/actions/workflows/publish.yml) +[![Maven Central](https://img.shields.io/maven-central/v/ch.ubique.gradle/alpaka.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22ch.ubique.gradle%22%20AND%20a:%22alpaka%22) + +Upload your app to the Alpaka App Distribution, label your launcher icon with some flavors, and have some build metadata in the BuildConfig and the Android manifest. ## Functionality @@ -15,27 +19,36 @@ The plugin contains the following functionality: ## Configuration +```kotlin +plugins { + id("ch.ubique.gradle.alpaka") version "8.6.0" +} +``` + +The major and minor version goes in lockstep with the Android Gradle Plugin, +also see [Releases](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/releases). + After applying the plugin to your project, you can set the following configuration in your build.gradle.kts: ```kotlin android { - defaultConfig { - launcherIconLabel = "tescht" // The default icon label per flavor (optional, nullable) - alpakaUploadKey = "..." // The upload key identifying an application in the Alpaka backend - } - - productFlavors { - create("dev") { - launcherIconLabel = "tescht" // Modify the default icon label per flavor (optional, nullable) - alpakaUploadKey = "..." // Modify the default uploadKey per flavor (optional) - } - } + defaultConfig { + launcherIconLabel = "tescht" // The default icon label per flavor (optional, nullable) + alpakaUploadKey = "..." // The upload key identifying an application in the Alpaka backend + } + + productFlavors { + create("dev") { + launcherIconLabel = "tescht" // Modify the default icon label per flavor (optional, nullable) + alpakaUploadKey = "..." // Modify the default uploadKey per flavor (optional) + } + } } alpaka { - changelogCommitCount = 10 // The number of commits to include in the changelog (optional, defaults to 10) - proxy = "host:port" // An optional proxy to set for the upload task. Use for local debugging only - labelAppIcons = false // Globally configure the generateAppIcon tasks to label with flavor name (optional, default is enabled) + changelogCommitCount = 10 // The number of commits to include in the changelog (optional, defaults to 10) + proxy = "host:port" // An optional proxy to set for the upload task. Use for local debugging only + labelAppIcons = false // Globally configure the generateAppIcon tasks to label with flavor name (optional, default is enabled) } ``` @@ -43,11 +56,31 @@ alpaka { These are the build information that are written to the `BuildConfig` class and Android manifest: -| BuildConfig name | Android manifest name | Description | Value | +| BuildConfig field | Android manifest meta-data name | Description | Value | |-------------------|------------------------------------|--------------------------------------------------------------------------|-----------------------------------------------------------------------------| | `BUILD_BATCH` | `ch.ubique.alpaka.build.batch` | An ID for a group of builds that belong together (e.g. multiple flavors) | `build_batch` Gradle property, defaults to `0` | | `BUILD_ID` | `ch.ubique.alpaka.build.id` | An ID for this build | `build_id` or `ubappid` Gradle property, defaults to `localbuild` | | `BUILD_NUMBER` | `ch.ubique.alpaka.build.number` | An incremental number of this build | `build_number` Gradle property, defaults to `0` | | `BUILD_TIMESTAMP` | `ch.ubique.alpaka.build.timestamp` | The timestamp of this build | `build_timestamp` Gradle property, defaults to `System.currentTimeMillis()` | | `BRANCH` | `ch.ubique.alpaka.branch` | The Git branch this build was created from | `branch` Gradle property, defaults to calling the systems Git command line | -| `FLAVOR` | `ch.ubique.alpaka.flavor` | The product flavor this build was created from | Product flavor name of the variant that started the gradle task | \ No newline at end of file +| `FLAVOR` | `ch.ubique.alpaka.flavor` | The product flavor this build was created from | Product flavor name of the variant that started the gradle task | + +## Development & Testing + +To test any changes to this plugin locally, you can use the example apps shipped with this repository, +or alternatively, deploy an artifact to your local maven repository and include that in an application of your choice: + +1. Define a custom version by setting the `VERSION` in alpaka/gradle.properties* +2. You might need to disable `signAllPublications()`* +3. Deploy the plugin artifact by running `./gradlew publishToMavenLocal` +4. Reference `mavenLocal()` in your application's build script's dependency repository list. +5. Apply your local plugin version. + +* do not accidentally commit these changes. + +## Deployment + +Create a [Release](https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/releases), +setting the Tag to the desired version prefixed with a `v`. + +Each release on Github will be deployed to Maven Central. diff --git a/alpaka/build.gradle.kts b/alpaka/build.gradle.kts index 9d8f7da..6377f35 100644 --- a/alpaka/build.gradle.kts +++ b/alpaka/build.gradle.kts @@ -1,7 +1,6 @@ plugins { alias(libs.plugins.kotlin) apply false alias(libs.plugins.pluginPublish) apply false - alias(libs.plugins.jfrog.artifactory) apply false } allprojects { diff --git a/alpaka/gradle.properties b/alpaka/gradle.properties index 40333ed..afc70c0 100644 --- a/alpaka/gradle.properties +++ b/alpaka/gradle.properties @@ -3,8 +3,29 @@ GROUP=ch.ubique.gradle ARTIFACT_ID=alpaka # VERSION will only be used if no property "githubRefName" is set (which the release workflow does) VERSION=0.0.0 -DISPLAY_NAME=Ubique Alpaka -DESCRIPTION=Adds tasks to apply flavor-specific icon overlays, inject build metadata into the Android manifest and upload the APK to the Ubique Alpaka backend -WEBSITE=https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android -VCS_URL=https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android IMPLEMENTATION_CLASS=ch.ubique.gradle.alpaka.AlpakaPlugin + +# POM metadata +POM_NAME=alpaka +POM_PACKAGING=jar +POM_DESCRIPTION=Upload your app to the Alpaka App Distribution, label your launcher icon with some flavors, and have some build metadata in the BuildConfig and the Android manifest. +POM_INCEPTION_YEAR=2024 + +# POM URLs +POM_URL=https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android +POM_SCM_URL=https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android +POM_SCM_CONNECTION=scm:git@github.com:UbiqueInnovation/gradle-plugin-alpaka-android.git +POM_SCM_DEV_CONNECTION=scm:git@github.com:UbiqueInnovation/gradle-plugin-alpaka-android.git + +# License information +POM_LICENCE_NAME=License +POM_LICENCE_URL=https://github.com/UbiqueInnovation/gradle-plugin-alpaka-android/blob/main/LICENSE +POM_LICENCE_DIST=repo + +# Developer information +POM_DEVELOPER_ID=UbiqueInnovation +POM_DEVELOPER_NAME=Ubique Innovation +POM_DEVELOPER_URL=https://www.ubique.ch/ + +# Sonatype metadata +SONATYPE_STAGING_PROFILE=ch.ubique diff --git a/alpaka/plugin/build.gradle.kts b/alpaka/plugin/build.gradle.kts index fd898b0..33292bd 100644 --- a/alpaka/plugin/build.gradle.kts +++ b/alpaka/plugin/build.gradle.kts @@ -1,3 +1,5 @@ +import com.vanniktech.maven.publish.GradlePublishPlugin +import com.vanniktech.maven.publish.SonatypeHost import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.jetbrains.kotlin.gradle.dsl.JvmTarget @@ -7,7 +9,7 @@ plugins { kotlin("jvm") `java-gradle-plugin` alias(libs.plugins.pluginPublish) - alias(libs.plugins.jfrog.artifactory) + alias(libs.plugins.vanniktech) } dependencies { @@ -43,64 +45,15 @@ gradlePlugin { id = property("ID").toString() implementationClass = property("IMPLEMENTATION_CLASS").toString() version = project.version - description = property("DESCRIPTION").toString() - displayName = property("DISPLAY_NAME").toString() - tags = listOf("android", "ubique") } } - website.set(property("WEBSITE").toString()) - vcsUrl.set(property("VCS_URL").toString()) } -tasks.create("setupPluginUploadFromEnvironment") { - doLast { - val key = System.getenv("GRADLE_PUBLISH_KEY") - val secret = System.getenv("GRADLE_PUBLISH_SECRET") - - if (key == null || secret == null) { - throw GradleException("gradlePublishKey and/or gradlePublishSecret are not defined environment variables") - } - - System.setProperty("gradle.publish.key", key) - System.setProperty("gradle.publish.secret", secret) - } -} - -// MAVEN PUBLISHING - -publishing { - publications { - register("mavenJava") { - from(components.getByName("java")) - artifactId = property("ARTIFACT_ID").toString() - groupId = property("GROUP").toString() - version = project.version.toString() - } - } -} - -artifactory { - val url = System.getenv("UB_ARTIFACTORY_URL") ?: project.property("ubiqueMavenRootUrl")?.toString() - setContextUrl(url) - publish { - repository { - repoKey = System.getenv("UB_ARTIFACTORY_REPO_ANDROID") ?: project.property("ubiqueMavenRepoName")?.toString() - username = System.getenv("UB_ARTIFACTORY_USER") ?: project.property("ubiqueMavenUser")?.toString() - password = System.getenv("UB_ARTIFACTORY_PASSWORD") ?: project.property("ubiqueMavenPass")?.toString() - } - - defaults { - publications("mavenJava") - setPublishArtifacts(true) - setProperties( - mapOf( - "build.status" to this.project.status.toString() - ) - ) - setPublishPom(true) - setPublishIvy(false) - } - } +mavenPublishing { + configure(GradlePublishPlugin()) + coordinates(property("GROUP").toString(), property("ARTIFACT_ID").toString(), project.version.toString()) + publishToMavenCentral(SonatypeHost.S01, true) + signAllPublications() } // enable test logging with gradle diff --git a/examplegroovy/build.gradle b/examplegroovy/build.gradle index 4e7b0d8..0c1b3d3 100644 --- a/examplegroovy/build.gradle +++ b/examplegroovy/build.gradle @@ -13,7 +13,7 @@ android { minSdk 26 targetSdk 34 versionCode 1 - versionName "1.0" + versionName project.version.toString() alpakaUploadKey = "defaultConfig upload key" } diff --git a/examplekts/build.gradle.kts b/examplekts/build.gradle.kts index 4115643..25205e8 100644 --- a/examplekts/build.gradle.kts +++ b/examplekts/build.gradle.kts @@ -16,7 +16,7 @@ android { minSdk = 26 targetSdk = 34 versionCode = 1 - versionName = "1.0" + versionName = project.version.toString() alpakaUploadKey = "defaultConfig upload key" } @@ -66,7 +66,6 @@ dependencies { implementation(libs.appcompat) implementation(libs.material) implementation(libs.activity) - implementation(libs.activity) } alpaka { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 095109e..2ee7bee 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,12 +1,12 @@ [versions] +agp = "8.6.1" kotlin = "2.0.20" pluginPublish = "1.2.2" -coroutines = "1.8.1" +vanniktech = "0.29.0" + okhttp = "4.12.0" retrofit = "2.11.0" moshi = "1.15.1" -agp = "8.6.1" -jfrog-artifactory = "5.1.10" coreKtx = "1.13.1" appcompat = "1.7.0" @@ -19,12 +19,9 @@ kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin"} pluginPublish = { id = "com.gradle.plugin-publish", version.ref = "pluginPublish"} androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -jfrog-artifactory = { id = "com.jfrog.artifactory", version.ref = "jfrog-artifactory" } +vanniktech = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech" } [libraries] -junit = "junit:junit:4.13.2" - -coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp"} retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit"} retrofitConverterScalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit"} @@ -40,4 +37,4 @@ material = { group = "com.google.android.material", name = "material", version.r activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } - +junit = "junit:junit:4.13.2" diff --git a/settings.gradle.kts b/settings.gradle.kts index 2f2b1a0..de066eb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,8 @@ dependencyResolutionManagement { } } +rootProject.name = "gradle-plugin-alpaka-android" + includeBuild("alpaka") include(":examplekts") include(":examplegroovy")