diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2293450..a20d376 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,8 +28,6 @@ jobs: - name: Set up pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 45b2630..546e686 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -30,8 +30,6 @@ jobs: - name: Set up pnpm uses: pnpm/action-setup@v4 - with: - version: 10 - name: Setup Gradle uses: gradle/actions/setup-gradle@v3 diff --git a/api-server-stubs-ktor/build.gradle.kts b/api-server-stubs-ktor/build.gradle.kts index 4dcbad7..f14d870 100644 --- a/api-server-stubs-ktor/build.gradle.kts +++ b/api-server-stubs-ktor/build.gradle.kts @@ -30,15 +30,22 @@ fabrikt { suspendModifier = enabled completionStage = enabled } + typeOverrides { + uuid = String + } } generate("mavenConnector") { - apiFile = rootProject.layout.projectDirectory.file("redocly/build/bundled/maven-connector-v1.yaml") + apiFile = rootProject.layout.projectDirectory.file("redocly/bundled/maven-connector-v1.yaml") basePackage = "org.modelix.services.maven_connector.stubs" } generate("repository") { - apiFile = rootProject.layout.projectDirectory.file("redocly/build/bundled/repository-v3.yaml") + apiFile = rootProject.layout.projectDirectory.file("redocly/bundled/repository-v3.yaml") basePackage = "org.modelix.services.repository.stubs" } + generate("workspaces") { + apiFile = rootProject.layout.projectDirectory.file("redocly/bundled/workspaces-v1.yaml") + basePackage = "org.modelix.services.workspaces.stubs" + } } tasks.withType { diff --git a/build.gradle.kts b/build.gradle.kts index 3003be1..2d75f88 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,9 +16,12 @@ fun computeVersion(): String { versionFile.readText().trim() } else { val gitVersion: groovy.lang.Closure by extra - val version = gitVersion() - versionFile.writeText(version) - version + gitVersion() + .let { + // Normalize the version so that is always a valid NPM version. + if (it.matches("""\d+\.\d+.\d+-.*""".toRegex())) it else "0.0.1-$it" + } + .also { versionFile.writeText(it) } } } @@ -30,9 +33,9 @@ subprojects { apply(plugin = "maven-publish") repositories { - mavenLocal() maven { url = uri("https://artifacts.itemis.cloud/repository/maven-mps/") } mavenCentral() + mavenLocal() } publishing { diff --git a/client-ts/build.gradle.kts b/client-ts/build.gradle.kts index dcf810b..122301e 100644 --- a/client-ts/build.gradle.kts +++ b/client-ts/build.gradle.kts @@ -40,6 +40,7 @@ fun registerNpmPackageTasks( "npmRepository" to "https://artifacts.itemis.cloud/repository/npm-open/", "npmVersion" to project.version.toString(), "npmName" to "@modelix/$npmPackageName", + "supportsES6" to "true", ) gitUserId = "modelix" gitRepoId = "modelix.openapi" diff --git a/package.json b/package.json index 08db6a2..80d6ef8 100644 --- a/package.json +++ b/package.json @@ -17,5 +17,6 @@ }, "dependencies": { "@stoplight/spectral-cli": "^6.14.2" - } + }, + "packageManager": "pnpm@10.9.0+sha512.0486e394640d3c1fb3c9d43d49cf92879ff74f8516959c235308f5a8f62e2e19528a65cdc2a3058f587cde71eba3d5b56327c8c33a97e4c4051ca48a10ca2d5f" } diff --git a/redocly/build.gradle.kts b/redocly/build.gradle.kts index 1a0808e..435be89 100644 --- a/redocly/build.gradle.kts +++ b/redocly/build.gradle.kts @@ -1,8 +1,61 @@ +import com.github.gradle.node.npm.task.NpmTask +import org.gradle.kotlin.dsl.register + plugins { base alias(libs.plugins.node) } -tasks.named("npm_run_join") { +tasks.assemble { dependsOn("npm_run_bundle") } + +val bundledDir = layout.projectDirectory.dir("bundled") +val publicationFile = bundledDir.file("modelix-openapi-specifications-${project.version}.tgz") + +val updateVersionTask = tasks.register("updatePackageVersion") { + workingDir.set(bundledDir.asFile) + npmCommand = listOf("version") + args.set(listOf( + project.version.toString(), + "--allow-same-version" + )) +} + +val npmPackTask = + tasks.register("npmPack") { + group = "build" + dependsOn("npm_run_bundle") + dependsOn(updateVersionTask) + + workingDir.set(bundledDir.asFile) + npmCommand = listOf("pack") + } + +val npmPublishTask = + tasks.register("npmPublish") { + group = "publishing" + dependsOn(npmPackTask) + + inputs.file(publicationFile) + + workingDir.set(bundledDir.asFile) + npmCommand.set(listOf("publish")) + args.set( + listOf( + publicationFile.asFile.absolutePath, + "--registry=https://artifacts.itemis.cloud/repository/npm-open/", + "--//artifacts.itemis.cloud/repository/npm-open/:_authToken=${project.findProperty( + "artifacts.itemis.cloud.npm.token", + )}", + ), + ) + } + +tasks.assemble { + dependsOn(npmPackTask) +} + +tasks.publish { + dependsOn(npmPublishTask) +} \ No newline at end of file diff --git a/redocly/bundled/.gitignore b/redocly/bundled/.gitignore new file mode 100644 index 0000000..63a3a28 --- /dev/null +++ b/redocly/bundled/.gitignore @@ -0,0 +1,2 @@ +*.tgz +*.yaml diff --git a/redocly/bundled/package.json b/redocly/bundled/package.json new file mode 100644 index 0000000..aaed23a --- /dev/null +++ b/redocly/bundled/package.json @@ -0,0 +1,25 @@ +{ + "name": "@modelix/openapi-specifications", + "version": "0.0.1-SNAPSHOT.4", + "description": "OpenApi yaml files of the Modelix services", + "homepage": "https://modelix.org/", + "repository": { + "type": "git", + "url": "https://github.com/modelix/modelix.openapi.git" + }, + "license": "Apache 2.0", + "files": [ + "./*.yaml" + ], + "scripts": { + "bundle": "redocly bundle", + "package": "npm pack", + "update-version": "npm version 0.0.1-SNAPSHOT.4" + }, + "publishConfig": { + "registry": "https://artifacts.itemis.cloud/repository/npm-open/" + }, + "devDependencies": { + "@redocly/cli": "^1.34.2" + } +} diff --git a/redocly/package.json b/redocly/package.json index e68c3a8..9e1e7b5 100644 --- a/redocly/package.json +++ b/redocly/package.json @@ -7,7 +7,6 @@ "@redocly/cli": "^1.34.2" }, "scripts": { - "bundle": "redocly bundle", - "join": "redocly join build/bundled/**/*.yaml --output=build/joined.yaml" + "bundle": "redocly bundle" } } diff --git a/redocly/redocly.yaml b/redocly/redocly.yaml index 426ad54..32ae77a 100644 --- a/redocly/redocly.yaml +++ b/redocly/redocly.yaml @@ -4,11 +4,16 @@ plugins: apis: repository@v3: root: ../specifications/repository/v3/repository.yaml - output: ./build/bundled/repository-v3.yaml + output: ./bundled/repository-v3.yaml decorators: plugin/use-server-path: {} maven-connector@v1: root: ../specifications/maven-connector/v1/maven.yaml - output: ./build/bundled/maven-connector-v1.yaml + output: ./bundled/maven-connector-v1.yaml + decorators: + plugin/use-server-path: {} + workspaces@v1: + root: ../specifications/workspaces/v1/workspaces.yaml + output: ./bundled/workspaces-v1.yaml decorators: plugin/use-server-path: {} diff --git a/settings.gradle.kts b/settings.gradle.kts index a835eec..51224fb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,5 +2,5 @@ rootProject.name = "modelix.openapi" include("redocly") -include("client-ts") +//include("client-ts") include("api-server-stubs-ktor") diff --git a/specifications/lionweb/bulk/v2024.1/lionweb.yaml b/specifications/lionweb/bulk/v2024.1/lionweb.yaml index f1fba5c..3b50c90 100644 --- a/specifications/lionweb/bulk/v2024.1/lionweb.yaml +++ b/specifications/lionweb/bulk/v2024.1/lionweb.yaml @@ -1,4 +1,4 @@ -openapi: "3.0.3" +openapi: "3.1.0" info: title: "modelix lionweb bulk API adapter" description: "modelix lionweb bulk API adapter" diff --git a/specifications/maven-connector/v1/maven.yaml b/specifications/maven-connector/v1/maven.yaml index 8bdf02a..ec98c20 100644 --- a/specifications/maven-connector/v1/maven.yaml +++ b/specifications/maven-connector/v1/maven.yaml @@ -1,17 +1,19 @@ -openapi: "3.0.3" +openapi: "3.1.0" info: title: "Modelix Maven Connector" version: "1.0.0" servers: - - url: '/api/modelix/maven-connector' + - url: '/modelix/maven-connector' description: Makes artifacts from maven repositories available to other services tags: - name: MavenConnector + - name: MavenRepositories + - name: MavenArtifacts paths: /: get: operationId: getMavenConnectorConfig - tags: [MavenConnector] + tags: [MavenRepositories, MavenArtifacts] responses: "200": description: OK @@ -22,6 +24,7 @@ paths: /repositories/: get: operationId: listMavenRepositories + tags: [MavenRepositories] responses: "200": description: OK @@ -32,7 +35,7 @@ paths: /repositories/{repositoryId}: get: operationId: getMavenRepository - tags: [MavenConnector] + tags: [MavenRepositories] parameters: - name: repositoryId in: path @@ -48,7 +51,7 @@ paths: $ref: '#/components/schemas/MavenRepository' put: operationId: updateMavenRepository - tags: [MavenConnector] + tags: [MavenRepositories] parameters: - name: repositoryId in: path @@ -65,7 +68,7 @@ paths: description: OK delete: operationId: deleteMavenRepository - tags: [MavenConnector] + tags: [MavenRepositories] parameters: - name: repositoryId in: path @@ -78,7 +81,7 @@ paths: /artifacts/: get: operationId: listMavenArtifacts - tags: [MavenConnector] + tags: [MavenArtifacts] responses: "200": description: OK @@ -86,6 +89,68 @@ paths: application/json: schema: $ref: '#/components/schemas/MavenArtifactList' + /artifacts/{groupId}/{artifactId}: + get: + operationId: getMavenArtifact + tags: [MavenArtifacts] + parameters: + - name: groupId + in: path + required: true + schema: + type: string + - name: artifactId + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/MavenArtifact' + put: + operationId: updateMavenArtifact + tags: [MavenArtifacts] + parameters: + - name: groupId + in: path + required: true + schema: + type: string + - name: artifactId + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/MavenArtifact' + responses: + "200": + description: OK + delete: + operationId: deleteMavenArtifact + tags: [MavenArtifacts] + parameters: + - name: groupId + in: path + required: true + schema: + type: string + - name: artifactId + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + components: schemas: MavenConnectorConfig: @@ -114,10 +179,8 @@ components: properties: id: type: string - nullable: false url: type: string - nullable: false MavenArtifactList: type: object required: [artifacts] diff --git a/specifications/repository/v3/repository.yaml b/specifications/repository/v3/repository.yaml index 759b13c..dc1d29a 100644 --- a/specifications/repository/v3/repository.yaml +++ b/specifications/repository/v3/repository.yaml @@ -1,9 +1,9 @@ -openapi: "3.0.3" +openapi: "3.1.0" info: - title: "Modelix Workspaces" + title: "Modelix Model Repository" version: "3.0.0" servers: - - url: '/api/modelix/repository' + - url: '/modelix/repository' description: modelix-workspaces-manager tags: - name: Repository diff --git a/specifications/workspaces/v1/workspaces.yaml b/specifications/workspaces/v1/workspaces.yaml new file mode 100644 index 0000000..1ca773a --- /dev/null +++ b/specifications/workspaces/v1/workspaces.yaml @@ -0,0 +1,404 @@ +openapi: "3.1.0" +info: + title: "Modelix Workspaces" + version: "1.0.0" +servers: + - url: '/modelix/workspaces' + description: modelix-workspaces-manager +tags: + - name: Workspaces + - name: Instances + - name: GitChangeDrafts +paths: + + /workspaces/: + get: + operationId: listWorkspaces + tags: [Workspaces] + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/WorkspaceList' } + + /workspaces/{workspaceId}: + get: + operationId: getWorkspace + tags: [Workspaces] + parameters: + - name: workspaceId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/WorkspaceConfig' } + put: + operationId: updateWorkspace + tags: [Workspaces] + parameters: + - name: workspaceId + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceConfig' + responses: + '200': + description: OK + delete: + operationId: deleteWorkspace + tags: [Workspaces] + parameters: + - name: workspaceId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + + /tasks/{taskId}/config: + get: + operationId: getWorkspaceByTaskId + tags: [Workspaces] + parameters: + - name: taskId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: { type: object } + + /tasks/{taskId}/context.tar.gz: + get: + operationId: getContextForTaskId + tags: [Workspaces] + parameters: + - name: taskId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/gzip: + schema: + type: string + format: binary + + /drafts/: + get: + operationId: listDrafts + tags: [GitChangeDrafts] + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/GitChangeDraftList' } + + /drafts/{draftId}/: + get: + operationId: getDraft + tags: [GitChangeDrafts] + parameters: + - name: draftId + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/GitChangeDraft' } + + /instances/: + get: + operationId: listInstances + tags: [Instances] + parameters: + - name: workspaceId + in: query + required: false + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/WorkspaceInstanceList' } + post: + operationId: createInstance + tags: [Instances] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceInstance' + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/WorkspaceInstance' } + + /instances/{instanceId}/: + get: + operationId: getInstance + tags: [Instances] + parameters: + - name: instanceId + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + content: + application/json: + schema: { $ref: '#/components/schemas/WorkspaceInstance' } + delete: + operationId: deleteInstance + tags: [Instances] + parameters: + - name: instanceId + in: path + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + + + /instances/{instanceId}/state: + get: + operationId: getInstanceState + tags: [Workspaces] + parameters: + - name: instanceId + in: path + required: true + schema: + type: string + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceInstanceStateObject' + post: + operationId: changeInstanceState + tags: [Workspaces] + parameters: + - name: instanceId + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceInstanceStateObject' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceInstanceStateObject' + + /instances/{instanceId}/enabled: + put: + operationId: enableInstance + tags: [Instances] + parameters: + - name: instanceId + in: path + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/WorkspaceInstanceEnabled' + responses: + '200': + description: OK + +components: + schemas: + + GitChangeDraftList: + type: object + required: [drafts] + properties: + drafts: { type: array, items: { $ref: '#/components/schemas/GitChangeDraft' } } + + GitChangeDraft: + type: object + required: [id, description, owner, gitRepository, baseGitBranch, baseGitCommit, modelixBranch] + properties: + id: { type: string, format: uuid } + description: { type: string } + owner: { type: string } + gitRepository: { type: string } + baseGitBranch: { type: string } + baseGitCommit: { type: string } + modelixBranch: { $ref: '#/components/schemas/ModelixBranchRef' } + + ModelixBranchRef: + type: object + required: [repositoryId, branchName] + properties: + repositoryId: { type: string } + branchName: { type: string } + + WorkspaceList: + type: object + required: [workspaces] + properties: + workspaces: { type: array, items: { $ref: '#/components/schemas/WorkspaceConfig' } } + + WorkspaceConfig: + type: object + required: [id, name, mpsVersion, memoryLimit, gitRepositories] + properties: + id: { type: string } + name: { type: string } + mpsVersion: { type: string } + memoryLimit: { type: string } + gitRepositories: + type: array + items: { $ref: '#/components/schemas/GitRepository' } + mavenRepositories: + type: array + items: { $ref: '#/components/schemas/MavenRepository' } + mavenArtifacts: + type: array + items: { $ref: '#/components/schemas/MavenArtifact' } + buildConfig: { $ref: '#/components/schemas/WorkspaceBuildConfig' } + runConfig: { $ref: '#/components/schemas/WorkspaceRunConfig' } + + MavenRepository: + type: object + required: [url] + properties: + url: { type: string } + + MavenArtifact: + type: object + required: [groupId, artifactId] + properties: + groupId: { type: string } + artifactId: { type: string } + version: { type: string } + + GitRepository: + type: object + required: [url] + properties: + url: { type: string } + credentials: { $ref: '#/components/schemas/GitCredentials' } + + GitCredentials: + type: object + required: [username, password] + properties: + username: { type: string } + password: { type: string } + + WorkspaceInstanceList: + type: object + required: [instances] + properties: + instances: { type: array, items: { $ref: '#/components/schemas/WorkspaceInstance' } } + + WorkspaceInstance: + type: object + required: [id, config, state, enabled] + properties: + id: { type: string, format: uuid } + name: { type: string } + config: { $ref: '#/components/schemas/WorkspaceConfig' } + drafts: { type: array, items: { type: string, format: uuid } } + owner: { type: string } + enabled: { type: boolean } + state: { $ref: '#/components/schemas/WorkspaceInstanceState' } + readonly: { type: boolean } + + WorkspaceInstanceState: + type: string + enum: [UNKNOWN, CREATED, DISABLED, WAITING_FOR_BUILD, BUILD_FAILED, LAUNCHING, RUNNING] + + WorkspaceInstanceStateObject: + type: object + required: [state] + properties: + state: { $ref: '#/components/schemas/WorkspaceInstanceState' } + + WorkspaceInstanceEnabled: + type: object + required: [enabled] + properties: + enabled: { type: boolean } + + WorkspaceBuildConfig: + type: object + required: [ignoredModules, additionalGenerationDependencies] + properties: + ignoredModules: { type: array, items: { type: string } } + additionalGenerationDependencies: + type: array + items: { $ref: '#/components/schemas/GenerationDependency' } + + GenerationDependency: + type: object + required: [from, to] + properties: + from: { type: string } + to: { type: string } + + WorkspaceRunConfig: + type: object + required: [loadUsedModulesOnly, memoryLimit] + properties: + loadUsedModulesOnly: { type: boolean } + memoryLimit: { type: string } + + securitySchemes: + modelixJwtAuth: + type: http + scheme: bearer + bearerFormat: JWT + +security: + - modelixJwtAuth: [] \ No newline at end of file