-
Notifications
You must be signed in to change notification settings - Fork 307
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 all 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
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,277 @@ | ||
| 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, windows-latest] | ||
| node-version: [20, 22, 24, 26] | ||
| runs-on: ${{ matrix.os }} | ||
| timeout-minutes: 30 | ||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Disable Windows Defender real-time monitoring | ||
| if: runner.os == 'Windows' | ||
| shell: powershell | ||
| run: Set-MpPreference -DisableRealtimeMonitoring $true | ||
|
|
||
| - 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: ${{ runner.temp }}/cli-artifact | ||
|
|
||
| - name: Install CLI native dependencies | ||
| if: steps.node-check.outputs.available == 'true' | ||
| shell: bash | ||
| run: | | ||
| cd "$RUNNER_TEMP/cli-artifact" | ||
| # The build resolves pnpm catalog: references to real versions. | ||
| # Run npm install in the isolated temp 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: Install tools (Windows) | ||
| if: steps.node-check.outputs.available == 'true' && runner.os == 'Windows' | ||
| shell: bash | ||
| run: | | ||
| ( | ||
| cd smoke-test/playwright && npm install && npx playwright install chromium | ||
| echo "Playwright installed" | ||
| ) & | ||
| PW_PID=$! | ||
|
|
||
| ( | ||
| # Install protoc via direct download | ||
| PROTOC_VERSION=28.3 | ||
| curl -sSL -o "$RUNNER_TEMP/protoc.zip" "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-win64.zip" | ||
| PROTOC_DIR="$RUNNER_TEMP/protoc" | ||
| mkdir -p "$PROTOC_DIR" | ||
| unzip -qo "$RUNNER_TEMP/protoc.zip" -d "$PROTOC_DIR" | ||
| echo "$PROTOC_DIR/bin" >> $GITHUB_PATH | ||
| # Install buf | ||
| BUF_VERSION=1.35.1 | ||
| TOOLS_DIR="$RUNNER_TEMP/tools" | ||
| mkdir -p "$TOOLS_DIR" | ||
| curl -sSL -o "$TOOLS_DIR/buf.exe" "https://github.com/bufbuild/buf/releases/download/v${BUF_VERSION}/buf-Windows-x86_64.exe" | ||
| echo "$TOOLS_DIR" >> $GITHUB_PATH | ||
| 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: Re-enable Windows Defender real-time monitoring | ||
| if: runner.os == 'Windows' | ||
| shell: powershell | ||
| run: Set-MpPreference -DisableRealtimeMonitoring $false | ||
|
|
||
| - 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 "$RUNNER_TEMP/cli-artifact/cli.cjs" docs dev > /tmp/fern-docs-dev.log 2>&1 & | ||
| FERN_PID=$! | ||
| echo "FERN_PID=$FERN_PID" >> $GITHUB_ENV | ||
|
|
||
| # Windows bundle installation (download + pnpm install) can take 3-5 minutes | ||
| TIMEOUT=300 | ||
| echo "Waiting for fern docs dev server to start (PID: $FERN_PID, timeout: ${TIMEOUT}s)..." | ||
| for i in $(seq 1 $TIMEOUT); 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 $TIMEOUT ]; then | ||
| echo "Timeout waiting for server to start after ${TIMEOUT}s" | ||
| 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.
Windows Defender is re-enabled too early, before the main test runs. The workflow disables Defender at line 68-71 to speed up tool installation, but then re-enables it at line 196-199 BEFORE the "Start fern docs dev server" step (line 201-250). The fern docs dev server performs a slow
pnpm installon Windows (as noted in the comment on line 215: "Windows bundle installation (download + pnpm install) can take 3-5 minutes"), which will be significantly slower with Defender enabled.Move the re-enable step to after all tests complete:
Spotted by Graphite

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