From 27710e6bd3bc62563a737a59579d41643ae4f77b Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Fri, 10 Oct 2025 15:13:05 +0200 Subject: [PATCH] [PARP-155] Implement Maven Central publishing workflow --- .github/workflows/deployment.yml | 67 +++++++++++++--------- .github/workflows/library-bump.yml | 2 +- .github/workflows/pull-request-android.yml | 2 +- .gitignore | 2 + README.md | 22 +++---- gradle.properties | 2 +- gradle/libs.versions.toml | 2 + mmd-core/build.gradle.kts | 63 ++++++++++++++++---- 8 files changed, 112 insertions(+), 50 deletions(-) diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 3cd1f96..1ed60e5 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -1,41 +1,56 @@ -name: Release - Deployment +name: Publish to Maven Central on: - workflow_dispatch: push: tags: - - release.* + - 'release.[0-9]+.[0-9]+.[0-9]+' jobs: - deploy: - name: Deployment - runs-on: [ Linux ] - env: - ARTIFACTORY_URL: ${{secrets.MUDITA_ARTIFACTORY_OUTPUT_URL}} - ARTIFACTORY_USERNAME: ${{secrets.MUDITA_ARTIFACTORY_USERNAME}} - ARTIFACTORY_PASSWORD: ${{secrets.MUDITA_ARTIFACTORY_PASSWORD}} + publish: + runs-on: ubuntu-latest + steps: - - name: Checkout + - name: Checkout code uses: actions/checkout@v4 - with: - fetch-depth: 100 - name: Set up JDK 17 - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: - java-version: 17 + java-version: '17' + distribution: 'temurin' + + - name: Validate version consistency + run: | + TAG_VERSION=${GITHUB_REF#refs/tags/release.} + GRADLE_VERSION=$(grep "library.version=" gradle.properties | cut -d'=' -f2) + + echo "Tag version: $TAG_VERSION" + echo "Gradle version: $GRADLE_VERSION" + + if [ "$TAG_VERSION" != "$GRADLE_VERSION" ]; then + echo "Error: Tag version ($TAG_VERSION) doesn't match gradle.properties version ($GRADLE_VERSION)" + exit 1 + fi + + echo "Version consistency validated" + + - name: Grant execute permission for gradlew + run: chmod +x gradlew - - name: Setup Android SDK - uses: android-actions/setup-android@v3 + - name: Build release + run: ./gradlew assembleRelease --no-daemon --stacktrace - - name: Lint kotlin check - timeout-minutes: 5 - run: ./gradlew ktlintCheck + - name: Create signing key file + run: echo "${{ secrets.SIGNING_KEY }}" | base64 -d > secring.gpg - - name: Full build - timeout-minutes: 5 - run: ./gradlew clean build + - name: Publish to Maven Central + env: + ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }} + ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }} + ORG_GRADLE_PROJECT_signing.keyId: ${{ secrets.SIGNING_KEY_ID }} + ORG_GRADLE_PROJECT_signing.password: ${{ secrets.SIGNING_PASSWORD }} + run: ./gradlew publishToMavenCentral --no-daemon --stacktrace - - name: Deploy artifactory - timeout-minutes: 5 - run: ./gradlew publish + - name: Clean up + if: always() + run: rm -f secring.gpg diff --git a/.github/workflows/library-bump.yml b/.github/workflows/library-bump.yml index 9190fc9..f73537c 100644 --- a/.github/workflows/library-bump.yml +++ b/.github/workflows/library-bump.yml @@ -15,7 +15,7 @@ on: jobs: check: name: Check Version Bump - runs-on: [ Linux ] + runs-on: ubuntu-latest if: github.event_name == 'pull_request' steps: diff --git a/.github/workflows/pull-request-android.yml b/.github/workflows/pull-request-android.yml index 0c0a34a..b488eff 100644 --- a/.github/workflows/pull-request-android.yml +++ b/.github/workflows/pull-request-android.yml @@ -15,7 +15,7 @@ on: jobs: test: name: Lint - Android - runs-on: [ Linux ] + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index 1ce5acb..94e0630 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ google-services.json *.hprof .DS_Store + +secring.gpg diff --git a/README.md b/README.md index 183f514..2019021 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Mudita Mindful Design (MMD) -A UI component library optimized for e‑ink displays on Android, built on top of Jetpack Compose Material 3 guidelines and classes. Our goal is to provide a consistent, predictable set of components that respects Material Design while addressing the specifics of e‑ink displays. +A UI component library optimized for E Ink® displays on Android, built on top of Jetpack Compose Material 3 guidelines and classes. Our goal is to provide a consistent, predictable set of components that respects Material Design while addressing the specifics of E Ink® displays. -> We intentionally rely on Material Design (Material 3) classes and patterns. This is by design and a good practice. It keeps us aligned with the Android ecosystem while adapting behavior and styling to e‑ink. +> We intentionally rely on Material Design (Material 3) classes and patterns. This is by design and a good practice. It keeps us aligned with the Android ecosystem while adapting behavior and styling to E Ink®. -## Why e‑ink? -E‑ink displays differ from standard LCD/OLED: +## Why E Ink®? +E Ink® displays differ from standard LCD/OLED: - slower refresh rates and potential ghosting/afterimage, - limited color palette (often grayscale), - great daylight readability with low power consumption, @@ -14,9 +14,9 @@ E‑ink displays differ from standard LCD/OLED: MMD minimizes flicker, reduces unnecessary animations, and simplifies color and typography to make the UI readable and energy‑efficient. ## Features -- **E‑ink optimized**: default color scheme, typography, and interaction patterns for e‑ink. +- **E Ink® optimized**: default color scheme, typography, and interaction patterns for E Ink®. - **Material Design 3‑based**: integration with `MaterialTheme` and compatibility with M3 components. -- **Ripple disabled**: ripple effects are turned off by default for better UX on e‑ink. +- **Ripple disabled**: ripple effects are turned off by default for better UX on E Ink®. - **Consistent typography**: ready‑to‑use `eInkTypography` and `eInkColorScheme` (monochromatic). - **Component set**: buttons, text fields, switches, tabs, app bars, and more. @@ -28,7 +28,7 @@ dependencies { ``` ## Configuration and theming -Enable the MMD theme in your Compose tree. By default, it applies an e‑ink‑friendly color scheme and typography and disables ripple effects globally. +Enable the MMD theme in your Compose tree. By default, it applies an E Ink®‑friendly color scheme and typography and disables ripple effects globally. ```kotlin import com.mudita.mmd.components.buttons.ButtonMMD @@ -39,14 +39,14 @@ import com.mudita.mmd.ThemeMMD fun App() { ThemeMMD { ButtonMMD(onClick = { /* ... */ }) { - TextMMD("Hello e‑ink") + TextMMD("Hello E Ink®") } } } ``` ## Using components -MMD works well with both Material 3 components and MMD‑provided components. Use our components where they bring e‑ink optimizations; otherwise, standard M3 components will remain consistent via theming. +MMD works well with both Material 3 components and MMD‑provided components. Use our components where they bring E Ink® optimizations; otherwise, standard M3 components will remain consistent via theming. ```kotlin import com.mudita.mmd.components.buttons.ButtonMMD @@ -63,11 +63,11 @@ fun Screen() { > Component names may vary by module and version. Explore `com.mudita.mmd.components.*` in your IDE for the full list and API. ## Accessibility and readability -- contrast and font sizes tuned for e‑ink, +- contrast and font sizes tuned for E Ink®, - avoid animations/effects that reduce readability, - utilities to support accessibility (e.g., unified text styles). -## Performance on e‑ink – best practices +## Performance on E Ink® – best practices - limit animations, auto‑refresh, and fancy transitions, - avoid frequent state changes leading to redraws, - prefer monochrome graphics and simple shapes, diff --git a/gradle.properties b/gradle.properties index d082b36..66f5755 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,4 +12,4 @@ library.namespace=com.mudita.mmd library.compileSdk=34 library.minSdk=28 library.targetSdk=34 -library.version=1.0.0 +library.version=1.0.1 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab84c43..8738f38 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,7 @@ compose = "1.7.3" material3 = "1.3.1" activity-compose = "1.10.1" dokka = "2.0.0" +maven = "0.34.0" [libraries] ktlint = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" } @@ -23,3 +24,4 @@ kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref compose = { id = "org.jetbrains.compose", version.ref = "compose" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } +maven-publish = {id = "com.vanniktech.maven.publish", version.ref = "maven" } diff --git a/mmd-core/build.gradle.kts b/mmd-core/build.gradle.kts index 0b5d838..47f4028 100644 --- a/mmd-core/build.gradle.kts +++ b/mmd-core/build.gradle.kts @@ -4,20 +4,53 @@ plugins { alias(libs.plugins.compose) alias(libs.plugins.compose.compiler) alias(libs.plugins.dokka) - `maven-publish` + alias(libs.plugins.maven.publish) + id("signing") } -group = properties["library.group"].toString() -version = - run { - System.getenv("GITHUB_REF_NAME")?.removePrefix("release.") - ?: properties["library.version"].toString() - } - kotlin { androidTarget { - mavenPublication { - artifactId = properties["library.artifactId"].toString() + mavenPublishing { + publishToMavenCentral() + signAllPublications() + + coordinates( + groupId = properties["library.group"].toString(), + artifactId = properties["library.artifactId"].toString(), + version = properties["library.version"].toString() + ) + + pom { + name.set("Mudita MMD Library") + description.set( + "A UI component library optimized for e‑ink displays on Android, " + + "built on top of Jetpack Compose Material 3 guidelines and classes. " + + "Our goal is to provide a consistent, " + + "predictable set of components that respects Material Design " + + "while addressing the specifics of e‑ink displays.", + ) + inceptionYear.set("2025") + url.set("https://github.com/mudita/MMD") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + distribution.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("krystianbroniszewskimudita") + name.set("Krystian Broniszewski") + email.set("krystian.broniszewski@mudita.com") + } + } + scm { + connection.set("scm:git:github.com/mudita/MMD.git") + developerConnection.set("scm:git:ssh://github.com/mudita/MMD.git") + url.set("https://github.com/mudita/MMD/tree/main") + } + } } publishLibraryVariants("release") @@ -64,3 +97,13 @@ android { } } } + +signing { + val keyFile = rootProject.file("secring.gpg") + val password = project.findProperty("signing.password") as? String + + if (keyFile.exists() && password != null) { + useInMemoryPgpKeys(keyFile.readText(), password) + sign(publishing.publications) + } +}