Skip to content

Commit e965493

Browse files
authored
feat(ci): validate OpenAPI spec by generating and building Go client (#2078)
This PR follows up on #2000. **What** Adds automated validation of our OpenAPI specification by generating a Go client from the spec and verifying that the generated code compiles successfully. **Why** - Fast feedback loop: Catch OpenAPI spec issues immediately by validating that client generation and compilation succeed. - Spec compliance: Ensure our OpenAPI spec adheres to the standard by using it in a real-world scenario (client generation + build). - Foundation for multi-language clients: While the generated code is currently discarded after validation, this establishes the infrastructure to generate and publish clients for multiple languages (e.g., TypeScript, Python) in the future. This approach provides validation beyond just schema checking - if the generated Go client builds successfully, we can be confident the spec is both valid and practical to use. **Folder structure** The repository structure follows these conventions: - `codegen/` - Contains only generated code (files, folders, etc.) and should never be modified manually. - `oapi-codegen-go/` - Follows the naming pattern [tool-name]-[language] where: - `oapi-codegen` is the code generation tool. - `go` is the target language. This convention makes it straightforward to add support for additional tools and languages in the future (e.g., openapi-generator-typescript, oapi-codegen-python). **Examples** - This is an [example](https://github.com/apify/apify-docs/actions/runs/19227338449/job/54957493226?pr=2078) of successfull action. - This is an [example](https://github.com/apify/apify-docs/actions/runs/19227226704/job/54957143384?pr=2078) of failed action (can generate Go client but compilation failed due to invalid OpenAPI spec). **Refs** - #1996 - #2057 <!-- CURSOR_SUMMARY --> > [!NOTE] > Adds a CI job that builds the OpenAPI spec, generates a Go client via oapi-codegen, and compiles it, with accompanying codegen config and ignores. > > - **CI/CD (`.github/workflows/openapi.yaml`)**: > - **New job `validate-go-codegen`**: Builds OpenAPI YAML, installs `oapi-codegen`, generates Go client, and builds it with Go 1.25. > - Update existing build to Node.js `24` and run `redoc:test`. > - **Go client codegen setup**: > - Add `codegen/oapi-codegen-go/go.mod` declaring tool and deps. > - Add `codegen/oapi-codegen-go/oapi-codegen.yaml` configuring client/model generation to `generated/client.gen.go`. > - **Repo housekeeping**: > - Update `.gitignore` to exclude `codegen/*/generated/` and `codegen/*/go.sum`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e657bac. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 8570823 commit e965493

File tree

4 files changed

+108
-30
lines changed

4 files changed

+108
-30
lines changed

.github/workflows/openapi.yaml

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,74 @@ name: Check OpenAPI specs
33
on:
44
push:
55

6-
#env:
7-
# APIFY_STAGING_TOKEN: ${{ secrets.APIFY_STAGING_TOKEN }}
8-
96
jobs:
107
build:
118
name: Build the specification file
129
runs-on: ubuntu-latest
1310

1411
steps:
15-
- uses: actions/checkout@v5
16-
17-
- name: Use Node.js 22
18-
uses: actions/setup-node@v6
19-
with:
20-
node-version: 24
21-
cache: 'npm'
22-
cache-dependency-path: 'package-lock.json'
23-
24-
- name: Enable corepack
25-
run: |
26-
corepack enable
27-
28-
- name: Install Dependencies
29-
run: npm ci --force
30-
env:
31-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
32-
33-
- run: |
34-
npm ci
35-
npm run redoc:test
36-
37-
# TODO
38-
# - uses: actions/setup-python@v5
39-
# with:
40-
# python-version: '3.10'
41-
# - run: python -m pip install schemathesis==3.35.0
12+
- uses: actions/checkout@v5
13+
14+
- name: Use Node.js 24
15+
uses: actions/setup-node@v6
16+
with:
17+
node-version: 24
18+
cache: "npm"
19+
cache-dependency-path: "package-lock.json"
20+
21+
- name: Enable corepack
22+
run: |
23+
corepack enable
24+
25+
- name: Install Dependencies
26+
run: npm ci --force
27+
env:
28+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
29+
30+
- run: |
31+
npm run redoc:test
32+
33+
validate-go-codegen:
34+
name: Validate Go client generation
35+
runs-on: ubuntu-latest
36+
37+
steps:
38+
- uses: actions/checkout@v5
39+
40+
- name: Use Node.js 24
41+
uses: actions/setup-node@v6
42+
with:
43+
node-version: 24
44+
cache: "npm"
45+
cache-dependency-path: "package-lock.json"
46+
47+
- name: Enable corepack
48+
run: |
49+
corepack enable
50+
51+
- name: Install Dependencies
52+
run: npm ci --force
53+
54+
- name: Build OpenAPI spec
55+
run: npm run redoc:build:clean:yaml
56+
57+
- name: Setup Go
58+
uses: actions/setup-go@v5
59+
with:
60+
go-version: "1.25"
61+
# Disable caching since go.sum is gitignored and regenerated on each run.
62+
cache: false
63+
64+
- name: Install oapi-codegen as tool
65+
working-directory: codegen/oapi-codegen-go
66+
run: go get -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
67+
68+
- name: Generate Go client
69+
working-directory: codegen/oapi-codegen-go
70+
run: go tool oapi-codegen -config oapi-codegen.yaml ../../static/api/openapi.yaml
71+
72+
- name: Build generated client
73+
working-directory: codegen/oapi-codegen-go
74+
run: |
75+
go mod tidy
76+
go build ./...

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ sources/api/*
2424
apify-api.yaml
2525
static/api
2626
apify-docs-theme/package-lock.json
27+
codegen/*/generated/
28+
codegen/*/go.sum
2729
.github/styles/Microsoft
2830
.github/styles/write-good

codegen/oapi-codegen-go/go.mod

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module apify-codegen-test
2+
3+
go 1.25
4+
5+
tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen
6+
7+
require github.com/oapi-codegen/runtime v1.1.2
8+
9+
require (
10+
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
11+
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 // indirect
12+
github.com/getkin/kin-openapi v0.133.0 // indirect
13+
github.com/go-openapi/jsonpointer v0.21.0 // indirect
14+
github.com/go-openapi/swag v0.23.0 // indirect
15+
github.com/google/uuid v1.5.0 // indirect
16+
github.com/josharian/intern v1.0.0 // indirect
17+
github.com/mailru/easyjson v0.7.7 // indirect
18+
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
19+
github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect
20+
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect
21+
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
22+
github.com/perimeterx/marshmallow v1.1.5 // indirect
23+
github.com/speakeasy-api/jsonpath v0.6.0 // indirect
24+
github.com/speakeasy-api/openapi-overlay v0.10.2 // indirect
25+
github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect
26+
github.com/woodsbury/decimal128 v1.3.0 // indirect
27+
golang.org/x/mod v0.21.0 // indirect
28+
golang.org/x/sync v0.9.0 // indirect
29+
golang.org/x/text v0.20.0 // indirect
30+
golang.org/x/tools v0.25.1 // indirect
31+
gopkg.in/yaml.v2 v2.4.0 // indirect
32+
gopkg.in/yaml.v3 v3.0.1 // indirect
33+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package: apify
2+
output: generated/client.gen.go
3+
generate:
4+
models: true
5+
client: true
6+
embedded-spec: false
7+
output-options:
8+
skip-prune: true

0 commit comments

Comments
 (0)