Skip to content

feat: add release email generation tooling#743

Open
hussain-s wants to merge 1 commit intoapache:mainfrom
hussain-s:feat/issue-719-release-email-tooling
Open

feat: add release email generation tooling#743
hussain-s wants to merge 1 commit intoapache:mainfrom
hussain-s:feat/issue-719-release-email-tooling

Conversation

@hussain-s
Copy link
Copy Markdown

Add release email generation tooling to scripts/apache_release.py for vote, result, and announcement emails.

Changes

  • add vote-email, result-email, and announce-email commands to scripts/apache_release.py
  • add Jinja templates for each generated email under scripts/templates/
  • align the generated email wording with Apache Incubator guidance and an Iceberg-style structure
  • add unit coverage for email rendering and argument handling in tests/test_apache_release_email.py
  • document the release-email commands in scripts/README.md

How I tested this

  • ran python3 scripts/apache_release.py vote-email --version 0.41.0 --rc 1
  • ran python3 scripts/apache_release.py result-email --version 0.41.0 --rc 1 --binding-yes 3
  • ran python3 scripts/apache_release.py announce-email --version 0.41.0
  • ran .venv/bin/python -m pytest tests/test_apache_release_email.py
  • ran .venv/bin/python -m pytest tests/

Notes

  • full test suite passed locally: 520 passed, 5 skipped
  • generated emails now explicitly mention incubation status and keep incubating in the artifact/release context where appropriate

Checklist

  • PR has an informative and human-readable title (this will be pulled into the release notes)
  • Changes are limited to a single goal (no scope creep)
  • Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
  • Any change in functionality is tested
  • New functions are documented (with a description, list of inputs, and expected output)
  • Placeholder code is flagged / future TODOs are captured in comments
  • Project documentation has been updated if adding/changing functionality.

@github-actions github-actions Bot added the area/ci Workflows, build, release scripts label Apr 18, 2026
@hussain-s hussain-s marked this pull request as ready for review April 18, 2026 21:50
@andreahlert andreahlert requested a review from Copilot April 19, 2026 11:03
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds release-email generation support to the existing Apache release helper script, providing templated vote/result/announcement emails aligned with Apache Incubator guidance.

Changes:

  • Added vote-email, result-email, and announce-email subcommands to scripts/apache_release.py with Jinja2-based rendering.
  • Introduced Jinja templates under scripts/templates/ for vote/result/announcement emails.
  • Added unit tests covering CLI parsing and template rendering for the new email commands.

Reviewed changes

Copilot reviewed 6 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
scripts/apache_release.py Adds template rendering, changelog-summary generation, clipboard copy support, and new email subcommands.
scripts/templates/vote_email.j2 New vote email template.
scripts/templates/result_email.j2 New result email template.
scripts/templates/announce_email.j2 New announcement email template.
tests/test_apache_release_email.py New tests for parser handling + rendering output.
scripts/README.md Documents the new email-generation commands.
.gitignore Adds uv.lock.
Comments suppressed due to low confidence (1)

scripts/apache_release.py:398

  • required_tools = command_requirements.get(...) returns the actual list stored in command_requirements. Later, required_tools.append("java") mutates that shared list, which can make subsequent validations in the same process incorrectly require Java for that command. Use a copy (e.g., list(...)) before appending to avoid side effects.
    required_tools = command_requirements.get(args.command, [])

    # Check for RAT if needed
    if hasattr(args, "check_licenses") or hasattr(args, "check_licenses_report"):
        if getattr(args, "check_licenses", False) or getattr(args, "check_licenses_report", False):
            required_tools.append("java")
            if not getattr(args, "rat_jar", None):

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/apache_release.py Outdated
Comment thread scripts/apache_release.py Outdated
Comment thread scripts/templates/result_email.j2 Outdated
Comment thread scripts/templates/vote_email.j2
Comment thread scripts/templates/result_email.j2
Comment thread scripts/templates/announce_email.j2
@hussain-s hussain-s force-pushed the feat/issue-719-release-email-tooling branch from 95cb22c to acbb9e1 Compare April 19, 2026 19:30
Comment thread scripts/apache_release.py Outdated
Comment thread scripts/apache_release.py Outdated
Copy link
Copy Markdown
Contributor

@skrawcz skrawcz left a comment

Choose a reason for hiding this comment

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

can you run the pre-commit check and fix those up please -- see dev guide for installing it. otherwise let's just assume jinja2 is required -- please add that as an optional dependency to pyproject.toml so someone can install what's required to run the release?

@andreahlert
Copy link
Copy Markdown
Collaborator

Code review

Found 1 issue:

  1. --binding-yes defaults to 3, so running result-email without specifying vote counts silently generates an email stating "Therefore, the release candidate has passed." A release manager could accidentally send a misleading result email before collecting any votes. Should be required=True instead of default=3.

burr/scripts/apache_release.py

Lines 1318 to 1325 in acbb9e1

result_email_parser.add_argument("--rc", dest="rc_num", required=True, help="RC number")
result_email_parser.add_argument(
"--binding-yes", type=int, default=3, help="Number of binding +1 votes"
)
result_email_parser.add_argument(
"--non-binding-yes", type=int, default=0, help="Number of non-binding +1 votes"
)
result_email_parser.add_argument("--abstain", type=int, default=0, help="Number of 0 votes")

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@hussain-s hussain-s force-pushed the feat/issue-719-release-email-tooling branch from acbb9e1 to a8941b2 Compare April 21, 2026 05:17
Comment thread scripts/apache_release.py
vote_thread_url: Optional[str] = None,
) -> dict[str, str]:
"""Build rendering context for the result email template."""
release_passed = binding_yes >= 3 and binding_yes > no_votes
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

no_votes mixes binding and non-binding -1 votes, but Apache voting rules only allow binding -1 to block a release. Concrete failure case: 3 binding +1, 2 binding -1, 3 non-binding -1 — no_votes=5, 3 > 5 is False, script outputs "not passed", but the binding tally (3 vs 2) actually passes under Apache rules.

Suggested fix — split into two flags and compare only binding -1:

# argparse (~line 1319) — replace --no-votes with:
result_email_parser.add_argument("--binding-no", type=int, default=0, help="Number of binding -1 votes")
result_email_parser.add_argument("--non-binding-no", type=int, default=0, help="Number of non-binding -1 votes")
# _build_result_email_context — update signature and logic:
def _build_result_email_context(version, rc_num, binding_yes, non_binding_yes, abstain, binding_no, non_binding_no, vote_thread_url=None):
    release_passed = binding_yes >= 3 and binding_yes > binding_no

The template tally line (-1: {{ no_votes }}) would need updating to show binding and non-binding -1 separately too.

🤖 Generated with Claude Code

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

Labels

area/ci Workflows, build, release scripts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants