-
Notifications
You must be signed in to change notification settings - Fork 303
fix(cli): run Windows post-processing on cached bundles + add docs preview smoke test #14765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 8 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
b02c1e3
fix(cli): run Windows post-processing on cached bundles
devin-ai-integration[bot] 581738f
chore(ci): add docs preview smoke test workflow
devin-ai-integration[bot] 500a7e3
fix(ci): remove hardcoded pnpm version in smoke test workflow
devin-ai-integration[bot] af57ae8
fix(ci): use prod CLI build, install native deps, add playwright pack…
devin-ai-integration[bot] 807c34d
fix(ci): download CLI artifact outside repo tree to avoid catalog: pr…
devin-ai-integration[bot] b2f02a0
fix(ci): use /tmp for CLI artifact to fully isolate from repo package…
devin-ai-integration[bot] 0727316
fix(ci): resolve pnpm catalog: versions in CLI build artifact
devin-ai-integration[bot] 4884ac3
fix(ci): remove flaky API reference pages from smoke test
devin-ai-integration[bot] 779e3cc
feat(ci): add windows-latest to docs preview smoke test matrix
devin-ai-integration[bot] 8b2687c
fix(ci): log warning instead of silently swallowing errors in loadPnp…
devin-ai-integration[bot] 822289e
fix(ci): fix biome noConsole lint error in loadPnpmCatalog
devin-ai-integration[bot] e9114db
fix(ci): increase server startup timeout to 300s for Windows bundle i…
devin-ai-integration[bot] a2b258f
fix(ci): add diagnostic curl step to capture Windows 500 response body
devin-ai-integration[bot] 75862d8
fix(ci): prevent diagnostic curl SIGPIPE failure in smoke test
devin-ai-integration[bot] e615642
fix(cli): resolve Windows symlinks as junctions/copies after bundle e…
devin-ai-integration[bot] 59d498a
fix(cli): fix biome import ordering and formatting
devin-ai-integration[bot] f5716c7
fix(ci): add Windows debug step to dump CLI debug log and check symli…
devin-ai-integration[bot] ba5e63d
fix(cli): resolve symlinks before pnpm i esbuild to prevent target pr…
devin-ai-integration[bot] 6d9c272
fix(cli): fix TS2532 undefined check on path parts array
devin-ai-integration[bot] 164a4f6
fix(cli): two-phase backup/restore for Windows file-traced packages
devin-ai-integration[bot] e7b8e20
fix(cli): remove backup/restore workaround and debug steps, fix at so…
devin-ai-integration[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,232 @@ | ||
| name: Docs Preview Smoke Test | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| paths: | ||
| - ".github/workflows/docs-preview-smoke-test.yml" | ||
| - "packages/cli/docs-preview/**" | ||
| - "packages/cli/cli/**" | ||
| - "smoke-test/**" | ||
| pull_request: | ||
| paths: | ||
| - ".github/workflows/docs-preview-smoke-test.yml" | ||
| - "packages/cli/docs-preview/**" | ||
| - "packages/cli/cli/**" | ||
| - "smoke-test/**" | ||
| workflow_dispatch: | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.ref }} | ||
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | ||
|
|
||
| env: | ||
| TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} | ||
| TURBO_TEAM: "buildwithfern" | ||
|
|
||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Install dependencies | ||
| uses: ./.github/actions/install | ||
|
|
||
| - name: Compile packages | ||
| run: pnpm compile | ||
|
|
||
| - name: Build CLI (prod) | ||
| run: pnpm turbo run dist:cli:prod --filter=@fern-api/cli | ||
|
|
||
| - name: Upload CLI artifact | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: cli-prod-bundle | ||
| path: packages/cli/cli/dist/prod/ | ||
| retention-days: 1 | ||
|
|
||
| smoke-test: | ||
| needs: build | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, macos-latest] | ||
| node-version: [20, 22, 24, 26] | ||
| runs-on: ${{ matrix.os }} | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Check Node.js version availability | ||
| id: node-check | ||
| shell: bash | ||
| run: | | ||
| NODE_VERSION="${{ matrix.node-version }}" | ||
| HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://nodejs.org/dist/latest-v${NODE_VERSION}.x/") | ||
| if [ "$HTTP_STATUS" = "200" ]; then | ||
| echo "available=true" >> $GITHUB_OUTPUT | ||
| echo "Node.js v${NODE_VERSION} is available" | ||
| else | ||
| echo "available=false" >> $GITHUB_OUTPUT | ||
| echo "Node.js v${NODE_VERSION} is not yet available (HTTP $HTTP_STATUS) — skipping" | ||
| fi | ||
|
|
||
| - name: Checkout repository | ||
| if: steps.node-check.outputs.available == 'true' | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Node.js | ||
| if: steps.node-check.outputs.available == 'true' | ||
| uses: actions/setup-node@v6 | ||
| with: | ||
| node-version: ${{ matrix.node-version }} | ||
| package-manager-cache: false | ||
|
|
||
| - name: Setup Go for protoc-gen-openapi | ||
| if: steps.node-check.outputs.available == 'true' | ||
| uses: actions/setup-go@v6 | ||
| with: | ||
| go-version: "1.22" | ||
|
|
||
| - name: Download CLI artifact | ||
| if: steps.node-check.outputs.available == 'true' | ||
| uses: actions/download-artifact@v7 | ||
| with: | ||
| name: cli-prod-bundle | ||
| path: /tmp/cli-artifact | ||
|
|
||
| - name: Install CLI native dependencies | ||
| if: steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| run: | | ||
| cd /tmp/cli-artifact | ||
| # The build resolves pnpm catalog: references to real versions. | ||
| # Run npm install in the isolated /tmp directory so npm doesn't | ||
| # walk up into the repo's pnpm workspace. | ||
| npm install --ignore-scripts | ||
|
|
||
| - name: Install tools (Linux) | ||
| if: steps.node-check.outputs.available == 'true' && runner.os == 'Linux' | ||
| run: | | ||
| ( | ||
| cd smoke-test/playwright && npm install && npx playwright install chromium | ||
| echo "Playwright installed" | ||
| ) & | ||
| PW_PID=$! | ||
|
|
||
| ( | ||
| sudo apt-get update && sudo apt-get install -y protobuf-compiler | ||
| BUF_VERSION=1.35.1 | ||
| curl -sSL "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/buf-Linux-x86_64.tar.gz" | sudo tar -xzC /usr/local --strip-components=1 | ||
| go install github.com/fern-api/protoc-gen-openapi/cmd/protoc-gen-openapi@v0.1.12 | ||
| echo "$(go env GOPATH)/bin" >> $GITHUB_PATH | ||
| echo "Proto toolchain installed" | ||
| ) & | ||
| PROTO_PID=$! | ||
|
|
||
| wait $PW_PID | ||
| wait $PROTO_PID | ||
|
|
||
| - name: Install tools (macOS) | ||
| if: steps.node-check.outputs.available == 'true' && runner.os == 'macOS' | ||
| run: | | ||
| ( | ||
| cd smoke-test/playwright && npm install && npx playwright install chromium | ||
| echo "Playwright installed" | ||
| ) & | ||
| PW_PID=$! | ||
|
|
||
| ( | ||
| brew install protobuf buf | ||
| go install github.com/fern-api/protoc-gen-openapi/cmd/protoc-gen-openapi@v0.1.12 | ||
| echo "$(go env GOPATH)/bin" >> $GITHUB_PATH | ||
| echo "Proto toolchain installed" | ||
| ) & | ||
| PROTO_PID=$! | ||
|
|
||
| wait $PW_PID | ||
| wait $PROTO_PID | ||
|
|
||
| - name: Start fern docs dev server | ||
| if: steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| env: | ||
| FERN_TOKEN: ${{ secrets.FERN_TOKEN }} | ||
| run: | | ||
| cd smoke-test/fern | ||
|
|
||
| # Use the locally-built CLI instead of the published npm version. | ||
| # The CLI will download the production docs bundle from S3 automatically. | ||
| FERN_NO_VERSION_REDIRECTION=true node "/tmp/cli-artifact/cli.cjs" docs dev > /tmp/fern-docs-dev.log 2>&1 & | ||
| FERN_PID=$! | ||
| echo "FERN_PID=$FERN_PID" >> $GITHUB_ENV | ||
|
|
||
| echo "Waiting for fern docs dev server to start (PID: $FERN_PID)..." | ||
| for i in $(seq 1 120); do | ||
| if grep -q "Docs preview server ready" /tmp/fern-docs-dev.log 2>/dev/null; then | ||
| echo "Server is ready after ${i}s!" | ||
| echo "--- Dev server logs ---" | ||
| cat /tmp/fern-docs-dev.log | ||
| echo "--- End dev server logs ---" | ||
| break | ||
| fi | ||
|
|
||
| if ! kill -0 $FERN_PID 2>/dev/null; then | ||
| echo "fern docs dev process (PID: $FERN_PID) exited unexpectedly" | ||
| echo "--- Dev server logs ---" | ||
| cat /tmp/fern-docs-dev.log | ||
| echo "--- End dev server logs ---" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ $i -eq 120 ]; then | ||
| echo "Timeout waiting for server to start after 120s" | ||
| echo "--- Dev server logs ---" | ||
| cat /tmp/fern-docs-dev.log | ||
| echo "--- End dev server logs ---" | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ $((i % 10)) -eq 0 ]; then | ||
| echo "--- Dev server logs at attempt $i ---" | ||
| tail -20 /tmp/fern-docs-dev.log | ||
| echo "--- End dev server logs ---" | ||
| fi | ||
|
|
||
| sleep 1 | ||
| done | ||
|
|
||
| - name: Run Playwright smoke tests | ||
| if: steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| working-directory: smoke-test/playwright | ||
| run: npx playwright test smoke.spec.ts --config playwright.config.ts | ||
|
|
||
| - name: Upload Playwright report | ||
| uses: actions/upload-artifact@v6 | ||
| if: always() && steps.node-check.outputs.available == 'true' | ||
| with: | ||
| name: smoke-test-playwright-report-${{ matrix.os }}-node${{ matrix.node-version }} | ||
| path: smoke-test/playwright/playwright-report/ | ||
| retention-days: 7 | ||
|
|
||
| - name: Print fern docs dev logs | ||
| if: always() && steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| run: cat /tmp/fern-docs-dev.log || true | ||
|
|
||
| - name: Stop fern docs dev server | ||
| if: always() && steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| run: | | ||
| if [ -n "$FERN_PID" ]; then | ||
| kill $FERN_PID 2>/dev/null || true | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟡 Empty catch block silently swallows errors in loadPnpmCatalog
The
catch {}block atpackages/cli/cli/build-utils.mjs:42silently discards any error fromreadFileSyncor the YAML parsing logic — no error variable is bound, nothing is logged, and no comment explains why. If thepnpm-workspace.yamlfile exists but is unreadable (permissions) or malformed, the function silently returns{}. This causes a confusing downstream error ingetDependencyVersion(line 58) that says the dependency "was not found in pnpm-workspace.yaml catalog" — masking the real root cause. This violates the REVIEW.md / CLAUDE.md rule: "Never swallow errors with empty catch blocks — at minimum log the error. If you truly want to ignore it, add a comment explaining why."Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch — fixed in 8b2687c. The catch block now logs a warning with the error message before returning the empty fallback.