royteeuwen opened a new pull request, #57: URL: https://github.com/apache/sling-org-apache-sling-committer-cli/pull/57
[SLING-13320](https://issues.apache.org/jira/browse/SLING-13320) ## What went wrong Step 6 of `release finalize` died with an opaque Gson error after everything irreversible had already succeeded: ``` com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 2 column 4 path $ at org.apache.sling.cli.impl.nexus.RepositoryService.getArtifacts(RepositoryService.java:250) ``` `finalize` promotes the staging repository in step 2, and `promote` passes `autoDropAfterRelease`, so Nexus drops it. Step 6 then still searched that repository for the staged POMs. Nexus answers a repository it no longer knows with an HTML error page, not JSON — verified against the live instance with Joerg's id: ``` GET /service/local/lucene/search?g=org.apache.sling&repositoryId=orgapachesling-3121 → HTTP 400, Content-Type: text/html <html> <head> ... <p>Repository to be searched does not exists!</p> ``` `getArtifacts` never checked the status and handed that page to Gson. `<html>` on line 1 parses as a lenient unquoted string; the trailing-content check then trips on ` <head>` — exactly the reported `line 2 column 4`. `UpdateLocalSiteCommand` already had a dist.apache.org fallback for precisely this situation, but it only triggered on an *empty* result, so the exception flew past it. And because `JsonSyntaxException` is unchecked, it also escaped `stepUpdateSite`'s `catch (GitAPIException | IOException)` — the "a website failure never fails finalize" guarantee in its javadoc did not hold. ## The fix - **`RepositoryService.getArtifacts`** checks the response status and reports a non-200 as an `IOException` naming the repository and the status, instead of parsing an error page as JSON. - **`UpdateLocalSiteCommand.resolveArtifactIds`** catches that and falls back to the released POMs on dist.apache.org, which answer the same question. - **`FinalizeCommand`** treats the repository as gone once it has promoted it (`stepPromoteStage` returns the repository still usable afterwards — unchanged in dry-run), so step 6 goes straight to the fallback rather than issuing a request bound to fail. - **`stepUpdateSite`** also catches `RuntimeException`, so an unchecked failure in the last step can no longer fail a finalize whose irreversible work has already succeeded. No behaviour that previously worked can change: before this, *every* non-200 was fatal — an HTML body gave `JsonSyntaxException`, an empty one `IllegalStateException` from `getAsJsonObject()` on `JsonNull`. ## Testing The mock Nexus now answers an unknown repository the way the real one does, so the regression test reproduces the reported exception exactly — with the fix reverted it fails with the same class, message and `line 2 column 4`. New tests: the status check on a dropped repository, the dist fallback when the staged POMs are unreadable, that finalize hands step 6 a null repository after promoting (and keeps it in dry-run), and that an unchecked failure in step 6 still exits OK. Full suite: 188 tests, green. Verified end to end against the live services, replaying the failed release (`orgapachesling-3121` = Apache Sling Security 1.3.2) with a real `sling-site` clone, nothing committed or pushed: ``` Could not read the POMs staged in orgapachesling-3121 (Got 400 instead of 200 when searching for the artifacts of orgapachesling-3121; ...); falling back to the released POMs on dist.apache.org. downloads.tpl already lists [org.apache.sling.security] at 1.3.2; nothing to do. ``` -- 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: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
