diff --git a/.github/workflows/issue-ops-triage.yml b/.github/workflows/issue-ops-triage.yml index ba265cd..eb84e58 100644 --- a/.github/workflows/issue-ops-triage.yml +++ b/.github/workflows/issue-ops-triage.yml @@ -10,7 +10,9 @@ concurrency: cancel-in-progress: true jobs: triage: - if: vars.IO_ENABLED == 'true' + # Skip bot-authored issues (e.g. Renovate's Dependency Dashboard): their `edited` events + # fire this trigger but carry no author_association to trust-tier, and errored at 0s (#17). + if: vars.IO_ENABLED == 'true' && github.event.issue.user.type != 'Bot' uses: wave-av/wave-foundation/.github/workflows/io-triage.yml@5d0b9e1a35efdb6d4e2ba55c483af670b69a8470 permissions: contents: read @@ -20,6 +22,7 @@ jobs: scripts_ref: "5d0b9e1a35efdb6d4e2ba55c483af670b69a8470" owner: ${{ vars.IO_OWNER }} secrets: - gh_pat: ${{ secrets.ISSUE_OPS_PAT }} + # gh_pat dropped (#17): ISSUE_OPS_PAT is absent org/repo-wide; IO_USE_APP=true uses the App + # token, and the reusable io-triage.yml cascades apptoken || gh_pat || github.token anyway. bot_app_id: ${{ secrets.BOT_ISSUE_OPS_APP_ID }} bot_private_key: ${{ secrets.BOT_ISSUE_OPS_PRIVATE_KEY }} diff --git a/.github/workflows/ticket-hygiene.yml b/.github/workflows/ticket-hygiene.yml index a6916e6..a79693d 100644 --- a/.github/workflows/ticket-hygiene.yml +++ b/.github/workflows/ticket-hygiene.yml @@ -126,15 +126,17 @@ jobs: id fieldValues(first:30){ nodes{ ... on ProjectV2ItemFieldSingleSelectValue { name field{ ... on ProjectV2SingleSelectField { name } } } } } - content{ ... on Issue { number state repository{ nameWithOwner } url author{ login } } } + content{ ... on Issue { number state repository{ nameWithOwner } url author{ login } + labels(first:20){ nodes{ name } } } } } } } } }' -F p="$PROJECT_ID" ${after:+-F after="$after"})" echo "$resp" | jq -c '.data.node.items.nodes[] | select(.content!=null and .content.state=="OPEN") | { itemId:.id, repo:.content.repository.nameWithOwner, num:.content.number, url:.content.url, author:(.content.author.login // ""), + hasTriage:([.content.labels.nodes[].name]|any(.=="needs-triage")), area:([.fieldValues.nodes[]|select(.field.name=="Area")|.name]|first), prio:([.fieldValues.nodes[]|select(.field.name=="Priority")|.name]|first) } - | select(.area==null or .prio==null)' > flagged.jsonl || true + | select(.area==null or .prio==null or .hasTriage)' > flagged.jsonl || true # Fixed allow-list, case-sensitive exact match only — the author login is NEVER # interpolated into a query or shell command, only compared in a bash case. @@ -152,12 +154,21 @@ jobs: -F p="$PROJECT_ID" -F i="$1" -F f="$2" -F o="$3" >/dev/null } - classified=0 + classified=0; unlabeled=0 while IFS= read -r row; do [ -n "$row" ] || continue repo="$(jq -r .repo <<<"$row")"; num="$(jq -r .num <<<"$row")" itemId="$(jq -r .itemId <<<"$row")"; login="$(jq -r .author <<<"$row")" area="$(jq -r .area <<<"$row")"; prio="$(jq -r .prio <<<"$row")" + + # Fully fielded but still carrying a stale needs-triage label (from before it was + # completed) — strip the label so the Triage-health chart stops overcounting. + if [ "$area" != "null" ] && [ "$prio" != "null" ]; then + gh issue edit "$num" -R "$repo" --remove-label needs-triage >/dev/null 2>&1 || true + unlabeled=$((unlabeled+1)) + continue + fi + bot_vals="$(bot_area_priority "$login")" if [ -n "$bot_vals" ]; then for pair in $bot_vals; do @@ -179,7 +190,7 @@ jobs: [ "$hasNext" = "true" ] || break done echo "### Triage-health sweep" >> "$GITHUB_STEP_SUMMARY" - echo "Flagged **$missing** open board item(s) missing Area or Priority as \`needs-triage\`; auto-classified **$classified** known-bot item(s)." >> "$GITHUB_STEP_SUMMARY" + echo "Flagged **$missing** open board item(s) missing Area or Priority as \`needs-triage\`; auto-classified **$classified** known-bot item(s); cleared the stale label from **$unlabeled** now-fully-fielded item(s)." >> "$GITHUB_STEP_SUMMARY" - name: Auto-add non-WSC issues to the board env: