You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2026/10/23 02:31:02 UTC
(groovy) branch master updated: add skill to see status of recent jira tickets
This is an automated email from the ASF dual-hosted git repository.
paulk-asert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 5a81281ec6 add skill to see status of recent jira tickets
5a81281ec6 is described below
commit 5a81281ec6e894b194017a880d26149cb79dd033
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri Oct 23 12:30:41 2026 +1000
add skill to see status of recent jira tickets
---
.agents/skills/groovy-jira/SKILL.md | 12 +++-
.agents/skills/groovy-jira/jira-recent.sh | 91 +++++++++++++++++++++++++++++++
2 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/.agents/skills/groovy-jira/SKILL.md b/.agents/skills/groovy-jira/SKILL.md
index cf796b0a4b..ad9474ef00 100644
--- a/.agents/skills/groovy-jira/SKILL.md
+++ b/.agents/skills/groovy-jira/SKILL.md
@@ -140,7 +140,7 @@ These are the recurring mistakes when AI tooling reaches for JIRA:
## Helper scripts
-Two vetted helpers ship in this skill's directory so the agent does
+Three vetted helpers ship in this skill's directory so the agent does
not re-derive the ASF JIRA REST calls on every run — per the
[Helper mechanisms and token economy](../../../AGENTS.md#helper-mechanisms-and-token-economy)
policy (the JIRA REST v2 API is stable and these change rarely; the
@@ -157,8 +157,14 @@ equivalent if you need to adapt it):
[out-dir]` → `issue.json` + a rendered `description.md`
(fields, description, every comment), and lists attachment URLs
for manual download.
-
-Both are read-only and anonymous (no auth, no mutation) — they do
+- [`jira-recent.sh`](jira-recent.sh) — `jira-recent.sh [days]` →
+ unresolved issues updated in the last `days` (default 30), each
+ linked to the GitHub PRs whose title names its key, grouped as
+ merged-PR-but-still-open / open PR / no open PR, plus open PRs in
+ the window naming none of the listed issues. Needs an
+ authenticated `gh` in addition to `curl` and `jq`.
+
+All are read-only (no mutation, and anonymous against JIRA) — they do
not change the read-only / hand-back posture this skill enforces.
Prefer them over an ad-hoc `curl`; fall back to the inline command
only if a script is unavailable or the query needs a field they
diff --git a/.agents/skills/groovy-jira/jira-recent.sh b/.agents/skills/groovy-jira/jira-recent.sh
new file mode 100755
index 0000000000..ff0011ee27
--- /dev/null
+++ b/.agents/skills/groovy-jira/jira-recent.sh
@@ -0,0 +1,91 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+# jira-recent.sh — list recently active open GROOVY issues, linked to their GitHub PRs.
+#
+# A vetted helper for a deterministic, rarely-changing operation (the
+# ASF JIRA REST v2 search endpoint joined with `gh pr list`), shipped per
+# the "Helper mechanisms and token economy" policy in AGENTS.md. The
+# curl + gh + jq below IS the documented manual equivalent — run it by
+# hand if you need to adapt it.
+#
+# Usage:
+# ./jira-recent.sh [days] # default: 30
+#
+# Environment:
+# GROOVY_REPO GitHub repo to match PRs against (default: apache/groovy)
+# PR_LIMIT number of most recent PRs (any state) to scan (default: 500)
+#
+# A PR is linked to an issue when its title contains the issue key
+# (GROOVY-NNNNN, or the branch-style GroovyNNNNN).
+# Output groups the unresolved issues updated in the last <days> days:
+# - merged PR but issue still open (candidates for resolving)
+# - open PR
+# - no open PR (closed-unmerged PRs, if any, are still shown)
+# followed by open PRs updated in the window that name none of the listed issues.
+#
+# ASF JIRA is anonymous-readable; `gh` must be authenticated for GitHub.
+set -euo pipefail
+
+DAYS="${1:-30}"
+REPO="${GROOVY_REPO:-apache/groovy}"
+PR_LIMIT="${PR_LIMIT:-500}"
+
+for tool in curl jq gh; do
+ command -v "${tool}" >/dev/null || { echo "$0: requires ${tool} on PATH" >&2; exit 1; }
+done
+
+TMP="$(mktemp -d)"
+trap 'rm -rf "${TMP}"' EXIT
+
+curl -fsSG 'https://issues.apache.org/jira/rest/api/2/search' \
+ --data-urlencode "jql=project = GROOVY AND statusCategory != Done AND updated >= -${DAYS}d ORDER BY key DESC" \
+ --data-urlencode 'maxResults=500' \
+ --data-urlencode 'fields=summary,updated' \
+ > "${TMP}/issues.json"
+
+gh pr list --repo "${REPO}" --state all --limit "${PR_LIMIT}" \
+ --json number,title,state,updatedAt \
+ > "${TMP}/prs.json"
+
+jq -r --argjson days "${DAYS}" --slurpfile prs "${TMP}/prs.json" '
+ def prs: map("#\(.number)(\(.state))") | join(" ") | if . == "" then "-" else . end;
+ def section($title; $rows):
+ "== \($title) (\($rows | length))",
+ ($rows[] | [.key, .updated, (.prs | prs), .summary[0:100]] | @tsv),
+ "";
+
+ ($prs[0] | map(. + {keys: [.title | ascii_upcase | scan("GROOVY-?[0-9]+") | sub("^GROOVY-?"; "GROOVY-")]})) as $p
+ | [.issues[] | .key as $k
+ | {key: $k, updated: .fields.updated[0:10], summary: (.fields.summary // ""),
+ prs: [$p[] | select(any(.keys[]; . == $k))]}
+ | . + {open: any(.prs[]; .state == "OPEN"), merged: any(.prs[]; .state == "MERGED")}
+ ] as $rows
+ | ($rows | map(.key)) as $listed
+ | (now - $days * 86400 | strftime("%Y-%m-%d")) as $since
+ | "Unresolved GROOVY issues updated since \($since): \($rows | length)",
+ "",
+ section("Merged PR, issue still open"; [$rows[] | select(.merged and (.open | not))]),
+ section("Open PR"; [$rows[] | select(.open)]),
+ section("No open PR"; [$rows[] | select((.open or .merged) | not)]),
+ ([$p[] | select(.state == "OPEN" and .updatedAt[0:10] >= $since
+ and all(.keys[]; . as $k | $listed | index($k) | not))] as $orphans
+ | "== Open PRs updated in window naming no listed issue (\($orphans | length))",
+ ($orphans[] | ["#\(.number)", .updatedAt[0:10], .title] | @tsv))
+' "${TMP}/issues.json"