Skip to content

Commit a67f35b

Browse files
authored
Maven Publishing (#5)
* Publish on Maven setup * Test * Fix checkout step * Fix google repo mgmt * Fix publish snapshot * Fix packageGroup * Debug * Refactoring * Update Readme * Remove test code * Reset version
1 parent ff261f7 commit a67f35b

File tree

12 files changed

+281
-49
lines changed

12 files changed

+281
-49
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: 'Setup JDK 17'
2+
description: 'Install and configure JDK 17'
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: Set up JDK 17
8+
shell: bash
9+
run: |
10+
sudo apt-get update
11+
sudo apt-get install -y openjdk-17-jdk
12+
echo "JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> $GITHUB_ENV
13+
14+
- name: Grant execute permission for gradlew
15+
shell: bash
16+
run: chmod +x gradlew

.github/workflows/ci.yml

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,24 @@ jobs:
1212
runs-on: ubuntu-latest
1313

1414
steps:
15-
- name: Checkout code
16-
run: |
17-
git init
18-
git remote add origin https://github.com/${{ github.repository }}.git
19-
git fetch --depth=1 origin ${{ github.sha }}
20-
git checkout ${{ github.sha }}
21-
22-
- name: Set up JDK 17
23-
run: |
24-
sudo apt-get update
25-
sudo apt-get install -y openjdk-17-jdk
26-
echo "JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64" >> $GITHUB_ENV
27-
28-
- name: Grant execute permission for gradlew
29-
run: chmod +x gradlew
30-
31-
- name: Run Library tests
32-
run: ./gradlew :nav-entry-scope-lib:testDebugUnitTest
33-
34-
- name: Run Processor tests
35-
run: ./gradlew :nav-entry-scope-processor:test
36-
37-
- name: Publish library modules to Maven Local
38-
run: |
39-
./gradlew publishToMavenLocal
40-
41-
- name: Run App tests
42-
run: ./gradlew :app:testDebugUnitTest
15+
- name: Checkout code
16+
run: |
17+
git init
18+
git remote add origin https://github.com/${{ github.repository }}.git
19+
git fetch --depth=1 origin ${{ github.sha }}
20+
git checkout ${{ github.sha }}
21+
22+
- name: Set up JDK 17
23+
uses: ./.github/actions/setup-jdk
24+
25+
- name: Run Library tests
26+
run: ./gradlew :nav-entry-scope-lib:testDebugUnitTest
27+
28+
- name: Run Processor tests
29+
run: ./gradlew :nav-entry-scope-processor:test
30+
31+
- name: Publish library modules to Maven Local
32+
run: ./gradlew publishToMavenLocal
33+
34+
- name: Run App tests
35+
run: ./gradlew :app:testDebugUnitTest
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Publish Snapshot to Maven Central
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'nav-entry-scope/**'
9+
10+
jobs:
11+
publish-snapshot:
12+
name: Publish Snapshot
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
run: |
18+
git init
19+
git remote add origin https://github.com/${{ github.repository }}.git
20+
git fetch --depth=1 origin ${{ github.sha }}
21+
git checkout ${{ github.sha }}
22+
23+
- name: Set up JDK 17
24+
uses: ./.github/actions/setup-jdk
25+
26+
- name: Extract base version from version catalog
27+
run: |
28+
BASE_VERSION=$(grep '^navEntryScope = ' gradle/libs.versions.toml | sed 's/.*= *"\(.*\)"/\1/')
29+
echo "VERSION=${BASE_VERSION}-SNAPSHOT" >> $GITHUB_ENV
30+
31+
- name: Publish Snapshot to Maven Central
32+
run: ./gradlew publishAllPublicationsToSnapshotRepository
33+
env:
34+
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
35+
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
36+
SIGNING_KEY_ID: ${{ secrets.GPG_KEY_ID }}
37+
SIGNING_PASSWORD: ${{ secrets.GPG_PASSPHRASE }}
38+
SIGNING_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
39+
VERSION: ${{ env.VERSION }}

.github/workflows/publish.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Publish to Maven Central
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
publish:
10+
name: Publish to Maven Central
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout code
15+
run: |
16+
git init
17+
git remote add origin https://github.com/${{ github.repository }}.git
18+
git fetch --depth=1 origin ${{ github.sha }}
19+
git checkout ${{ github.sha }}
20+
21+
- name: Set up JDK 17
22+
uses: ./.github/actions/setup-jdk
23+
24+
- name: Extract version from tag
25+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
26+
27+
- name: Run tests before publishing
28+
run: |
29+
./gradlew :nav-entry-scope-lib:testDebugUnitTest
30+
./gradlew :nav-entry-scope-processor:test
31+
32+
- name: Publish to Maven Central
33+
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
34+
env:
35+
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
36+
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
37+
SIGNING_KEY_ID: ${{ secrets.GPG_KEY_ID }}
38+
SIGNING_PASSWORD: ${{ secrets.GPG_PASSPHRASE }}
39+
SIGNING_KEY: ${{ secrets.GPG_PRIVATE_KEY }}

README.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
[![CI](https://github.com/mercari/nav-entry-scope-android/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mercari/nav-entry-scope-android/actions/workflows/ci.yml)
44
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE.txt)
5+
[![Latest version (lib)](https://img.shields.io/maven-central/v/com.mercari/nav-entry-scope?label=nav-entry-scope)](https://central.sonatype.com/artifact/com.mercari/nav-entry-scope)
6+
[![Latest version (processor)](https://img.shields.io/maven-central/v/com.mercari/nav-entry-scope-processor?label=nav-entry-scope-processor)](https://central.sonatype.com/artifact/com.mercari/nav-entry-scope-processor)
57
![Android](https://img.shields.io/badge/Platform-Android-green.svg)
68
![API](https://img.shields.io/badge/API-24%2B-brightgreen.svg)
79
![Kotlin](https://img.shields.io/badge/Kotlin-2.0-blue.svg)
@@ -32,7 +34,20 @@ Use NavEntryScope when you have:
3234

3335
## How to Use
3436

35-
### 1. Annotate Shared Dependencies
37+
### 1. Add Dependencies
38+
39+
Add the library and annotation processor to your module's `build.gradle.kts`:
40+
41+
```kotlin
42+
dependencies {
43+
implementation("com.mercari:nav-entry-scope:<version>")
44+
ksp("com.mercari:nav-entry-scope-processor:<version>")
45+
}
46+
```
47+
48+
Replace `<version>` with the latest version shown in the badge above.
49+
50+
### 2. Annotate Shared Dependencies
3651

3752
```kotlin
3853
@Module
@@ -45,7 +60,7 @@ interface YourModule {
4560
}
4661
```
4762

48-
### 2. Inject into ViewModels
63+
### 3. Inject into ViewModels
4964

5065
ViewModels remain standard `@HiltViewModel` classes. Injecting a dependency that depends on `@NavEntryScoped` into your ViewModel is also supported.
5166

@@ -56,7 +71,7 @@ class YourViewModel @Inject constructor(
5671
) : ViewModel()
5772
```
5873

59-
### 3. Use in Compose
74+
### 4. Use in Compose
6075

6176
Replace `hiltViewModel()` with `navEntryScopedViewModel()`:
6277

@@ -92,6 +107,38 @@ Annotation processor (KSP) that generates:
92107
- `NavEntry_EntryPoint` - Hilt EntryPoint interface installed in `NavEntryComponent`
93108
- `NavEntry_Module` - Dagger module installed in `ViewModelComponent` that provides NavEntryScoped dependencies
94109

110+
## Local Development
111+
112+
### Testing Changes Locally
113+
114+
To test library changes immediately in the sample app, publish to Maven Local:
115+
116+
```bash
117+
./gradlew publishToMavenLocal
118+
```
119+
120+
The sample app is already configured to use `mavenLocal()`, so changes will be picked up on the next build.
121+
122+
### Using Snapshots
123+
124+
To use snapshot versions of the library, add the snapshot repository to your `settings.gradle.kts`:
125+
126+
```kotlin
127+
dependencyResolutionManagement {
128+
repositories {
129+
maven("https://central.sonatype.com/repository/maven-snapshots/")
130+
mavenCentral()
131+
}
132+
}
133+
```
134+
135+
Then use the snapshot version in your dependencies:
136+
137+
```kotlin
138+
implementation("com.mercari:nav-entry-scope:<version>-SNAPSHOT")
139+
ksp("com.mercari:nav-entry-scope-processor:<version>-SNAPSHOT")
140+
```
141+
95142
## Contribution
96143

97144
If you want to submit a PR for bug fixes or documentation, please read the [CONTRIBUTING.md](CONTRIBUTING.md) and follow the instruction beforehand.

build.gradle.kts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,34 @@ plugins {
66
alias(libs.plugins.kotlin.compose) apply false
77
alias(libs.plugins.kotlin.jvm) apply false
88
alias(libs.plugins.ksp) apply false
9+
alias(libs.plugins.nexus.publish)
10+
}
11+
12+
nexusPublishing {
13+
packageGroup.set("com.mercari")
14+
repositories {
15+
sonatype {
16+
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
17+
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
18+
username.set(providers.environmentVariable("SONATYPE_USERNAME"))
19+
password.set(providers.environmentVariable("SONATYPE_PASSWORD"))
20+
}
21+
}
22+
}
23+
24+
allprojects {
25+
plugins.withId("maven-publish") {
26+
configure<PublishingExtension> {
27+
repositories {
28+
maven {
29+
name = "snapshot"
30+
url = uri("https://central.sonatype.com/repository/maven-snapshots/")
31+
credentials {
32+
username = providers.environmentVariable("SONATYPE_USERNAME").orNull ?: ""
33+
password = providers.environmentVariable("SONATYPE_PASSWORD").orNull ?: ""
34+
}
35+
}
36+
}
37+
}
38+
}
939
}

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ hiltDagger = "2.57.2"
1616
navigation = "2.9.5"
1717
kotlinxCoroutines = "1.10.2"
1818
navEntryScope = "1.0.0"
19+
nexusPublish = "2.0.0"
1920

2021
[libraries]
2122
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -58,3 +59,4 @@ kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "ko
5859
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
5960
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
6061
hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hiltDagger" }
62+
nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublish" }

gradle/publishing.gradle.kts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import org.gradle.api.publish.PublishingExtension
2+
import org.gradle.api.publish.maven.MavenPublication
3+
4+
plugins.withId("maven-publish") {
5+
afterEvaluate {
6+
extensions.configure<PublishingExtension> {
7+
publications.withType<MavenPublication>().configureEach {
8+
groupId = "com.mercari"
9+
version = System.getenv("VERSION") ?: project.property("navEntryScopeVersion") as String
10+
11+
pom {
12+
url.set("https://github.com/mercari/nav-entry-scope-android")
13+
14+
licenses {
15+
license {
16+
name.set("MIT License")
17+
url.set("https://github.com/mercari/nav-entry-scope-android/blob/main/LICENSE.txt")
18+
}
19+
}
20+
developers {
21+
developer {
22+
id.set("bxttx")
23+
name.set("Luca Bettelli")
24+
email.set("l-bettelli@mercari.com")
25+
}
26+
developer {
27+
id.set("rsfez")
28+
name.set("Robin Sfez")
29+
email.set("rsfez@mercari.com")
30+
}
31+
}
32+
scm {
33+
connection.set("scm:git:git://github.com/mercari/nav-entry-scope-android.git")
34+
developerConnection.set("scm:git:ssh://github.com/mercari/nav-entry-scope-android.git")
35+
url.set("https://github.com/mercari/nav-entry-scope-android")
36+
}
37+
}
38+
}
39+
}
40+
}
41+
}

gradle/signing.gradle.kts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import org.gradle.api.publish.PublishingExtension
2+
import org.gradle.plugins.signing.SigningExtension
3+
4+
plugins.withId("maven-publish") {
5+
plugins.withId("signing") {
6+
val publishing = extensions.getByType<PublishingExtension>()
7+
val signing = extensions.getByType<SigningExtension>()
8+
9+
val signingKey = System.getenv("SIGNING_KEY")
10+
val signingPassword = System.getenv("SIGNING_PASSWORD")
11+
12+
if (signingKey != null && signingPassword != null) {
13+
signing.useInMemoryPgpKeys(signingKey, signingPassword)
14+
signing.sign(publishing.publications)
15+
}
16+
}
17+
}

nav-entry-scope/lib/build.gradle.kts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ plugins {
77
alias(libs.plugins.hilt.android)
88
id("kotlin-kapt")
99
`maven-publish`
10+
signing
1011
}
1112

1213
android {
@@ -65,21 +66,22 @@ dependencies {
6566
testImplementation(libs.junit)
6667
}
6768

69+
extra["navEntryScopeVersion"] = libs.versions.navEntryScope.get()
70+
6871
afterEvaluate {
6972
publishing {
7073
publications {
7174
create<MavenPublication>("release") {
7275
from(components["release"])
73-
74-
groupId = "com.mercari"
7576
artifactId = "nav-entry-scope"
76-
version = "1.0.0"
77-
7877
pom {
7978
name.set("NavEntryScope Library")
80-
description.set("Core library for NavEntryScope pattern")
79+
description.set("Navigation entry scoping library for Jetpack Compose - manages ViewModel lifecycle tied to navigation back stack entries")
8180
}
8281
}
8382
}
8483
}
85-
}
84+
}
85+
86+
apply(from = rootProject.file("gradle/publishing.gradle.kts"))
87+
apply(from = rootProject.file("gradle/signing.gradle.kts"))

0 commit comments

Comments
 (0)