Skip to content

Commit 2f457fe

Browse files
committed
Merge branch 'main' into FedeZara/refactor/rename-fern-cli-error-to-task-abort-signal
2 parents 62c9885 + 694a8cd commit 2f457fe

38,092 files changed

Lines changed: 615623 additions & 2688794 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/settings.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@
4141
]
4242
},
4343
"hooks": {
44+
"WorktreeCreate": [
45+
{
46+
"hooks": [
47+
{
48+
"type": "command",
49+
"command": "bash \"$(git rev-parse --show-toplevel)/scripts/worktree-create-hook.sh\""
50+
}
51+
]
52+
}
53+
],
4454
"PostToolUse": [
4555
{
4656
"matcher": "Edit|MultiEdit|Write",

.cursorindexingignore

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ seed/php-model/*
3434
!seed/php-model/seed.yml
3535
seed/php-sdk/*
3636
!seed/php-sdk/seed.yml
37-
seed/postman/*
38-
!seed/postman/seed.yml
3937
seed/pydantic/*
4038
!seed/pydantic/seed.yml
4139
seed/pydantic-v2/*
@@ -54,7 +52,5 @@ seed/rust-sdk/*
5452
!seed/rust-sdk/seed.yml
5553
seed/swift-sdk/*
5654
!seed/swift-sdk/seed.yml
57-
seed/ts-express/*
58-
!seed/ts-express/seed.yml
5955
seed/ts-sdk/*
60-
!seed/ts-sdk/seed.yml
56+
!seed/ts-sdk/seed.yml

.devin/settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ PR titles are validated by CI (`.github/workflows/lint-pr-title.yml`) using [sem
88

99
**Allowed types**: `fix`, `feat`, `revert`, `break`, `chore`
1010

11-
**Allowed scopes**: `docs`, `changelog`, `internal`, `cli`, `typescript`, `python`, `java`, `csharp`, `go`, `php`, `ruby`, `seed`, `postman`, `ci`, `lint`, `fastapi`, `spring`, `express`, `openapi`, `deps`, `deps-dev`, `fiber`, `pydantic`, `ai-search`, `swift`, `rust`
11+
**Allowed scopes**: `docs`, `changelog`, `internal`, `cli`, `typescript`, `python`, `java`, `csharp`, `go`, `php`, `ruby`, `seed`, `ci`, `lint`, `fastapi`, `spring`, `openapi`, `deps`, `deps-dev`, `pydantic`, `ai-search`, `swift`, `rust`
1212

1313
**Examples**:
1414
- `chore(docs): update guidelines`

.github/CODEOWNERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ generators/go-v2/* @amckinney
66
generators/java/* @tstanmay13
77
generators/openapi/* @dsinghvi @amckinney
88
generators/php/* @amckinney
9-
generators/postman/* @dsinghvi @amckinney
109
generators/python/* @amckinney
1110
generators/python-v2/* @amckinney
1211
generators/ruby-v2/* @iamnamananand996

.github/actions/auto-update-seed/action.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Run seed and then automatically create and merge PR with changes
55
# However, we don't need to validate git diff since we are always updating the seed
66
inputs:
77
generator-name:
8-
description: Generator to use (e.g., go-sdk, ruby-sdk)
8+
description: Generator to use (e.g., go-sdk)
99
required: true
1010
generator-path:
1111
description: The path to the source code of the generator (e.g., generators/go, generators/ruby)
@@ -25,6 +25,14 @@ inputs:
2525
description: The matrix strategy index of the job (to differentiate when parallelizing jobs)
2626
required: false
2727
default: "0"
28+
dockerhub-username:
29+
description: Docker Hub username for authenticated pulls (avoids rate limits)
30+
required: false
31+
default: ""
32+
dockerhub-token:
33+
description: Docker Hub token for authenticated pulls (avoids rate limits)
34+
required: false
35+
default: ""
2836

2937
runs:
3038
using: "composite"
@@ -40,6 +48,8 @@ runs:
4048
allow-unexpected-failures: ${{ inputs.allow-unexpected-failures }}
4149
skip-scripts: ${{ inputs.skip-scripts }}
4250
skip-git-diff-check: true
51+
dockerhub-username: ${{ inputs.dockerhub-username }}
52+
dockerhub-token: ${{ inputs.dockerhub-token }}
4353

4454
# Add changes first to simplify git diff checks, no changes will NOT error here
4555
- name: Check for changes

.github/actions/cached-seed/action.yaml

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Run seed generation with caching for a specific generator.
33

44
inputs:
55
generator-name:
6-
description: Generator to use (e.g., go-sdk, ruby-sdk)
6+
description: Generator to use (e.g., go-sdk)
77
required: true
88
generator-path:
99
description: The path to the source code of the generator (e.g., generators/go, generators/ruby)
@@ -20,13 +20,52 @@ inputs:
2020
description: Whether to allow unexpected failures during seed generation
2121
required: false
2222
default: "false"
23+
dockerhub-username:
24+
description: Docker Hub username for authenticated pulls (avoids rate limits)
25+
required: false
26+
default: ""
27+
dockerhub-token:
28+
description: Docker Hub token for authenticated pulls (avoids rate limits)
29+
required: false
30+
default: ""
2331

2432
runs:
2533
using: "composite"
2634
steps:
2735
- name: Install
2836
uses: ./.github/actions/install
2937

38+
- name: Log in to Docker Hub
39+
if: ${{ inputs.dockerhub-username != '' }}
40+
uses: docker/login-action@v3
41+
with:
42+
username: ${{ inputs.dockerhub-username }}
43+
password: ${{ inputs.dockerhub-token }}
44+
45+
- name: Clear stale Docker image cache
46+
shell: bash
47+
run: rm -rf /tmp/docker-cache
48+
49+
- name: Cache Docker images
50+
id: docker-cache
51+
uses: actions/cache@v4
52+
with:
53+
path: /tmp/docker-cache
54+
key: ${{ runner.os }}-docker-${{ inputs.generator-name }}-${{ hashFiles('**/Dockerfile*') }}
55+
restore-keys: |
56+
${{ runner.os }}-docker-${{ inputs.generator-name }}-
57+
58+
- name: Load cached Docker images
59+
shell: bash
60+
run: |
61+
for f in /tmp/docker-cache/*.tar; do
62+
[ -f "$f" ] && docker load -i "$f" || true
63+
done
64+
65+
- name: Record pre-existing Docker images
66+
shell: bash
67+
run: docker images -q | sort -u > /tmp/docker-images-before.txt
68+
3069
- name: Seed Test
3170
shell: bash
3271
env:
@@ -55,3 +94,19 @@ runs:
5594
echo "Seed test failed (attempt $attempt/3), retrying in 10s..."
5695
sleep 10
5796
done
97+
98+
- name: Save Docker images for cache
99+
if: always()
100+
shell: bash
101+
run: |
102+
if [ ! -f /tmp/docker-images-before.txt ]; then
103+
echo "Skipping cache save: docker-images-before.txt not found"
104+
exit 0
105+
fi
106+
mkdir -p /tmp/docker-cache
107+
comm -13 /tmp/docker-images-before.txt <(docker images -q | sort -u) | while read -r id; do
108+
img=$(docker inspect --format '{{index .RepoTags 0}}' "$id" 2>/dev/null || true)
109+
[ -z "$img" ] && continue
110+
fname=$(echo "$img" | tr '/:' '_')
111+
docker save "$img" -o "/tmp/docker-cache/${fname}.tar" 2>/dev/null || true
112+
done
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Fetch Benchmark Specs
2+
description: Download large public OpenAPI specs for SDK generation benchmarking
3+
4+
outputs:
5+
specs-fetched:
6+
description: "Space-separated list of spec names that were successfully fetched"
7+
value: ${{ steps.summary.outputs.specs-fetched }}
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Fetch Square OpenAPI spec
13+
id: fetch-square
14+
shell: bash
15+
run: |
16+
# Pinned to a specific commit SHA for reproducibility.
17+
# A live endpoint would be preferable but Square does not publish one.
18+
FETCH_OK=false
19+
for ATTEMPT in 1 2 3; do
20+
echo "Attempt ${ATTEMPT}/3: Fetching Square OpenAPI spec..."
21+
if curl -sSfL --retry 2 --retry-delay 5 \
22+
"https://raw.githubusercontent.com/square/connect-api-specification/ba11c0a1f006b81dcd3633adb9090e9b2f03fef7/api.json" \
23+
-o benchmarks/fern/apis/square/openapi.json; then
24+
BYTES=$(wc -c < benchmarks/fern/apis/square/openapi.json)
25+
echo "Downloaded Square OpenAPI spec (${BYTES} bytes)"
26+
if [ "$BYTES" -ge 100000 ]; then
27+
FETCH_OK=true
28+
break
29+
fi
30+
echo "::warning::Square spec unexpectedly small (${BYTES} bytes) on attempt ${ATTEMPT}"
31+
else
32+
echo "::warning::curl failed on attempt ${ATTEMPT}"
33+
fi
34+
[ "$ATTEMPT" -lt 3 ] && sleep 5
35+
done
36+
if [ "$FETCH_OK" = "true" ]; then
37+
echo "square-ok=true" >> $GITHUB_OUTPUT
38+
else
39+
echo "::warning::Failed to fetch Square spec after 3 attempts. Skipping Square benchmarks."
40+
rm -f benchmarks/fern/apis/square/openapi.json
41+
echo "square-ok=false" >> $GITHUB_OUTPUT
42+
fi
43+
44+
- name: Summarize fetched specs
45+
id: summary
46+
shell: bash
47+
run: |
48+
SPECS=""
49+
if [ "${{ steps.fetch-square.outputs.square-ok }}" = "true" ]; then
50+
SPECS="square"
51+
fi
52+
if [ -z "$SPECS" ]; then
53+
echo "::error::No benchmark specs could be fetched. Benchmark will be skipped."
54+
exit 1
55+
fi
56+
echo "specs-fetched=$SPECS" >> $GITHUB_OUTPUT
57+
echo "Successfully fetched specs: $SPECS"

.github/actions/get-test-matrix/action.yaml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,11 @@ runs:
6060
if [[ "${{inputs.package-alphabetically}}" == "false" || \
6161
"${{ inputs.sdk-name }}" == "fastapi" || \
6262
"${{ inputs.sdk-name }}" == "go-model" || \
63-
"${{ inputs.sdk-name }}" == "java-spring" || \
6463
"${{ inputs.sdk-name }}" == "openapi" || \
6564
"${{ inputs.sdk-name }}" == "php-model" || \
66-
"${{ inputs.sdk-name }}" == "postman" || \
67-
"${{ inputs.sdk-name }}" == "ruby-sdk" || \
65+
"${{ inputs.sdk-name }}" == "ruby-sdk-v2" || \
6866
"${{ inputs.sdk-name }}" == "rust-model" || \
69-
"${{ inputs.sdk-name }}" == "ts-express" ]]; then
67+
false ]]; then
7068
echo "split-tests=false" >> $GITHUB_OUTPUT
7169
else
7270
echo "split-tests=true" >> $GITHUB_OUTPUT

.github/actions/install/action.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,6 @@ runs:
2424
${{ runner.os }}-turbo-${{ github.job }}-
2525
${{ runner.os }}-turbo-
2626
27-
# Ensure npm 11.5.1 or later is installed
28-
- name: ⎔ Update npm
29-
shell: bash
30-
run: npm install -g npm@latest
31-
3227
- name: 📥 Install dependencies
3328
shell: bash
3429
run: |
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Run SDK Generation Benchmark
2+
description: Run SDK generation for a single generator against benchmark specs and record timing
3+
4+
inputs:
5+
generator:
6+
description: "Generator name (e.g. ts-sdk, python-sdk)"
7+
required: true
8+
skip-scripts:
9+
description: "If true, skip post-generation build/test scripts (--skip-scripts). Measures generator-only time."
10+
required: false
11+
default: "false"
12+
13+
runs:
14+
using: composite
15+
steps:
16+
- name: Build seed CLI
17+
shell: bash
18+
run: pnpm seed:build
19+
20+
- name: Run benchmark for ${{ inputs.generator }}
21+
shell: bash
22+
run: |
23+
GENERATOR="${{ inputs.generator }}"
24+
RESULTS_DIR="benchmark-results"
25+
mkdir -p "$RESULTS_DIR"
26+
27+
for SPEC in square; do
28+
# Skip specs whose OAS file was not successfully fetched
29+
if [ ! -f "benchmarks/fern/apis/${SPEC}/openapi.json" ]; then
30+
echo "::warning::Skipping ${GENERATOR} x ${SPEC} — OpenAPI spec not available"
31+
echo "{\"generator\":\"${GENERATOR}\",\"spec\":\"${SPEC}\",\"duration_seconds\":0,\"exit_code\":-1,\"skipped\":true}" \
32+
>> "${RESULTS_DIR}/${GENERATOR}.jsonl"
33+
continue
34+
fi
35+
36+
echo "::group::Benchmarking ${GENERATOR} against ${SPEC}"
37+
38+
# $EPOCHSECONDS requires bash 5+ (available on GitHub Actions Ubuntu runners)
39+
START_TIME=$EPOCHSECONDS
40+
EXIT_CODE=0
41+
42+
# Run generation (--skip-scripts omits post-gen build/test for cleaner signal)
43+
SKIP_FLAG=""
44+
if [ "${{ inputs.skip-scripts }}" = "true" ]; then
45+
SKIP_FLAG="--skip-scripts"
46+
fi
47+
pnpm seed:local run \
48+
--generator "${GENERATOR}" \
49+
--path "benchmarks/fern/apis/${SPEC}" \
50+
${SKIP_FLAG} 2>&1 || EXIT_CODE=$?
51+
52+
END_TIME=$EPOCHSECONDS
53+
DURATION=$(( END_TIME - START_TIME ))
54+
55+
if [ "$EXIT_CODE" -ne 0 ]; then
56+
echo "::warning::Benchmark ${GENERATOR} x ${SPEC} exited with code ${EXIT_CODE} after ${DURATION}s"
57+
fi
58+
59+
echo "Benchmark: ${GENERATOR} x ${SPEC} = ${DURATION}s (exit ${EXIT_CODE})"
60+
61+
# Write result as JSON (includes exit code so failures are distinguishable)
62+
echo "{\"generator\":\"${GENERATOR}\",\"spec\":\"${SPEC}\",\"duration_seconds\":${DURATION},\"exit_code\":${EXIT_CODE}}" \
63+
>> "${RESULTS_DIR}/${GENERATOR}.jsonl"
64+
65+
echo "::endgroup::"
66+
done

0 commit comments

Comments
 (0)