From fe623ef75e4edca8a68fb628941c1570bbd9b646 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:05:13 +0200 Subject: [PATCH 01/18] fix: ETU-70889: Test publish fail --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67f5c34..058a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,3 +83,8 @@ jobs: upload_to_bucket: false fail_threshold: warn + test-publish-fail: + uses: ./.github/workflows/publish.yml + with: + path: fixture/openapi-bad.yaml + secrets: inherit \ No newline at end of file From 217f0f203a969699731df5851f49298ac998d9f8 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:15:27 +0200 Subject: [PATCH 02/18] fix: ETU-70889: Test publish fail --- .github/workflows/ci.yml | 2 +- fixture/api-spec-registry/components.yaml | 37 ++++++ fixture/api-spec-registry/openapi.yaml | 135 ++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 fixture/api-spec-registry/components.yaml create mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 058a794..dc2b600 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,5 +86,5 @@ jobs: test-publish-fail: uses: ./.github/workflows/publish.yml with: - path: fixture/openapi-bad.yaml + path: fixture/api-spec-registry/openapi.yaml secrets: inherit \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml new file mode 100644 index 0000000..db34563 --- /dev/null +++ b/fixture/api-spec-registry/components.yaml @@ -0,0 +1,37 @@ +schemas: + ProblemDetail: + description: Problem Details for HTTP APIs (RFC 9457) + required: + - title + - status + type: object + properties: + type: + type: string + description: A URI reference that identifies the problem type + examples: + - https://example.com/probs/out-of-credit + title: + type: string + description: A short, human-readable summary of the problem type + examples: + - You do not have enough credit. + status: + type: integer + description: The HTTP status code generated by the origin server + format: int32 + examples: + - 403 + detail: + type: string + description: A human-readable explanation specific to this occurrence + examples: + - Your current balance is 30, but that costs 50. + instance: + type: string + description: A URI reference that identifies the specific occurrence + examples: + - https://example.net/account/12345/msgs/abc + examples: + - title: API specification is invalid + status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml new file mode 100644 index 0000000..956ee63 --- /dev/null +++ b/fixture/api-spec-registry/openapi.yaml @@ -0,0 +1,135 @@ +openapi: 3.1.2 +info: + title: API Specification registry + version: 1.0.0 + summary: Enturs central registry of OpenAPI specifications + description: Enturs central registry of OpenAPI specifications + contact: + name: API Support + url: https://entur.no + email: support@entur.no + x-entur-metadata: + id: api-spec-registry + owner: team-api + audience: internal +tags: +- name: API specifications +servers: +- url: https://api.entur.io/api-spec-registry + description: Production +components: + securitySchemes: + jwt: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + SpecMetadata: + type: object + properties: + repository: + type: string + examples: + - api-spec-registry + examples: + - repository: api-spec-registry + Spec: + type: object + properties: + id: + type: string + examples: + - api-spec-registry + examples: + - id: api-spec-registry +paths: + "/specs": + put: + tags: + - API specifications + security: + - jwt: [] + summary: Upload specification + description: Upload a specification to the registry. + operationId: uploadSpec + parameters: + - name: dryRun + in: query + description: If true, the specification will not be stored, but all the validation + logic will be performed. + schema: + type: boolean + default: false + requestBody: + description: Specification with metadata + content: + multipart/form-data: + schema: + type: object + properties: + spec: {} + metadata: + "$ref": "#/components/schemas/SpecMetadata" + responses: + '201': + description: Uploaded specification contained changes from the current version + '204': + description: Uploaded specification was identical to the current version + '400': + description: Uploaded specification was invalid + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:opprett + get: + tags: + - API specifications + summary: Get specifications + description: Get all specifications stored in the registry. + operationId: getSpecs + parameters: + - name: maxVersionsPerSpec + in: query + description: How many of the newest versions to fetch for each spec + schema: + type: integer + minimum: 0 + default: 5 + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/Spec" + "/specs/{specId}": + delete: + tags: + - API specifications + security: + - jwt: [] + summary: Delete specification + description: Delete a specification from the registry. + operationId: deleteSpec + parameters: + - name: specId + in: path + required: true + description: The ID of the specification to delete. + schema: + type: string + responses: + '204': + description: Specification deleted successfully + '404': + description: Specification not found + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:slett From 10dafb0e387cd5dd290fbcc79c25e9a5da5f1ee2 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:35:22 +0200 Subject: [PATCH 03/18] fix: ETU-70889: Test publish fail --- .github/workflows/publish.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2f8a010..193b71b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -172,13 +172,17 @@ jobs: METADATA="{\"repository\": \"$REPO_NAME\"}" echo "Publishing spec: $GHA_API_PATH" - - curl --fail-with-body -sS \ + + RESPONSE=$(curl --fail-with-body -sS \ -X PUT \ -H "Authorization: Bearer $ID_TOKEN" \ -F "metadata=$METADATA;type=application/json" \ -F "spec=@/tmp/specs/$filename" \ - "$CLOUD_RUN_ENDPOINT" - + "$CLOUD_RUN_ENDPOINT" 2>&1) || { + DETAIL=$(echo "$RESPONSE" | jq -r '.detail') + echo "::error file=$GHA_API_PATH,line=1::$DETAIL" + exit 1 + } + echo "Successfully published: $GHA_API_PATH" From 04943aa3de00c7bb4e90cde7e65de7404658224b Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:39:01 +0200 Subject: [PATCH 04/18] fix: ETU-70889: Test publish fail --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 193b71b..c4ff6cd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -178,7 +178,7 @@ jobs: -H "Authorization: Bearer $ID_TOKEN" \ -F "metadata=$METADATA;type=application/json" \ -F "spec=@/tmp/specs/$filename" \ - "$CLOUD_RUN_ENDPOINT" 2>&1) || { + "$CLOUD_RUN_ENDPOINT") || { DETAIL=$(echo "$RESPONSE" | jq -r '.detail') echo "::error file=$GHA_API_PATH,line=1::$DETAIL" exit 1 From 45417aeca361542656354fa21fcde83dba5273b6 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:45:59 +0200 Subject: [PATCH 05/18] fix: ETU-70889: Test publish fail --- .github/workflows/publish.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c4ff6cd..6591704 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -173,6 +173,9 @@ jobs: echo "Publishing spec: $GHA_API_PATH" + # Make path relative to workspace root for GitHub annotations + RELATIVE_PATH="${GHA_API_PATH#$GITHUB_WORKSPACE/}" + RESPONSE=$(curl --fail-with-body -sS \ -X PUT \ -H "Authorization: Bearer $ID_TOKEN" \ @@ -180,7 +183,7 @@ jobs: -F "spec=@/tmp/specs/$filename" \ "$CLOUD_RUN_ENDPOINT") || { DETAIL=$(echo "$RESPONSE" | jq -r '.detail') - echo "::error file=$GHA_API_PATH,line=1::$DETAIL" + echo "::error file=$RELATIVE_PATH,line=1::$DETAIL" exit 1 } From ae062a91fcb593fcb6823d9935ad55ba28a169d7 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:55:20 +0200 Subject: [PATCH 06/18] fix: ETU-70889: Test publish fail --- .github/workflows/publish.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6591704..90835e3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -173,9 +173,6 @@ jobs: echo "Publishing spec: $GHA_API_PATH" - # Make path relative to workspace root for GitHub annotations - RELATIVE_PATH="${GHA_API_PATH#$GITHUB_WORKSPACE/}" - RESPONSE=$(curl --fail-with-body -sS \ -X PUT \ -H "Authorization: Bearer $ID_TOKEN" \ @@ -183,7 +180,7 @@ jobs: -F "spec=@/tmp/specs/$filename" \ "$CLOUD_RUN_ENDPOINT") || { DETAIL=$(echo "$RESPONSE" | jq -r '.detail') - echo "::error file=$RELATIVE_PATH,line=1::$DETAIL" + echo "::error::$DETAIL" exit 1 } From c116b3afec51035e4fc15aa8a6b7d84321bee41c Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:59:40 +0200 Subject: [PATCH 07/18] Revert "fix: ETU-70889: Test publish fail" This reverts commit 217f0f203a969699731df5851f49298ac998d9f8. --- .github/workflows/ci.yml | 2 +- fixture/api-spec-registry/components.yaml | 37 ------ fixture/api-spec-registry/openapi.yaml | 135 ---------------------- 3 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 fixture/api-spec-registry/components.yaml delete mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc2b600..058a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,5 +86,5 @@ jobs: test-publish-fail: uses: ./.github/workflows/publish.yml with: - path: fixture/api-spec-registry/openapi.yaml + path: fixture/openapi-bad.yaml secrets: inherit \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml deleted file mode 100644 index db34563..0000000 --- a/fixture/api-spec-registry/components.yaml +++ /dev/null @@ -1,37 +0,0 @@ -schemas: - ProblemDetail: - description: Problem Details for HTTP APIs (RFC 9457) - required: - - title - - status - type: object - properties: - type: - type: string - description: A URI reference that identifies the problem type - examples: - - https://example.com/probs/out-of-credit - title: - type: string - description: A short, human-readable summary of the problem type - examples: - - You do not have enough credit. - status: - type: integer - description: The HTTP status code generated by the origin server - format: int32 - examples: - - 403 - detail: - type: string - description: A human-readable explanation specific to this occurrence - examples: - - Your current balance is 30, but that costs 50. - instance: - type: string - description: A URI reference that identifies the specific occurrence - examples: - - https://example.net/account/12345/msgs/abc - examples: - - title: API specification is invalid - status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml deleted file mode 100644 index 956ee63..0000000 --- a/fixture/api-spec-registry/openapi.yaml +++ /dev/null @@ -1,135 +0,0 @@ -openapi: 3.1.2 -info: - title: API Specification registry - version: 1.0.0 - summary: Enturs central registry of OpenAPI specifications - description: Enturs central registry of OpenAPI specifications - contact: - name: API Support - url: https://entur.no - email: support@entur.no - x-entur-metadata: - id: api-spec-registry - owner: team-api - audience: internal -tags: -- name: API specifications -servers: -- url: https://api.entur.io/api-spec-registry - description: Production -components: - securitySchemes: - jwt: - type: http - scheme: bearer - bearerFormat: JWT - schemas: - SpecMetadata: - type: object - properties: - repository: - type: string - examples: - - api-spec-registry - examples: - - repository: api-spec-registry - Spec: - type: object - properties: - id: - type: string - examples: - - api-spec-registry - examples: - - id: api-spec-registry -paths: - "/specs": - put: - tags: - - API specifications - security: - - jwt: [] - summary: Upload specification - description: Upload a specification to the registry. - operationId: uploadSpec - parameters: - - name: dryRun - in: query - description: If true, the specification will not be stored, but all the validation - logic will be performed. - schema: - type: boolean - default: false - requestBody: - description: Specification with metadata - content: - multipart/form-data: - schema: - type: object - properties: - spec: {} - metadata: - "$ref": "#/components/schemas/SpecMetadata" - responses: - '201': - description: Uploaded specification contained changes from the current version - '204': - description: Uploaded specification was identical to the current version - '400': - description: Uploaded specification was invalid - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:opprett - get: - tags: - - API specifications - summary: Get specifications - description: Get all specifications stored in the registry. - operationId: getSpecs - parameters: - - name: maxVersionsPerSpec - in: query - description: How many of the newest versions to fetch for each spec - schema: - type: integer - minimum: 0 - default: 5 - responses: - '200': - description: Success - content: - application/json: - schema: - type: array - items: - "$ref": "#/components/schemas/Spec" - "/specs/{specId}": - delete: - tags: - - API specifications - security: - - jwt: [] - summary: Delete specification - description: Delete a specification from the registry. - operationId: deleteSpec - parameters: - - name: specId - in: path - required: true - description: The ID of the specification to delete. - schema: - type: string - responses: - '204': - description: Specification deleted successfully - '404': - description: Specification not found - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:slett From c55397eb2e1bfeccc68db6f185ad5bee40c816d1 Mon Sep 17 00:00:00 2001 From: rikard Date: Mon, 13 Apr 2026 11:59:40 +0200 Subject: [PATCH 08/18] Revert "fix: ETU-70889: Test publish fail" This reverts commit fe623ef75e4edca8a68fb628941c1570bbd9b646. --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 058a794..67f5c34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,8 +83,3 @@ jobs: upload_to_bucket: false fail_threshold: warn - test-publish-fail: - uses: ./.github/workflows/publish.yml - with: - path: fixture/openapi-bad.yaml - secrets: inherit \ No newline at end of file From 6e3b766ac8c5a82bf10ea94d87225be84b377ea0 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:50:29 +0200 Subject: [PATCH 09/18] Reapply "fix: ETU-70889: Test publish fail" This reverts commit c55397eb2e1bfeccc68db6f185ad5bee40c816d1. --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67f5c34..058a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,3 +83,8 @@ jobs: upload_to_bucket: false fail_threshold: warn + test-publish-fail: + uses: ./.github/workflows/publish.yml + with: + path: fixture/openapi-bad.yaml + secrets: inherit \ No newline at end of file From 1462a9461686650a246d1c58202a98a67455b60a Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:50:29 +0200 Subject: [PATCH 10/18] Reapply "fix: ETU-70889: Test publish fail" This reverts commit c116b3afec51035e4fc15aa8a6b7d84321bee41c. --- .github/workflows/ci.yml | 2 +- fixture/api-spec-registry/components.yaml | 37 ++++++ fixture/api-spec-registry/openapi.yaml | 135 ++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 fixture/api-spec-registry/components.yaml create mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 058a794..dc2b600 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,5 +86,5 @@ jobs: test-publish-fail: uses: ./.github/workflows/publish.yml with: - path: fixture/openapi-bad.yaml + path: fixture/api-spec-registry/openapi.yaml secrets: inherit \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml new file mode 100644 index 0000000..db34563 --- /dev/null +++ b/fixture/api-spec-registry/components.yaml @@ -0,0 +1,37 @@ +schemas: + ProblemDetail: + description: Problem Details for HTTP APIs (RFC 9457) + required: + - title + - status + type: object + properties: + type: + type: string + description: A URI reference that identifies the problem type + examples: + - https://example.com/probs/out-of-credit + title: + type: string + description: A short, human-readable summary of the problem type + examples: + - You do not have enough credit. + status: + type: integer + description: The HTTP status code generated by the origin server + format: int32 + examples: + - 403 + detail: + type: string + description: A human-readable explanation specific to this occurrence + examples: + - Your current balance is 30, but that costs 50. + instance: + type: string + description: A URI reference that identifies the specific occurrence + examples: + - https://example.net/account/12345/msgs/abc + examples: + - title: API specification is invalid + status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml new file mode 100644 index 0000000..956ee63 --- /dev/null +++ b/fixture/api-spec-registry/openapi.yaml @@ -0,0 +1,135 @@ +openapi: 3.1.2 +info: + title: API Specification registry + version: 1.0.0 + summary: Enturs central registry of OpenAPI specifications + description: Enturs central registry of OpenAPI specifications + contact: + name: API Support + url: https://entur.no + email: support@entur.no + x-entur-metadata: + id: api-spec-registry + owner: team-api + audience: internal +tags: +- name: API specifications +servers: +- url: https://api.entur.io/api-spec-registry + description: Production +components: + securitySchemes: + jwt: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + SpecMetadata: + type: object + properties: + repository: + type: string + examples: + - api-spec-registry + examples: + - repository: api-spec-registry + Spec: + type: object + properties: + id: + type: string + examples: + - api-spec-registry + examples: + - id: api-spec-registry +paths: + "/specs": + put: + tags: + - API specifications + security: + - jwt: [] + summary: Upload specification + description: Upload a specification to the registry. + operationId: uploadSpec + parameters: + - name: dryRun + in: query + description: If true, the specification will not be stored, but all the validation + logic will be performed. + schema: + type: boolean + default: false + requestBody: + description: Specification with metadata + content: + multipart/form-data: + schema: + type: object + properties: + spec: {} + metadata: + "$ref": "#/components/schemas/SpecMetadata" + responses: + '201': + description: Uploaded specification contained changes from the current version + '204': + description: Uploaded specification was identical to the current version + '400': + description: Uploaded specification was invalid + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:opprett + get: + tags: + - API specifications + summary: Get specifications + description: Get all specifications stored in the registry. + operationId: getSpecs + parameters: + - name: maxVersionsPerSpec + in: query + description: How many of the newest versions to fetch for each spec + schema: + type: integer + minimum: 0 + default: 5 + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/Spec" + "/specs/{specId}": + delete: + tags: + - API specifications + security: + - jwt: [] + summary: Delete specification + description: Delete a specification from the registry. + operationId: deleteSpec + parameters: + - name: specId + in: path + required: true + description: The ID of the specification to delete. + schema: + type: string + responses: + '204': + description: Specification deleted successfully + '404': + description: Specification not found + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:slett From 67398b1d1dd4a95cf958393d2d6036110f11c9a6 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:52:14 +0200 Subject: [PATCH 11/18] fix: ETU-70889: Added link to spec file in error from backend when publishing spec. --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 90835e3..c4ff6cd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -180,7 +180,7 @@ jobs: -F "spec=@/tmp/specs/$filename" \ "$CLOUD_RUN_ENDPOINT") || { DETAIL=$(echo "$RESPONSE" | jq -r '.detail') - echo "::error::$DETAIL" + echo "::error file=$GHA_API_PATH,line=1::$DETAIL" exit 1 } From d18a84548e38af8025a14ab5e05b905d4b52be8b Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:56:08 +0200 Subject: [PATCH 12/18] Revert "Reapply "fix: ETU-70889: Test publish fail"" This reverts commit 1462a9461686650a246d1c58202a98a67455b60a. --- .github/workflows/ci.yml | 2 +- fixture/api-spec-registry/components.yaml | 37 ------ fixture/api-spec-registry/openapi.yaml | 135 ---------------------- 3 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 fixture/api-spec-registry/components.yaml delete mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc2b600..058a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,5 +86,5 @@ jobs: test-publish-fail: uses: ./.github/workflows/publish.yml with: - path: fixture/api-spec-registry/openapi.yaml + path: fixture/openapi-bad.yaml secrets: inherit \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml deleted file mode 100644 index db34563..0000000 --- a/fixture/api-spec-registry/components.yaml +++ /dev/null @@ -1,37 +0,0 @@ -schemas: - ProblemDetail: - description: Problem Details for HTTP APIs (RFC 9457) - required: - - title - - status - type: object - properties: - type: - type: string - description: A URI reference that identifies the problem type - examples: - - https://example.com/probs/out-of-credit - title: - type: string - description: A short, human-readable summary of the problem type - examples: - - You do not have enough credit. - status: - type: integer - description: The HTTP status code generated by the origin server - format: int32 - examples: - - 403 - detail: - type: string - description: A human-readable explanation specific to this occurrence - examples: - - Your current balance is 30, but that costs 50. - instance: - type: string - description: A URI reference that identifies the specific occurrence - examples: - - https://example.net/account/12345/msgs/abc - examples: - - title: API specification is invalid - status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml deleted file mode 100644 index 956ee63..0000000 --- a/fixture/api-spec-registry/openapi.yaml +++ /dev/null @@ -1,135 +0,0 @@ -openapi: 3.1.2 -info: - title: API Specification registry - version: 1.0.0 - summary: Enturs central registry of OpenAPI specifications - description: Enturs central registry of OpenAPI specifications - contact: - name: API Support - url: https://entur.no - email: support@entur.no - x-entur-metadata: - id: api-spec-registry - owner: team-api - audience: internal -tags: -- name: API specifications -servers: -- url: https://api.entur.io/api-spec-registry - description: Production -components: - securitySchemes: - jwt: - type: http - scheme: bearer - bearerFormat: JWT - schemas: - SpecMetadata: - type: object - properties: - repository: - type: string - examples: - - api-spec-registry - examples: - - repository: api-spec-registry - Spec: - type: object - properties: - id: - type: string - examples: - - api-spec-registry - examples: - - id: api-spec-registry -paths: - "/specs": - put: - tags: - - API specifications - security: - - jwt: [] - summary: Upload specification - description: Upload a specification to the registry. - operationId: uploadSpec - parameters: - - name: dryRun - in: query - description: If true, the specification will not be stored, but all the validation - logic will be performed. - schema: - type: boolean - default: false - requestBody: - description: Specification with metadata - content: - multipart/form-data: - schema: - type: object - properties: - spec: {} - metadata: - "$ref": "#/components/schemas/SpecMetadata" - responses: - '201': - description: Uploaded specification contained changes from the current version - '204': - description: Uploaded specification was identical to the current version - '400': - description: Uploaded specification was invalid - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:opprett - get: - tags: - - API specifications - summary: Get specifications - description: Get all specifications stored in the registry. - operationId: getSpecs - parameters: - - name: maxVersionsPerSpec - in: query - description: How many of the newest versions to fetch for each spec - schema: - type: integer - minimum: 0 - default: 5 - responses: - '200': - description: Success - content: - application/json: - schema: - type: array - items: - "$ref": "#/components/schemas/Spec" - "/specs/{specId}": - delete: - tags: - - API specifications - security: - - jwt: [] - summary: Delete specification - description: Delete a specification from the registry. - operationId: deleteSpec - parameters: - - name: specId - in: path - required: true - description: The ID of the specification to delete. - schema: - type: string - responses: - '204': - description: Specification deleted successfully - '404': - description: Specification not found - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:slett From 5c60131fc9f99cc8e360c61e5707547a454178a4 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:56:08 +0200 Subject: [PATCH 13/18] Revert "Reapply "fix: ETU-70889: Test publish fail"" This reverts commit 6e3b766ac8c5a82bf10ea94d87225be84b377ea0. --- .github/workflows/ci.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 058a794..67f5c34 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,8 +83,3 @@ jobs: upload_to_bucket: false fail_threshold: warn - test-publish-fail: - uses: ./.github/workflows/publish.yml - with: - path: fixture/openapi-bad.yaml - secrets: inherit \ No newline at end of file From 62e651fe249622aa1cc646e4846fbe9546150fcf Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:59:49 +0200 Subject: [PATCH 14/18] Reapply "Reapply "fix: ETU-70889: Test publish fail"" This reverts commit 5c60131fc9f99cc8e360c61e5707547a454178a4. --- .github/workflows/ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 67f5c34..058a794 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,3 +83,8 @@ jobs: upload_to_bucket: false fail_threshold: warn + test-publish-fail: + uses: ./.github/workflows/publish.yml + with: + path: fixture/openapi-bad.yaml + secrets: inherit \ No newline at end of file From 651ef4cde27a6013b06800cf7b4e016bc6779a28 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 09:59:49 +0200 Subject: [PATCH 15/18] Reapply "Reapply "fix: ETU-70889: Test publish fail"" This reverts commit d18a84548e38af8025a14ab5e05b905d4b52be8b. --- .github/workflows/ci.yml | 2 +- fixture/api-spec-registry/components.yaml | 37 ++++++ fixture/api-spec-registry/openapi.yaml | 135 ++++++++++++++++++++++ 3 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 fixture/api-spec-registry/components.yaml create mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 058a794..dc2b600 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,5 +86,5 @@ jobs: test-publish-fail: uses: ./.github/workflows/publish.yml with: - path: fixture/openapi-bad.yaml + path: fixture/api-spec-registry/openapi.yaml secrets: inherit \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml new file mode 100644 index 0000000..db34563 --- /dev/null +++ b/fixture/api-spec-registry/components.yaml @@ -0,0 +1,37 @@ +schemas: + ProblemDetail: + description: Problem Details for HTTP APIs (RFC 9457) + required: + - title + - status + type: object + properties: + type: + type: string + description: A URI reference that identifies the problem type + examples: + - https://example.com/probs/out-of-credit + title: + type: string + description: A short, human-readable summary of the problem type + examples: + - You do not have enough credit. + status: + type: integer + description: The HTTP status code generated by the origin server + format: int32 + examples: + - 403 + detail: + type: string + description: A human-readable explanation specific to this occurrence + examples: + - Your current balance is 30, but that costs 50. + instance: + type: string + description: A URI reference that identifies the specific occurrence + examples: + - https://example.net/account/12345/msgs/abc + examples: + - title: API specification is invalid + status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml new file mode 100644 index 0000000..956ee63 --- /dev/null +++ b/fixture/api-spec-registry/openapi.yaml @@ -0,0 +1,135 @@ +openapi: 3.1.2 +info: + title: API Specification registry + version: 1.0.0 + summary: Enturs central registry of OpenAPI specifications + description: Enturs central registry of OpenAPI specifications + contact: + name: API Support + url: https://entur.no + email: support@entur.no + x-entur-metadata: + id: api-spec-registry + owner: team-api + audience: internal +tags: +- name: API specifications +servers: +- url: https://api.entur.io/api-spec-registry + description: Production +components: + securitySchemes: + jwt: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + SpecMetadata: + type: object + properties: + repository: + type: string + examples: + - api-spec-registry + examples: + - repository: api-spec-registry + Spec: + type: object + properties: + id: + type: string + examples: + - api-spec-registry + examples: + - id: api-spec-registry +paths: + "/specs": + put: + tags: + - API specifications + security: + - jwt: [] + summary: Upload specification + description: Upload a specification to the registry. + operationId: uploadSpec + parameters: + - name: dryRun + in: query + description: If true, the specification will not be stored, but all the validation + logic will be performed. + schema: + type: boolean + default: false + requestBody: + description: Specification with metadata + content: + multipart/form-data: + schema: + type: object + properties: + spec: {} + metadata: + "$ref": "#/components/schemas/SpecMetadata" + responses: + '201': + description: Uploaded specification contained changes from the current version + '204': + description: Uploaded specification was identical to the current version + '400': + description: Uploaded specification was invalid + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:opprett + get: + tags: + - API specifications + summary: Get specifications + description: Get all specifications stored in the registry. + operationId: getSpecs + parameters: + - name: maxVersionsPerSpec + in: query + description: How many of the newest versions to fetch for each spec + schema: + type: integer + minimum: 0 + default: 5 + responses: + '200': + description: Success + content: + application/json: + schema: + type: array + items: + "$ref": "#/components/schemas/Spec" + "/specs/{specId}": + delete: + tags: + - API specifications + security: + - jwt: [] + summary: Delete specification + description: Delete a specification from the registry. + operationId: deleteSpec + parameters: + - name: specId + in: path + required: true + description: The ID of the specification to delete. + schema: + type: string + responses: + '204': + description: Specification deleted successfully + '404': + description: Specification not found + content: + application/problem+json: + schema: + "$ref": "components.yaml#/schemas/ProblemDetail" + x-entur-permissions: + value: api-spec-registry.api-specs:slett From 18c1282e09c3abb2a4ee35920003972338867501 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 10:01:12 +0200 Subject: [PATCH 16/18] fix: ETU-70889: Emit github error annotation on error from backend on validate. --- .github/workflows/ci.yml | 2 +- .github/workflows/validate.yml | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc2b600..00fb12b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,7 +84,7 @@ jobs: fail_threshold: warn test-publish-fail: - uses: ./.github/workflows/publish.yml + uses: ./.github/workflows/validate.yml with: path: fixture/api-spec-registry/openapi.yaml secrets: inherit \ No newline at end of file diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index e5539c9..b84d102 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -143,12 +143,17 @@ jobs: METADATA="{\"repository\": \"$REPO_NAME\"}" echo "Uploading to api-spec-registry with dryRun=true..." - curl --fail-with-body -sS \ + + RESPONSE=$(curl --fail-with-body -sS \ -X PUT \ -H "Authorization: Bearer $ID_TOKEN" \ -F "metadata=$METADATA;type=application/json" \ -F "spec=@/tmp/specs/$filename" \ - "$CLOUD_RUN_ENDPOINT?dryRun=true" + "$CLOUD_RUN_ENDPOINT?dryRun=true") || { + DETAIL=$(echo "$RESPONSE" | jq -r '.detail') + echo "::error file=$GHA_API_PATH,line=1::$DETAIL" + exit 1 + } echo "Successfully validated: $GHA_API_PATH" From 8468e26f79f5d8dcdf37667a47cf277a75928701 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 10:03:57 +0200 Subject: [PATCH 17/18] fix: ETU-70889: Testing that no error on validate ok spec. --- fixture/api-spec-registry/openapi.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml index 956ee63..c19de19 100644 --- a/fixture/api-spec-registry/openapi.yaml +++ b/fixture/api-spec-registry/openapi.yaml @@ -9,7 +9,7 @@ info: url: https://entur.no email: support@entur.no x-entur-metadata: - id: api-spec-registry + id: gha-api owner: team-api audience: internal tags: From 19e179fbab2c7342843e648df4a8b8047420d865 Mon Sep 17 00:00:00 2001 From: rikard Date: Tue, 14 Apr 2026 10:11:29 +0200 Subject: [PATCH 18/18] fix: ETU-70889: Reverted test. --- .github/workflows/ci.yml | 8 +- fixture/api-spec-registry/components.yaml | 37 ------ fixture/api-spec-registry/openapi.yaml | 135 ---------------------- 3 files changed, 1 insertion(+), 179 deletions(-) delete mode 100644 fixture/api-spec-registry/components.yaml delete mode 100644 fixture/api-spec-registry/openapi.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 00fb12b..4d4f16c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,10 +81,4 @@ jobs: artifact: "specs" path: "openapi-good.json" upload_to_bucket: false - fail_threshold: warn - - test-publish-fail: - uses: ./.github/workflows/validate.yml - with: - path: fixture/api-spec-registry/openapi.yaml - secrets: inherit \ No newline at end of file + fail_threshold: warn \ No newline at end of file diff --git a/fixture/api-spec-registry/components.yaml b/fixture/api-spec-registry/components.yaml deleted file mode 100644 index db34563..0000000 --- a/fixture/api-spec-registry/components.yaml +++ /dev/null @@ -1,37 +0,0 @@ -schemas: - ProblemDetail: - description: Problem Details for HTTP APIs (RFC 9457) - required: - - title - - status - type: object - properties: - type: - type: string - description: A URI reference that identifies the problem type - examples: - - https://example.com/probs/out-of-credit - title: - type: string - description: A short, human-readable summary of the problem type - examples: - - You do not have enough credit. - status: - type: integer - description: The HTTP status code generated by the origin server - format: int32 - examples: - - 403 - detail: - type: string - description: A human-readable explanation specific to this occurrence - examples: - - Your current balance is 30, but that costs 50. - instance: - type: string - description: A URI reference that identifies the specific occurrence - examples: - - https://example.net/account/12345/msgs/abc - examples: - - title: API specification is invalid - status: 400 diff --git a/fixture/api-spec-registry/openapi.yaml b/fixture/api-spec-registry/openapi.yaml deleted file mode 100644 index c19de19..0000000 --- a/fixture/api-spec-registry/openapi.yaml +++ /dev/null @@ -1,135 +0,0 @@ -openapi: 3.1.2 -info: - title: API Specification registry - version: 1.0.0 - summary: Enturs central registry of OpenAPI specifications - description: Enturs central registry of OpenAPI specifications - contact: - name: API Support - url: https://entur.no - email: support@entur.no - x-entur-metadata: - id: gha-api - owner: team-api - audience: internal -tags: -- name: API specifications -servers: -- url: https://api.entur.io/api-spec-registry - description: Production -components: - securitySchemes: - jwt: - type: http - scheme: bearer - bearerFormat: JWT - schemas: - SpecMetadata: - type: object - properties: - repository: - type: string - examples: - - api-spec-registry - examples: - - repository: api-spec-registry - Spec: - type: object - properties: - id: - type: string - examples: - - api-spec-registry - examples: - - id: api-spec-registry -paths: - "/specs": - put: - tags: - - API specifications - security: - - jwt: [] - summary: Upload specification - description: Upload a specification to the registry. - operationId: uploadSpec - parameters: - - name: dryRun - in: query - description: If true, the specification will not be stored, but all the validation - logic will be performed. - schema: - type: boolean - default: false - requestBody: - description: Specification with metadata - content: - multipart/form-data: - schema: - type: object - properties: - spec: {} - metadata: - "$ref": "#/components/schemas/SpecMetadata" - responses: - '201': - description: Uploaded specification contained changes from the current version - '204': - description: Uploaded specification was identical to the current version - '400': - description: Uploaded specification was invalid - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:opprett - get: - tags: - - API specifications - summary: Get specifications - description: Get all specifications stored in the registry. - operationId: getSpecs - parameters: - - name: maxVersionsPerSpec - in: query - description: How many of the newest versions to fetch for each spec - schema: - type: integer - minimum: 0 - default: 5 - responses: - '200': - description: Success - content: - application/json: - schema: - type: array - items: - "$ref": "#/components/schemas/Spec" - "/specs/{specId}": - delete: - tags: - - API specifications - security: - - jwt: [] - summary: Delete specification - description: Delete a specification from the registry. - operationId: deleteSpec - parameters: - - name: specId - in: path - required: true - description: The ID of the specification to delete. - schema: - type: string - responses: - '204': - description: Specification deleted successfully - '404': - description: Specification not found - content: - application/problem+json: - schema: - "$ref": "components.yaml#/schemas/ProblemDetail" - x-entur-permissions: - value: api-spec-registry.api-specs:slett