diff --git a/.github/workflows/test-claude-add-issue-comment.lock.yml b/.github/workflows/test-claude-add-issue-comment.lock.yml index c931dc7cb2..7dbd981610 100644 --- a/.github/workflows/test-claude-add-issue-comment.lock.yml +++ b/.github/workflows/test-claude-add-issue-comment.lock.yml @@ -256,7 +256,7 @@ jobs: ## Adding a Comment to an Issue or Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -657,6 +657,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1054,68 +1058,6 @@ jobs: name: test-claude-add-issue-comment.log path: /tmp/test-claude-add-issue-comment.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue_comment: needs: test-claude-add-issue-comment diff --git a/.github/workflows/test-claude-add-issue-labels.lock.yml b/.github/workflows/test-claude-add-issue-labels.lock.yml index 4b036f36cb..8ddcf1d80c 100644 --- a/.github/workflows/test-claude-add-issue-labels.lock.yml +++ b/.github/workflows/test-claude-add-issue-labels.lock.yml @@ -256,7 +256,7 @@ jobs: ## Adding Labels to Issues or Pull Requests - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -657,6 +657,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1054,68 +1058,6 @@ jobs: name: test-claude-add-issue-labels.log path: /tmp/test-claude-add-issue-labels.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore add_labels: needs: test-claude-add-issue-labels diff --git a/.github/workflows/test-claude-command.lock.yml b/.github/workflows/test-claude-command.lock.yml index 60a1a3afc9..9e21e8b0eb 100644 --- a/.github/workflows/test-claude-command.lock.yml +++ b/.github/workflows/test-claude-command.lock.yml @@ -494,7 +494,7 @@ jobs: ## Adding a Comment to an Issue or Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -895,6 +895,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1292,68 +1296,6 @@ jobs: name: test-claude-command.log path: /tmp/test-claude-command.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue_comment: needs: test-claude-command diff --git a/.github/workflows/test-claude-create-issue.lock.yml b/.github/workflows/test-claude-create-issue.lock.yml index 1929b8ef21..cdf7703d0c 100644 --- a/.github/workflows/test-claude-create-issue.lock.yml +++ b/.github/workflows/test-claude-create-issue.lock.yml @@ -85,7 +85,7 @@ jobs: ## Creating an Issue - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -486,6 +486,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -883,68 +887,6 @@ jobs: name: test-claude-create-issue.log path: /tmp/test-claude-create-issue.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue: needs: test-claude-create-issue diff --git a/.github/workflows/test-claude-create-pull-request.lock.yml b/.github/workflows/test-claude-create-pull-request.lock.yml index d21efec20e..acb8c4578b 100644 --- a/.github/workflows/test-claude-create-pull-request.lock.yml +++ b/.github/workflows/test-claude-create-pull-request.lock.yml @@ -89,7 +89,7 @@ jobs: ## Creating a Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -99,10 +99,11 @@ jobs: To create a pull request: 1. Make any file changes directly in the working directory - 2. Leave the changes uncommitted and unstaged - 3. Write the PR specification: + 2. If you haven't done so already, create a local branch using an appropriate unique name + 3. Add and commit your files to the branch. Be careful to add exactly the files you intend, and check there are no extra files left un-added. Check you haven't deleted or changed any files you didn't intend to. + 4. Do not push your changes. That will be done later. Instead append the PR specification to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}": ```json - {"type": "create-pull-request", "title": "PR title", "body": "PR body in markdown", "labels": ["optional", "labels"]} + {"type": "create-pull-request", "branch": "branch-name", "title": "PR title", "body": "PR body in markdown", "labels": ["optional", "labels"]} ``` **Example JSONL file content:** @@ -495,6 +496,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -894,10 +899,33 @@ jobs: if-no-files-found: warn - name: Generate git patch if: always() + env: + GITHUB_AW_SAFE_OUTPUTS: ${{ env.GITHUB_AW_SAFE_OUTPUTS }} run: | # Check current git status echo "Current git status:" git status + + # Extract branch name from JSONL output + BRANCH_NAME="" + if [ -f "$GITHUB_AW_SAFE_OUTPUTS" ]; then + echo "Checking for branch name in JSONL output..." + while IFS= read -r line; do + if [ -n "$line" ]; then + # Extract branch from create-pull-request line using simple grep and sed + if echo "$line" | grep -q '"type"[[:space:]]*:[[:space:]]*"create-pull-request"'; then + echo "Found create-pull-request line: $line" + # Extract branch value using sed + BRANCH_NAME=$(echo "$line" | sed -n 's/.*"branch"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') + if [ -n "$BRANCH_NAME" ]; then + echo "Extracted branch name: $BRANCH_NAME" + break + fi + fi + fi + done < "$GITHUB_AW_SAFE_OUTPUTS" + fi + # Get the initial commit SHA from the base branch of the pull request if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then INITIAL_SHA="$GITHUB_BASE_REF" @@ -908,35 +936,59 @@ jobs: # Configure git user for GitHub Actions git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" + + # If we have a branch name, check if that branch exists and get its diff + if [ -n "$BRANCH_NAME" ]; then + echo "Looking for branch: $BRANCH_NAME" + # Check if the branch exists + if git show-ref --verify --quiet refs/heads/$BRANCH_NAME; then + echo "Branch $BRANCH_NAME exists, generating patch from branch changes" + # Generate patch from the base to the branch + git format-patch "$INITIAL_SHA".."$BRANCH_NAME" --stdout > /tmp/aw.patch || echo "Failed to generate patch from branch" > /tmp/aw.patch + echo "Patch file created from branch: $BRANCH_NAME" + else + echo "Branch $BRANCH_NAME does not exist, falling back to current HEAD" + BRANCH_NAME="" + fi fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" + + # If no branch or branch doesn't exist, use the existing logic + if [ -z "$BRANCH_NAME" ]; then + echo "Using current HEAD for patch generation" + # Stage any unstaged files + git add -A || true + # Check if there are staged files to commit + if ! git diff --cached --quiet; then + echo "Staged files found, committing them..." + git commit -m "[agent] staged files" || true + echo "Staged files committed" + else + echo "No staged files to commit" + fi + # Check updated git status + echo "Updated git status after committing staged files:" + git status + # Show compact diff information between initial commit and HEAD (committed changes only) + echo '## Git diff' >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true + echo '```' >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + # Check if there are any committed changes since the initial commit + if git diff --quiet "$INITIAL_SHA" HEAD; then + echo "No committed changes detected since initial commit" + echo "Skipping patch generation - no committed changes to create patch from" + else + echo "Committed changes detected, generating patch..." + # Generate patch from initial commit to HEAD (committed changes only) + git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch + echo "Patch file created at /tmp/aw.patch" + fi + fi + + # Show patch info if it exists + if [ -f /tmp/aw.patch ]; then ls -la /tmp/aw.patch # Show the first 50 lines of the patch for review echo '## Git Patch' >> $GITHUB_STEP_SUMMARY @@ -1037,9 +1089,10 @@ jobs: return; } console.log('Found create-pull-request item:', { title: pullRequestItem.title, bodyLength: pullRequestItem.body.length }); - // Extract title and body from the JSON item + // Extract title, body, and branch from the JSON item let title = pullRequestItem.title.trim(); let bodyLines = pullRequestItem.body.split('\n'); + let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; // If no title was found, use a default if (!title) { title = 'Agent Output'; @@ -1067,18 +1120,33 @@ jobs: console.log('Labels:', labels); console.log('Draft:', draft); console.log('Body length:', body.length); - // Generate unique branch name using cryptographic random hex - const randomHex = crypto.randomBytes(8).toString('hex'); - const branchName = `${workflowId}/${randomHex}`; + // Use branch name from JSONL if provided, otherwise generate unique branch name + if (!branchName) { + console.log('No branch name provided in JSONL, generating unique branch name'); + // Generate unique branch name using cryptographic random hex + const randomHex = crypto.randomBytes(8).toString('hex'); + branchName = `${workflowId}/${randomHex}`; + } else { + console.log('Using branch name from JSONL:', branchName); + } console.log('Generated branch name:', branchName); console.log('Base branch:', baseBranch); // Create a new branch using git CLI // Configure git (required for commits) execSync('git config --global user.email "action@github.com"', { stdio: 'inherit' }); execSync('git config --global user.name "GitHub Action"', { stdio: 'inherit' }); - // Create and checkout new branch - execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); - console.log('Created and checked out branch:', branchName); + // Handle branch creation/checkout + const branchFromJsonl = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; + if (branchFromJsonl) { + console.log('Checking if branch from JSONL exists:', branchFromJsonl); + console.log('Branch does not exist locally, creating new branch:', branchFromJsonl); + execSync(`git checkout -b ${branchFromJsonl}`, { stdio: 'inherit' }); + console.log('Using existing/created branch:', branchFromJsonl); + } else { + // Create and checkout new branch with generated name + execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); + console.log('Created and checked out new branch:', branchName); + } // Apply the patch using git CLI console.log('Applying patch...'); // Apply the patch using git apply diff --git a/.github/workflows/test-claude-mcp.lock.yml b/.github/workflows/test-claude-mcp.lock.yml index 9b315a8e24..56cc3a12a5 100644 --- a/.github/workflows/test-claude-mcp.lock.yml +++ b/.github/workflows/test-claude-mcp.lock.yml @@ -277,7 +277,7 @@ jobs: ## Creating an Issue - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -679,6 +679,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1076,68 +1080,6 @@ jobs: name: test-claude-mcp.log path: /tmp/test-claude-mcp.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue: needs: test-claude-mcp diff --git a/.github/workflows/test-claude-update-issue.lock.yml b/.github/workflows/test-claude-update-issue.lock.yml index 25181ba635..9a33540bb9 100644 --- a/.github/workflows/test-claude-update-issue.lock.yml +++ b/.github/workflows/test-claude-update-issue.lock.yml @@ -260,7 +260,7 @@ jobs: ## Updating Issues - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -661,6 +661,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1058,68 +1062,6 @@ jobs: name: test-claude-update-issue.log path: /tmp/test-claude-update-issue.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore update_issue: needs: test-claude-update-issue diff --git a/.github/workflows/test-codex-add-issue-comment.lock.yml b/.github/workflows/test-codex-add-issue-comment.lock.yml index ab84276dcb..9e9eb08c76 100644 --- a/.github/workflows/test-codex-add-issue-comment.lock.yml +++ b/.github/workflows/test-codex-add-issue-comment.lock.yml @@ -258,7 +258,7 @@ jobs: ## Adding a Comment to an Issue or Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -595,6 +595,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -937,68 +941,6 @@ jobs: name: test-codex-add-issue-comment.log path: /tmp/test-codex-add-issue-comment.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue_comment: needs: test-codex-add-issue-comment diff --git a/.github/workflows/test-codex-add-issue-labels.lock.yml b/.github/workflows/test-codex-add-issue-labels.lock.yml index 89bfc35417..da706d34b1 100644 --- a/.github/workflows/test-codex-add-issue-labels.lock.yml +++ b/.github/workflows/test-codex-add-issue-labels.lock.yml @@ -258,7 +258,7 @@ jobs: ## Adding Labels to Issues or Pull Requests - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -595,6 +595,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -937,68 +941,6 @@ jobs: name: test-codex-add-issue-labels.log path: /tmp/test-codex-add-issue-labels.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore add_labels: needs: test-codex-add-issue-labels diff --git a/.github/workflows/test-codex-command.lock.yml b/.github/workflows/test-codex-command.lock.yml index cbd87fd0a6..bbf4a25f55 100644 --- a/.github/workflows/test-codex-command.lock.yml +++ b/.github/workflows/test-codex-command.lock.yml @@ -494,7 +494,7 @@ jobs: ## Adding a Comment to an Issue or Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -895,6 +895,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1292,68 +1296,6 @@ jobs: name: test-codex-command.log path: /tmp/test-codex-command.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue_comment: needs: test-codex-command diff --git a/.github/workflows/test-codex-create-issue.lock.yml b/.github/workflows/test-codex-create-issue.lock.yml index d0cecd8859..d2f0e2a2ed 100644 --- a/.github/workflows/test-codex-create-issue.lock.yml +++ b/.github/workflows/test-codex-create-issue.lock.yml @@ -87,7 +87,7 @@ jobs: ## Creating an Issue - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -424,6 +424,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -766,68 +770,6 @@ jobs: name: test-codex-create-issue.log path: /tmp/test-codex-create-issue.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue: needs: test-codex-create-issue diff --git a/.github/workflows/test-codex-create-pull-request.lock.yml b/.github/workflows/test-codex-create-pull-request.lock.yml index c8c43de299..fc37ee6c87 100644 --- a/.github/workflows/test-codex-create-pull-request.lock.yml +++ b/.github/workflows/test-codex-create-pull-request.lock.yml @@ -91,7 +91,7 @@ jobs: ## Creating a Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -101,10 +101,11 @@ jobs: To create a pull request: 1. Make any file changes directly in the working directory - 2. Leave the changes uncommitted and unstaged - 3. Write the PR specification: + 2. If you haven't done so already, create a local branch using an appropriate unique name + 3. Add and commit your files to the branch. Be careful to add exactly the files you intend, and check there are no extra files left un-added. Check you haven't deleted or changed any files you didn't intend to. + 4. Do not push your changes. That will be done later. Instead append the PR specification to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}": ```json - {"type": "create-pull-request", "title": "PR title", "body": "PR body in markdown", "labels": ["optional", "labels"]} + {"type": "create-pull-request", "branch": "branch-name", "title": "PR title", "body": "PR body in markdown", "labels": ["optional", "labels"]} ``` **Example JSONL file content:** @@ -433,6 +434,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -777,10 +782,33 @@ jobs: if-no-files-found: warn - name: Generate git patch if: always() + env: + GITHUB_AW_SAFE_OUTPUTS: ${{ env.GITHUB_AW_SAFE_OUTPUTS }} run: | # Check current git status echo "Current git status:" git status + + # Extract branch name from JSONL output + BRANCH_NAME="" + if [ -f "$GITHUB_AW_SAFE_OUTPUTS" ]; then + echo "Checking for branch name in JSONL output..." + while IFS= read -r line; do + if [ -n "$line" ]; then + # Extract branch from create-pull-request line using simple grep and sed + if echo "$line" | grep -q '"type"[[:space:]]*:[[:space:]]*"create-pull-request"'; then + echo "Found create-pull-request line: $line" + # Extract branch value using sed + BRANCH_NAME=$(echo "$line" | sed -n 's/.*"branch"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p') + if [ -n "$BRANCH_NAME" ]; then + echo "Extracted branch name: $BRANCH_NAME" + break + fi + fi + fi + done < "$GITHUB_AW_SAFE_OUTPUTS" + fi + # Get the initial commit SHA from the base branch of the pull request if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then INITIAL_SHA="$GITHUB_BASE_REF" @@ -791,35 +819,59 @@ jobs: # Configure git user for GitHub Actions git config --global user.email "action@github.com" git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" + + # If we have a branch name, check if that branch exists and get its diff + if [ -n "$BRANCH_NAME" ]; then + echo "Looking for branch: $BRANCH_NAME" + # Check if the branch exists + if git show-ref --verify --quiet refs/heads/$BRANCH_NAME; then + echo "Branch $BRANCH_NAME exists, generating patch from branch changes" + # Generate patch from the base to the branch + git format-patch "$INITIAL_SHA".."$BRANCH_NAME" --stdout > /tmp/aw.patch || echo "Failed to generate patch from branch" > /tmp/aw.patch + echo "Patch file created from branch: $BRANCH_NAME" + else + echo "Branch $BRANCH_NAME does not exist, falling back to current HEAD" + BRANCH_NAME="" + fi fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" + + # If no branch or branch doesn't exist, use the existing logic + if [ -z "$BRANCH_NAME" ]; then + echo "Using current HEAD for patch generation" + # Stage any unstaged files + git add -A || true + # Check if there are staged files to commit + if ! git diff --cached --quiet; then + echo "Staged files found, committing them..." + git commit -m "[agent] staged files" || true + echo "Staged files committed" + else + echo "No staged files to commit" + fi + # Check updated git status + echo "Updated git status after committing staged files:" + git status + # Show compact diff information between initial commit and HEAD (committed changes only) + echo '## Git diff' >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY + git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true + echo '```' >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + # Check if there are any committed changes since the initial commit + if git diff --quiet "$INITIAL_SHA" HEAD; then + echo "No committed changes detected since initial commit" + echo "Skipping patch generation - no committed changes to create patch from" + else + echo "Committed changes detected, generating patch..." + # Generate patch from initial commit to HEAD (committed changes only) + git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch + echo "Patch file created at /tmp/aw.patch" + fi + fi + + # Show patch info if it exists + if [ -f /tmp/aw.patch ]; then ls -la /tmp/aw.patch # Show the first 50 lines of the patch for review echo '## Git Patch' >> $GITHUB_STEP_SUMMARY @@ -920,9 +972,10 @@ jobs: return; } console.log('Found create-pull-request item:', { title: pullRequestItem.title, bodyLength: pullRequestItem.body.length }); - // Extract title and body from the JSON item + // Extract title, body, and branch from the JSON item let title = pullRequestItem.title.trim(); let bodyLines = pullRequestItem.body.split('\n'); + let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; // If no title was found, use a default if (!title) { title = 'Agent Output'; @@ -950,18 +1003,33 @@ jobs: console.log('Labels:', labels); console.log('Draft:', draft); console.log('Body length:', body.length); - // Generate unique branch name using cryptographic random hex - const randomHex = crypto.randomBytes(8).toString('hex'); - const branchName = `${workflowId}/${randomHex}`; + // Use branch name from JSONL if provided, otherwise generate unique branch name + if (!branchName) { + console.log('No branch name provided in JSONL, generating unique branch name'); + // Generate unique branch name using cryptographic random hex + const randomHex = crypto.randomBytes(8).toString('hex'); + branchName = `${workflowId}/${randomHex}`; + } else { + console.log('Using branch name from JSONL:', branchName); + } console.log('Generated branch name:', branchName); console.log('Base branch:', baseBranch); // Create a new branch using git CLI // Configure git (required for commits) execSync('git config --global user.email "action@github.com"', { stdio: 'inherit' }); execSync('git config --global user.name "GitHub Action"', { stdio: 'inherit' }); - // Create and checkout new branch - execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); - console.log('Created and checked out branch:', branchName); + // Handle branch creation/checkout + const branchFromJsonl = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; + if (branchFromJsonl) { + console.log('Checking if branch from JSONL exists:', branchFromJsonl); + console.log('Branch does not exist locally, creating new branch:', branchFromJsonl); + execSync(`git checkout -b ${branchFromJsonl}`, { stdio: 'inherit' }); + console.log('Using existing/created branch:', branchFromJsonl); + } else { + // Create and checkout new branch with generated name + execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); + console.log('Created and checked out new branch:', branchName); + } // Apply the patch using git CLI console.log('Applying patch...'); // Apply the patch using git apply diff --git a/.github/workflows/test-codex-mcp.lock.yml b/.github/workflows/test-codex-mcp.lock.yml index abfbaebbab..d3487a8cd6 100644 --- a/.github/workflows/test-codex-mcp.lock.yml +++ b/.github/workflows/test-codex-mcp.lock.yml @@ -277,7 +277,7 @@ jobs: ## Creating an Issue - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -614,6 +614,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -956,68 +960,6 @@ jobs: name: test-codex-mcp.log path: /tmp/test-codex-mcp.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue: needs: test-codex-mcp diff --git a/.github/workflows/test-codex-update-issue.lock.yml b/.github/workflows/test-codex-update-issue.lock.yml index 2222bcc120..e8e5e49ffd 100644 --- a/.github/workflows/test-codex-update-issue.lock.yml +++ b/.github/workflows/test-codex-update-issue.lock.yml @@ -262,7 +262,7 @@ jobs: ## Updating Issues - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -599,6 +599,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -941,68 +945,6 @@ jobs: name: test-codex-update-issue.log path: /tmp/test-codex-update-issue.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore update_issue: needs: test-codex-update-issue diff --git a/.github/workflows/test-proxy.lock.yml b/.github/workflows/test-proxy.lock.yml index 6c81172474..f338268ec4 100644 --- a/.github/workflows/test-proxy.lock.yml +++ b/.github/workflows/test-proxy.lock.yml @@ -253,7 +253,7 @@ jobs: ## Adding a Comment to an Issue or Pull Request - **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. + **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file "${{ env.GITHUB_AW_SAFE_OUTPUTS }}". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them. **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type. @@ -657,6 +657,10 @@ jobs: // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); @@ -1054,68 +1058,6 @@ jobs: name: test-proxy.log path: /tmp/test-proxy.log if-no-files-found: warn - - name: Generate git patch - if: always() - run: | - # Check current git status - echo "Current git status:" - git status - # Get the initial commit SHA from the base branch of the pull request - if [ "$GITHUB_EVENT_NAME" = "pull_request" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ]; then - INITIAL_SHA="$GITHUB_BASE_REF" - else - INITIAL_SHA="$GITHUB_SHA" - fi - echo "Base commit SHA: $INITIAL_SHA" - # Configure git user for GitHub Actions - git config --global user.email "action@github.com" - git config --global user.name "GitHub Action" - # Stage any unstaged files - git add -A || true - # Check if there are staged files to commit - if ! git diff --cached --quiet; then - echo "Staged files found, committing them..." - git commit -m "[agent] staged files" || true - echo "Staged files committed" - else - echo "No staged files to commit" - fi - # Check updated git status - echo "Updated git status after committing staged files:" - git status - # Show compact diff information between initial commit and HEAD (committed changes only) - echo '## Git diff' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - git diff --name-only "$INITIAL_SHA"..HEAD >> $GITHUB_STEP_SUMMARY || true - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - # Check if there are any committed changes since the initial commit - if git diff --quiet "$INITIAL_SHA" HEAD; then - echo "No committed changes detected since initial commit" - echo "Skipping patch generation - no committed changes to create patch from" - else - echo "Committed changes detected, generating patch..." - # Generate patch from initial commit to HEAD (committed changes only) - git format-patch "$INITIAL_SHA"..HEAD --stdout > /tmp/aw.patch || echo "Failed to generate patch" > /tmp/aw.patch - echo "Patch file created at /tmp/aw.patch" - ls -la /tmp/aw.patch - # Show the first 50 lines of the patch for review - echo '## Git Patch' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - echo '```diff' >> $GITHUB_STEP_SUMMARY - head -50 /tmp/aw.patch >> $GITHUB_STEP_SUMMARY || echo "Could not display patch contents" >> $GITHUB_STEP_SUMMARY - echo '...' >> $GITHUB_STEP_SUMMARY - echo '```' >> $GITHUB_STEP_SUMMARY - echo '' >> $GITHUB_STEP_SUMMARY - fi - - name: Upload git patch - if: always() - uses: actions/upload-artifact@v4 - with: - name: aw.patch - path: /tmp/aw.patch - if-no-files-found: ignore create_issue_comment: needs: test-proxy diff --git a/pkg/workflow/compiler.go b/pkg/workflow/compiler.go index c696768ae5..5ee5ba0887 100644 --- a/pkg/workflow/compiler.go +++ b/pkg/workflow/compiler.go @@ -1947,7 +1947,7 @@ func (c *Compiler) buildMainJob(data *WorkflowData, jobName string, taskJobCreat } // Build outputs for all engines (GITHUB_AW_SAFE_OUTPUTS functionality) - // Only include output if the workflow actually uses the output feature + // Only include output if the workflow actually uses the safe-outputs feature var outputs map[string]string if data.SafeOutputs != nil { outputs = map[string]string{ @@ -2162,7 +2162,7 @@ func (c *Compiler) generateMainJobSteps(yaml *strings.Builder, data *WorkflowDat } } - // Generate output file setup step only if output feature is used (GITHUB_AW_SAFE_OUTPUTS functionality) + // Generate output file setup step only if safe-outputs feature is used (GITHUB_AW_SAFE_OUTPUTS functionality) if data.SafeOutputs != nil { c.generateOutputFileSetup(yaml, data) } @@ -2191,7 +2191,7 @@ func (c *Compiler) generateMainJobSteps(yaml *strings.Builder, data *WorkflowDat // add workflow_complete.txt c.generateWorkflowComplete(yaml) - // Add output collection step only if output feature is used (GITHUB_AW_SAFE_OUTPUTS functionality) + // Add output collection step only if safe-outputs feature is used (GITHUB_AW_SAFE_OUTPUTS functionality) if data.SafeOutputs != nil { c.generateOutputCollectionStep(yaml, data) } @@ -2207,8 +2207,8 @@ func (c *Compiler) generateMainJobSteps(yaml *strings.Builder, data *WorkflowDat // upload agent logs c.generateUploadAgentLogs(yaml, logFile, logFileFull) - // Add git patch generation step only if output feature is used - if data.SafeOutputs != nil { + // Add git patch generation step only if safe-outputs create-pull-request feature is used + if data.SafeOutputs != nil && data.SafeOutputs.CreatePullRequests != nil { c.generateGitPatchStep(yaml) } @@ -2286,7 +2286,7 @@ func (c *Compiler) generateUploadAwInfo(yaml *strings.Builder) { func (c *Compiler) generatePrompt(yaml *strings.Builder, data *WorkflowData, engine AgenticEngine) { yaml.WriteString(" - name: Create prompt\n") - // Only add GITHUB_AW_SAFE_OUTPUTS environment variable if output feature is used + // Only add GITHUB_AW_SAFE_OUTPUTS environment variable if safe-outputs feature is used if data.SafeOutputs != nil { yaml.WriteString(" env:\n") yaml.WriteString(" GITHUB_AW_SAFE_OUTPUTS: ${{ env.GITHUB_AW_SAFE_OUTPUTS }}\n") @@ -2341,7 +2341,7 @@ func (c *Compiler) generatePrompt(yaml *strings.Builder, data *WorkflowData, eng } yaml.WriteString("\n") yaml.WriteString(" \n") - yaml.WriteString(" **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools and do NOT attempt to use `gh` or the GitHub API. Instead write JSON objects to the file \"${{ env.GITHUB_AW_SAFE_OUTPUTS }}\". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them.\n") + yaml.WriteString(" **IMPORTANT**: To do the actions mentioned in the header of this section, do NOT attempt to use MCP tools, do NOT attempt to use `gh`, do NOT attempt to use the GitHub API. You don't have write access to the GitHub repo. Instead write JSON objects to the file \"${{ env.GITHUB_AW_SAFE_OUTPUTS }}\". Each line should contain a single JSON object (JSONL format). You can write them one by one as you do them.\n") yaml.WriteString(" \n") yaml.WriteString(" **Format**: Write one JSON object per line. Each object must have a `type` field specifying the action type.\n") yaml.WriteString(" \n") @@ -2369,10 +2369,11 @@ func (c *Compiler) generatePrompt(yaml *strings.Builder, data *WorkflowData, eng yaml.WriteString(" \n") yaml.WriteString(" To create a pull request:\n") yaml.WriteString(" 1. Make any file changes directly in the working directory\n") - yaml.WriteString(" 2. Leave the changes uncommitted and unstaged\n") - yaml.WriteString(" 3. Write the PR specification:\n") + yaml.WriteString(" 2. If you haven't done so already, create a local branch using an appropriate unique name\n") + yaml.WriteString(" 3. Add and commit your files to the branch. Be careful to add exactly the files you intend, and check there are no extra files left un-added. Check you haven't deleted or changed any files you didn't intend to.\n") + yaml.WriteString(" 4. Do not push your changes. That will be done later. Instead append the PR specification to the file \"${{ env.GITHUB_AW_SAFE_OUTPUTS }}\":\n") yaml.WriteString(" ```json\n") - yaml.WriteString(" {\"type\": \"create-pull-request\", \"title\": \"PR title\", \"body\": \"PR body in markdown\", \"labels\": [\"optional\", \"labels\"]}\n") + yaml.WriteString(" {\"type\": \"create-pull-request\", \"branch\": \"branch-name\", \"title\": \"PR title\", \"body\": \"PR body in markdown\", \"labels\": [\"optional\", \"labels\"]}\n") yaml.WriteString(" ```\n") yaml.WriteString(" \n") } @@ -2931,7 +2932,7 @@ func (c *Compiler) generateEngineExecutionSteps(yaml *strings.Builder, data *Wor fmt.Fprintf(yaml, " %s: %s\n", key, value) } } - // Add environment section to pass GITHUB_AW_SAFE_OUTPUTS to the action only if output feature is used + // Add environment section to pass GITHUB_AW_SAFE_OUTPUTS to the action only if safe-outputs feature is used if data.SafeOutputs != nil { yaml.WriteString(" env:\n") yaml.WriteString(" GITHUB_AW_SAFE_OUTPUTS: ${{ env.GITHUB_AW_SAFE_OUTPUTS }}\n") diff --git a/pkg/workflow/git_patch.go b/pkg/workflow/git_patch.go index 9dd9e05b70..d164c3b049 100644 --- a/pkg/workflow/git_patch.go +++ b/pkg/workflow/git_patch.go @@ -6,10 +6,33 @@ import "strings" func (c *Compiler) generateGitPatchStep(yaml *strings.Builder) { yaml.WriteString(" - name: Generate git patch\n") yaml.WriteString(" if: always()\n") + yaml.WriteString(" env:\n") + yaml.WriteString(" GITHUB_AW_SAFE_OUTPUTS: ${{ env.GITHUB_AW_SAFE_OUTPUTS }}\n") yaml.WriteString(" run: |\n") yaml.WriteString(" # Check current git status\n") yaml.WriteString(" echo \"Current git status:\"\n") yaml.WriteString(" git status\n") + yaml.WriteString(" \n") + yaml.WriteString(" # Extract branch name from JSONL output\n") + yaml.WriteString(" BRANCH_NAME=\"\"\n") + yaml.WriteString(" if [ -f \"$GITHUB_AW_SAFE_OUTPUTS\" ]; then\n") + yaml.WriteString(" echo \"Checking for branch name in JSONL output...\"\n") + yaml.WriteString(" while IFS= read -r line; do\n") + yaml.WriteString(" if [ -n \"$line\" ]; then\n") + yaml.WriteString(" # Extract branch from create-pull-request line using simple grep and sed\n") + yaml.WriteString(" if echo \"$line\" | grep -q '\"type\"[[:space:]]*:[[:space:]]*\"create-pull-request\"'; then\n") + yaml.WriteString(" echo \"Found create-pull-request line: $line\"\n") + yaml.WriteString(" # Extract branch value using sed\n") + yaml.WriteString(" BRANCH_NAME=$(echo \"$line\" | sed -n 's/.*\"branch\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p')\n") + yaml.WriteString(" if [ -n \"$BRANCH_NAME\" ]; then\n") + yaml.WriteString(" echo \"Extracted branch name: $BRANCH_NAME\"\n") + yaml.WriteString(" break\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" done < \"$GITHUB_AW_SAFE_OUTPUTS\"\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" \n") yaml.WriteString(" # Get the initial commit SHA from the base branch of the pull request\n") yaml.WriteString(" if [ \"$GITHUB_EVENT_NAME\" = \"pull_request\" ] || [ \"$GITHUB_EVENT_NAME\" = \"pull_request_review_comment\" ]; then\n") yaml.WriteString(" INITIAL_SHA=\"$GITHUB_BASE_REF\"\n") @@ -20,35 +43,59 @@ func (c *Compiler) generateGitPatchStep(yaml *strings.Builder) { yaml.WriteString(" # Configure git user for GitHub Actions\n") yaml.WriteString(" git config --global user.email \"action@github.com\"\n") yaml.WriteString(" git config --global user.name \"GitHub Action\"\n") - yaml.WriteString(" # Stage any unstaged files\n") - yaml.WriteString(" git add -A || true\n") - yaml.WriteString(" # Check if there are staged files to commit\n") - yaml.WriteString(" if ! git diff --cached --quiet; then\n") - yaml.WriteString(" echo \"Staged files found, committing them...\"\n") - yaml.WriteString(" git commit -m \"[agent] staged files\" || true\n") - yaml.WriteString(" echo \"Staged files committed\"\n") - yaml.WriteString(" else\n") - yaml.WriteString(" echo \"No staged files to commit\"\n") + yaml.WriteString(" \n") + yaml.WriteString(" # If we have a branch name, check if that branch exists and get its diff\n") + yaml.WriteString(" if [ -n \"$BRANCH_NAME\" ]; then\n") + yaml.WriteString(" echo \"Looking for branch: $BRANCH_NAME\"\n") + yaml.WriteString(" # Check if the branch exists\n") + yaml.WriteString(" if git show-ref --verify --quiet refs/heads/$BRANCH_NAME; then\n") + yaml.WriteString(" echo \"Branch $BRANCH_NAME exists, generating patch from branch changes\"\n") + yaml.WriteString(" # Generate patch from the base to the branch\n") + yaml.WriteString(" git format-patch \"$INITIAL_SHA\"..\"$BRANCH_NAME\" --stdout > /tmp/aw.patch || echo \"Failed to generate patch from branch\" > /tmp/aw.patch\n") + yaml.WriteString(" echo \"Patch file created from branch: $BRANCH_NAME\"\n") + yaml.WriteString(" else\n") + yaml.WriteString(" echo \"Branch $BRANCH_NAME does not exist, falling back to current HEAD\"\n") + yaml.WriteString(" BRANCH_NAME=\"\"\n") + yaml.WriteString(" fi\n") yaml.WriteString(" fi\n") - yaml.WriteString(" # Check updated git status\n") - yaml.WriteString(" echo \"Updated git status after committing staged files:\"\n") - yaml.WriteString(" git status\n") - yaml.WriteString(" # Show compact diff information between initial commit and HEAD (committed changes only)\n") - yaml.WriteString(" echo '## Git diff' >> $GITHUB_STEP_SUMMARY\n") - yaml.WriteString(" echo '' >> $GITHUB_STEP_SUMMARY\n") - yaml.WriteString(" echo '```' >> $GITHUB_STEP_SUMMARY\n") - yaml.WriteString(" git diff --name-only \"$INITIAL_SHA\"..HEAD >> $GITHUB_STEP_SUMMARY || true\n") - yaml.WriteString(" echo '```' >> $GITHUB_STEP_SUMMARY\n") - yaml.WriteString(" echo '' >> $GITHUB_STEP_SUMMARY\n") - yaml.WriteString(" # Check if there are any committed changes since the initial commit\n") - yaml.WriteString(" if git diff --quiet \"$INITIAL_SHA\" HEAD; then\n") - yaml.WriteString(" echo \"No committed changes detected since initial commit\"\n") - yaml.WriteString(" echo \"Skipping patch generation - no committed changes to create patch from\"\n") - yaml.WriteString(" else\n") - yaml.WriteString(" echo \"Committed changes detected, generating patch...\"\n") - yaml.WriteString(" # Generate patch from initial commit to HEAD (committed changes only)\n") - yaml.WriteString(" git format-patch \"$INITIAL_SHA\"..HEAD --stdout > /tmp/aw.patch || echo \"Failed to generate patch\" > /tmp/aw.patch\n") - yaml.WriteString(" echo \"Patch file created at /tmp/aw.patch\"\n") + yaml.WriteString(" \n") + yaml.WriteString(" # If no branch or branch doesn't exist, use the existing logic\n") + yaml.WriteString(" if [ -z \"$BRANCH_NAME\" ]; then\n") + yaml.WriteString(" echo \"Using current HEAD for patch generation\"\n") + yaml.WriteString(" # Stage any unstaged files\n") + yaml.WriteString(" git add -A || true\n") + yaml.WriteString(" # Check if there are staged files to commit\n") + yaml.WriteString(" if ! git diff --cached --quiet; then\n") + yaml.WriteString(" echo \"Staged files found, committing them...\"\n") + yaml.WriteString(" git commit -m \"[agent] staged files\" || true\n") + yaml.WriteString(" echo \"Staged files committed\"\n") + yaml.WriteString(" else\n") + yaml.WriteString(" echo \"No staged files to commit\"\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" # Check updated git status\n") + yaml.WriteString(" echo \"Updated git status after committing staged files:\"\n") + yaml.WriteString(" git status\n") + yaml.WriteString(" # Show compact diff information between initial commit and HEAD (committed changes only)\n") + yaml.WriteString(" echo '## Git diff' >> $GITHUB_STEP_SUMMARY\n") + yaml.WriteString(" echo '' >> $GITHUB_STEP_SUMMARY\n") + yaml.WriteString(" echo '```' >> $GITHUB_STEP_SUMMARY\n") + yaml.WriteString(" git diff --name-only \"$INITIAL_SHA\"..HEAD >> $GITHUB_STEP_SUMMARY || true\n") + yaml.WriteString(" echo '```' >> $GITHUB_STEP_SUMMARY\n") + yaml.WriteString(" echo '' >> $GITHUB_STEP_SUMMARY\n") + yaml.WriteString(" # Check if there are any committed changes since the initial commit\n") + yaml.WriteString(" if git diff --quiet \"$INITIAL_SHA\" HEAD; then\n") + yaml.WriteString(" echo \"No committed changes detected since initial commit\"\n") + yaml.WriteString(" echo \"Skipping patch generation - no committed changes to create patch from\"\n") + yaml.WriteString(" else\n") + yaml.WriteString(" echo \"Committed changes detected, generating patch...\"\n") + yaml.WriteString(" # Generate patch from initial commit to HEAD (committed changes only)\n") + yaml.WriteString(" git format-patch \"$INITIAL_SHA\"..HEAD --stdout > /tmp/aw.patch || echo \"Failed to generate patch\" > /tmp/aw.patch\n") + yaml.WriteString(" echo \"Patch file created at /tmp/aw.patch\"\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" \n") + yaml.WriteString(" # Show patch info if it exists\n") + yaml.WriteString(" if [ -f /tmp/aw.patch ]; then\n") yaml.WriteString(" ls -la /tmp/aw.patch\n") yaml.WriteString(" # Show the first 50 lines of the patch for review\n") yaml.WriteString(" echo '## Git Patch' >> $GITHUB_STEP_SUMMARY\n") diff --git a/pkg/workflow/git_patch_test.go b/pkg/workflow/git_patch_test.go index 128dfb04c7..3b9aaa1688 100644 --- a/pkg/workflow/git_patch_test.go +++ b/pkg/workflow/git_patch_test.go @@ -30,8 +30,7 @@ func TestGitPatchGeneration(t *testing.T) { on: workflow_dispatch: safe-outputs: - add-issue-label: - allowed: ["bug", "enhancement"] + create-pull-request: --- # Test Git Patch diff --git a/pkg/workflow/js/collect_ndjson_output.cjs b/pkg/workflow/js/collect_ndjson_output.cjs index 42911e8fb5..98c6d1b96a 100644 --- a/pkg/workflow/js/collect_ndjson_output.cjs +++ b/pkg/workflow/js/collect_ndjson_output.cjs @@ -263,6 +263,10 @@ async function main() { // Sanitize text content item.title = sanitizeContent(item.title); item.body = sanitizeContent(item.body); + // Sanitize branch name if present + if (item.branch && typeof item.branch === 'string') { + item.branch = sanitizeContent(item.branch); + } // Sanitize labels if present if (item.labels && Array.isArray(item.labels)) { item.labels = item.labels.map(label => typeof label === 'string' ? sanitizeContent(label) : label); diff --git a/pkg/workflow/js/create_pull_request.cjs b/pkg/workflow/js/create_pull_request.cjs index e46563ceeb..52ab8cac31 100644 --- a/pkg/workflow/js/create_pull_request.cjs +++ b/pkg/workflow/js/create_pull_request.cjs @@ -58,9 +58,10 @@ async function main() { console.log('Found create-pull-request item:', { title: pullRequestItem.title, bodyLength: pullRequestItem.body.length }); - // Extract title and body from the JSON item + // Extract title, body, and branch from the JSON item let title = pullRequestItem.title.trim(); let bodyLines = pullRequestItem.body.split('\n'); + let branchName = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; // If no title was found, use a default if (!title) { @@ -96,9 +97,15 @@ async function main() { console.log('Draft:', draft); console.log('Body length:', body.length); - // Generate unique branch name using cryptographic random hex - const randomHex = crypto.randomBytes(8).toString('hex'); - const branchName = `${workflowId}/${randomHex}`; + // Use branch name from JSONL if provided, otherwise generate unique branch name + if (!branchName) { + console.log('No branch name provided in JSONL, generating unique branch name'); + // Generate unique branch name using cryptographic random hex + const randomHex = crypto.randomBytes(8).toString('hex'); + branchName = `${workflowId}/${randomHex}`; + } else { + console.log('Using branch name from JSONL:', branchName); + } console.log('Generated branch name:', branchName); console.log('Base branch:', baseBranch); @@ -108,9 +115,19 @@ async function main() { execSync('git config --global user.email "action@github.com"', { stdio: 'inherit' }); execSync('git config --global user.name "GitHub Action"', { stdio: 'inherit' }); - // Create and checkout new branch - execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); - console.log('Created and checked out branch:', branchName); + // Handle branch creation/checkout + const branchFromJsonl = pullRequestItem.branch ? pullRequestItem.branch.trim() : null; + if (branchFromJsonl) { + console.log('Checking if branch from JSONL exists:', branchFromJsonl); + + console.log('Branch does not exist locally, creating new branch:', branchFromJsonl); + execSync(`git checkout -b ${branchFromJsonl}`, { stdio: 'inherit' }); + console.log('Using existing/created branch:', branchFromJsonl); + } else { + // Create and checkout new branch with generated name + execSync(`git checkout -b ${branchName}`, { stdio: 'inherit' }); + console.log('Created and checked out new branch:', branchName); + } // Apply the patch using git CLI console.log('Applying patch...');