name: E2E (Goose)

# Live end-to-end check: drive the real Goose CLI through oneharness and assert
# the JSON contract (scripts/e2e-goose.sh). Unlike ci.yml this needs network, a
# model call, and a provider key (OPENAI_API_KEY), so it lives in its own
# workflow gated to trusted contexts only.
#
# Security: a secret must never be reachable by untrusted code. GitHub already
# withholds secrets from fork pull requests; the job `if` below is defense in
# depth — it runs only in the canonical repo and never for a PR whose head is a
# fork, so this workflow can be edited in a fork PR without exposing the key.

on:
  push:
    branches: [main]
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: e2e-goose-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always
  # In CI the harness is installed and auth verified up front, so any e2e skip
  # means detection/install/spawn broke (e.g. an unresolved .cmd shim on Windows)
  # — fail instead of going green having tested nothing. See scripts/e2e-lib.sh.
  OH_E2E_NO_SKIP: 1

jobs:
  live:
    name: goose live e2e (${{ matrix.os }})
    if: >-
      github.repository == 'nickderobertis/oneharness' &&
      (github.event_name != 'pull_request' ||
       github.event.pull_request.head.repo.full_name == github.repository)
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@v4

      - name: Verify the provider key is present
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          if [ -z "${OPENAI_API_KEY:-}" ]; then
            echo "::error::OPENAI_API_KEY secret is not set. Add a provider key (and optionally set the GOOSE_E2E_MODEL repo variable), then sync it (just secrets-sync) or set it: gh secret set OPENAI_API_KEY --repo ${{ github.repository }}"
            exit 1
          fi

      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - uses: taiki-e/install-action@v2
        with:
          tool: just

      - name: Install Goose CLI (Unix)
        if: runner.os != 'Windows'
        run: |
          curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      # Windows uses Goose's PowerShell installer (the parallel of download_cli.sh);
      # it installs goose.exe under %USERPROFILE%\.local\bin.
      - name: Install Goose CLI (Windows)
        if: runner.os == 'Windows'
        shell: pwsh
        run: |
          $env:CONFIGURE = 'false'
          # No .ps1 is published as a release asset (only download_cli.sh); the
          # PowerShell installer lives in the repo tree.
          irm 'https://raw.githubusercontent.com/block/goose/main/download_cli.ps1' | iex
          $dir = Join-Path $env:USERPROFILE '.local\bin'
          if (Test-Path $dir) { Add-Content -Path $env:GITHUB_PATH -Value $dir }

      - name: Live e2e against the real CLI
        env:
          GOOSE_PROVIDER: openai
          GOOSE_MODEL: ${{ vars.GOOSE_E2E_MODEL }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        run: |
          goose --version
          just live-goose
