Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion .github/workflows/gh-aw-issue-fixer.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
name: Issue Fixer
on:
workflow_call:
inputs:
allowed-bot-users:
description: Comma-separated GitHub logins (from load-allowed-authors allowed_issue_authors_csv)
required: false
type: string
default: github-actions[bot]
secrets:
COPILOT_GITHUB_TOKEN:
required: true

permissions:
actions: read

jobs:
prefetch-issue-context:
uses: ./.github/workflows/prefetch-issue-context.yml

run:
needs: prefetch-issue-context
permissions:
actions: read
contents: write
Expand All @@ -21,6 +34,7 @@ jobs:
!contains(join(github.event.issue.labels.*.name, ','), 'oblt-aw/triage/res-not-accessible-by-integration')
uses: elastic/ai-github-actions/.github/workflows/gh-aw-issue-fixer.lock.yml@main
with:
allowed-bot-users: ${{ inputs.allowed-bot-users }}
additional-instructions: |
Your task is to fix issues requested through `/ai implement` comments.

Expand All @@ -31,8 +45,13 @@ jobs:
- `oblt-aw/triage/res-not-accessible-by-integration`
- The issue must already contain a triage-generated resolution plan.

**Prefetched issue context (source of truth for issue body and comments):**
On public repositories, GitHub MCP guard policies apply `min-integrity: approved` and can hide triage comments (for example from `github-actions` with `CONTRIBUTOR` association). Use the prefetched thread below instead of MCP reads when verifying the resolution plan or `/ai implement` trigger.

${{ needs.prefetch-issue-context.outputs.context }}

**Implementation Workflow (sequential and methodical):**
1. Read the resolution plan from the issue and extract ordered tasks. Treat this plan as the source of truth.
1. Read the resolution plan from the prefetched issue context (or the issue via MCP when available) and extract ordered tasks. Treat this plan as the source of truth.
2. Execute the plan strictly step by step, without skipping steps.
3. For each step, document what changed and why in commit messages and PR description.
4. Run validation/tests described in the plan and confirm the issue is resolved.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ permissions:
pull-requests: write

jobs:
prefetch-issue-context:
uses: ./.github/workflows/prefetch-issue-context.yml

res-not-accessible-integration-fixer:
needs: prefetch-issue-context
if: >-
github.event.label.name == 'oblt-aw/ai/fix-ready' &&
contains(join(github.event.issue.labels.*.name, ','), 'oblt-aw/triage/res-not-accessible-by-integration')
Expand All @@ -31,8 +35,13 @@ jobs:
- `oblt-aw/triage/res-not-accessible-by-integration`
- The issue must already contain a triage-generated resolution plan.

**Prefetched issue context (source of truth for issue body and comments):**
On public repositories, GitHub MCP guard policies apply `min-integrity: approved` and can hide triage comments (for example from `github-actions` with `CONTRIBUTOR` association). Use the prefetched thread below instead of MCP reads when verifying the resolution plan.

${{ needs.prefetch-issue-context.outputs.context }}

**Implementation Workflow (sequential and methodical):**
1. Read the resolution plan from the issue and extract ordered tasks.
1. Read the resolution plan from the prefetched issue context (or the issue via MCP when available) and extract ordered tasks.
2. Execute the plan strictly step by step, without skipping steps.
3. For each step, document what changed and why in commit messages and PR description.
4. Apply least-privilege permissions changes only (no over-broad permission grants).
Expand Down
11 changes: 10 additions & 1 deletion .github/workflows/gh-aw-security-fixer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ permissions:
pull-requests: write

jobs:
prefetch-issue-context:
uses: ./.github/workflows/prefetch-issue-context.yml

security-issue-fixer:
needs: prefetch-issue-context
uses: elastic/ai-github-actions/.github/workflows/gh-aw-issue-fixer.lock.yml@main
with:
allowed-bot-users: ${{ inputs.allowed-bot-users }}
Expand All @@ -31,8 +35,13 @@ jobs:
- At least one of `oblt-aw/triage/security-injection`, `oblt-aw/triage/security-secrets`, `oblt-aw/triage/security-supply-chain`, `oblt-aw/triage/security-least-privilege`
- The issue must already contain a triage-generated resolution plan.

**Prefetched issue context (source of truth for issue body and comments):**
On public repositories, GitHub MCP guard policies apply `min-integrity: approved` and can hide triage comments (for example from `github-actions` with `CONTRIBUTOR` association). Use the prefetched thread below instead of MCP reads when verifying the resolution plan.

${{ needs.prefetch-issue-context.outputs.context }}

**Implementation Workflow (sequential and methodical):**
1. Read the resolution plan from the issue and extract ordered tasks.
1. Read the resolution plan from the prefetched issue context (or the issue via MCP when available) and extract ordered tasks.
2. Execute the plan strictly step by step, without skipping steps.
3. For each step, document what changed and why in commit messages and PR description.
4. **Least-privilege (MANDATORY):** Grant only the minimum permissions required. Never add broad scopes (e.g., avoid `contents: write` when `contents: read` suffices). Prefer job-level permissions over workflow-root permissions.
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/oblt-aw-ingress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ jobs:
uses: ./.github/workflows/get-enabled-workflows.yml

load-allowed-authors:
if: github.event_name == 'pull_request' || github.event_name == 'issues'
if: >-
github.event_name == 'pull_request' ||
github.event_name == 'issues' ||
github.event_name == 'issue_comment'
uses: ./.github/workflows/load-allowed-authors.yml

agent-suggestions:
Expand Down Expand Up @@ -101,7 +104,7 @@ jobs:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}

issue-fixer:
needs: dashboard-enabled-workflows
needs: [dashboard-enabled-workflows, load-allowed-authors]
if: >-
github.event_name == 'issue_comment' &&
github.event.action == 'created' &&
Expand All @@ -112,6 +115,8 @@ jobs:
!contains(join(github.event.issue.labels.*.name, ','), 'oblt-aw/triage/res-not-accessible-by-integration') &&
(needs['dashboard-enabled-workflows'].outputs['effective-raw'] == '' || contains(fromJSON(needs['dashboard-enabled-workflows'].outputs['enabled-workflows']), 'obs:issue-fixer'))
uses: ./.github/workflows/gh-aw-issue-fixer.yml
with:
allowed-bot-users: ${{ needs['load-allowed-authors'].outputs['allowed_issue_authors_csv'] }}
secrets: inherit

mention-in-issue:
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/prefetch-issue-context.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Prefetch issue context
on:
workflow_call:
outputs:
context:
description: Markdown snapshot of the issue body and comment thread
value: ${{ jobs.prefetch.outputs.context }}

permissions:
contents: read

jobs:
prefetch:
runs-on: ubuntu-latest
permissions:
issues: read
outputs:
context: ${{ steps.prefetch.outputs.context }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed

- name: Prefetch issue and comments for agent prompt
id: prefetch
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
REPOSITORY: ${{ github.repository }}
run: bash scripts/obs/prefetchIssueContext.sh
1 change: 1 addition & 0 deletions config/obs/allowed_issue_authors.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
"github-actions",
"github-actions[bot]",
"elastic-vault-github-plugin-prod[bot]"
]
59 changes: 59 additions & 0 deletions scripts/obs/prefetchIssueContext.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# Copyright 2026-2027 Elasticsearch B.V.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

# Prefetch issue title, body, labels, and comments for GH-AW issue fixer prompts.
# Public-repo MCP guard policies (min-integrity: approved) can hide triage bot comments
# (e.g. github-actions with CONTRIBUTOR association). This script uses GITHUB_TOKEN
# directly so the agent still receives the full thread.
set -euo pipefail

issue_number="${ISSUE_NUMBER:?ISSUE_NUMBER is required}"
repository="${REPOSITORY:?REPOSITORY is required}"

issue_json=$(gh issue view "$issue_number" --repo "$repository" --json number,title,body,labels,author,state,url)
issue_title=$(jq -r '.title' <<<"$issue_json")
issue_body=$(jq -r '.body // ""' <<<"$issue_json")
issue_author=$(jq -r '.author.login' <<<"$issue_json")
issue_state=$(jq -r '.state' <<<"$issue_json")
issue_url=$(jq -r '.url' <<<"$issue_json")
issue_labels=$(jq -r '[.labels[].name] | join(", ")' <<<"$issue_json")

comments_json=$(gh api "repos/${repository}/issues/${issue_number}/comments" --paginate)
comment_count=$(jq 'length' <<<"$comments_json")

{
echo "Issue #${issue_number}: ${issue_title}"
echo "URL: ${issue_url}"
echo "State: ${issue_state}"
echo "Author: ${issue_author}"
echo "Labels: ${issue_labels:-<none>}"
echo
echo "## Issue body"
echo "$issue_body"
echo
echo "## Comments (${comment_count})"
if [ "$comment_count" -eq 0 ]; then
echo "<no comments>"
else
jq -r '.[] | "### Comment by \(.user.login) (\(.created_at))\n\n\(.body)\n"' <<<"$comments_json"
fi
} >"${RUNNER_TEMP}/prefetched-issue-context.md"

{
echo 'context<<EOF'
cat "${RUNNER_TEMP}/prefetched-issue-context.md"
echo 'EOF'
} >>"${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"
Loading