Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 25 additions & 16 deletions .github/workflows/auto-triage-issues.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 16 additions & 3 deletions .github/workflows/auto-triage-issues.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ rate-limit:
permissions:
contents: read
issues: read
engine: copilot
engine:
id: copilot
model: gpt-4.1-mini
strict: true
network:
allowed:
Expand All @@ -28,6 +30,16 @@ tools:
min-integrity: approved
bash:
- "jq *"
- "cat *"
steps:
pre-agent:
- name: Fetch unlabeled issues
run: |
mkdir -p /tmp/gh-aw/agent
gh api "repos/github/gh-aw/issues?state=open&labels=&per_page=30" \
Comment on lines +37 to +39
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pre-agent fetch step does not set GH_TOKEN/GITHUB_TOKEN. On github.com runners, configure_gh_for_ghe.sh does not authenticate gh, so this gh api ... call is likely to run unauthenticated (or fail/rate-limit). Also, without an explicit GH_TOKEN in the pre-agent step, the compiler’s DIFC proxy injection for integrity filtering won’t trigger even though min-integrity: approved is configured. Add the appropriate token env vars on this step (and preferably rely on $GITHUB_REPOSITORY rather than hard-coding github/gh-aw).

Suggested change
run: |
mkdir -p /tmp/gh-aw/agent
gh api "repos/github/gh-aw/issues?state=open&labels=&per_page=30" \
env:
GH_TOKEN: ${{ github.token }}
GITHUB_TOKEN: ${{ github.token }}
run: |
mkdir -p /tmp/gh-aw/agent
gh api "repos/$GITHUB_REPOSITORY/issues?state=open&labels=&per_page=30" \

Copilot uses AI. Check for mistakes.
--jq '[.[] | select(.labels | length == 0) | {number: .number, title: .title, body: .body}]' \
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gh api repos/.../issues returns both issues and pull requests. The current jq filter only checks for labels | length == 0, so unlabeled PRs can be included in /tmp/gh-aw/agent/unlabeled-issues.json and then triaged/labeled as if they were issues. Update the jq filter (or API path) to explicitly exclude items with a pull_request field, or switch to a search that enforces is:issue.

Suggested change
--jq '[.[] | select(.labels | length == 0) | {number: .number, title: .title, body: .body}]' \
--jq '[.[] | select((.pull_request | not) and (.labels | length == 0)) | {number: .number, title: .title, body: .body}]' \

Copilot uses AI. Check for mistakes.
> /tmp/gh-aw/agent/unlabeled-issues.json
echo "Unlabeled issues: $(jq length /tmp/gh-aw/agent/unlabeled-issues.json)"
Comment on lines +35 to +42
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The frontmatter steps: block is using a nested pre-agent: key, but the compiler appears to treat steps: as the pre-agent step list already. This structure is producing a malformed compiled workflow (see auto-triage-issues.lock.yml where pre-agent: ends up inside a GitHub Actions step). Convert this to the supported format (make steps: a plain array of step objects) and re-run gh aw compile so the generated lock file is valid.

Suggested change
pre-agent:
- name: Fetch unlabeled issues
run: |
mkdir -p /tmp/gh-aw/agent
gh api "repos/github/gh-aw/issues?state=open&labels=&per_page=30" \
--jq '[.[] | select(.labels | length == 0) | {number: .number, title: .title, body: .body}]' \
> /tmp/gh-aw/agent/unlabeled-issues.json
echo "Unlabeled issues: $(jq length /tmp/gh-aw/agent/unlabeled-issues.json)"
- name: Fetch unlabeled issues
run: |
mkdir -p /tmp/gh-aw/agent
gh api "repos/github/gh-aw/issues?state=open&labels=&per_page=30" \
--jq '[.[] | select(.labels | length == 0) | {number: .number, title: .title, body: .body}]' \
> /tmp/gh-aw/agent/unlabeled-issues.json
echo "Unlabeled issues: $(jq length /tmp/gh-aw/agent/unlabeled-issues.json)"

Copilot uses AI. Check for mistakes.
safe-outputs:
add-labels:
max: 10
Expand Down Expand Up @@ -68,9 +80,9 @@ When an issue is opened or edited:

When running on schedule:

1. **Fetch unlabeled issues** using GitHub tools
1. **Read pre-fetched unlabeled issues** from `/tmp/gh-aw/agent/unlabeled-issues.json` (populated by the pre-agent step). If the file is missing or contains an empty JSON array (`[]`), fall back to `search_issues` with query `repo:github/gh-aw is:issue is:open no:label` — **do NOT use `list_issues`** as it returns an oversized payload.
2. **Process up to 10 unlabeled issues** (respecting safe-output limits)
3. **Apply labels** to each issue based on classification
3. **Apply labels** to each issue based on classification; the pre-fetched data already includes `number`, `title`, and `body`. Only call `issue_read` when you need additional metadata not present in those fields (e.g., comments, reactions, or author association details not available in the pre-fetch).
4. **Create a summary report** as a discussion with statistics on processed issues

### On Manual/On-Demand Runs (workflow_dispatch)
Expand Down Expand Up @@ -261,6 +273,7 @@ When running on schedule, create a discussion report following these formatting

## Important Notes

- **Do NOT call `search_repositories`** — it is not available in this workflow. Use `search_issues` with `no:label` to find unlabeled issues, and `get_label` to verify a label exists.
- **Be conservative** - Better to add `needs-triage` than apply incorrect labels
- **Context matters** - Consider the full issue context, not just keywords
- **Respect limits** - Maximum 10 label operations per run (safe-output limit)
Expand Down
Loading