This is an automated email from the ASF dual-hosted git repository. royteeuwen pushed a commit to branch feature/SLING-13253-tally-votes in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-committer-cli.git
commit f88958a5364cf0f1431e0ad772b0935aef8d9ee7 Author: Roy Teeuwen <[email protected]> AuthorDate: Sat Jul 4 15:04:55 2026 +0200 SLING-13253 - release tally-votes: PMC-aware result email Makes 'release tally-votes' aware of PMC membership when counting binding vs non-binding votes and generating the result email. Part of splitting PR #28 into per-command changes. --- .../sling/cli/impl/release/TallyVotesCommand.java | 18 ++++++++ src/main/resources/templates/tally-votes.email | 3 +- .../cli/impl/release/TallyVotesCommandTest.java | 50 +++++++++++++++++++++- 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java index 3daca17..a621168 100644 --- a/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java +++ b/src/main/java/org/apache/sling/cli/impl/release/TallyVotesCommand.java @@ -139,6 +139,7 @@ public class TallyVotesCommand implements Command { .replace("##DATE##", dateProvider.getCurrentDateForEmailHeader()) .replace("##RELEASE_NAME##", releaseFullName) .replace("##BINDING_VOTERS##", String.join(", ", bindingVoters)) + .replace("##CLOSING_ACTION##", closingAction(releaseFullName, currentMember.isPMCMember())) .replace( "##USER_NAME##", membersFinder.getCurrentMember().getName()); @@ -193,6 +194,23 @@ public class TallyVotesCommand implements Command { return CommandLine.ExitCode.OK; } + /** + * Builds the closing paragraph of the result email. PMC members copy the release to the dist + * directory themselves; non-PMC release managers can only promote to Maven Central and must ask + * a PMC member to handle the dist upload (which is restricted to PMC members). PMC membership is + * derived from the current user, so no flag is needed. + */ + private String closingAction(String releaseFullName, boolean isPmcMember) { + if (isPmcMember) { + return "I will copy this release to the Sling dist directory and\n" + + "promote the artifacts to the central Maven repository."; + } + return "I will promote the artifacts to the central Maven repository.\n\n" + + "As I am not a PMC member, I cannot copy the release to the dist directory myself.\n\n" + + "ACTION NEEDED: can a PMC member please copy " + releaseFullName + + " to the Sling dist directory (https://dist.apache.org/repos/dist/release/sling/)?"; + } + // TODO - better detection of '+1' votes private boolean isPositiveVote(Email e) { return cleanup(e.getBody()).contains("+1"); diff --git a/src/main/resources/templates/tally-votes.email b/src/main/resources/templates/tally-votes.email index af68d64..2b08093 100644 --- a/src/main/resources/templates/tally-votes.email +++ b/src/main/resources/templates/tally-votes.email @@ -11,8 +11,7 @@ The vote has passed with the following result: +1 (binding): ##BINDING_VOTERS## +1 (non-binding): ##NON_BINDING_VOTERS## -I will copy this release to the Sling dist directory and -promote the artifacts to the central Maven repository. +##CLOSING_ACTION## Regards, ##USER_NAME## diff --git a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java index dcd28a2..7ab433c 100644 --- a/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java +++ b/src/test/java/org/apache/sling/cli/impl/release/TallyVotesCommandTest.java @@ -110,6 +110,49 @@ public class TallyVotesCommandTest { + "John Doe\n")); } + @Test + public void testDryRunNonPmc() throws Exception { + // Daniel (a non-PMC committer) is the release manager running tally-votes; PMC status is + // auto-detected from the current user, so the result email asks a PMC member to do the dist + // upload. + Mailer mailer = mock(Mailer.class); + List<Email> thread = new ArrayList<>() { + { + add(mockEmail("[email protected]", "Daniel")); + add(mockEmail("[email protected]", "Alice")); + add(mockEmail("[email protected]", "Bob")); + add(mockEmail("[email protected]", "Charlie")); + } + }; + prepareExecution(mailer, thread, "daniel"); + Command command = createCommand(123, ExecutionMode.DRY_RUN); + assertEquals(CommandLine.ExitCode.OK, (int) command.call()); + verifyNoInteractions(mailer); + assertTrue(logCapture.containsMessage(""" + From: Daniel <[email protected]> + To: "Sling Developers List" <[email protected]> + Reply-To: "Sling Developers List" <[email protected]> + Date: Thu, 1 Jan 1970 01:00:00 +0100 + Subject: [RESULT] [VOTE] Release Apache Sling CLI Test 1.0.0 + + Hi, + + The vote has passed with the following result: + + +1 (binding): Alice, Bob, Charlie + +1 (non-binding): none + + I will promote the artifacts to the central Maven repository. + + As I am not a PMC member, I cannot copy the release to the dist directory myself. + + ACTION NEEDED: can a PMC member please copy Apache Sling CLI Test 1.0.0 to the Sling dist directory (https://dist.apache.org/repos/dist/release/sling/)? + + Regards, + Daniel + """)); + } + @Test public void testDryRunNotEnoughBindingVotes() throws Exception { Mailer mailer = mock(Mailer.class); @@ -184,8 +227,13 @@ public class TallyVotesCommandTest { } private void prepareExecution(Mailer mailer, List<Email> thread) throws IOException, IllegalAccessException { + prepareExecution(mailer, thread, "johndoe"); + } + + private void prepareExecution(Mailer mailer, List<Email> thread, String currentUsername) + throws IOException, IllegalAccessException { CredentialsService credentialsService = mock(CredentialsService.class); - when(credentialsService.getAsfCredentials()).thenReturn(new Credentials("johndoe", "secret")); + when(credentialsService.getAsfCredentials()).thenReturn(new Credentials(currentUsername, "secret")); MembersFinder membersFinder = spy(new MembersFinder()); Set<Member> members = new HashSet<>() {
