figma-agent 0.2.2

Local font helper for Figma, Linux and macOS
name: Parity

on:
  push:
    branches: [main]
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

env:
  FIGMA_VERSION: "126.4.11"
  # Upstream Figma agent 126.4.11 binds 44950 (HTTP) and 44960 (HTTPS).
  ORIG_HTTP_PORT: "44950"
  ORIG_TLS_PORT: "44960"
  LOCAL_HTTP_PORT: "45000"
  LOCAL_TLS_PORT: "45001"

jobs:
  parity:
    name: parity (${{ matrix.runner }})
    strategy:
      fail-fast: false
      matrix:
        include:
          - runner: macos-latest
            arch_slug: mac-arm
          - runner: macos-15-intel
            arch_slug: mac

    runs-on: ${{ matrix.runner }}

    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false

      - uses: dtolnay/rust-toolchain@stable

      - name: Install test fonts
        run: |
          brew install --cask \
            font-inter \
            font-recursive \
            font-fira-code \
            font-source-han-sans-vf

      - name: Cache Figma DMG
        id: dmg-cache
        uses: actions/cache@v5
        with:
          path: /tmp/Figma.dmg
          key: figma-${{ matrix.arch_slug }}-${{ env.FIGMA_VERSION }}

      - name: Download Figma DMG
        if: steps.dmg-cache.outputs.cache-hit != 'true'
        run: |
          curl -fL -o /tmp/Figma.dmg \
            "https://desktop.figma.com/${{ matrix.arch_slug }}/Figma-${{ env.FIGMA_VERSION }}.dmg"

      - name: Install upstream agent to canonical location
        run: |
          DEST_DIR="$HOME/Library/Application Support/Figma"
          mkdir -p "$DEST_DIR"
          hdiutil attach /tmp/Figma.dmg -nobrowse -readonly -mountpoint /Volumes/Figma
          cp -R /Volumes/Figma/Figma.app/Contents/Library/FigmaAgent.app "$DEST_DIR/"
          echo "ORIG_AGENT=$DEST_DIR/FigmaAgent.app/Contents/MacOS/figma_agent" >> $GITHUB_ENV

      - name: Build local agent
        run: cargo build --release

      - name: Configure local agent ports
        run: |
          mkdir -p "$HOME/.config/figma-agent"
          cat > "$HOME/.config/figma-agent/config.json" <<EOF
          {
            "host": "127.0.0.1",
            "port": ${{ env.LOCAL_HTTP_PORT }},
            "tls_port": ${{ env.LOCAL_TLS_PORT }}
          }
          EOF
          cat "$HOME/.config/figma-agent/config.json"

      - name: Pin upstream agent (block self-update)
        run: echo "127.0.0.1 desktop.figma.com" | sudo tee -a /etc/hosts

      - name: Start upstream agent and warm
        run: |
          "$ORIG_AGENT" > /tmp/orig.log 2>&1 &
          echo $! > /tmp/orig.pid
          curl -fs --retry 60 --retry-connrefused --retry-all-errors --retry-delay 2 \
            --max-time 300 -H "Origin: https://www.figma.com" \
            "http://127.0.0.1:${{ env.ORIG_HTTP_PORT }}/figma/font-files" > /dev/null

      - name: Start local agent and warm
        run: |
          ./target/release/figma-agent > /tmp/local.log 2>&1 &
          echo $! > /tmp/local.pid
          curl -fs --retry 60 --retry-connrefused --retry-all-errors --retry-delay 2 \
            --max-time 300 -H "Origin: https://www.figma.com" \
            "http://127.0.0.1:${{ env.LOCAL_HTTP_PORT }}/figma/font-files" > /dev/null

      - name: Compare HTTP responses (font-files + all binaries)
        run: |
          python3 scripts/parity.py \
            --upstream-url "http://127.0.0.1:${{ env.ORIG_HTTP_PORT }}" \
            --local-url "http://127.0.0.1:${{ env.LOCAL_HTTP_PORT }}" \
            --origin-header "https://www.figma.com"

      - name: Compare HTTPS responses (font-files + all binaries)
        run: |
          python3 scripts/parity.py \
            --upstream-url "https://127.0.0.1:${{ env.ORIG_TLS_PORT }}" \
            --local-url "https://127.0.0.1:${{ env.LOCAL_TLS_PORT }}" \
            --origin-header "https://www.figma.com" \
            --insecure-tls

      - name: Teardown
        if: ${{ !cancelled() }}
        run: |
          [ -f /tmp/orig.pid ] && kill "$(cat /tmp/orig.pid)" 2>/dev/null || true
          [ -f /tmp/local.pid ] && kill "$(cat /tmp/local.pid)" 2>/dev/null || true
          echo "=== upstream log (tail) ==="
          tail -40 /tmp/orig.log 2>/dev/null || true
          echo "=== local log (tail) ==="
          tail -40 /tmp/local.log 2>/dev/null || true