Skip to content

Commit a887966

Browse files
committed
Add Maven Central publishing configuration, update npm build output handling, and enhance documentation
1 parent e1f04dd commit a887966

5 files changed

Lines changed: 165 additions & 9 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ yarn-error.log*
2727
/buildSrc/build
2828
/.gradle
2929

30+
/.build.env
31+
/frontend-build/

README.md

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ npm start
2525
```
2626

2727
The app uses `REACT_APP_API_BASE_URL=http://localhost:9090/api` in local development.
28+
The login flow is token-based: the UI calls the mock login API, stores the returned token, and sends it as a bearer token on later API calls.
2829

2930
## Gradle
3031

@@ -43,19 +44,42 @@ Available Gradle tasks:
4344
./gradlew npmBuild
4445
./gradlew npmTest
4546
./gradlew npmStart
47+
./gradlew frontendJar
48+
./gradlew frontendSourcesJar
49+
./gradlew assemble
50+
./gradlew release --no-configuration-cache
4651
```
4752

4853
The Node integration is configured to use the local Node runtime from `nvm` rather than downloading a separate Node distribution.
4954

55+
Archive outputs:
56+
57+
- `frontendJar`: packages the npm `build/` output as the main JAR artifact
58+
- `frontendSourcesJar`: packages all git-tracked files as the sources JAR
59+
60+
`frontendSourcesJar` uses `git ls-files`, so if Gradle reports configuration-cache incompatibility, run it with:
61+
62+
```bash
63+
./gradlew frontendSourcesJar --no-configuration-cache
64+
```
65+
66+
Project versioning is driven by `gradle.properties`.
67+
5068
## Mock APIs
5169

5270
WireMock mappings live in [`wiremock/mappings`](/data/Git/error-sense-ui/wiremock/mappings).
5371

54-
- `GET /api/developer-reports`
55-
- `GET /api/reviewer-reports`
56-
- `PUT /api/reviewer-reports/:id`
72+
- `POST /api/v1/auth/login`
73+
- `GET /api/v1/errsense/report/dev-summary`
74+
- `GET /api/v1/errsense/report/owner-review`
75+
- `PUT /api/v1/errsense/report/owner-review/:id`
5776
- Generic `OPTIONS /api/*` preflight handler for local CORS
5877

78+
Mock login response:
79+
80+
- returns a bearer token: `mock-errsense-token`
81+
- report APIs require `Authorization: Bearer mock-errsense-token`
82+
5983
## Build
6084

6185
```bash
@@ -68,6 +92,42 @@ Or with Gradle:
6892
./gradlew npmBuild
6993
```
7094

95+
## Publishing
96+
97+
The Gradle build is configured for Maven Central publishing with:
98+
99+
- `maven-publish`
100+
- `signing`
101+
- `io.github.gradle-nexus.publish-plugin`
102+
- `net.researchgate.release`
103+
104+
Publish flow:
105+
106+
```bash
107+
./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository --no-configuration-cache
108+
```
109+
110+
Required environment variables:
111+
112+
- `OSSRH_USERNAME`
113+
- `OSSRH_PASSWORD`
114+
- `SIGNING_KEY_FILE`
115+
- `SIGNING_KEY_PASSWORD`
116+
117+
Release flow:
118+
119+
```bash
120+
./gradlew release --no-configuration-cache
121+
```
122+
123+
The release plugin:
124+
125+
- reads and updates the version from `gradle.properties`
126+
- publishes to Sonatype
127+
- closes and releases the Sonatype staging repository
128+
- creates a Git tag using `<project-name>-<version>`
129+
- requires releases to run from the `master` branch
130+
71131
## Docker
72132

73133
This project uses a standard multi-stage Docker build for container images. Jib is not the recommended path for this frontend-only repo.
@@ -101,3 +161,13 @@ Login example:
101161
```bash
102162
echo "$GITHUB_TOKEN" | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
103163
```
164+
165+
## GitHub Actions
166+
167+
GitHub Actions builds and pushes the container image to GHCR using the first 8 characters of the commit SHA as the tag.
168+
169+
Example tag:
170+
171+
```text
172+
ghcr.io/openprojectx/error-sense-ui:5a9619ee
173+
```

build.gradle.kts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,88 @@
1+
import net.researchgate.release.ReleaseExtension
2+
13
plugins {
4+
`maven-publish`
5+
signing
6+
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
7+
id("net.researchgate.release") version "3.1.0"
28
id("node-frontend")
39
id("frontend-archive")
410
id("frontend-jib")
511
}
612

713
group = "org.openprojectx.ai"
8-
version = "0.1.0-SNAPSHOT"
914

1015
allprojects {
1116
repositories {
1217
mavenCentral()
1318
}
1419
}
20+
21+
publishing {
22+
publications {
23+
create<MavenPublication>("mavenFrontend") {
24+
artifactId = project.name
25+
artifact(tasks.named("frontendJar"))
26+
artifact(tasks.named("frontendSourcesJar"))
27+
28+
pom {
29+
name.set(project.name)
30+
description.set("React frontend for the Error Sense dashboard")
31+
url.set("https://github.com/openprojectx/error-sense-ui")
32+
33+
licenses {
34+
license {
35+
name.set("Apache License 2.0")
36+
url.set("https://www.apache.org/licenses/LICENSE-2.0")
37+
}
38+
}
39+
40+
developers {
41+
developer {
42+
id.set("openprojectx")
43+
name.set("OpenProjectX")
44+
email.set("admin@openprojectx.org")
45+
}
46+
}
47+
48+
scm {
49+
url.set("https://github.com/openprojectx/error-sense-ui")
50+
connection.set("scm:git:https://github.com/openprojectx/error-sense-ui.git")
51+
developerConnection.set("scm:git:ssh://git@github.com:openprojectx/error-sense-ui.git")
52+
}
53+
}
54+
}
55+
}
56+
}
57+
58+
signing {
59+
val keyFile = System.getenv("SIGNING_KEY_FILE")
60+
val keyPass = System.getenv("SIGNING_KEY_PASSWORD")
61+
62+
if (!keyFile.isNullOrBlank()) {
63+
val keyText = file(keyFile).readText()
64+
useInMemoryPgpKeys(keyText, keyPass)
65+
sign(publishing.publications)
66+
}
67+
}
68+
69+
nexusPublishing {
70+
repositories {
71+
sonatype {
72+
nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/"))
73+
snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/"))
74+
username.set(System.getenv("OSSRH_USERNAME"))
75+
password.set(System.getenv("OSSRH_PASSWORD"))
76+
}
77+
}
78+
}
79+
80+
configure<ReleaseExtension> {
81+
buildTasks.set(listOf("publishToSonatype", "closeAndReleaseSonatypeStagingRepository"))
82+
versionPropertyFile.set("gradle.properties")
83+
tagTemplate.set("\$name-\$version")
84+
85+
with(git) {
86+
requireBranch.set("master")
87+
}
88+
}

buildSrc/src/main/kotlin/frontend-archive.gradle.kts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import org.gradle.jvm.tasks.Jar
22
import org.gradle.api.file.DuplicatesStrategy
3+
import java.io.File
34

45
plugins {
56
base
@@ -26,24 +27,28 @@ val frontendJar = tasks.register<Jar>("frontendJar") {
2627
archiveBaseName.set(project.name)
2728
archiveClassifier.set("")
2829

29-
from(layout.projectDirectory.dir("build")) {
30-
exclude("libs/**")
31-
exclude("tmp/**")
30+
from(layout.projectDirectory.dir("frontend-build")) {
3231
into("/")
3332
}
3433
}
3534

3635
val frontendSourcesJar = tasks.register<Jar>("frontendSourcesJar") {
3736
description = "Packages all git-tracked files as a sources JAR."
3837
group = "build"
38+
dependsOn("npmInstall")
3939
notCompatibleWithConfigurationCache("Uses git ls-files to resolve tracked source inputs.")
4040

4141
archiveBaseName.set(project.name)
4242
archiveClassifier.set("sources")
4343
duplicatesStrategy = DuplicatesStrategy.FAIL
4444

45-
from(layout.projectDirectory) {
46-
include(trackedFilePatterns)
45+
trackedFilePatterns.forEach { relativePath ->
46+
val parentPath = File(relativePath).parent
47+
from(layout.projectDirectory.file(relativePath)) {
48+
if (parentPath != null) {
49+
into(parentPath)
50+
}
51+
}
4752
}
4853
}
4954

buildSrc/src/main/kotlin/node-frontend.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ tasks.register<NpmTask>("npmBuild") {
2626
dependsOn("npmInstall")
2727
args.set(listOf("run", "build"))
2828
workingDir.set(projectDir)
29+
environment.set(
30+
mapOf(
31+
"BUILD_PATH" to "frontend-build"
32+
)
33+
)
2934
}
3035
//
3136
//tasks.register<NpmTask>("npmTest") {

0 commit comments

Comments
 (0)