Skip to content

chore(seed): Adjust devbox and scripts to enable seed --local for all sdk generators#14709

Merged
jsklan merged 9 commits intomainfrom
jsklan/fix-seed-local
Apr 7, 2026
Merged

chore(seed): Adjust devbox and scripts to enable seed --local for all sdk generators#14709
jsklan merged 9 commits intomainfrom
jsklan/fix-seed-local

Conversation

@jsklan
Copy link
Copy Markdown
Contributor

@jsklan jsklan commented Apr 7, 2026

@jsklan jsklan requested a review from amckinney as a code owner April 7, 2026 13:26
Copy link
Copy Markdown

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🌱 Seed Test Selector

Select languages to run seed tests for:

  • Python
  • TypeScript
  • Java
  • Go
  • Ruby
  • C#
  • PHP
  • Swift
  • Rust
  • OpenAPI

How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR.

@jsklan jsklan enabled auto-merge (squash) April 7, 2026 13:26
"export PATH=\"$(go env GOPATH)/bin:$PATH\"",
"command -v golangci-lint &>/dev/null || { echo 'Installing golangci-lint...'; go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.10.1 2>/dev/null || true; }",
"mkdir -p \"$HOME/.local/bin\"",
"if [ ! -f \"$HOME/.local/bin/composer\" ]; then echo 'Installing composer...'; curl -sSL https://getcomposer.org/download/latest-2.x/composer.phar -o \"$HOME/.local/bin/composer\" && chmod +x \"$HOME/.local/bin/composer\"; fi",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Unverified binary downloads in devbox init hook

Two PHP PHAR executables are downloaded via curl -sSL … | chmod +x with no integrity check (no --sha256 or signature verification). The latest-2.x URL path for composer is mutable — it resolves to whatever the server currently serves. If either getcomposer.org or cs.symfony.com is compromised, or if DNS/routing is hijacked, a malicious PHP executable will be silently installed and placed on $PATH of every developer who initialises this devbox, giving the attacker arbitrary code execution on their machine. The once-written guard ([ ! -f … ]) prevents re-download but provides no tamper detection after the fact.

Prompt To Fix With AI
Pin the composer and php-cs-fixer downloads to a specific, immutable release URL and verify a SHA-256 checksum before making the file executable. For example:

```bash
# Composer: pin to a specific version and verify checksum
COMPOSER_VERSION="2.8.4"
COMPOSER_EXPECTED_SHA="<sha256 from https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar.sha256sum>"
if [ ! -f "$HOME/.local/bin/composer" ]; then
  curl -sSL "https://getcomposer.org/download/${COMPOSER_VERSION}/composer.phar" -o "$HOME/.local/bin/composer"
  echo "${COMPOSER_EXPECTED_SHA}  $HOME/.local/bin/composer" | sha256sum -c - || { rm "$HOME/.local/bin/composer"; echo 'Composer checksum mismatch!'; exit 1; }
  chmod +x "$HOME/.local/bin/composer"
fi

# php-cs-fixer: similarly pin to a versioned URL
PHP_CS_FIXER_VERSION="v3.65.0"
PHP_CS_FIXER_EXPECTED_SHA="<sha256 from the release>"
if [ ! -f "$HOME/.local/bin/php-cs-fixer" ]; then
  curl -sSL "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases/download/${PHP_CS_FIXER_VERSION}/php-cs-fixer.phar" -o "$HOME/.local/bin/php-cs-fixer"
  echo "${PHP_CS_FIXER_EXPECTED_SHA}  $HOME/.local/bin/php-cs-fixer" | sha256sum -c - || { rm "$HOME/.local/bin/php-cs-fixer"; echo 'php-cs-fixer checksum mismatch!'; exit 1; }
  chmod +x "$HOME/.local/bin/php-cs-fixer"
fi
```

Update the expected SHAs any time you bump the version. This eliminates the mutable-URL risk and detects tampering of already-cached files.

Severity: medium | Confidence: 80%

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 5 additional findings.

Open in Devin Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

SDK Generation Benchmark Results

Comparing PR branch against main baseline.

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
csharp-sdk square N/A N/A 132s N/A
go-sdk square N/A N/A 298s N/A
java-sdk square N/A N/A 329s N/A
php-sdk square N/A N/A 128s N/A
python-sdk square N/A N/A 169s N/A
ruby-sdk-v2 square N/A N/A 158s N/A
rust-sdk square N/A N/A 130s N/A
swift-sdk square N/A N/A 92s N/A
ts-sdk square N/A N/A 143s N/A

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).

graphite-app[bot]

This comment was marked as resolved.

Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Comment on lines +338 to +343
env_paths = os.environ.get("FERN_CORE_UTILITIES_PATH")
if env_paths is not None:
for source in env_paths.split(":"):
if os.path.exists(os.path.join(source, relative_filepath)):
return source
return env_paths.split(":")[0]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback returns first path even when file doesn't exist in any path. If FERN_CORE_UTILITIES_PATH contains multiple colon-separated paths but relative_filepath doesn't exist in any of them, line 343 returns the first path regardless. This will cause file-not-found errors downstream.

Should raise an error or return a default when no valid path is found:

if env_paths is not None:
    for source in env_paths.split(":"):
        if os.path.exists(os.path.join(source, relative_filepath)):
            return source
    # File not found in any provided path - fall through to default behavior

Remove line 343 to fall through to the default logic instead of blindly returning an invalid path.

Suggested change
env_paths = os.environ.get("FERN_CORE_UTILITIES_PATH")
if env_paths is not None:
for source in env_paths.split(":"):
if os.path.exists(os.path.join(source, relative_filepath)):
return source
return env_paths.split(":")[0]
env_paths = os.environ.get("FERN_CORE_UTILITIES_PATH")
if env_paths is not None:
for source in env_paths.split(":"):
if os.path.exists(os.path.join(source, relative_filepath)):
return source

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

SDK Generation Benchmark Results

Comparing PR branch against latest nightly baseline on main (2026-04-07T04:47:12Z).

Full benchmark table (click to expand)
Generator Spec main (generator) main (E2E) PR (generator) Delta
csharp-sdk square 129s 170s 126s -3s (-2.3%)
go-sdk square 281s 352s 286s +5s (+1.8%)
java-sdk square 324s 376s 331s +7s (+2.2%)
php-sdk square 127s 162s 124s -3s (-2.4%)
python-sdk square 164s 206s 162s -2s (-1.2%)
ruby-sdk-v2 square 151s 189s 153s +2s (+1.3%)
rust-sdk square 133s 131s 127s -6s (-4.5%)
swift-sdk square 142s 506s 139s -3s (-2.1%)
ts-sdk square 142s 174s 140s -2s (-1.4%)

main (generator): generator-only time via --skip-scripts (includes Docker image build, container startup, IR parsing, and code generation — this is the same Docker-based flow customers use via fern generate). main (E2E): full customer-observable time including build/test scripts (nightly baseline, informational). Delta is computed against generator-only baseline.
⚠️ = generation exited with a non-zero exit code (timing may not reflect a successful run).
Baseline from nightly runs on main (latest: 2026-04-07T04:47:12Z). Trigger benchmark-baseline to refresh.

@jsklan jsklan merged commit 9817c18 into main Apr 7, 2026
267 checks passed
@jsklan jsklan deleted the jsklan/fix-seed-local branch April 7, 2026 18:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants