diff --git a/.github/workflows/reusable-codex-run.yml b/.github/workflows/reusable-codex-run.yml index 569e122e7..41418bd46 100644 --- a/.github/workflows/reusable-codex-run.yml +++ b/.github/workflows/reusable-codex-run.yml @@ -227,6 +227,7 @@ jobs: path: .workflows-lib token: ${{ steps.auth_token.outputs.checkout_token }} + - name: Set up Python uses: actions/setup-python@v6 with: @@ -462,6 +463,51 @@ jobs: echo "Workspace is clean for Codex." fi + + # Surface merge conflicts before Codex runs + # When action='conflict', we need to attempt the merge BEFORE invoking Codex + # so that conflicts are visible in the workspace. Otherwise Codex checks + # git status, sees no conflicts (because merge hasn't been attempted yet), + # and exits early despite prompt instructions to run the merge. + # IMPORTANT: This runs AFTER dependency installation to avoid breaking + # pip install if requirements files contain conflict markers. + - name: Surface merge conflicts + if: inputs.prompt_file == '.github/codex/prompts/fix_merge_conflicts.md' + env: + WORKFLOW_BASE_REF: ${{ github.event.pull_request.base.ref || '' }} + run: | + set -euo pipefail + + # Determine the base branch to merge from: + # 1. Use GITHUB_BASE_REF if set (PR workflows). + # 2. Use WORKFLOW_BASE_REF from the workflow_call context if provided. + # 3. Derive the default branch from origin/HEAD. + # 4. Fall back to 'main' for backward compatibility. + base_branch="${GITHUB_BASE_REF:-}" + if [ -z "$base_branch" ] && [ -n "${WORKFLOW_BASE_REF:-}" ]; then + base_branch="$WORKFLOW_BASE_REF" + fi + if [ -z "$base_branch" ]; then + base_branch="$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || true)" + fi + if [ -z "$base_branch" ]; then + echo "Warning: could not determine base branch automatically; defaulting to 'main'." + base_branch="main" + fi + + echo "Using base branch '$base_branch' to surface merge conflicts." + git fetch origin "$base_branch" + + # Attempt merge but do not fail the job on expected conflicts + merge_exit=0 + git merge --no-commit --no-ff "origin/$base_branch" || merge_exit=$? + if [ $merge_exit -ne 0 ]; then + echo "Merge conflicts detected (expected for conflict resolution)" + git status + else + echo "No merge conflicts - merge succeeded automatically" + fi + - name: Run Codex id: run_codex env: diff --git a/tests/workflows/test_keepalive_workflow.py b/tests/workflows/test_keepalive_workflow.py index f2fc28df7..368206ca1 100644 --- a/tests/workflows/test_keepalive_workflow.py +++ b/tests/workflows/test_keepalive_workflow.py @@ -68,7 +68,7 @@ def _assert_no_dispatch(data: dict) -> None: assert _dispatch_events(data) == [] -# First line of the keepalive instruction from .github/templates/keepalive-instruction.md +# First line of the keepalive instruction from .github/codex/prompts/keepalive_next_task.md # The full instruction is multi-line; tests check that the instruction starts correctly. DEFAULT_COMMAND_PREFIX = ( "@codex Your objective is to satisfy the **Acceptance Criteria** by completing each " @@ -157,6 +157,7 @@ def test_keepalive_idle_threshold_logic() -> None: assert body_lines[2] == "" assert "" in created[0]["body"]