mirror of
https://github.com/vercel-labs/fx.git
synced 2026-10-28 10:15:17 +08:00
- Run the full deterministic E2E suite on Linux in four shards on every pull request, plus the MCP conformance baseline, all against one shared build of fx. - Run macOS arm64 unit tests and platform E2E files only when a change touches macOS-specific code, build.zig, macOS signing, or the native SDK addon, or carries the ci:macos label. Otherwise the macOS arm64 check passes without a macOS runner. - Remove the four-platform Full CI workflow and the separate cross-target compile jobs. - Smoke-test the Linux arm64, macOS x86_64, and macOS arm64 binaries in Binary Size, and reuse the base build for later pushes to the same pull request. - Build the SDK WASM surfaces and Node-API addons once and share them across the SDK test jobs. - Run PGSO on pull requests only when the PGSO pipeline changes, and keep release PGSO evidence for 90 days. - Run the long-turn memory, libfx runtime, and live ACP jobs only on request. - Limit libfx publishing to an archive check, an install smoke test, and a registry byte comparison. - Add a warning when an E2E file passes only on retry. - Remove the unused Prepare Release workflow and document the new CI rules.
201 lines
7.4 KiB
YAML
201 lines
7.4 KiB
YAML
name: Binary Size
|
|
|
|
on:
|
|
pull_request:
|
|
|
|
concurrency:
|
|
group: binary-size-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
compare:
|
|
name: ReleaseSafe delta (${{ matrix.name }})
|
|
runs-on: ${{ matrix.runner }}
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
include:
|
|
- name: linux-x86_64
|
|
target: x86_64-linux
|
|
runner: ubuntu-24.04
|
|
section_format: elf
|
|
expected_file: "ELF 64-bit LSB.*x86-64"
|
|
- name: linux-aarch64
|
|
target: aarch64-linux
|
|
runner: ubuntu-24.04-arm
|
|
section_format: elf
|
|
expected_file: "ELF 64-bit LSB.*ARM aarch64"
|
|
- name: macos-x86_64
|
|
target: x86_64-macos
|
|
runner: macos-15-intel
|
|
section_format: macho
|
|
expected_file: "Mach-O 64-bit executable x86_64"
|
|
- name: macos-aarch64
|
|
target: aarch64-macos
|
|
runner: macos-15
|
|
section_format: macho
|
|
expected_file: "Mach-O 64-bit executable arm64"
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
HEAD_SHA: ${{ github.sha }}
|
|
EXPECTED_FILE: ${{ matrix.expected_file }}
|
|
SECTION_FORMAT: ${{ matrix.section_format }}
|
|
TARGET: ${{ matrix.target }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Setup Zig
|
|
uses: mlugg/setup-zig@v2
|
|
with:
|
|
version: "0.16.0"
|
|
use-cache: false
|
|
|
|
- name: Test size reporter
|
|
run: python3 -m unittest scripts.tests.test_binary_size -v
|
|
|
|
- name: Build pull request binary
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
evidence_dir="$RUNNER_TEMP/fx-binary-size-evidence"
|
|
mkdir -p "$evidence_dir"
|
|
test "$(git rev-parse HEAD)" = "$HEAD_SHA"
|
|
zig build \
|
|
-Dtarget=${{ matrix.target }} \
|
|
-Doptimize=ReleaseSafe \
|
|
--cache-dir "$RUNNER_TEMP/fx-head-cache" \
|
|
--global-cache-dir "$RUNNER_TEMP/fx-global-cache"
|
|
cp zig-out/bin/fx "$evidence_dir/head-fx"
|
|
file "$evidence_dir/head-fx" > "$evidence_dir/head-file.txt"
|
|
cat "$evidence_dir/head-file.txt"
|
|
grep -Eq "$EXPECTED_FILE" "$evidence_dir/head-file.txt"
|
|
if [ "$SECTION_FORMAT" = "macho" ]; then
|
|
size -m "$evidence_dir/head-fx" > "$evidence_dir/head-sections.txt"
|
|
else
|
|
size -A -d "$evidence_dir/head-fx" > "$evidence_dir/head-sections.txt"
|
|
fi
|
|
cat "$evidence_dir/head-sections.txt"
|
|
|
|
# Linux x86_64 gets the same smoke test in CI. The other platforms run
|
|
# nowhere else on a pull request, so this is where a broken binary shows up.
|
|
- name: Smoke test native binary
|
|
if: matrix.name != 'linux-x86_64'
|
|
env:
|
|
AI_GATEWAY_API_KEY: ""
|
|
VERCEL_OIDC_TOKEN: ""
|
|
run: scripts/smoke-binary.sh "$RUNNER_TEMP/fx-binary-size-evidence/head-fx"
|
|
|
|
- name: Restore base binary
|
|
id: base-cache
|
|
uses: actions/cache/restore@v4
|
|
with:
|
|
path: ${{ runner.temp }}/fx-binary-size-base-bin
|
|
key: binary-size-base-v1-${{ matrix.target }}-zig-0.16.0-${{ env.BASE_SHA }}
|
|
|
|
- name: Build base binary
|
|
if: steps.base-cache.outputs.cache-hit != 'true'
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
base_worktree="$RUNNER_TEMP/fx-binary-size-base"
|
|
cleanup() {
|
|
git worktree remove --force "$base_worktree" >/dev/null 2>&1 || true
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
git worktree add --detach "$base_worktree" "$BASE_SHA"
|
|
test "$(git -C "$base_worktree" rev-parse HEAD)" = "$BASE_SHA"
|
|
(
|
|
cd "$base_worktree"
|
|
zig build \
|
|
-Dtarget=${{ matrix.target }} \
|
|
-Doptimize=ReleaseSafe \
|
|
--cache-dir "$RUNNER_TEMP/fx-base-cache" \
|
|
--global-cache-dir "$RUNNER_TEMP/fx-global-cache"
|
|
)
|
|
mkdir -p "$RUNNER_TEMP/fx-binary-size-base-bin"
|
|
cp "$base_worktree/zig-out/bin/fx" "$RUNNER_TEMP/fx-binary-size-base-bin/fx"
|
|
|
|
- name: Save base binary
|
|
if: steps.base-cache.outputs.cache-hit != 'true'
|
|
uses: actions/cache/save@v4
|
|
with:
|
|
path: ${{ runner.temp }}/fx-binary-size-base-bin
|
|
key: binary-size-base-v1-${{ matrix.target }}-zig-0.16.0-${{ env.BASE_SHA }}
|
|
|
|
- name: Measure base binary
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
evidence_dir="$RUNNER_TEMP/fx-binary-size-evidence"
|
|
cp "$RUNNER_TEMP/fx-binary-size-base-bin/fx" "$evidence_dir/base-fx"
|
|
file "$evidence_dir/base-fx" > "$evidence_dir/base-file.txt"
|
|
cat "$evidence_dir/base-file.txt"
|
|
grep -Eq "$EXPECTED_FILE" "$evidence_dir/base-file.txt"
|
|
if [ "$SECTION_FORMAT" = "macho" ]; then
|
|
size -m "$evidence_dir/base-fx" > "$evidence_dir/base-sections.txt"
|
|
else
|
|
size -A -d "$evidence_dir/base-fx" > "$evidence_dir/base-sections.txt"
|
|
fi
|
|
cat "$evidence_dir/base-sections.txt"
|
|
|
|
- name: Compare binary sizes
|
|
id: size
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
evidence_dir="$RUNNER_TEMP/fx-binary-size-evidence"
|
|
python3 -m scripts.binary_size \
|
|
--base-binary "$evidence_dir/base-fx" \
|
|
--head-binary "$evidence_dir/head-fx" \
|
|
--base-sections "$evidence_dir/base-sections.txt" \
|
|
--head-sections "$evidence_dir/head-sections.txt" \
|
|
--base-sha "$BASE_SHA" \
|
|
--head-sha "$HEAD_SHA" \
|
|
--target "$TARGET" \
|
|
--warning-bytes 52429 \
|
|
--output-json "$evidence_dir/report.json" \
|
|
--output-markdown "$evidence_dir/report.md" \
|
|
--github-output "$GITHUB_OUTPUT"
|
|
cat "$evidence_dir/report.md" >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Annotate notable growth
|
|
if: steps.size.outputs.warning == 'true'
|
|
env:
|
|
DELTA_BYTES: ${{ steps.size.outputs.delta_bytes }}
|
|
run: |
|
|
printf '%s\n' \
|
|
"::warning title=Binary size increase::${TARGET} ReleaseSafe grew by ${DELTA_BYTES} bytes; inspect the retained section report."
|
|
|
|
- name: Upload size evidence
|
|
if: always()
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: binary-size-evidence-${{ matrix.name }}-${{ github.event.pull_request.number }}
|
|
path: |
|
|
${{ runner.temp }}/fx-binary-size-evidence/report.json
|
|
${{ runner.temp }}/fx-binary-size-evidence/report.md
|
|
${{ runner.temp }}/fx-binary-size-evidence/base-file.txt
|
|
${{ runner.temp }}/fx-binary-size-evidence/head-file.txt
|
|
${{ runner.temp }}/fx-binary-size-evidence/base-sections.txt
|
|
${{ runner.temp }}/fx-binary-size-evidence/head-sections.txt
|
|
if-no-files-found: warn
|
|
retention-days: 30
|
|
|
|
- name: Upload binaries for investigation
|
|
if: steps.size.outputs.warning == 'true'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: binary-size-binaries-${{ matrix.name }}-${{ github.event.pull_request.number }}
|
|
path: |
|
|
${{ runner.temp }}/fx-binary-size-evidence/base-fx
|
|
${{ runner.temp }}/fx-binary-size-evidence/head-fx
|
|
compression-level: 0
|
|
retention-days: 7
|