name: Upstream Build App

on:
  schedule:
    - cron: '30 6 * * *'
  pull_request:
    paths:
      - install.sh
      - Makefile
      - scripts/patch-linux-window-ui.js
      - scripts/patch-linux-window-ui.test.js
      - scripts/patches/**
      - scripts/ci/validate-patch-report.js
      - .github/workflows/upstream-build-app.yml
  push:
    branches:
      - main
    paths:
      - install.sh
      - Makefile
      - scripts/patch-linux-window-ui.js
      - scripts/patch-linux-window-ui.test.js
      - scripts/patches/**
      - scripts/ci/validate-patch-report.js
      - .github/workflows/upstream-build-app.yml
  workflow_dispatch:

permissions:
  contents: read

env:
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
  UPSTREAM_DMG_URL: https://persistent.oaistatic.com/codex-app-prod/Codex.dmg
  UPSTREAM_DMG_PATH: /tmp/codex-upstream-ci/Codex.dmg
  DMG_CACHE_SCHEMA_VERSION: v1

jobs:
  build-app-upstream-dmg:
    name: Build App Against Upstream DMG
    runs-on: ubuntu-latest
    timeout-minutes: 60

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 24

      - name: Install build dependencies
        run: |
          set -euo pipefail
          sudo apt-get update
          sudo apt-get install -y p7zip-full make g++ python3 curl unzip

      - name: Capture upstream DMG metadata
        id: upstream-metadata
        run: |
          set -euo pipefail

          headers_file="$(mktemp)"
          trap 'rm -f "$headers_file"' EXIT

          curl -fsSLI "$UPSTREAM_DMG_URL" > "$headers_file"

          last_modified="$(awk 'BEGIN{IGNORECASE=1} /^last-modified:/ {sub(/\r$/,""); sub(/^[^:]+: /,""); print; exit}' "$headers_file")"
          etag="$(awk 'BEGIN{IGNORECASE=1} /^etag:/ {sub(/\r$/,""); sub(/^[^:]+: /,""); gsub(/"/,""); print; exit}' "$headers_file")"
          content_length="$(awk 'BEGIN{IGNORECASE=1} /^content-length:/ {sub(/\r$/,""); sub(/^[^:]+: /,""); print; exit}' "$headers_file")"

          if [ -z "$last_modified" ]; then
            last_modified="unknown"
          fi
          if [ -z "$etag" ]; then
            etag="no-etag"
          fi
          if [ -z "$content_length" ]; then
            content_length="unknown"
          fi

          cache_segment="$(printf '%s|%s|%s\n' "$last_modified" "$etag" "$content_length" | sha256sum | cut -d' ' -f1)"

          {
            echo "last_modified=$last_modified"
            echo "etag=$etag"
            echo "content_length=$content_length"
            echo "cache_segment=$cache_segment"
          } >> "$GITHUB_OUTPUT"

      - name: Restore cached upstream DMG
        id: dmg-cache
        uses: actions/cache@v4
        with:
          path: /tmp/codex-upstream-ci/Codex.dmg
          key: upstream-dmg-${{ env.DMG_CACHE_SCHEMA_VERSION }}-${{ steps.upstream-metadata.outputs.cache_segment }}

      - name: Download upstream DMG
        if: steps.dmg-cache.outputs.cache-hit != 'true'
        run: |
          set -euo pipefail
          mkdir -p "$(dirname "$UPSTREAM_DMG_PATH")"
          curl -fL --retry 3 -o "$UPSTREAM_DMG_PATH" "$UPSTREAM_DMG_URL"

      - name: Record local DMG fingerprint
        id: local-dmg
        run: |
          set -euo pipefail

          test -s "$UPSTREAM_DMG_PATH"

          dmg_sha256="$(sha256sum "$UPSTREAM_DMG_PATH" | cut -d' ' -f1)"
          dmg_size_bytes="$(stat -c '%s' "$UPSTREAM_DMG_PATH")"
          tested_at_utc="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"

          {
            echo "sha256=$dmg_sha256"
            echo "size_bytes=$dmg_size_bytes"
            echo "tested_at_utc=$tested_at_utc"
          } >> "$GITHUB_OUTPUT"

          cat > upstream-dmg-metadata.json <<JSON
          {
            "url": "$UPSTREAM_DMG_URL",
            "path": "$UPSTREAM_DMG_PATH",
            "last_modified": "${{ steps.upstream-metadata.outputs.last_modified }}",
            "etag": "${{ steps.upstream-metadata.outputs.etag }}",
            "content_length": "${{ steps.upstream-metadata.outputs.content_length }}",
            "sha256": "$dmg_sha256",
            "size_bytes": "$dmg_size_bytes",
            "tested_at_utc": "$tested_at_utc",
            "cache_schema_version": "${{ env.DMG_CACHE_SCHEMA_VERSION }}"
          }
          JSON

      - name: Build app from upstream DMG
        run: CODEX_PATCH_REPORT_JSON="$GITHUB_WORKSPACE/patch-report.json" make build-app DMG=/tmp/codex-upstream-ci/Codex.dmg

      - name: Validate required upstream patches
        run: node scripts/ci/validate-patch-report.js patch-report.json --profile upstream-build

      - name: Upload upstream DMG metadata artifact
        uses: actions/upload-artifact@v4
        with:
          name: upstream-dmg-metadata
          path: |
            upstream-dmg-metadata.json
            patch-report.json

      - name: Write build summary
        run: |
          {
            echo "## Upstream Build App"
            echo ""
            echo "- DMG URL: \`$UPSTREAM_DMG_URL\`"
            echo "- DMG Last-Modified: \`${{ steps.upstream-metadata.outputs.last_modified }}\`"
            echo "- DMG ETag: \`${{ steps.upstream-metadata.outputs.etag }}\`"
            echo "- DMG Content-Length: \`${{ steps.upstream-metadata.outputs.content_length }}\`"
            echo "- DMG SHA-256: \`${{ steps.local-dmg.outputs.sha256 }}\`"
            echo "- DMG Size (bytes): \`${{ steps.local-dmg.outputs.size_bytes }}\`"
            echo "- Tested At (UTC): \`${{ steps.local-dmg.outputs.tested_at_utc }}\`"
            echo "- Cache Hit: \`${{ steps.dmg-cache.outputs.cache-hit || 'false' }}\`"
            echo "- Build command: \`make build-app DMG=/tmp/codex-upstream-ci/Codex.dmg\`"
            echo "- Patch report: \`patch-report.json\`"
          } >> "$GITHUB_STEP_SUMMARY"
