1+ import com.github.gradle.node.npm.task.NpmTask
2+ import com.github.gradle.node.pnpm.task.PnpmTask
3+ import org.openapitools.generator.gradle.plugin.tasks.GenerateTask
4+
5+ plugins {
6+ base
7+ `maven- publish`
8+ alias(libs.plugins.openapi.generator)
9+ alias(libs.plugins.node)
10+ }
11+
12+ val packageOutputDir = layout.buildDirectory.dir(" packages" ) // Output for .tgz files
13+
14+ val publishAllClients by tasks.registering {
15+ group = " publishing"
16+ }
17+ val packageAllClients by tasks.registering {
18+ group = " build"
19+ }
20+
21+ // Helper function to register tasks for a specific client type
22+ fun registerNpmPackageTasks (
23+ clientType : String , // e.g., "fetch", "axios", "redux"
24+ npmPackageName : String , // e.g., "modelix-api-client-ts-fetch"
25+ openApiGeneratorName : String , // e.g., "typescript-fetch"
26+ ) {
27+ val clientBuildDir = layout.buildDirectory.dir(" generate" ).map { it.dir(openApiGeneratorName) }
28+ val publicationFile = clientBuildDir.map { it.file(" modelix-${npmPackageName} -${project.version} .tgz" ) }
29+
30+ val generatorTask = tasks.register(" generateTypescript$clientType " , GenerateTask ::class ) {
31+ group = " openapi tools"
32+ inputSpecRootDirectory = rootProject.layout.projectDirectory.dir(" specifications" ).asFile.absolutePath
33+ inputSpecRootDirectorySkipMerge = false
34+ configOptions = mapOf (
35+ " npmRepository" to " https://artifacts.itemis.cloud/repository/npm-open/" ,
36+ " npmVersion" to project.version.toString(),
37+ " npmName" to " @modelix/$npmPackageName " ,
38+ )
39+ gitUserId = " modelix"
40+ gitRepoId = " modelix.api-specifications"
41+ generatorName = openApiGeneratorName
42+ outputDir = layout.buildDirectory.dir(" generate/$openApiGeneratorName " ).get().asFile.absolutePath
43+ }
44+
45+ // Task to run 'pnpm install'
46+ val pnpmInstallTask = tasks.register<PnpmTask >(" pnpmInstall${clientType.capitalize()} " ) {
47+ group = " build"
48+ description = " Run pnpm install for $openApiGeneratorName client"
49+ dependsOn(generatorTask) // Must run after generation
50+
51+ workingDir.set(clientBuildDir)
52+ pnpmCommand = listOf (" install" )
53+
54+ // Define inputs/outputs for better up-to-date checks and caching
55+ // inputs.dir(clientBuildDir.map { it.dir("src") }).withPathSensitivity(PathSensitivity.RELATIVE) // Source might change
56+ inputs.file(clientBuildDir.map { it.file(" package.json" ) }).withPathSensitivity(PathSensitivity .RELATIVE )
57+ // Add pnpm-lock.yaml if you commit/use it
58+ // inputs.file(clientBuildDir.map { it.file("pnpm-lock.yaml") }).optional().withPathSensitivity(PathSensitivity.RELATIVE)
59+ outputs.dir(clientBuildDir.map { it.dir(" node_modules" ) })
60+ // If 'pnpm install' triggers a build (via 'prepare' script) that creates a 'dist' folder:
61+ // outputs.dir(clientBuildDir.map { it.dir("dist") })
62+ }
63+
64+ // Task to run 'npm pack'
65+ val npmPackTask = tasks.register<NpmTask >(" npmPack${clientType.capitalize()} " ) {
66+ group = " build"
67+ description = " Run npm pack for $npmPackageName "
68+ dependsOn(pnpmInstallTask) // Must run after pnpm install
69+
70+ // npm pack creates the .tgz in the *current* working directory
71+ workingDir.set(clientBuildDir.get().asFile) // Run npm pack from the project root
72+ npmCommand = listOf (" pack" )
73+ // Argument is the path to the directory containing package.json
74+ args.set(listOf (clientBuildDir.get().asFile.absolutePath))
75+
76+ inputs.dir(clientBuildDir)
77+ inputs.files(pnpmInstallTask.map { it.outputs.files })
78+
79+ outputs.file(publicationFile)
80+ }
81+
82+ val publishPackageTasks = tasks.register<NpmTask >(" publish${clientType.capitalize()} " ) {
83+ group = " publishing" // Standard Gradle group for publishing
84+ description = " Publishes the $npmPackageName package to the configured NPM registry."
85+ dependsOn(npmPackTask) // Must run after the package is copied
86+
87+ // Input: The specific .tgz file to be published
88+ inputs.file(publicationFile)
89+
90+ workingDir.set(project.projectDir) // Can run from project root
91+ npmCommand.set(listOf (" publish" ))
92+ // Argument is the path to the .tgz file in the build/packages directory
93+ args.set(listOf (
94+ publicationFile.get().asFile.absolutePath,
95+ " --registry=https://artifacts.itemis.cloud/repository/npm-open/" ,
96+ " --//artifacts.itemis.cloud/repository/npm-open/:_authToken=${project.findProperty(" artifacts.itemis.cloud.npm.token" ).toString()} "
97+ ))
98+
99+ // Add --access public if publishing public packages to npmjs.com scoped or not
100+ // if (isPublicPackage) {
101+ // args.add("--access")
102+ // args.add("public")
103+ // }
104+
105+ // Ensure registry/auth is configured via .npmrc or node {} block
106+ doFirst {
107+ logger.lifecycle(" Attempting to publish ${publicationFile.get().asFile.name} ..." )
108+ logger.info(" Ensure NPM registry and authentication are configured (e.g., via .npmrc)" )
109+ if (! publicationFile.get().asFile.exists()) {
110+ throw GradleException (" Package file to publish does not exist: ${publicationFile.get().asFile.absolutePath} " )
111+ }
112+ }
113+ }
114+
115+ packageAllClients {
116+ dependsOn(npmPackTask)
117+ }
118+ publishAllClients {
119+ dependsOn(publishPackageTasks)
120+ }
121+ }
122+
123+ // Register the tasks for each client type
124+ registerNpmPackageTasks(
125+ clientType = " fetch" ,
126+ npmPackageName = " api-client-ts-fetch" ,
127+ openApiGeneratorName = " typescript-fetch"
128+ )
129+ registerNpmPackageTasks(
130+ clientType = " axios" ,
131+ npmPackageName = " api-client-ts-axios" ,
132+ openApiGeneratorName = " typescript-axios"
133+ )
134+ registerNpmPackageTasks(
135+ clientType = " redux" ,
136+ npmPackageName = " api-client-ts-redux" ,
137+ openApiGeneratorName = " typescript-redux-query"
138+ )
139+
140+ tasks.assemble {
141+ dependsOn(packageAllClients)
142+ }
143+
144+ tasks.publish {
145+ dependsOn(publishAllClients)
146+ }
0 commit comments