You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by "royteeuwen (via GitHub)" <gi...@apache.org> on 2026/08/04 20:25:00 UTC
[PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
royteeuwen opened a new pull request, #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40
Promoting a release also requires updating the website, which `finalize` did not do. `UpdateLocalSiteCommand` already edited `releases.md` and `downloads.tpl`, but it only printed a `git diff` — so nothing it produced ever landed.
`finalize` now orchestrates that command as step 6/6, reusing its editing and commit/push helpers rather than reimplementing them, following the existing `planDistRelease` / `publishToDistRelease` pattern. The checkout is cloned from gitbox so the same ASF credentials that already commit to `dist.apache.org` can push.
### Downloads entries are matched on the artifact id
Matching on the display name silently did nothing for roughly a third of releases, because the name on the downloads page regularly differs from the released component name:
| Release | `downloads.tpl` entry |
|---|---|
| Commons Mime | Commons Mime **Type Service** |
| Tracer | **Log** Tracer |
| Event **Impl** | Event |
| **Webconsole** Security Provider | **Web Console** Security Provider |
| Installer Configuration **Factory** | Installer Configuration **Support** |
| Testing OSGi Mock | Testing OSGi Mock **Core** + **JUnit 4** + **JUnit 5** (3 entries) |
The old regex also excluded digits, so `I18n`, `osgi-mock.junit4/5`, `metrics-rrd4j` and `auth.saml2` could never match, and the change count it returned was discarded by the caller — so the no-op was invisible.
Entries are now keyed on the artifact id, which is also what the site's own `renovate.json` keys on. Artifact ids come from the staged POMs, or from the released POMs in `dist/release` once the staging repository has been dropped, so this works both before and after promotion. Since a release name maps to its child modules only through the `<parent>` chain, that resolution reuses `PomParser` instead of guessing.
### Only entries on the same major version are rewritten
`dist/release` keeps several major streams published side by side while the downloads page lists a single, latest-major entry per artifact — `resourceresolver` is listed at `2.0.2` while `1.12.16` is still distributed. Nine artifacts are currently in that state (`engine`, `resourceresolver`, `servlets.resolver`, `sling-mock*`, …). Matching on the artifact id alone would therefore have turned a Resource Resolver `1.12.18` maintenance release into a **downgrade** of the `2.x` entry. A maintenance release of an older line now reports that the page tracks another major version and touches nothing. Composite versions (`4.1.0-1.86.0`, `7.0.5-2.8.2`) and the Groovy `${starterVersion}` interpolation are handled too.
An artifact with no entry at all is reported so it can be added by hand — which is what the release guide asks for when a brand new module is released.
### The news page stays manual
A new `release update-news` command adds an announcement entry. It is deliberately *not* part of `finalize`, since the release guide only asks for a news entry when a release warrants an announcement.
### Notes
- The display-name based `updateDownloads` is removed in the second commit; it had no callers left, since the `--release` path also resolves artifact ids.
- `FinalizeCommandTest` was cloning the real `sling-site` and attempting an actual push to gitbox — it "passed" only because the step warns rather than fails. That is now stubbed, so no test touches the network.
- A step 6 failure is warned about but does not fail `finalize`: everything irreversible has already succeeded by that point.
- 158 tests pass; `mvn clean verify` is green.
The matching rules were validated against the live `downloads.tpl` and the last 45 releases from `releases.md` before and after the change.
Companion docs update: apache/sling-site `docs/release-management-finalize-website`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "royteeuwen (via GitHub)" <gi...@apache.org>.
royteeuwen commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5218890569
> I think there are multiple changes in this PR, and it would be good to be able to review them independently. Maybe with https://docs.github.com/en/pull-requests/get-started/stacked-prs-quickstart ?
Done :D give it a try and let me know if you find it better :)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "royteeuwen (via GitHub)" <gi...@apache.org>.
royteeuwen commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184226010
@raducotescu as requested ;)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "royteeuwen (via GitHub)" <gi...@apache.org>.
royteeuwen commented on code in PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#discussion_r3781511107
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateDistCommand.java:
##########
@@ -390,6 +390,17 @@ private static boolean belongsToVersion(String fileName, String artifactId, Stri
return next == '.' || next == '-';
}
+ /**
+ * Returns the names of every {@code .pom} published in {@code dist/release} for {@code version}, across
+ * all artifacts. Used to resolve a release's artifact ids from the released POMs once the staging
+ * repository is gone; the caller narrows the candidates down by reading each POM's {@code <name>}.
+ */
+ static List<String> listReleasePomFileNames(String version) throws IOException {
Review Comment:
Agreed — the dist.apache.org access is now a `DistRepository` class in a new `org.apache.sling.cli.impl.dist` package (matching how `nexus`, `jira` and `pgp` are grouped). It owns the SVN listing, the previous-version selection and the publish, so both `update-dist` and the website update call it instead of reaching into a command. `UpdateDistCommand` keeps only what is its own: the staged-artifact download and the release plan.
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java:
##########
@@ -46,63 +76,289 @@
})
@CommandLine.Command(
name = UpdateLocalSiteCommand.NAME,
- description = "Updates the Sling website with the new release information, " + "based on a local checkout",
+ description = "Updates the Sling website with the new release information, based on a local checkout",
subcommands = CommandLine.HelpCommand.class)
public class UpdateLocalSiteCommand extends AbstractReleaseCommand {
static final String GROUP = "release";
static final String NAME = "update-local-site";
- private static final String GIT_CHECKOUT = "/tmp/sling-site";
+ /** System property, or {@code SLING_CLI_SITE_CHECKOUT} environment variable, overriding the checkout. */
+ static final String CHECKOUT_PROPERTY = "sling.cli.site.checkout";
+
+ /** Cloned over https from gitbox so the same ASF credentials that commit to dist.apache.org can push. */
+ static final String SITE_GIT_URL = "https://gitbox.apache.org/repos/asf/sling-site.git";
+
+ /**
+ * Where the site is checked out. Deliberately not under the shared temporary directory: the checkout is
+ * reused across runs and is committed from, so a world-writable location would let anything else on the
+ * host substitute the content that gets pushed to the website. Resolved per call so it can be redirected.
+ */
+ static String checkoutDir() {
+ String configured = System.getProperty(CHECKOUT_PROPERTY);
+ if (configured == null || configured.isBlank()) {
+ configured = System.getenv("SLING_CLI_SITE_CHECKOUT");
Review Comment:
You are right, and my reason was weak: the env var only existed because the helpers shared by `update-local-site`, `update-news` and `finalize` resolved it from global state. It is now a `--site-checkout` option (a small `SiteCheckoutOptions` mixin, like `ReusableCLIOptions`) and the path is threaded through as a parameter, so there is no hidden global state — that also removed the `System.setProperty` juggling the tests needed. The environment variable is gone entirely, not kept as a fallback: nothing else in the CLI takes an option that way, the only other env vars being the ASF credentials, which are secrets passed via `--env-file`.
##########
src/main/java/org/apache/sling/cli/impl/DateProvider.java:
##########
@@ -30,7 +31,7 @@ public class DateProvider {
private static final DateTimeFormatter jiraReleaseDate = DateTimeFormatter.ofPattern("yyyy-MM-d");
public OffsetDateTime getCurrentDate() {
- return OffsetDateTime.now();
+ return OffsetDateTime.now(ZoneId.systemDefault());
Review Comment:
It is a fix for SonarCloud `java:S8688` ("Explicitly specify the time zone by passing a ZoneId or a Clock to the .now() method"), which was flagged as an existing issue on `DateProvider` — `OffsetDateTime.now()` became `OffsetDateTime.now(ZoneId.systemDefault())`, so behaviour is unchanged. You are right that it is unrelated to this PR; I picked it up while clearing the Sonar remarks the analysis raised here. Happy to pull it into a separate PR if you would rather keep this one focused.
##########
src/test/java/org/apache/sling/cli/impl/release/UpdateNewsCommandTest.java:
##########
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+package org.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.Credentials;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.ExecutionMode;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.junit.LogCapture;
+import org.apache.sling.cli.impl.nexus.RepositoryService;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.people.Member;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.eclipse.jgit.api.AddCommand;
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.DiffCommand;
+import org.eclipse.jgit.api.FetchCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.PushCommand;
+import org.eclipse.jgit.api.ResetCommand;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.MockedConstruction;
+import org.mockito.MockedStatic;
+import picocli.CommandLine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class UpdateNewsCommandTest {
+
+ @Rule
+ public final OsgiContext osgiContext = new OsgiContext();
+
+ @Rule
+ public final LogCapture logCapture = new LogCapture(UpdateNewsCommand.class);
+
+ @Rule
+ public final TemporaryFolder checkout = new TemporaryFolder();
+
+ /** Keeps the site checkout inside the test's temporary folder rather than the real user's home. */
+ @Before
+ public void redirectCheckout() {
+ System.setProperty(
+ UpdateLocalSiteCommand.CHECKOUT_PROPERTY, checkout.getRoot().getAbsolutePath());
+ }
+
+ @After
+ public void restoreCheckout() {
+ System.clearProperty(UpdateLocalSiteCommand.CHECKOUT_PROPERTY);
+ }
+
+ private PushCommand pushCommand;
+ private CommitCommand commitCommand;
+
+ /** Stubs out JGit so nothing is cloned, opened, reset or pushed for real. */
+ private MockedStatic<Git> stubGit() {
Review Comment:
Fair, and it turned out to be more than a style point: those mocks had to be taught about `checkout()`, `setDepth()` and `setCommitter()` one breakage at a time, and kept passing while the real behaviour was broken. Both test classes now run against a real repository instead — a `SiteRepository` rule seeds a bare "upstream" plus a checkout from the existing site fixtures, and the tests clone, fetch, commit and push between them, entirely locally. That matches the rest of the suite, where `MockJira` and `MockNexus` are real local HTTP servers rather than mocked clients. It paid for itself immediately: it caught that the commit had the wrong committer identity, which the mocked version could not see. Only the network services (Nexus, dist.apache.org, Whimsy) are still mocked.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184676534
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [1 New issue](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5190945558
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [85.9% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5191058879
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [85.9% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "rombert (via GitHub)" <gi...@apache.org>.
rombert commented on code in PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#discussion_r3783580611
##########
src/main/java/org/apache/sling/cli/impl/DateProvider.java:
##########
@@ -30,7 +31,7 @@ public class DateProvider {
private static final DateTimeFormatter jiraReleaseDate = DateTimeFormatter.ofPattern("yyyy-MM-d");
public OffsetDateTime getCurrentDate() {
- return OffsetDateTime.now();
+ return OffsetDateTime.now(ZoneId.systemDefault());
Review Comment:
It's small enough to not ask you to generate a new PR but for the future please keep cleanups in a separate PR.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5218812565
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.1% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "rombert (via GitHub)" <gi...@apache.org>.
rombert commented on code in PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#discussion_r3756860314
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateDistCommand.java:
##########
@@ -390,6 +390,17 @@ private static boolean belongsToVersion(String fileName, String artifactId, Stri
return next == '.' || next == '-';
}
+ /**
+ * Returns the names of every {@code .pom} published in {@code dist/release} for {@code version}, across
+ * all artifacts. Used to resolve a release's artifact ids from the released POMs once the staging
+ * repository is gone; the caller narrows the candidates down by reading each POM's {@code <name>}.
+ */
+ static List<String> listReleasePomFileNames(String version) throws IOException {
Review Comment:
This is a smell that we need to move some code out of the `UpdateDistCommand` - reusable code should live in another class.
##########
src/test/java/org/apache/sling/cli/impl/release/UpdateNewsCommandTest.java:
##########
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+package org.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.Credentials;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.ExecutionMode;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.junit.LogCapture;
+import org.apache.sling.cli.impl.nexus.RepositoryService;
+import org.apache.sling.cli.impl.nexus.StagingRepository;
+import org.apache.sling.cli.impl.people.Member;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.apache.sling.testing.mock.osgi.junit.OsgiContext;
+import org.eclipse.jgit.api.AddCommand;
+import org.eclipse.jgit.api.CloneCommand;
+import org.eclipse.jgit.api.CommitCommand;
+import org.eclipse.jgit.api.DiffCommand;
+import org.eclipse.jgit.api.FetchCommand;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.PushCommand;
+import org.eclipse.jgit.api.ResetCommand;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.MockedConstruction;
+import org.mockito.MockedStatic;
+import picocli.CommandLine;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockConstruction;
+import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class UpdateNewsCommandTest {
+
+ @Rule
+ public final OsgiContext osgiContext = new OsgiContext();
+
+ @Rule
+ public final LogCapture logCapture = new LogCapture(UpdateNewsCommand.class);
+
+ @Rule
+ public final TemporaryFolder checkout = new TemporaryFolder();
+
+ /** Keeps the site checkout inside the test's temporary folder rather than the real user's home. */
+ @Before
+ public void redirectCheckout() {
+ System.setProperty(
+ UpdateLocalSiteCommand.CHECKOUT_PROPERTY, checkout.getRoot().getAbsolutePath());
+ }
+
+ @After
+ public void restoreCheckout() {
+ System.clearProperty(UpdateLocalSiteCommand.CHECKOUT_PROPERTY);
+ }
+
+ private PushCommand pushCommand;
+ private CommitCommand commitCommand;
+
+ /** Stubs out JGit so nothing is cloned, opened, reset or pushed for real. */
+ private MockedStatic<Git> stubGit() {
Review Comment:
There is some heavy mocking done here and also in https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40/changes#diff-bb658e24600352f9b0bf075f38bb9021316945bf351355c9a9a76a2d5da8e4c3R100 . Have you considered alternatives?
##########
src/main/java/org/apache/sling/cli/impl/DateProvider.java:
##########
@@ -30,7 +31,7 @@ public class DateProvider {
private static final DateTimeFormatter jiraReleaseDate = DateTimeFormatter.ofPattern("yyyy-MM-d");
public OffsetDateTime getCurrentDate() {
- return OffsetDateTime.now();
+ return OffsetDateTime.now(ZoneId.systemDefault());
Review Comment:
This seems unrelated, why is it needed?
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateNewsCommand.java:
##########
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+package org.apache.sling.cli.impl.release;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.nexus.RepositoryService;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+
+/**
+ * Announces a release on the Sling website's news page.
+ *
+ * <p>Deliberately <em>not</em> part of {@link FinalizeCommand}: the release management guide only asks for a
+ * news entry when a release warrants an announcement, which is a judgement call, and most module releases do
+ * not get one. Run this by hand for the releases that do.
+ */
+@Component(
Review Comment:
Cool, nice that you added this :-)
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java:
##########
@@ -46,63 +76,289 @@
})
@CommandLine.Command(
name = UpdateLocalSiteCommand.NAME,
- description = "Updates the Sling website with the new release information, " + "based on a local checkout",
+ description = "Updates the Sling website with the new release information, based on a local checkout",
subcommands = CommandLine.HelpCommand.class)
public class UpdateLocalSiteCommand extends AbstractReleaseCommand {
static final String GROUP = "release";
static final String NAME = "update-local-site";
- private static final String GIT_CHECKOUT = "/tmp/sling-site";
+ /** System property, or {@code SLING_CLI_SITE_CHECKOUT} environment variable, overriding the checkout. */
+ static final String CHECKOUT_PROPERTY = "sling.cli.site.checkout";
+
+ /** Cloned over https from gitbox so the same ASF credentials that commit to dist.apache.org can push. */
+ static final String SITE_GIT_URL = "https://gitbox.apache.org/repos/asf/sling-site.git";
+
+ /**
+ * Where the site is checked out. Deliberately not under the shared temporary directory: the checkout is
+ * reused across runs and is committed from, so a world-writable location would let anything else on the
+ * host substitute the content that gets pushed to the website. Resolved per call so it can be redirected.
+ */
+ static String checkoutDir() {
+ String configured = System.getProperty(CHECKOUT_PROPERTY);
+ if (configured == null || configured.isBlank()) {
+ configured = System.getenv("SLING_CLI_SITE_CHECKOUT");
Review Comment:
Why an env var and not a regular CLI argument?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "royteeuwen (via GitHub)" <gi...@apache.org>.
royteeuwen commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5290131647
Thanks @rombert — all four points addressed in `819df9c`:
| Comment | Change |
|---|---|
| reusable code out of `UpdateDistCommand` | new `DistRepository` in `org.apache.sling.cli.impl.dist`; commands call it instead of each other |
| env var vs CLI argument | `--site-checkout` option, threaded as a parameter; env var removed entirely |
| unrelated `DateProvider` change | it is a Sonar `java:S8688` fix (explicit time zone); explained inline, happy to split it out |
| heavy mocking in the tests | both site test classes now run against a real repository via a `SiteRepository` rule |
The mocking one was worth doing: the real-repository tests immediately caught that the commit was recording the wrong committer identity, which the mocked version could not see.
Note the stack has grown a layer, since the review feedback sits below the shallow-clone work: #47 (merged) → #40 → #48.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "royteeuwen (via GitHub)" <gi...@apache.org>.
royteeuwen merged PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5185020313
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.1% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184320203
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate failed**
Failed conditions
 [59.3% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list) (required ≥ 80%)
 [D Security Rating on New Code](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) (required ≥ A)
<!-- sqra:qg_revision=506aaa532656ee31d3ea825b49153cf862d6aaf3bd53b7ed40ce65249594d1a9 -->
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
##
 Catch issues before they fail your Quality Gate with our IDE extension  [SonarQube for IDE](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184352957
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate failed**
Failed conditions
 [59.3% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list) (required ≥ 80%)
 [D Security Rating on New Code](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) (required ≥ A)
<!-- sqra:qg_revision=506aaa532656ee31d3ea825b49153cf862d6aaf3bd53b7ed40ce65249594d1a9 -->
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
##
 Catch issues before they fail your Quality Gate with our IDE extension  [SonarQube for IDE](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5219001295
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.1% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "github-advanced-security[bot] (via GitHub)" <gi...@apache.org>.
github-advanced-security[bot] commented on code in PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#discussion_r3715942916
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateLocalSiteCommand.java:
##########
@@ -46,62 +71,238 @@
})
@CommandLine.Command(
name = UpdateLocalSiteCommand.NAME,
- description = "Updates the Sling website with the new release information, " + "based on a local checkout",
+ description = "Updates the Sling website with the new release information, based on a local checkout",
subcommands = CommandLine.HelpCommand.class)
public class UpdateLocalSiteCommand extends AbstractReleaseCommand {
static final String GROUP = "release";
static final String NAME = "update-local-site";
- private static final String GIT_CHECKOUT = "/tmp/sling-site";
+ static final String GIT_CHECKOUT = "/tmp/sling-site";
+
+ /** Cloned over https from gitbox so the same ASF credentials that commit to dist.apache.org can push. */
+ static final String SITE_GIT_URL = "https://gitbox.apache.org/repos/asf/sling-site.git";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UpdateLocalSiteCommand.class);
@Reference
private RepositoryService repositoryService;
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ @Reference
+ private CredentialsService credentialsService;
+
+ @Reference
+ private MembersFinder membersFinder;
+
+ @CommandLine.Mixin
+ private ReusableCLIOptions reusableCLIOptions;
@Override
public Integer call() {
try {
- ensureRepo();
- try (Git git = Git.open(new File(GIT_CHECKOUT))) {
+ Set<Release> releases = resolveReleases(repositoryService);
+ if (releases.isEmpty()) {
+ LOGGER.error("Provide either --repository or --release.");
+ return CommandLine.ExitCode.USAGE;
+ }
+ StagingRepository repository = repositoryId != null ? repositoryService.find(repositoryId) : null;
- Set<Release> releases = resolveReleases(repositoryService);
- if (releases.isEmpty()) {
- logger.error("Provide either --repository or --release.");
- return CommandLine.ExitCode.USAGE;
- }
+ SiteUpdate update = updateLocalSite(repositoryService, repository, releases);
+ applySiteUpdate(
+ update,
+ reusableCLIOptions.executionMode,
+ credentialsService.getAsfCredentials(),
+ membersFinder.getCurrentMember());
+ } catch (GitAPIException | IOException e) {
+ LOGGER.warn("Failed executing command", e);
+ return CommandLine.ExitCode.SOFTWARE;
+ }
+ return CommandLine.ExitCode.OK;
+ }
- JBakeContentUpdater updater = new JBakeContentUpdater();
+ /**
+ * The result of editing the site checkout.
+ *
+ * @param hasChanges whether the checkout has anything to commit
+ * @param releaseNames the releases the edit covered, for the commit message
+ * @param downloadsNotListed releases with no downloads-page entry at all, which a human must add;
+ * releases skipped because the page tracks another major version are not
+ * listed here, since for those there is legitimately nothing to do
+ */
+ record SiteUpdate(boolean hasChanges, String releaseNames, List<String> downloadsNotListed) {}
- Path templatePath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "templates", "downloads.tpl");
- Path releasesPath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "content", "releases.md");
- LocalDateTime now = LocalDateTime.now();
- for (Release release : releases) {
- updater.updateDownloads(templatePath, release.getComponent(), release.getVersion());
- updater.updateReleases(releasesPath, release.getComponent(), release.getVersion(), now);
- }
+ /**
+ * Clones or refreshes the site checkout and applies the release information to {@code releases.md} and
+ * {@code downloads.tpl}. Nothing is committed; shared with {@link FinalizeCommand} so the editing flow
+ * is not duplicated there.
+ */
+ static SiteUpdate updateLocalSite(
+ RepositoryService repositoryService, StagingRepository repository, Set<Release> releases)
+ throws GitAPIException, IOException {
+
+ ensureRepo();
+ JBakeContentUpdater updater = new JBakeContentUpdater();
+ Path templatePath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "templates", "downloads.tpl");
+ Path releasesPath = Paths.get(GIT_CHECKOUT, "src", "main", "jbake", "content", "releases.md");
+
+ List<String> notListed = new ArrayList<>();
+ LocalDateTime now = LocalDateTime.now();
+
+ for (Release release : releases) {
+ updater.updateReleases(releasesPath, release.getComponent(), release.getVersion(), now);
+ updateDownloadsFor(repositoryService, repository, release, updater, templatePath, notListed);
+ }
+
+ String releaseNames =
+ releases.stream().map(Release::getFullName).sorted().collect(Collectors.joining(", "));
+
+ try (Git git = Git.open(new File(GIT_CHECKOUT))) {
+ git.diff().setOutputStream(System.out).call();
+ boolean hasChanges = !git.status().call().isClean();
+ return new SiteUpdate(hasChanges, releaseNames, notListed);
+ }
+ }
+
+ /** Updates every downloads-page entry belonging to {@code release}, recording why nothing changed. */
+ private static void updateDownloadsFor(
+ RepositoryService repositoryService,
+ StagingRepository repository,
+ Release release,
+ JBakeContentUpdater updater,
+ Path templatePath,
+ List<String> notListed)
+ throws IOException {
- git.diff().setOutputStream(System.out).call();
+ Set<String> artifactIds = resolveArtifactIds(repositoryService, repository, release);
+ if (artifactIds.isEmpty()) {
+ LOGGER.warn(
+ "Could not determine the artifact id(s) for {}; downloads.tpl not updated for it.",
+ release.getFullName());
+ notListed.add(release.getFullName());
+ return;
+ }
+
+ int updated = 0;
+ int otherMajor = 0;
+ for (String artifactId : artifactIds) {
+ JBakeContentUpdater.DownloadsUpdate result =
+ updater.updateDownloadsByArtifactId(templatePath, artifactId, release.getVersion());
+ updated += result.updated();
+ otherMajor += result.skippedOtherMajor();
+ }
+
+ if (updated > 0) {
+ LOGGER.info("Updated {} downloads.tpl entry/entries for {}", updated, release.getFullName());
+ } else if (otherMajor > 0) {
+ // dist.apache.org keeps several major streams published while the downloads page lists only the
+ // latest; a maintenance release of an older line therefore has nothing to update here
+ LOGGER.info(
+ "downloads.tpl lists {} only for another major version; leaving it unchanged for {}.",
+ artifactIds,
+ release.getFullName());
+ } else {
+ LOGGER.warn(
+ "downloads.tpl has no entry for {} ({}); it may need to be added by hand.",
+ release.getFullName(),
+ artifactIds);
+ notListed.add(release.getFullName());
+ }
+ }
+
+ /**
+ * Resolves the artifact ids of {@code release}, preferring the staged POMs and falling back to the
+ * released POMs on dist.apache.org so a run after promotion still works.
+ */
+ private static Set<String> resolveArtifactIds(
+ RepositoryService repositoryService, StagingRepository repository, Release release) throws IOException {
+ if (repository != null) {
+ Set<String> staged = repositoryService.getArtifactIds(repository, release);
+ if (!staged.isEmpty()) {
+ return new TreeSet<>(staged);
}
- } catch (GitAPIException | IOException e) {
- logger.warn("Failed executing command", e);
- return CommandLine.ExitCode.SOFTWARE;
}
- return CommandLine.ExitCode.OK;
+ List<String> candidates = UpdateDistCommand.listReleasePomFileNames(release.getVersion());
+ if (candidates.isEmpty()) {
+ return Set.of();
+ }
+ return new TreeSet<>(
+ repositoryService.getArtifactIdsFromPomUrls(UpdateDistCommand.DIST_RELEASE_URL, candidates, release));
+ }
+
+ /** Commits and pushes the site update, honouring the execution mode. */
+ static void applySiteUpdate(SiteUpdate update, ExecutionMode mode, Credentials credentials, Member author)
+ throws GitAPIException, IOException {
+
+ if (!update.hasChanges()) {
+ LOGGER.info("The Sling website is already up to date; nothing to commit.");
+ return;
+ }
+ commitAndPushSiteChanges(
+ "Released " + update.releaseNames(),
+ "Commit the website changes above and push to sling-site?",
+ mode,
+ credentials,
+ author);
+ }
+
+ /**
+ * Commits everything staged under the site content directory and pushes it, honouring the execution
+ * mode. Shared by every command that edits the site checkout.
+ */
+ static void commitAndPushSiteChanges(
+ String message, String confirmQuestion, ExecutionMode mode, Credentials credentials, Member author)
+ throws GitAPIException, IOException {
+ switch (mode) {
+ case DRY_RUN:
+ LOGGER.info(
+ "Would commit the changes above to {} with message \"{}\" and push.", SITE_GIT_URL, message);
+ break;
+ case INTERACTIVE:
+ if (InputOption.YES.equals(UserInput.yesNo(confirmQuestion, InputOption.YES))) {
+ commitAndPush(message, credentials, author);
+ } else {
+ LOGGER.info("Aborted; the changes are left in {}.", GIT_CHECKOUT);
+ }
+ break;
+ case AUTO:
+ commitAndPush(message, credentials, author);
+ break;
+ }
+ }
+
+ private static void commitAndPush(String message, Credentials credentials, Member author)
+ throws GitAPIException, IOException {
+ try (Git git = Git.open(new File(GIT_CHECKOUT))) {
Review Comment:
## SonarCloud / Temporary files should not be created in publicly writable directories
<!--SONAR_ISSUE_KEY:AZ_Odx_wFzwiTi2kGWiD-->Make sure publicly writable directories are used safely here. <p>See more on <a href="https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&issues=AZ_Odx_wFzwiTi2kGWiD&open=AZ_Odx_wFzwiTi2kGWiD&pullRequest=40">SonarQube Cloud</a></p>
[Show more details](https://github.com/apache/sling-org-apache-sling-committer-cli/security/code-scanning/4)
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateNewsCommand.java:
##########
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+package org.apache.sling.cli.impl.release;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.nexus.RepositoryService;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+
+/**
+ * Announces a release on the Sling website's news page.
+ *
+ * <p>Deliberately <em>not</em> part of {@link FinalizeCommand}: the release management guide only asks for a
+ * news entry when a release warrants an announcement, which is a judgement call, and most module releases do
+ * not get one. Run this by hand for the releases that do.
+ */
+@Component(
+ service = Command.class,
+ property = {
+ Command.PROPERTY_NAME_COMMAND_GROUP + "=" + UpdateNewsCommand.GROUP,
+ Command.PROPERTY_NAME_COMMAND_NAME + "=" + UpdateNewsCommand.NAME
+ })
+@CommandLine.Command(
+ name = UpdateNewsCommand.NAME,
+ description = "Announces a release on the Sling website's news page. Run only for releases worth announcing;"
+ + " this is not part of finalize.",
+ subcommands = CommandLine.HelpCommand.class)
+public class UpdateNewsCommand extends AbstractReleaseCommand {
+
+ static final String GROUP = "release";
+ static final String NAME = "update-news";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UpdateNewsCommand.class);
+
+ @CommandLine.Option(
+ names = {"--link"},
+ description = "Optional page the announcement should link to, e.g."
+ + " /news/sling-14-released.html or /documentation/bundles/sling-pipes.html")
+ private String link;
+
+ @CommandLine.Mixin
+ private ReusableCLIOptions reusableCLIOptions;
+
+ @Reference
+ private RepositoryService repositoryService;
+
+ @Reference
+ private CredentialsService credentialsService;
+
+ @Reference
+ private MembersFinder membersFinder;
+
+ @Override
+ public Integer call() {
+ try {
+ Set<Release> releases = resolveReleases(repositoryService);
+ if (releases.isEmpty()) {
+ LOGGER.error("Provide either --repository or --release.");
+ return CommandLine.ExitCode.USAGE;
+ }
+
+ UpdateLocalSiteCommand.ensureRepo();
+ Path newsPath =
+ Paths.get(UpdateLocalSiteCommand.GIT_CHECKOUT, "src", "main", "jbake", "content", "news.md");
Review Comment:
## SonarCloud / Temporary files should not be created in publicly writable directories
<!--SONAR_ISSUE_KEY:AZ_Odx_4FzwiTi2kGWiE-->Make sure publicly writable directories are used safely here. <p>See more on <a href="https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&issues=AZ_Odx_4FzwiTi2kGWiE&open=AZ_Odx_4FzwiTi2kGWiE&pullRequest=40">SonarQube Cloud</a></p>
[Show more details](https://github.com/apache/sling-org-apache-sling-committer-cli/security/code-scanning/2)
##########
src/main/java/org/apache/sling/cli/impl/release/UpdateNewsCommand.java:
##########
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ */
+package org.apache.sling.cli.impl.release;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalDateTime;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.sling.cli.impl.Command;
+import org.apache.sling.cli.impl.CredentialsService;
+import org.apache.sling.cli.impl.jbake.JBakeContentUpdater;
+import org.apache.sling.cli.impl.nexus.RepositoryService;
+import org.apache.sling.cli.impl.people.MembersFinder;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+
+/**
+ * Announces a release on the Sling website's news page.
+ *
+ * <p>Deliberately <em>not</em> part of {@link FinalizeCommand}: the release management guide only asks for a
+ * news entry when a release warrants an announcement, which is a judgement call, and most module releases do
+ * not get one. Run this by hand for the releases that do.
+ */
+@Component(
+ service = Command.class,
+ property = {
+ Command.PROPERTY_NAME_COMMAND_GROUP + "=" + UpdateNewsCommand.GROUP,
+ Command.PROPERTY_NAME_COMMAND_NAME + "=" + UpdateNewsCommand.NAME
+ })
+@CommandLine.Command(
+ name = UpdateNewsCommand.NAME,
+ description = "Announces a release on the Sling website's news page. Run only for releases worth announcing;"
+ + " this is not part of finalize.",
+ subcommands = CommandLine.HelpCommand.class)
+public class UpdateNewsCommand extends AbstractReleaseCommand {
+
+ static final String GROUP = "release";
+ static final String NAME = "update-news";
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UpdateNewsCommand.class);
+
+ @CommandLine.Option(
+ names = {"--link"},
+ description = "Optional page the announcement should link to, e.g."
+ + " /news/sling-14-released.html or /documentation/bundles/sling-pipes.html")
+ private String link;
+
+ @CommandLine.Mixin
+ private ReusableCLIOptions reusableCLIOptions;
+
+ @Reference
+ private RepositoryService repositoryService;
+
+ @Reference
+ private CredentialsService credentialsService;
+
+ @Reference
+ private MembersFinder membersFinder;
+
+ @Override
+ public Integer call() {
+ try {
+ Set<Release> releases = resolveReleases(repositoryService);
+ if (releases.isEmpty()) {
+ LOGGER.error("Provide either --repository or --release.");
+ return CommandLine.ExitCode.USAGE;
+ }
+
+ UpdateLocalSiteCommand.ensureRepo();
+ Path newsPath =
+ Paths.get(UpdateLocalSiteCommand.GIT_CHECKOUT, "src", "main", "jbake", "content", "news.md");
+
+ JBakeContentUpdater updater = new JBakeContentUpdater();
+ LocalDateTime now = LocalDateTime.now();
+ boolean changed = false;
+ for (Release release : releases) {
+ if (updater.updateNews(newsPath, release.getFullName(), link, now)) {
+ LOGGER.info("Added a news entry for {}", release.getFullName());
+ changed = true;
+ } else {
+ LOGGER.info("The news page already announces {}; skipping.", release.getFullName());
+ }
+ }
+
+ if (!changed) {
+ LOGGER.info("Nothing to commit.");
+ return CommandLine.ExitCode.OK;
+ }
+
+ try (Git git = Git.open(new File(UpdateLocalSiteCommand.GIT_CHECKOUT))) {
Review Comment:
## SonarCloud / Temporary files should not be created in publicly writable directories
<!--SONAR_ISSUE_KEY:AZ_Odx_4FzwiTi2kGWiG-->Make sure publicly writable directories are used safely here. <p>See more on <a href="https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&issues=AZ_Odx_4FzwiTi2kGWiG&open=AZ_Odx_4FzwiTi2kGWiG&pullRequest=40">SonarQube Cloud</a></p>
[Show more details](https://github.com/apache/sling-org-apache-sling-committer-cli/security/code-scanning/3)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184254900
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate failed**
Failed conditions
 [59.3% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list) (required ≥ 80%)
 [D Security Rating on New Code](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) (required ≥ A)
<!-- sqra:qg_revision=506aaa532656ee31d3ea825b49153cf862d6aaf3bd53b7ed40ce65249594d1a9 -->
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
##
 Catch issues before they fail your Quality Gate with our IDE extension  [SonarQube for IDE](https://www.sonarsource.com/products/sonarlint/features/connected-mode/?referrer=pull-request)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184401975
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate failed**
Failed conditions
 [57.4% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list) (required ≥ 80%)
<!-- sqra:qg_revision=57dfdd1dae4b4a949920b0d8613335b3b39e1f6fbe336de2c84804c229b90150 -->
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5184558418
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate failed**
Failed conditions
 [57.6% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list) (required ≥ 80%)
<!-- sqra:qg_revision=9452112da2310477d3e91b76ec453576c55cb4991fcb77bfcc00885673bc0803 -->
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5218989842
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.1% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] SLING-13253 - finalize: update the Sling website as the last step [sling-org-apache-sling-committer-cli]
Posted by "sonarqubecloud[bot] (via GitHub)" <gi...@apache.org>.
sonarqubecloud[bot] commented on PR #40:
URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/40#issuecomment-5290152619
## [](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40) **Quality Gate passed**
Issues
 [0 New issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [0 Accepted issues](https://sonarcloud.io/project/issues?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=ACCEPTED)
Measures
 [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)
 [86.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_coverage&view=list)
 [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40&metric=new_duplicated_lines_density&view=list)
<!-- sqra-placement-anchor -->
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=apache_sling-org-apache-sling-committer-cli&pullRequest=40)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: commits-unsubscribe@sling.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org