ci: cache exact Hermes compilers and fixtures with bounded reports (#92) #241
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
| name: ci | |
| on: | |
| pull_request: | |
| branches: | |
| - master | |
| push: | |
| branches: | |
| - master | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24.x' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install Dependency | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun install --frozen-lockfile | |
| - name: Run lint and typecheck | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun run lint | |
| test: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24.x' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install Dependency | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun install --frozen-lockfile | |
| - name: Run unit tests with coverage | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun run test:coverage | |
| - name: Upload coverage artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: coverage | |
| path: coverage | |
| retention-days: 7 | |
| if-no-files-found: error | |
| node18-smoke: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| - name: Install Dependency | |
| run: bun install --frozen-lockfile | |
| - name: Build package | |
| run: bun run build | |
| # Node 18 goes on PATH only after the build: typescript >= 7 ships an | |
| # extensionless ESM bin/tsc that Node 18.17 cannot load. | |
| - name: Set up the oldest supported Node.js | |
| uses: actions/setup-node@v7 | |
| with: | |
| node-version: '18.17.0' | |
| - name: Load every built module and run the offline commands | |
| run: node scripts/smoke-lib.js | |
| - name: Check late abort errors on the oldest supported Node.js | |
| run: >- | |
| node tests/fixtures/hermes-async-check.cjs | |
| '{"operation":"abort","modulePath":"./lib/utils/hermes-base.js"}' | |
| - name: Check debug-output failure cleanup on Node 18 | |
| env: | |
| HERMES_TEST_NODE: node | |
| run: bun test tests/hermes-blockers.test.ts | |
| publish-dry-run: | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24.x' | |
| registry-url: 'https://registry.npmjs.org' | |
| - name: Install Dependency | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: bun install --frozen-lockfile | |
| - name: Prepare dry run publish version | |
| env: | |
| PUBLISH_DRY_RUN: 'true' | |
| PUBLISH_VERSION: 0.0.0-dry-run.${{ github.run_id }}.${{ github.run_attempt }} | |
| run: bun scripts/prepublish.ts | |
| - name: Dry run publish | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: npm publish --dry-run --access public --tag dry-run | |
| hermes-integration: | |
| name: hermes-hbc-${{ matrix.hbc }}${{ matrix.suffix }} | |
| runs-on: blacksmith-4vcpu-ubuntu-2404 | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - hbc: 96 | |
| suffix: "" | |
| package: react-native@0.77.3 | |
| directory: react-native | |
| executable: sdks/hermesc/linux64-bin/hermesc | |
| - hbc: 98 | |
| suffix: "" | |
| package: hermes-compiler@250829098.0.16 | |
| directory: hermes-compiler | |
| executable: hermesc/linux64-bin/hermesc | |
| - hbc: 98 | |
| suffix: -patch17 | |
| package: hermes-compiler@250829098.0.17 | |
| directory: hermes-compiler | |
| executable: hermesc/linux64-bin/hermesc | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| persist-credentials: false | |
| - uses: oven-sh/setup-bun@v2 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: '24.x' | |
| - run: bun install --frozen-lockfile | |
| - name: Cache the exact compiler package | |
| id: compiler-cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ${{ runner.temp }}/hermes-tests/${{ matrix.directory }} | |
| # Full package version, not just HBC: .16 and .17 must never collide. | |
| key: hermesc-v1-${{ runner.os }}-${{ runner.arch }}-${{ matrix.package }} | |
| - name: Install and verify the pinned real compiler | |
| shell: bash | |
| env: | |
| COMPILER_PACKAGE: ${{ matrix.package }} | |
| COMPILER_DIRECTORY: ${{ matrix.directory }} | |
| COMPILER_EXECUTABLE: ${{ matrix.executable }} | |
| EXPECTED_HBC: ${{ matrix.hbc }} | |
| COMPILER_CACHE_HIT: ${{ steps.compiler-cache.outputs.cache-hit }} | |
| run: | | |
| set -euo pipefail | |
| root="$RUNNER_TEMP/hermes-tests/$COMPILER_DIRECTORY" | |
| if [ "$COMPILER_CACHE_HIT" != true ]; then | |
| mkdir -p "$root" | |
| archive=$(npm pack "$COMPILER_PACKAGE" --pack-destination "$RUNNER_TEMP" --silent) | |
| tar -xzf "$RUNNER_TEMP/$archive" --strip-components=1 -C "$root" \ | |
| "package/$COMPILER_EXECUTABLE" package/package.json | |
| fi | |
| # Cache hits still prove package identity, executable presence and HBC. | |
| node -e 'const p = require(process.argv[1]); if (`${p.name}@${p.version}` !== process.env.COMPILER_PACKAGE) throw new Error("unexpected compiler package");' "$root/package.json" | |
| export HERMESC="$root/$COMPILER_EXECUTABLE" | |
| test -x "$HERMESC" | |
| "$HERMESC" -version | |
| bun -e 'import {probeHbcVersion} from "./src/utils/hermes-base"; if (probeHbcVersion(process.env.HERMESC) !== Number(process.env.EXPECTED_HBC)) throw new Error("unexpected HBC version");' | |
| echo "HERMESC=$HERMESC" >> "$GITHUB_ENV" | |
| - name: Cache pinned Metro fixtures | |
| id: metro-cache | |
| uses: actions/cache@v6 | |
| with: | |
| path: ${{ runner.temp }}/hermes-metro-fixtures | |
| key: metro-fixtures-v1-${{ runner.os }}-e6a870a1c26c4b64c7860d7e1aa575707d22ad88 | |
| - name: Fetch and verify pinned real Metro fixtures | |
| shell: bash | |
| env: | |
| METRO_CACHE_HIT: ${{ steps.metro-cache.outputs.cache-hit }} | |
| run: | | |
| set -euo pipefail | |
| root="$RUNNER_TEMP/hermes-metro-fixtures" | |
| mkdir -p "$root" | |
| base="https://raw.githubusercontent.com/sunnylqm/hbc-diff-benchmark/e6a870a1c26c4b64c7860d7e1aa575707d22ad88" | |
| if [ "$METRO_CACHE_HIT" != true ]; then | |
| for file in base.jsbundle s3-medium-feature.jsbundle; do | |
| curl --fail --location --retry 2 --max-time 60 "$base/fixtures/$file" -o "$root/$file" | |
| done | |
| curl --fail --location --retry 2 --max-time 60 "$base/LICENSE" -o "$root/LICENSE" | |
| fi | |
| test -s "$root/LICENSE" | |
| # Verification is unconditional, including on exact cache hits. | |
| echo "11c8ad8f7e8c7c59ee45582c77d896a35fa646617f3ba0f5b338a425a7c93b7d $root/base.jsbundle" | sha256sum --check | |
| echo "a693e68254b6c13fae8f839d20c14f9d11c5ab98d4be1b8d13ba1e929a12d752 $root/s3-medium-feature.jsbundle" | sha256sum --check | |
| echo "HERMES_METRO_FIXTURES=$root" >> "$GITHUB_ENV" | |
| - name: Run real compiler and fallback regressions | |
| run: bun test tests/hermes-*.test.ts | |
| - name: Run seeded differential fuzzing | |
| run: bun run fuzz:hermes-base --rounds 50 --seed ${{ matrix.hbc }} --out "${{ runner.temp }}/hermes-fuzz" | |
| - name: Preserve failing fuzz cases | |
| if: failure() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: hermes-fuzz-hbc-${{ matrix.hbc }}${{ matrix.suffix }} | |
| path: ${{ runner.temp }}/hermes-fuzz | |
| retention-days: 7 | |
| if-no-files-found: ignore |