Skip to content

Release digest skill improvements - #1597

Open
sfierro wants to merge 1 commit into
mainfrom
sfierro/release-digest-skill-improvements
Open

Release digest skill improvements#1597
sfierro wants to merge 1 commit into
mainfrom
sfierro/release-digest-skill-improvements

Conversation

@sfierro

@sfierro sfierro commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The release digest script now supports --pre-release and --since <tag> baseline selection. Documentation describes already-cut release handling and uses the detected tag automatically during pre-release processing.

Changes

Release digest baseline selection

Layer / File(s) Summary
CLI baseline resolution
.agents/skills/release-digest/scripts/gather_changes.py
The script parses baseline options, validates explicit tags, resolves pre-release baselines, and uses the selected tag for change collection.
Pre-release workflow documentation
.agents/skills/release-digest/SKILL.md
Instructions describe pre-release ranges, option exclusivity, and automatic use of the QA tag as the new release.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • Kiln-AI/Kiln#1507: Introduced the earlier change-gathering baseline logic extended by this update.

Poem

A rabbit hops through tags so neat,
Rewinds the baseline for a pre-release treat.
“Since” marks a path, while QA tags gleam,
The digest gathers changes like a dream.
No prompt needed—the newest tag leads!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning No PR description was provided, so none of the required template sections are filled in. Add the required template sections: What does this PR do?, Related Issues, CLA confirmation, and the checklists.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: improvements to the release-digest skill.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sfierro/release-digest-skill-improvements

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces --pre-release and --since command-line options to the release-digest script, allowing users to customize the baseline tag for generating change digests. The documentation in SKILL.md has been updated to reflect these new options. The feedback suggests handling the edge case where --pre-release is used but no prior tag exists in the repository to avoid an unhandled git error.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

if args.pre_release:
# The newest tag is a pre-release still being QA'd; baseline is the tag before
# it, so the range covers exactly what the pre-release contains.
prior = run(["git", "describe", "--tags", "--abbrev=0", f"{latest}^"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

If latest is the only tag in the repository, running git describe on latest^ will fail because there is no prior tag. Using the helper run here will cause the script to exit with a generic git error message. It would be more user-friendly to handle this case gracefully and print a clear error message.

Suggested change
prior = run(["git", "describe", "--tags", "--abbrev=0", f"{latest}^"])
prior_result = subprocess.run(
["git", "describe", "--tags", "--abbrev=0", f"{latest}^"],
capture_output=True,
text=True,
)
if prior_result.returncode != 0:
sys.stderr.write(
f"ERROR: --pre-release mode failed because no prior tag could be found before {latest}.\n"
)
sys.exit(1)
prior = prior_result.stdout.strip()

@github-actions

Copy link
Copy Markdown

📊 Coverage Report

Overall Coverage: 92%

Diff: origin/main...HEAD

No lines with coverage information in this diff.


@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.agents/skills/release-digest/SKILL.md (1)

198-200: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the checklist to reflect conditional prompting.

The checklist item "Asked the user for the new release name" conflicts with the updated Phase 3 instructions, which explicitly state that no prompting is needed in --pre-release mode. Updating this item will prevent the agent from getting confused or inappropriately blocking on user input.

📝 Proposed fix
- - [ ] Asked the user for the new release name (used in the title)
+ - [ ] Determined the new release name (from pre-release tag, or asked the user)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/release-digest/SKILL.md around lines 198 - 200, Update the
release-digest checklist item for asking the user for a new release name to
reflect that prompting is required only when not running in --pre-release mode,
matching the conditional behavior described in Phase 3.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/release-digest/scripts/gather_changes.py:
- Around line 109-137: Update resolve_base_tag to accept a head_ref parameter,
handle and validate args.since before discovering the latest tag, and pass
head_ref to all git describe calls so tag discovery follows the fetched remote
reference rather than local HEAD. In main(), resolve head_ref before evaluating
last_tag and pass it into resolve_base_tag; preserve pre-release behavior by
finding the prior tag relative to the selected head_ref.

---

Outside diff comments:
In @.agents/skills/release-digest/SKILL.md:
- Around line 198-200: Update the release-digest checklist item for asking the
user for a new release name to reflect that prompting is required only when not
running in --pre-release mode, matching the conditional behavior described in
Phase 3.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 465ef6da-dab9-4820-84eb-a6a90a282f56

📥 Commits

Reviewing files that changed from the base of the PR and between dfdfd27 and 5a3516c.

📒 Files selected for processing (2)
  • .agents/skills/release-digest/SKILL.md
  • .agents/skills/release-digest/scripts/gather_changes.py

Comment on lines +109 to +137
def resolve_base_tag(args: argparse.Namespace) -> str:
"""Pick the tag to compare against, honoring --since / --pre-release overrides.

Default: the newest tag reachable from HEAD (`git describe`). But when the newest
tag is a just-cut pre-release (main is already even with it), that baseline yields
an empty range -- so `--pre-release` steps back one tag to recap what went INTO the
pre-release, and `--since TAG` lets the caller name the baseline explicitly.
"""
latest = run(["git", "describe", "--tags", "--abbrev=0"])
if args.since:
check = subprocess.run(
["git", "rev-parse", "--verify", "--quiet", f"{args.since}^{{commit}}"],
capture_output=True,
text=True,
)
if check.returncode != 0:
sys.stderr.write(f"ERROR: --since tag {args.since!r} does not exist.\n")
sys.exit(1)
return args.since
if args.pre_release:
# The newest tag is a pre-release still being QA'd; baseline is the tag before
# it, so the range covers exactly what the pre-release contains.
prior = run(["git", "describe", "--tags", "--abbrev=0", f"{latest}^"])
sys.stderr.write(
f"Pre-release mode: newest tag {latest} treated as the release being "
f"QA'd; comparing against the prior tag {prior}.\n"
)
return prior
return latest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use head_ref for tag discovery and evaluate --since before latest.

There are two issues with the current resolve_base_tag implementation:

  1. git describe defaults to the local HEAD. Because git fetch updates origin/main but not your local branch, any newly tagged releases on origin won't be seen if your local branch is behind, leading to an incorrect (inflated) change set.
  2. latest is computed unconditionally. If the current branch has no reachable tags, the script will crash even if the caller explicitly provided a valid --since tag.

Determine head_ref first, pass it to resolve_base_tag, and defer computing latest until after --since is handled.

🐛 Proposed fixes

Update resolve_base_tag to accept head_ref and reorder the logic:

-def resolve_base_tag(args: argparse.Namespace) -> str:
+def resolve_base_tag(args: argparse.Namespace, head_ref: str) -> str:
     """Pick the tag to compare against, honoring --since / --pre-release overrides.
 
-    Default: the newest tag reachable from HEAD (`git describe`). But when the newest
+    Default: the newest tag reachable from the target branch. But when the newest
     tag is a just-cut pre-release (main is already even with it), that baseline yields
     an empty range -- so `--pre-release` steps back one tag to recap what went INTO the
     pre-release, and `--since TAG` lets the caller name the baseline explicitly.
     """
-    latest = run(["git", "describe", "--tags", "--abbrev=0"])
     if args.since:
         check = subprocess.run(
             ["git", "rev-parse", "--verify", "--quiet", f"{args.since}^{{commit}}"],
             capture_output=True,
             text=True,
         )
         if check.returncode != 0:
             sys.stderr.write(f"ERROR: --since tag {args.since!r} does not exist.\n")
             sys.exit(1)
         return args.since
 
+    latest = run(["git", "describe", "--tags", "--abbrev=0", head_ref])
     if args.pre_release:
         # The newest tag is a pre-release still being QA'd; baseline is the tag before
         # it, so the range covers exactly what the pre-release contains.
         prior = run(["git", "describe", "--tags", "--abbrev=0", f"{latest}^"])
         sys.stderr.write(
             f"Pre-release mode: newest tag {latest} treated as the release being "
             f"QA'd; comparing against the prior tag {prior}.\n"
         )
         return prior
     return latest

Then in main(), resolve head_ref before evaluating last_tag:

-    last_tag = resolve_base_tag(args)
-
     # Prefer origin/main; fall back to local main if there's no remote-tracking ref.
     head_ref = "origin/main"
     check = subprocess.run(
         ["git", "rev-parse", "--verify", "--quiet", head_ref],
         capture_output=True,
         text=True,
     )
     if check.returncode != 0:
         head_ref = "main"
 
+    last_tag = resolve_base_tag(args, head_ref)
+
     rng = f"{last_tag}..{head_ref}"

Also applies to: 171-184

🧰 Tools
🪛 ast-grep (0.44.1)

[error] 118-122: Command coming from incoming request
Context: subprocess.run(
["git", "rev-parse", "--verify", "--quiet", f"{args.since}^{{commit}}"],
capture_output=True,
text=True,
)
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').

(subprocess-from-request)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/release-digest/scripts/gather_changes.py around lines 109 -
137, Update resolve_base_tag to accept a head_ref parameter, handle and validate
args.since before discovering the latest tag, and pass head_ref to all git
describe calls so tag discovery follows the fetched remote reference rather than
local HEAD. In main(), resolve head_ref before evaluating last_tag and pass it
into resolve_base_tag; preserve pre-release behavior by finding the prior tag
relative to the selected head_ref.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants