This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 32ed0575fac77640a241f535e079bc4527615ab0 Author: Nick <[email protected]> AuthorDate: Tue Oct 27 10:25:04 2026 -0600 SOLR-18119: Generate changes HTML only for releases (#5180) Changes.html is now generated by the release tooling instead of the gradle documentation build, so local builds no longer render it. (cherry picked from commit 8b7383e7acc1855a45de746fbc67ea14019c7ba3) --- build.gradle | 1 - ...LR-18119-generate-changes-html-for-releases.yml | 8 ++ dev-docs/how-to-contribute.adoc | 1 - dev-docs/solr-source-code.adoc | 2 - dev-tools/scripts/buildAndPushRelease.py | 7 ++ .../scripts}/changes-to-html/ChangesFancyStyle.css | 0 .../changes-to-html/ChangesFixedWidthStyle.css | 0 .../changes-to-html/ChangesSimpleStyle.css | 0 .../scripts}/changes2html.py | 79 ++++++++++---- dev-tools/scripts/releaseWizard.yaml | 2 +- gradle/documentation/changes-to-html.gradle | 117 --------------------- gradle/documentation/documentation.gradle | 3 +- solr/distribution/build.gradle | 9 +- solr/distribution/gradle.lockfile | 2 +- solr/documentation/gradle.lockfile | 2 +- solr/solr-ref-guide/build.gradle | 2 + 16 files changed, 82 insertions(+), 153 deletions(-) diff --git a/build.gradle b/build.gradle index 6bd4467abab..a402db4213a 100644 --- a/build.gradle +++ b/build.gradle @@ -209,7 +209,6 @@ apply from: file('gradle/lucene-dev/lucene-dev-repo-composite.gradle') apply from: file('gradle/documentation/pull-lucene-javadocs.gradle') apply from: file('gradle/documentation/documentation.gradle') -apply from: file('gradle/documentation/changes-to-html.gradle') apply from: file('gradle/documentation/markdown.gradle') apply from: file('gradle/documentation/render-javadoc.gradle') diff --git a/changelog/unreleased/SOLR-18119-generate-changes-html-for-releases.yml b/changelog/unreleased/SOLR-18119-generate-changes-html-for-releases.yml new file mode 100644 index 00000000000..34bf2afc2a6 --- /dev/null +++ b/changelog/unreleased/SOLR-18119-generate-changes-html-for-releases.yml @@ -0,0 +1,8 @@ +title: > + Changes.html is generated by the release tooling instead of the documentation build, so local builds no longer render it. +type: other +authors: + - name: Nick Shanin +links: + - name: SOLR-18119 + url: https://issues.apache.org/jira/browse/SOLR-18119 diff --git a/dev-docs/how-to-contribute.adoc b/dev-docs/how-to-contribute.adoc index 6e0ebfc9d53..8e6772dcb76 100644 --- a/dev-docs/how-to-contribute.adoc +++ b/dev-docs/how-to-contribute.adoc @@ -33,7 +33,6 @@ In order to make a new contribution to Solr you will use the fork you have creat 1. Create a new Jira issue in the Solr project: https://issues.apache.org/jira/projects/SOLR/issues 2. Create a new branch in your Solr fork to provide a PR for your contribution on the newly created issue. Make any necessary changes for the given bug/feature in that branch. You can use additional information in these dev-docs to build and test your code as well as ensure it passes code quality checks. 3. Once you are satisfied with your changes, get your branch ready for a PR by running `./gradlew tidy updateLicenses check -x test`. This will format your source code, update licenses of any dependency version changes and run all pre-commit tests. Commit the changes. -* Note: the `check` command requires `python3` to be present on your `PATH` to validate documentation. 4. Open a PR of your branch against the `main` branch of the apache/solr repository. When you open a PR on your fork, this should be the default option. * The title of your PR should include the Solr Jira issue that you opened, i.e. `SOLR-12345: New feature`. * The PR description will automatically populate with a pre-set template that you will need to fill out. diff --git a/dev-docs/solr-source-code.adoc b/dev-docs/solr-source-code.adoc index fd22d4e0c7d..3301dbc7503 100644 --- a/dev-docs/solr-source-code.adoc +++ b/dev-docs/solr-source-code.adoc @@ -34,8 +34,6 @@ To build the documentation, type `./gradlew -p solr documentation`. `./gradlew check` will assemble Solr and run all validation tasks unit tests. -NOTE: the `check` command requires `python3` to be present on your `PATH` to validate documentation. - To build the final Solr artifacts run `./gradlew assemble`. Lastly, there is developer oriented documentation in `./dev-docs/README.adoc` that you may find useful in working with Solr. diff --git a/dev-tools/scripts/buildAndPushRelease.py b/dev-tools/scripts/buildAndPushRelease.py index 44416eed723..dc91a3d0e87 100755 --- a/dev-tools/scripts/buildAndPushRelease.py +++ b/dev-tools/scripts/buildAndPushRelease.py @@ -26,8 +26,10 @@ from subprocess import TimeoutExpired import textwrap import urllib.request, urllib.error, urllib.parse import xml.etree.ElementTree as ET +from pathlib import Path import scriptutil +from changes2html import write_changes_html LOG = '/tmp/release.log' dev_mode = False @@ -120,6 +122,11 @@ def prepare(root, version, pause_before_sign, mf_username, gpg_key_id, gpg_passw if pause_before_sign: input("Tests complete! Please press ENTER to proceed to assembleRelease: ") + changes_html_dir = Path(root) / 'solr' / 'documentation' / 'build' / 'site' / 'changes' + print(' Generate Changes.html for the release') + changes_html_file = write_changes_html(Path(root) / 'CHANGELOG.md', changes_html_dir) + print(' Generated %s' % changes_html_file) + print(' prepare-release') cmd = './gradlew --no-daemon assembleRelease' \ ' -Dversion.release=%s' % version diff --git a/gradle/documentation/changes-to-html/ChangesFancyStyle.css b/dev-tools/scripts/changes-to-html/ChangesFancyStyle.css similarity index 100% rename from gradle/documentation/changes-to-html/ChangesFancyStyle.css rename to dev-tools/scripts/changes-to-html/ChangesFancyStyle.css diff --git a/gradle/documentation/changes-to-html/ChangesFixedWidthStyle.css b/dev-tools/scripts/changes-to-html/ChangesFixedWidthStyle.css similarity index 100% rename from gradle/documentation/changes-to-html/ChangesFixedWidthStyle.css rename to dev-tools/scripts/changes-to-html/ChangesFixedWidthStyle.css diff --git a/gradle/documentation/changes-to-html/ChangesSimpleStyle.css b/dev-tools/scripts/changes-to-html/ChangesSimpleStyle.css similarity index 100% rename from gradle/documentation/changes-to-html/ChangesSimpleStyle.css rename to dev-tools/scripts/changes-to-html/ChangesSimpleStyle.css diff --git a/gradle/documentation/changes-to-html/changes2html.py b/dev-tools/scripts/changes2html.py similarity index 94% rename from gradle/documentation/changes-to-html/changes2html.py rename to dev-tools/scripts/changes2html.py index 287c3205145..003a00d1dfc 100755 --- a/gradle/documentation/changes-to-html/changes2html.py +++ b/dev-tools/scripts/changes2html.py @@ -18,16 +18,26 @@ # """ -Transforms Solr's CHANGELOG.md into Changes.html +Transforms Solr's CHANGELOG.md into Changes.html. -Input is from CHANGELOG.md, output is to STDOUT +By default, output is written to STDOUT. Release tooling can pass --output-dir +to write Changes.html and its stylesheets to a directory for packaging. """ -import sys +import argparse import re +import shutil +import sys from pathlib import Path +STYLESHEETS = ( + 'ChangesFancyStyle.css', + 'ChangesSimpleStyle.css', + 'ChangesFixedWidthStyle.css', +) + + class ChangelogParser: """Parse CHANGELOG.md generated by logchange""" @@ -776,36 +786,59 @@ class HTMLGenerator: return ''.join(html_parts) -def main(): - """Main entry point""" - if len(sys.argv) < 2: - # Try to read from CHANGELOG.md in current directory - changelog_file = Path('CHANGELOG.md') - if not changelog_file.exists(): - print("Usage: changes2html.py <changelog-file>", file=sys.stderr) - sys.exit(1) - else: - changelog_file = Path(sys.argv[1]) - +def render_changes_html(changelog_file): + """Render a changelog file and return its HTML.""" + changelog_file = Path(changelog_file) if not changelog_file.exists(): - print(f"Error: {changelog_file} not found", file=sys.stderr) - sys.exit(1) + raise FileNotFoundError(changelog_file) - # Read changelog with open(changelog_file, 'r', encoding='utf-8') as f: content = f.read() - # Parse parser = ChangelogParser() parser.parse(content) - # Generate HTML generator = HTMLGenerator() - html = generator.generate(parser.releases, parser.title, parser.preamble) + return generator.generate(parser.releases, parser.title, parser.preamble) + - # Output - sys.stdout.reconfigure(encoding='utf-8') #UTF-8 encoding for Windows compatibility - print(html) +def write_changes_html(changelog_file, output_dir): + """Write Changes.html and its stylesheets into output_dir.""" + output_dir = Path(output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + + html = render_changes_html(changelog_file) + output_file = output_dir / 'Changes.html' + with output_file.open('w', encoding='utf-8') as f: + print(html, file=f) + + stylesheet_dir = Path(__file__).parent / 'changes-to-html' + for stylesheet in STYLESHEETS: + shutil.copyfile(stylesheet_dir / stylesheet, output_dir / stylesheet) + + return output_file + + +def main(): + """Main entry point""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('changelog_file', nargs='?', default='CHANGELOG.md') + parser.add_argument( + '--output-dir', + type=Path, + help='write Changes.html and stylesheets to this directory instead of STDOUT', + ) + args = parser.parse_args() + + try: + if args.output_dir: + write_changes_html(args.changelog_file, args.output_dir) + else: + html = render_changes_html(args.changelog_file) + sys.stdout.reconfigure(encoding='utf-8') #UTF-8 encoding for Windows compatibility + print(html) + except FileNotFoundError as error: + parser.error(f"{error.args[0]} not found") if __name__ == '__main__': diff --git a/dev-tools/scripts/releaseWizard.yaml b/dev-tools/scripts/releaseWizard.yaml index 27437a82882..504f8478eb9 100644 --- a/dev-tools/scripts/releaseWizard.yaml +++ b/dev-tools/scripts/releaseWizard.yaml @@ -778,7 +778,7 @@ groups: cmd: git diff --stat changelog CHANGELOG.md stdout: true - !Command - cmd: "{{ gradle_cmd }} :solr:documentation:changesToHtml" + cmd: python3 -u dev-tools/scripts/changes2html.py CHANGELOG.md --output-dir solr/documentation/build/site/changes logfile: changes-to-html.log tee: true - !Command diff --git a/gradle/documentation/changes-to-html.gradle b/gradle/documentation/changes-to-html.gradle deleted file mode 100644 index 46635ca0dc5..00000000000 --- a/gradle/documentation/changes-to-html.gradle +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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. - */ - -import org.gradle.process.ExecOperations -import javax.inject.Inject - -def resources = scriptResources(buildscript) - -configure(project(':solr:documentation')) { - task changesToHtml(type: ChangesToHtmlTask) { - siteDir = resources - script = file("${resources}/changes2html.py") - } - - // Make the rendered HTML of changes available as a separate - // artifact for the distribution. - configurations { - changesHtml - } - - artifacts { - changesHtml changesToHtml.targetDir, { - builtBy changesToHtml - } - } -} - -// compile CHANGELOG.md into an html file -abstract class ChangesToHtmlTask extends DefaultTask { - - @Inject - abstract ExecOperations getExecOperations() - - @Internal - Project productProject = project.parent - - @Internal - String productName = productProject.name - - @InputFile - File changesFile = project.rootProject.file('CHANGELOG.md') - - @InputDirectory - File siteDir - - @OutputDirectory - final DirectoryProperty targetDir = project.objects.directoryProperty() - .fileProvider(project.providers.provider {project.file("${project.docroot}/changes")}) - - @InputFile - def script - - def toHtml() { - def output = new ByteArrayOutputStream() - - // Check if Python is available - if (!pythonExists()) { - logger.warn("WARNING: Python is not installed, skipping creating Changes.html") - return - } - - def result = execOperations.exec { - executable "python3" - standardOutput project.file("${targetDir.get().getAsFile()}/Changes.html").newOutputStream() - errorOutput = output - ignoreExitValue = true - - args += [ - script.toString(), - changesFile.toString() - ] - } - - if (result.getExitValue() != 0) { - throw new GradleException("Changes generation failed:\n${output}") - } - } - - @TaskAction - def convert() { - project.mkdir targetDir - if (changesFile.exists()) { - toHtml() - project.copy { - from siteDir - into targetDir - include "*.css" - } - } else { - throw new GradleException("Changes file ${changesFile} not found.") - } - } - - def pythonExists() { - try { - def process = "python3 --version".execute() - process.waitFor() - return process.exitValue() == 0 - } catch (Exception e) { - return false - } - } -} diff --git a/gradle/documentation/documentation.gradle b/gradle/documentation/documentation.gradle index c680fe25d54..29a585b9025 100644 --- a/gradle/documentation/documentation.gradle +++ b/gradle/documentation/documentation.gradle @@ -67,8 +67,7 @@ configure(project(':solr:documentation')) { dependsOn project.parent.subprojects.collect {prj -> prj.tasks.matching {it.name == 'renderSiteJavadoc'} } - dependsOn 'changesToHtml', 'copyDocumentationAssets', - 'markdownToHtml', 'createDocumentationIndex' + dependsOn 'copyDocumentationAssets', 'markdownToHtml', 'createDocumentationIndex' } // Javadoc references are validated at compile time by DocLint diff --git a/solr/distribution/build.gradle b/solr/distribution/build.gradle index b3e2e6e0bee..8de83fe54c4 100644 --- a/solr/distribution/build.gradle +++ b/solr/distribution/build.gradle @@ -48,15 +48,16 @@ if (project.ext.useGpgForSigning) { // Prepare the "source" distribution artifact. apply from: buildscript.sourceFile.toPath().resolveSibling("source-release.gradle") -// Set up the HTML-rendered "changes" distribution artifact by linking to documentation's output. +// The release tooling creates this Python-rendered output after `clean check`. +def documentationProject = project(':solr:documentation') +def releaseChangesHtmlDir = new File(documentationProject.buildDir, 'site/changes') + configurations { - changesHtml openApiSpecFile docker } dependencies { - changesHtml project(path: ":solr:documentation", configuration: "changesHtml") openApiSpecFile project(path: ":solr:api", configuration: "openapiSpec") docker project(path: ':solr:docker', configuration: 'packagingOfficial') } @@ -128,7 +129,7 @@ task assembleRelease(type: Sync) { description "Assemble all Solr artifacts for a release." dependsOn ":mavenToLocalFolder" - from(configurations.changesHtml, { + from(releaseChangesHtmlDir, { into "changes" }) diff --git a/solr/distribution/gradle.lockfile b/solr/distribution/gradle.lockfile index 61a77fa5e03..08fd62ba52a 100644 --- a/solr/distribution/gradle.lockfile +++ b/solr/distribution/gradle.lockfile @@ -2,4 +2,4 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. # To regenerate this file, run: ./gradlew :solr:distribution:dependencies --write-locks -empty=changesHtml,docker,jarValidation,openApiSpecFile +empty=docker,jarValidation,openApiSpecFile diff --git a/solr/documentation/gradle.lockfile b/solr/documentation/gradle.lockfile index 141af17f307..0282140511f 100644 --- a/solr/documentation/gradle.lockfile +++ b/solr/documentation/gradle.lockfile @@ -9,4 +9,4 @@ org.apache.lucene:lucene-expressions:10.4.0=javadocs org.apache.lucene:lucene-queries:10.4.0=javadocs org.apache.lucene:lucene-queryparser:10.4.0=javadocs org.apache.lucene:lucene-spatial-extras:10.4.0=javadocs -empty=changesHtml,jarValidation,minimalSite,site +empty=jarValidation,minimalSite,site diff --git a/solr/solr-ref-guide/build.gradle b/solr/solr-ref-guide/build.gradle index c84ce7c4b10..3e69411a5d5 100644 --- a/solr/solr-ref-guide/build.gradle +++ b/solr/solr-ref-guide/build.gradle @@ -487,6 +487,8 @@ task checkSiteLinks(type: NpxTask) { "--debug", // Ignore the java docs url in the header, since it is an absolute path "--url-ignore", "${project(':solr:documentation').docroot.toPath()}/index\\.html", + // Changes.html is generated by release tooling; relative links to it are expected to be missing locally. + "--url-ignore", "changes/+Changes\\.html", "--json", "-v", ]
