Skip to content

[ML] Add external changelog source support for release notes#145958

Open
edsavage wants to merge 13 commits intoelastic:mainfrom
edsavage:feature/ml-cpp-changelog-integration
Open

[ML] Add external changelog source support for release notes#145958
edsavage wants to merge 13 commits intoelastic:mainfrom
edsavage:feature/ml-cpp-changelog-integration

Conversation

@edsavage
Copy link
Copy Markdown
Contributor

@edsavage edsavage commented Apr 9, 2026

Summary

Extends the changelog bundling infrastructure to pull changelog entries from external repositories at bundle time. Initially configured for elastic/ml-cpp, this enables ml-cpp changelog YAML entries to appear in the Elasticsearch release notes with correct PR links.

Motivation

Currently, ml-cpp changes are manually copied into CHANGELOG.asciidoc at release time — a process that's error-prone, creates merge conflicts, and misses entries. The ml-cpp team has adopted the ES per-PR YAML changelog format (identical schema) and needs a way for those entries to flow into the ES release notes automatically.

This resolves elastic/ml-cpp#2217, originally filed by @pugnascotia when the changelog system was created.

Changes

Schema

  • changelog-schema.json: added optional source_repo field (string, e.g. elastic/ml-cpp). Existing entries without this field continue to work — it defaults to elastic/elasticsearch.

ChangelogEntry

  • Added sourceRepo field with @JsonProperty("source_repo") for correct snake_case YAML deserialization.
  • Added getRepoUrl() helper that returns https://github.com/<source_repo>, defaulting to elastic/elasticsearch when null.
  • Added parse(String) overload for parsing YAML directly from a string (used by external changelog fetching to avoid temp file I/O).

BundleChangelogsTask

  • Added ExternalChangelogSource record (implements Serializable for Gradle @Input fingerprinting) with repoUrl, sourceRepo, and changelogPath fields.
  • Added fetchExternalChangelogs() method that:
    1. Normalizes the branch ref (strips upstream/ prefixes, rejects raw SHAs)
    2. Fetches the branch directly from the repo URL via git fetch into FETCH_HEAD (no persistent remote added — no side effects on the local checkout)
    3. Lists changelog YAML files via git ls-tree
    4. Reads each file via git show and parses directly from the string content
    5. Sets sourceRepo on each parsed entry automatically
    6. Gracefully handles missing branches, missing directories, and parse failures (warns and continues)
  • Added normalizeBranchForExternalFetch() to strip remote prefixes and reject SHAs that are meaningless for external repos.
  • External sources list annotated with @Input for proper Gradle up-to-date checking.

Configuration

  • External changelog sources are defined in build-tools-internal/src/main/resources/external-changelog-sources.yml — adding or removing external repos is a config-only change, no Java modifications needed:
    - repoUrl: https://github.com/elastic/ml-cpp.git
      sourceRepo: elastic/ml-cpp
      changelogPath: docs/changelog
  • ReleaseToolsPlugin loads this config at task configuration time via Jackson YAML.

Templates

  • index.md, breaking-changes.md, deprecations.md: replaced hardcoded https://github.com/elastic/elasticsearch URLs with ${change.repoUrl} so PR/issue links point to the correct repository. ES entries are unaffected (default URL is elastic/elasticsearch).

Tests

  • ExternalChangelogSourceTests: 5 test cases covering:
    • YAML parsing with source_repo field
    • Default repo URL when source_repo is absent
    • Branch normalization (strips prefixes)
    • SHA rejection
    • ExternalChangelogSource record construction

E2E verification

Tested locally with a test git repo containing ml-cpp changelog entries:

  1. ./gradlew bundleChangelogs --branch main — fetched 3 ml-cpp entries via FETCH_HEAD, merged into the 9.4.0 bundle with sourceRepo: elastic/ml-cpp
  2. ./gradlew generateReleaseNotes — rendered ml-cpp entries with correct links:
    * Add EuroBERT and Jina v5 ops to graph validation allowlist [#3015](https://github.com/elastic/ml-cpp/pull/3015)
    * Harden pytorch_inference with TorchScript model graph validation [#3008](https://github.com/elastic/ml-cpp/pull/3008) (issue: [#2890](https://github.com/elastic/ml-cpp/issues/2890))
    
  3. ES-native entries continued rendering with elastic/elasticsearch links as before.

Example

An ml-cpp changelog entry:

pr: 3008
summary: "Harden pytorch_inference with TorchScript model graph validation"
area: Machine Learning
type: enhancement
issues: [2890]

Renders in the release notes as:

  • Harden pytorch_inference with TorchScript model graph validation #3008 (issue: #2890)

Test plan

  • compileJava passes
  • ReleaseNotesGeneratorTest and existing template tests pass (backward compatible)
  • validateChangelogs passes (existing ES entries validate against updated schema)
  • ExternalChangelogSourceTests pass (5 new test cases)
  • E2E: bundleChangelogs --branch main includes ml-cpp entries with sourceRepo
  • E2E: generateReleaseNotes renders correct repo-specific PR links

Related

Extends the changelog bundling infrastructure to pull changelog entries
from external repositories (initially elastic/ml-cpp) at bundle time.

Changes:
- changelog-schema.json: add optional source_repo field for entries
  from external repos
- ChangelogEntry: add sourceRepo field and getRepoUrl() helper that
  returns the correct GitHub base URL for PR/issue links
- BundleChangelogsTask: add ExternalChangelogSource config and fetch
  logic that clones external repo changelogs via git and merges them
  into the bundle with sourceRepo set automatically
- ReleaseToolsPlugin: wire up elastic/ml-cpp as an external source
- Templates (index.md, breaking-changes.md, deprecations.md): use
  change.repoUrl instead of hardcoded elastic/elasticsearch URLs

This enables ml-cpp changelog YAML entries to appear in the ES
release notes with correct PR links pointing to elastic/ml-cpp.

Resolves: elastic/ml-cpp#2217
Made-with: Cursor
@edsavage edsavage requested a review from a team as a code owner April 9, 2026 03:07
@elasticsearchmachine elasticsearchmachine added the needs:triage Requires assignment of a team area label label Apr 9, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 9, 2026

Walkthrough

The bundle-changelogs task now accepts external changelog sources via a new ExternalChangelogSource input, fetches and parses YAML entries from those external repos (normalizing refs), annotates entries with sourceRepo, merges and re-sorts them with local entries, and outputs a combined ChangelogBundle. Schema and templates were updated to use source_repo/repoUrl.

Changes

Cohort / File(s) Summary
Task + external fetch logic
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java
Added ExternalChangelogSource record, externalSources input getter/setter, external-fetch flow in executeTask, fetchExternalChangelogs(...), and ref helpers normalizeBranchForExternalFetch(...) and isShaRef(...). Errors in external fetch are logged and do not fail the task.
Changelog model
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ChangelogEntry.java
Added sourceRepo field, JSON accessors (source_repo), getRepoUrl() fallback to default, new parse(String) factory, and updated equals/hashCode/toString to include sourceRepo.
Plugin config loader
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java
Loads external-changelog-sources.yml and passes parsed sources to BundleChangelogsTask; updates task description.
Schema & templates
build-tools-internal/src/main/resources/changelog-schema.json, .../templates/*.md
Added source_repo to JSON schema; templates changed to use change.repoUrl (repo-relative PR/issue links) instead of hard-coded elasticsearch URL.
External sources resource
build-tools-internal/src/main/resources/external-changelog-sources.yml
New resource defining external changelog sources (repoUrl, sourceRepo, changelogPath) with example entry.
Tests
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java
New tests for ChangelogEntry.parse, getRepoUrl fallback, isShaRef and normalizeBranchForExternalFetch, and ExternalChangelogSource accessors.

Sequence Diagram(s)

sequenceDiagram
    participant Plugin as ReleaseToolsPlugin
    participant Task as BundleChangelogsTask
    participant Git as Git (external repo)
    participant Parser as YAML Parser
    participant Bundle as ChangelogBundle

    Plugin->>Task: configure(externalSources)
    Task->>Git: fetch(branchRef) for local repo
    Git->>Parser: show/list local `*.yaml`
    Parser->>Task: parsed local entries
    loop for each ExternalChangelogSource
        Task->>Git: shallow fetch(normalizeBranch)
        Git->>Git: list `changelogPath` (`*.yaml`)
        Git->>Parser: git show each YAML
        Parser->>Task: parsed external entries (set sourceRepo)
        Task-->>Task: merge entries
    end
    Task->>Task: sort by PR number
    Task->>Bundle: create/write ChangelogBundle
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

"I nibbled docs and hopped through git,
fetched distant notes bit by bit.
I stitched the yarn of PR and repo,
a bundle stitched, neat as a bow.
— 🐰"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely describes the main change: adding external changelog source support for release notes, with the ML context specified.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining motivation, detailed changes, configuration, and E2E verification of external changelog source functionality.
Linked Issues check ✅ Passed The PR fully implements the objectives from issue #2217: enables external per-PR YAML changelog files to be pulled automatically, integrates ml-cpp changelogs via git fetch, provides repo-specific links in release notes, and eliminates manual ML changelog merging.
Out of Scope Changes check ✅ Passed All changes are directly scoped to supporting external changelog sources: schema updates, ChangelogEntry enhancements, BundleChangelogsTask additions, configuration loading, template updates for repo-specific links, and comprehensive tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@edsavage edsavage added >docs General docs changes >non-issue :ml Machine learning v9.4.0 labels Apr 9, 2026
@elasticsearchmachine elasticsearchmachine added the Team:ML Meta label for the ML team label Apr 9, 2026
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/ml-core (Team:ML)

@elasticsearchmachine elasticsearchmachine removed the needs:triage Requires assignment of a team area label label Apr 9, 2026
Moves the external changelog source configuration from hardcoded
Java to a YAML config file (external-changelog-sources.yml) in
build-tools-internal/src/main/resources/. Adding or removing
external repos is now a config-only change.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends the release-notes changelog bundling pipeline so it can pull per-PR YAML changelog entries from external repositories (initially elastic/ml-cpp) and render PR/issue links pointing at the correct GitHub repo.

Changes:

  • Adds an optional source_repo field to the changelog schema and introduces ChangelogEntry.sourceRepo / repoUrl for link generation.
  • Adds support in BundleChangelogsTask to fetch and merge changelog YAML files from configured external git repositories at bundle time.
  • Updates markdown templates to build PR/issue links from ${change.repoUrl} instead of hardcoding elastic/elasticsearch.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
build-tools-internal/src/main/resources/templates/index.md Uses ${change.repoUrl} for PR/issue links in release notes.
build-tools-internal/src/main/resources/templates/breaking-changes.md Uses ${change.repoUrl} for PR/issue links in breaking changes notes.
build-tools-internal/src/main/resources/templates/deprecations.md Uses ${change.repoUrl} for PR/issue links in deprecations notes.
build-tools-internal/src/main/resources/external-changelog-sources.yml Adds config listing external changelog sources (ml-cpp).
build-tools-internal/src/main/resources/changelog-schema.json Adds optional source_repo field to schema.
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java Loads external sources config and wires it into bundleChangelogs.
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ChangelogEntry.java Adds sourceRepo and getRepoUrl() helper for templates.
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java Fetches external changelog YAMLs via git and merges entries into the bundle.
Comments suppressed due to low confidence (1)

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java:204

  • BundleChangelogsTask declares an @OutputFile property (bundleFile) and ReleaseToolsPlugin sets it, but executeTask() writes the bundle to a hard-coded path (docs/release-notes/changelog-bundles/<version>.yml) instead of using bundleFile (or changelogBundlesDirectory). This makes the task’s declared outputs inconsistent with what it actually produces and can break Gradle’s output tracking/caching. Use the configured output properties when writing the bundle.
            entries.sort(Comparator.comparing(ChangelogEntry::getPr));

            ChangelogBundle bundle = new ChangelogBundle(version, finalize, Instant.now().toString(), entries);

            yamlMapper.writeValue(new File("docs/release-notes/changelog-bundles/" + version + ".yml"), bundle);
        } finally {

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

- Add @input annotation to externalSources property (required by Gradle)
- Add Serializable to ExternalChangelogSource record (required for
  Gradle input fingerprinting)

Made-with: Cursor
@edsavage edsavage force-pushed the feature/ml-cpp-changelog-integration branch from 9fafee9 to fe4c7f8 Compare April 9, 2026 03:36
- Add @JsonProperty("source_repo") to ChangelogEntry for correct
  snake_case YAML deserialization
- Add ChangelogEntry.parse(String) overload to avoid temp file I/O
- Replace persistent git remote with FETCH_HEAD-based fetch (no
  side effects on the local repo)
- Add normalizeBranchForExternalFetch() to strip upstream/ prefixes
  and reject raw SHAs for external sources
- Add ExternalChangelogSourceTests covering: YAML parsing with
  source_repo, default repo URL, branch normalization, SHA rejection

Made-with: Cursor
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.


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

Comment on lines +306 to +316
private static String normalizeBranchForExternalFetch(String branchRef) {
if (branchRef.matches("^[0-9a-f]{7,40}$")) {
throw new IllegalArgumentException(
"Cannot use a commit SHA (" + branchRef + ") for external changelog sources. Use a branch name instead."
);
}
int slashIndex = branchRef.indexOf('/');
if (slashIndex >= 0) {
return branchRef.substring(slashIndex + 1);
}
return branchRef;
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

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

normalizeBranchForExternalFetch() currently strips everything up to the first '/' for any ref (e.g. "feature/foo" becomes "foo", and "refs/heads/main" becomes "heads/main"). That will break valid branch names containing slashes and common fully-qualified refs when fetching from external repositories. Consider only stripping known remote prefixes (e.g. "upstream/" and "origin/") rather than truncating on the first slash, and leave other refs untouched.

Copilot uses AI. Check for mistakes.
Only strip known remote prefixes (upstream/, origin/) instead of
truncating at the first slash. Branch names like feature/foo and
refs/heads/main are now passed through unchanged.

Also made the method package-private (removed reflection from tests)
and added test cases for slash-containing branch names.

Made-with: Cursor
@edsavage edsavage force-pushed the feature/ml-cpp-changelog-integration branch from a3791ae to 8eab7b7 Compare April 9, 2026 04:35
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java`:
- Around line 248-250: The task currently aborts when a SHA-style --branch/ref
is passed because normalizeBranchForExternalFetch() throws; instead detect SHA
refs in fetchExternalChangelogs(ExternalChangelogSource source, String
branchRef) and early-return an empty List (skip external fetching) when
branchRef matches a commit SHA pattern (e.g., 40 hex chars or common shorter SHA
lengths), leaving local SHA handling intact; update the same check where
external fetch is invoked later (the other fetch call around the 299-303 area)
so both code paths skip external sources for SHA refs rather than calling
normalizeBranchForExternalFetch() and failing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 800b2eca-8e53-44f8-a3ed-c47e75d50835

📥 Commits

Reviewing files that changed from the base of the PR and between 0d29050 and 8eab7b7.

📒 Files selected for processing (2)
  • build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java
  • build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java

When --branch is a commit SHA (valid for ES-local changelogs),
skip external changelog fetching instead of aborting the task.
This preserves the existing SHA workflow while external sources
are simply omitted from that particular bundle.

Made-with: Cursor
@edsavage edsavage force-pushed the feature/ml-cpp-changelog-integration branch from 1c0f1a1 to ea5cf1b Compare April 10, 2026 00:11
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java (1)

303-305: Consider case-insensitive SHA detection.

The regex ^[0-9a-f]{7,40}$ only matches lowercase hexadecimal. Git SHAs from some tools or clipboard operations may be uppercase or mixed-case. If this is intentional (requiring callers to normalize), document it; otherwise consider case-insensitive matching.

Option: Case-insensitive matching
     static boolean isShaRef(String ref) {
-        return ref.matches("^[0-9a-f]{7,40}$");
+        return ref.matches("(?i)^[0-9a-f]{7,40}$");
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java`
around lines 303 - 305, The isShaRef method currently only matches lowercase
hex; update it to accept mixed- or upper-case SHAs by making the regex
case-insensitive (e.g., use a case-insensitive flag or Pattern.CASE_INSENSITIVE)
or normalize the ref (e.g., toLowerCase()) before matching; adjust the
implementation in isShaRef(String ref) and add a brief comment stating that SHA
matching is case-insensitive.
build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java (2)

91-102: Test method name is misleading.

This test verifies that record accessor methods return constructor-provided values, which is implicit behavior for Java records. The name testExternalChangelogSourceSerialization suggests it tests java.io.Serializable serialization/deserialization round-tripping.

Consider renaming to testExternalChangelogSourceAccessors or removing the test if accessor correctness is considered trivial for records.

Suggested rename
     `@Test`
-    public void testExternalChangelogSourceSerialization() {
+    public void testExternalChangelogSourceAccessors() {
         var source = new BundleChangelogsTask.ExternalChangelogSource(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java`
around lines 91 - 102, The test method name
testExternalChangelogSourceSerialization is misleading because it only asserts
the record accessors of BundleChangelogsTask.ExternalChangelogSource; rename the
test to something like testExternalChangelogSourceAccessors (or remove the test
if deemed redundant) and update any references accordingly so the test name
reflects that it verifies repoUrl(), sourceRepo(), and changelogPath() return
the constructor values.

81-89: Consider testing uppercase hex SHA handling.

The isShaRef implementation uses [0-9a-f] which only matches lowercase hex. While Git typically outputs lowercase SHAs, some tools or copy-paste scenarios may produce uppercase. Adding a test case would document the expected behavior.

Optional: Add uppercase test case to document behavior
     `@Test`
     public void testIsShaRef() {
         assertThat(BundleChangelogsTask.isShaRef("abc1234"), equalTo(true));
         assertThat(BundleChangelogsTask.isShaRef("a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"), equalTo(true));
         assertThat(BundleChangelogsTask.isShaRef("main"), equalTo(false));
         assertThat(BundleChangelogsTask.isShaRef("9.3"), equalTo(false));
         assertThat(BundleChangelogsTask.isShaRef("upstream/main"), equalTo(false));
         assertThat(BundleChangelogsTask.isShaRef("feature/foo"), equalTo(false));
+        // Uppercase hex is not detected as SHA (by design - normalize to lowercase before checking)
+        assertThat(BundleChangelogsTask.isShaRef("ABC1234DEF5678"), equalTo(false));
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java`
around lines 81 - 89, Add a test case in
ExternalChangelogSourceTests.testIsShaRef to cover uppercase hex SHAs: call
BundleChangelogsTask.isShaRef with an uppercase SHA (e.g., 40 hex chars A-F and
0-9) and assert the expected boolean result to document behavior; reference the
existing testIsShaRef method and BundleChangelogsTask.isShaRef to locate where
to add the new assertion and decide whether the expected outcome should be true
(if you want to accept uppercase) or false (if you want to document rejection).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java`:
- Around line 303-305: The isShaRef method currently only matches lowercase hex;
update it to accept mixed- or upper-case SHAs by making the regex
case-insensitive (e.g., use a case-insensitive flag or Pattern.CASE_INSENSITIVE)
or normalize the ref (e.g., toLowerCase()) before matching; adjust the
implementation in isShaRef(String ref) and add a brief comment stating that SHA
matching is case-insensitive.

In
`@build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java`:
- Around line 91-102: The test method name
testExternalChangelogSourceSerialization is misleading because it only asserts
the record accessors of BundleChangelogsTask.ExternalChangelogSource; rename the
test to something like testExternalChangelogSourceAccessors (or remove the test
if deemed redundant) and update any references accordingly so the test name
reflects that it verifies repoUrl(), sourceRepo(), and changelogPath() return
the constructor values.
- Around line 81-89: Add a test case in
ExternalChangelogSourceTests.testIsShaRef to cover uppercase hex SHAs: call
BundleChangelogsTask.isShaRef with an uppercase SHA (e.g., 40 hex chars A-F and
0-9) and assert the expected boolean result to document behavior; reference the
existing testIsShaRef method and BundleChangelogsTask.isShaRef to locate where
to add the new assertion and decide whether the expected outcome should be true
(if you want to accept uppercase) or false (if you want to document rejection).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ad78d2ed-aef7-459a-b9f9-e679382b4e6e

📥 Commits

Reviewing files that changed from the base of the PR and between 0d29050 and df79cc9.

📒 Files selected for processing (3)
  • build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/BundleChangelogsTask.java
  • build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java
  • build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ExternalChangelogSourceTests.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/ReleaseToolsPlugin.java

- Make isShaRef case-insensitive to handle uppercase/mixed-case SHAs
- Rename testExternalChangelogSourceSerialization to
  testExternalChangelogSourceAccessors (more accurate name)
- Add test cases for uppercase and mixed-case SHA detection

Made-with: Cursor
@edsavage edsavage force-pushed the feature/ml-cpp-changelog-integration branch from df79cc9 to 10aa45f Compare April 10, 2026 03:10
Tests for sourceRepo propagation via setSourceRepo, invalid
YAML parsing, and isShaRef boundary conditions.

Made-with: Cursor
@edsavage edsavage requested a review from valeriy42 April 13, 2026 01:48
@edsavage edsavage added the :Delivery/Build Build or test infrastructure label Apr 21, 2026
@elasticsearchmachine
Copy link
Copy Markdown
Collaborator

Pinging @elastic/es-delivery (Team:Delivery)

@elasticsearchmachine elasticsearchmachine added the Team:Delivery Meta label for Delivery team label Apr 21, 2026
@macroscopeapp
Copy link
Copy Markdown

macroscopeapp Bot commented Apr 21, 2026

Approvability

Verdict: Needs human review

This PR introduces a new feature that fetches changelog entries from external repositories during build time. The author does not own any of the 9 modified files (all owned by @elastic/es-delivery), which warrants review by the designated code owners. Additionally, new features introducing new capabilities should receive human review.

You can customize Macroscope's approvability policy. Learn more.

Copy link
Copy Markdown
Contributor

@breskeby breskeby left a comment

Choose a reason for hiding this comment

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

lgtm. one nit issue about changelog entry ordering

}
}

entries.sort(Comparator.comparing(ChangelogEntry::getPr));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: With multiple repos, entries sharing a PR number have undefined ordering. Adding sourceRepo as a secondary sort key would make output deterministic.

* All other refs (including branch names with slashes like {@code feature/foo})
* are passed through unchanged.
*/
static boolean isShaRef(String ref) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the javadoc does not match and I guess is meant for the method below

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

Labels

:Delivery/Build Build or test infrastructure >docs General docs changes :ml Machine learning >non-issue Team:Delivery Meta label for Delivery team Team:ML Meta label for the ML team v9.5.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate changelog YAML files for ML?

5 participants