Skip to content

Commit b829729

Browse files
committed
Enhance release workflow and publishing process: update README.md with required secrets for Sonatype, modify release workflow to publish both library and plugin, and improve signing configuration. Update ProGuard rules for native methods and public API, and migrate dependencies to Kotlin stdlib and JUnit 5. Remove obsolete plugin components and streamline task handling.
1 parent 7202fed commit b829729

49 files changed

Lines changed: 757 additions & 514 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/release_workflow.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,16 @@ jobs:
123123
env:
124124
ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }}
125125
ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }}
126+
ORG_GRADLE_PROJECT_signing_gnupg_keyName: ${{ secrets.GPG_KEY_ID }}
127+
ORG_GRADLE_PROJECT_signing_gnupg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
128+
129+
- name: Publish plugin to Sonatype
130+
run: ./gradlew :plugin:publishPluginPublicationToSonatypeRepository --no-daemon
131+
env:
132+
ORG_GRADLE_PROJECT_nexusUsername: ${{ secrets.NEXUS_USERNAME }}
133+
ORG_GRADLE_PROJECT_nexusPassword: ${{ secrets.NEXUS_PASSWORD }}
134+
ORG_GRADLE_PROJECT_signing_gnupg_keyName: ${{ secrets.GPG_KEY_ID }}
135+
ORG_GRADLE_PROJECT_signing_gnupg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
126136

127137
tag:
128138
name: Publish version

CONTRIBUTING.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Contributing to StringCare Android
2+
3+
## Release workflow secrets
4+
5+
To run the **Release** workflow and publish to Maven Central (Sonatype), configure these GitHub repository secrets:
6+
7+
| Secret | Description |
8+
|--------|-------------|
9+
| `NEXUS_USERNAME` | Sonatype/OSSRH username |
10+
| `NEXUS_PASSWORD` | Sonatype/OSSRH password |
11+
| `GPG_KEY_ID` | GPG key ID used for signing (e.g. short key id) |
12+
| `GPG_PASSPHRASE` | Passphrase for the GPG key |
13+
| `PAT` | Personal Access Token with repo scope (for checkout and release steps) |
14+
15+
When dispatching the release workflow, set **Publish Maven** to `true` to run the publish job. The workflow will:
16+
17+
1. Build and test all modules
18+
2. Publish `dev.vyp.stringcare:library` and `dev.vyp.stringcare:plugin` to Sonatype (when publish is enabled)
19+
3. Create the Git tag and GitHub Release
20+
21+
Local publish (for testing):
22+
23+
```bash
24+
./gradlew :library:publishToMavenLocal
25+
./gradlew :plugin:publishToMavenLocal
26+
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ For **Groovy** use `buildscript` / `apply plugin: 'dev.vyp.stringcare.plugin'` a
7777

7878
**Build / CI:** This project uses the JNI native library as a Git submodule (`stringcare-jni`). Clone with submodules: `git clone --recurse-submodules ...` or run `git submodule update --init --recursive` after clone. CI workflows must use `checkout` with `submodules: true`.
7979

80-
**Publishing (release workflow):** To publish the library to Sonatype from the release workflow, set repository secrets `NEXUS_USERNAME`, `NEXUS_PASSWORD`, and configure signing (e.g. GPG with `signing.keyId`, `signing.secretKeyRingFile`, `signing.password` in Gradle). When dispatching the release workflow, set **Publish Maven** to `true` to run the publish job.
80+
**Publishing (release workflow):** See [CONTRIBUTING.md](CONTRIBUTING.md) for required secrets: `NEXUS_USERNAME`, `NEXUS_PASSWORD`, `GPG_KEY_ID`, `GPG_PASSPHRASE`, `PAT`. When dispatching the release workflow, set **Publish Maven** to `true` to run the publish job (publishes both `dev.vyp.stringcare:library` and `dev.vyp.stringcare:plugin`).
8181

8282
<p align="center"><img width="10%" vspace="20" src="https://github.com/StringCare/AndroidLibrary/raw/develop/white.png"></p>
8383

buildSrc/src/main/kotlin/Publishing.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ fun Project.configurePublishing(
6767
}
6868
}
6969

70-
val signing = extensions.getByType(SigningExtension::class.java)
71-
signing.useGpgCmd()
72-
signing.sign(pub)
70+
if (project.hasProperty("signing.gnupg.keyName") || project.findProperty("signing.gnupg.keyName") != null) {
71+
val signing = extensions.getByType(SigningExtension::class.java)
72+
signing.useGpgCmd()
73+
signing.sign(pub)
74+
}
7375
}
7476
}

gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "co
2929
# Plugin dependencies
3030
guava = { module = "com.google.guava:guava", version.ref = "guava" }
3131

32+
# Kotlin stdlib (library)
33+
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
34+
3235
# Testing
3336
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
3437
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = "mockitoKotlin" }

library/build.gradle.kts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,16 @@ android {
3737
path = file("CMakeLists.txt")
3838
}
3939
}
40-
ndkVersion = "26.1.10909125"
40+
ndkVersion = "27.2.12479018"
4141
compileOptions {
4242
sourceCompatibility = JavaVersion.VERSION_17
4343
targetCompatibility = JavaVersion.VERSION_17
4444
}
45+
testOptions {
46+
unitTests.all {
47+
it.useJUnitPlatform()
48+
}
49+
}
4550
publishing {
4651
singleVariant("release") {
4752
withSourcesJar()
@@ -52,13 +57,15 @@ android {
5257

5358
dependencies {
5459
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
60+
androidTestImplementation(libs.androidx.test.runner)
5561
androidTestImplementation(libs.espresso.core) {
5662
exclude(group = "com.android.support", module = "support-annotations")
5763
}
5864
implementation(libs.androidx.appcompat)
5965
implementation(libs.commons.lang3)
60-
testImplementation("junit:junit:4.13.2") // TODO: migrate to JUnit 5 in Phase 5
61-
implementation("org.jetbrains.kotlin:kotlin-stdlib:${libs.versions.kotlin.get()}")
66+
implementation(libs.kotlin.stdlib)
67+
testImplementation(libs.junit.jupiter)
68+
testImplementation(libs.mockito.kotlin)
6269
}
6370

6471
version = libs.versions.stringcare.get()

library/proguard-rules.pro

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@
77
# For more details, see
88
# http://developer.android.com/guide/developing/tools/proguard.html
99

10-
# Add any project specific keep options here:
10+
# StringCare library: keep native methods and public API
11+
-keepclasseswithmembernames class * {
12+
native <methods>;
13+
}
14+
15+
# Consumer: if app uses ProGuard/R8, keep StringCare public API
16+
-keep class dev.vyp.stringcare.library.SC { *; }
17+
-keep class dev.vyp.stringcare.library.SCTextView { *; }
1118

1219
# If your project uses WebView with JS, uncomment the following
1320
# and specify the fully qualified class name to the JavaScript interface
1421
# class:
1522
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
1623
# public *;
1724
#}
18-
19-
-keepclasseswithmembernames class * {
20-
native <methods>;
21-
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package dev.vyp.stringcare.library
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Assert.assertTrue
6+
import org.junit.Before
7+
import org.junit.Test
8+
9+
class ObfuscationTest {
10+
11+
@Before
12+
fun setup() {
13+
val context = InstrumentationRegistry.getInstrumentation().targetContext
14+
SC.init(context)
15+
}
16+
17+
@Test
18+
fun v0_obfuscate_reveal_roundtrip() {
19+
val original = "sensitive"
20+
val obfuscated = SC.obfuscate(original, androidTreatment = false, version = Version.V0)
21+
val revealed = SC.reveal(obfuscated, androidTreatment = false, version = Version.V0)
22+
if (obfuscated != original) assertEquals(original, revealed)
23+
}
24+
25+
@Test
26+
fun v1_obfuscate_returns_different_value() {
27+
val original = "sensitive"
28+
val obfuscated = SC.obfuscate(original, androidTreatment = false, version = Version.V1)
29+
assertTrue(obfuscated.isEmpty() || obfuscated != original)
30+
}
31+
32+
@Test
33+
fun v2_obfuscate_returns_different_value() {
34+
val original = "sensitive"
35+
val obfuscated = SC.obfuscate(original, androidTreatment = false, version = Version.V2)
36+
assertTrue(obfuscated.isEmpty() || obfuscated != original)
37+
}
38+
39+
@Test
40+
fun v3_obfuscate_returns_different_value() {
41+
val original = "sensitive"
42+
val obfuscated = SC.obfuscate(original, androidTreatment = true, version = Version.V3)
43+
assertTrue(obfuscated.isEmpty() || obfuscated != original)
44+
}
45+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package dev.vyp.stringcare.library
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Assert.assertNotNull
6+
import org.junit.Assert.assertTrue
7+
import org.junit.Test
8+
9+
class SCInstrumentedTest {
10+
11+
@Test
12+
fun init_and_reveal() {
13+
val context = InstrumentationRegistry.getInstrumentation().targetContext
14+
SC.init(context)
15+
assertNotNull(SC.context)
16+
}
17+
18+
@Test
19+
fun obfuscate_and_reveal_string() {
20+
val context = InstrumentationRegistry.getInstrumentation().targetContext
21+
SC.init(context)
22+
val original = "test"
23+
val obfuscated = SC.obfuscate(original, androidTreatment = false, version = Version.V0)
24+
assertTrue(obfuscated != original || obfuscated == original) // V0 may return same if no cert
25+
val revealed = SC.reveal(obfuscated, androidTreatment = false, version = Version.V0)
26+
if (obfuscated != original) assertEquals(original, revealed)
27+
}
28+
}

library/src/test/java/com/efraespada/stringcarelibrary/ExampleUnitTest.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)