Skip to content

Commit bedb2de

Browse files
committed
Merge remote-tracking branch 'origin/main' into lucene_snapshot_10_3
2 parents 97a6a86 + 5ce0c64 commit bedb2de

File tree

159 files changed

+5147
-1254
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+5147
-1254
lines changed

.buildkite/scripts/pull-request/__snapshots__/pipeline.test.ts.snap

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,68 @@ exports[`generatePipelines should generate correct pipelines with a non-docs cha
309309
},
310310
]
311311
`;
312+
313+
exports[`generatePipelines should generate correct pipelines with a different branch that is not skipped 1`] = `
314+
[
315+
{
316+
"name": "bwc-snapshots",
317+
"pipeline": {
318+
"steps": [
319+
{
320+
"group": "bwc-snapshots",
321+
"steps": [
322+
{
323+
"agents": {
324+
"buildDirectory": "/dev/shm/bk",
325+
"image": "family/elasticsearch-ubuntu-2404",
326+
"machineType": "custom-32-98304",
327+
"provider": "gcp",
328+
},
329+
"command": ".ci/scripts/run-gradle.sh -Dignore.tests.seed v{{matrix.BWC_VERSION}}#bwcTest",
330+
"env": {
331+
"BWC_VERSION": "{{matrix.BWC_VERSION}}",
332+
},
333+
"label": "{{matrix.BWC_VERSION}} / bwc-snapshots",
334+
"matrix": {
335+
"setup": {
336+
"BWC_VERSION": [
337+
"7.17.14",
338+
"8.10.3",
339+
"8.11.0",
340+
],
341+
},
342+
},
343+
"timeout_in_minutes": 300,
344+
},
345+
],
346+
},
347+
],
348+
},
349+
},
350+
{
351+
"name": "skip-branch",
352+
"pipeline": {
353+
"steps": [
354+
{
355+
"command": "echo 1",
356+
"label": "skip-me",
357+
},
358+
],
359+
},
360+
},
361+
{
362+
"name": "using-defaults",
363+
"pipeline": {
364+
"env": {
365+
"CUSTOM_ENV_VAR": "value",
366+
},
367+
"steps": [
368+
{
369+
"command": "echo 'hello world'",
370+
"label": "test-step",
371+
},
372+
],
373+
},
374+
},
375+
]
376+
`;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
config:
2+
skip-target-branches: "test-branch"
3+
steps:
4+
- label: skip-me
5+
command: echo 1

.buildkite/scripts/pull-request/pipeline.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ describe("generatePipelines", () => {
88
setBwcVersionsPath(`${import.meta.dir}/mocks/bwcVersions`);
99
setSnapshotBwcVersionsPath(`${import.meta.dir}/mocks/snapshotBwcVersions`);
1010

11+
process.env["GITHUB_PR_TARGET_BRANCH"] = "test-branch";
1112
process.env["GITHUB_PR_LABELS"] = "test-label-1,test-label-2";
1213
process.env["GITHUB_PR_TRIGGER_COMMENT"] = "";
1314
});
@@ -36,6 +37,12 @@ describe("generatePipelines", () => {
3637
testWithTriggerCheck(`${import.meta.dir}/mocks/pipelines`, ["build.gradle"]);
3738
});
3839

40+
test("should generate correct pipelines with a different branch that is not skipped", () => {
41+
process.env["GITHUB_PR_TARGET_BRANCH"] = "main";
42+
43+
testWithTriggerCheck(`${import.meta.dir}/mocks/pipelines`, ["build.gradle"]);
44+
});
45+
3946
test("should generate correct pipeline when using a trigger comment for it", () => {
4047
process.env["GITHUB_PR_TRIGGER_COMMENT"] = "run elasticsearch-ci/using-defaults";
4148

.buildkite/scripts/pull-request/pipeline.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ const changedFilesIncludedCheck = (pipeline: EsPipeline, changedFiles: string[])
5050
return true;
5151
};
5252

53+
const checkTargetBranch = (pipeline: EsPipeline, targetBranch: string | undefined) => {
54+
if (!targetBranch || !pipeline.config?.["skip-target-branches"]) {
55+
return true;
56+
}
57+
58+
return !getArray(pipeline.config["skip-target-branches"]).some((branch) => branch === targetBranch);
59+
};
60+
5361
const triggerCommentCheck = (pipeline: EsPipeline): boolean => {
5462
if (process.env["GITHUB_PR_TRIGGER_COMMENT"] && pipeline.config?.["trigger-phrase"]) {
5563
return !!process.env["GITHUB_PR_TRIGGER_COMMENT"].match(pipeline.config["trigger-phrase"]);
@@ -138,6 +146,7 @@ export const generatePipelines = (
138146
}
139147

140148
let filters: ((pipeline: EsPipeline) => boolean)[] = [
149+
(pipeline) => checkTargetBranch(pipeline, process.env["GITHUB_PR_TARGET_BRANCH"]),
141150
(pipeline) => labelCheckAllow(pipeline, labels),
142151
(pipeline) => labelCheckSkip(pipeline, labels),
143152
(pipeline) => changedFilesExcludedCheck(pipeline, changedFiles),

.buildkite/scripts/pull-request/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export type EsPipelineConfig = {
55
"included-regions"?: string | string[];
66
"excluded-regions"?: string | string[];
77
"trigger-phrase"?: string;
8+
"skip-target-branches"?: string | string[];
89
};
910
};
1011

.buildkite/scripts/validate-transport-version-backport.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#!/bin/bash
22
set -euo pipefail
33

4+
if [[ "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" == "main" ]]; then
5+
# Don't run on PRs targeting main
6+
exit 0
7+
fi
8+
49
echo "--- Looking for transport version changes"
510

611
# Get any changes in this pull request to transport definitions

BUILDING.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,70 @@ will have the `origin` attribute been set to `Generated by Gradle`.
9797
> If you want to add a level of verification you can manually confirm the checksum (e.g. by looking it up on the website of the library)
9898
> Please replace the content of the `origin` attribute by `official site` in that case.
9999
100+
##### Handling transitive dependencies
101+
102+
Dependency management is a critical aspect of maintaining a secure and reliable build system, requiring explicit control over what we rely on. The Elasticsearch build mainly uses component metadata rules declared in the `ComponentMetadataRulesPlugin`
103+
plugin to manage transitive dependencies and avoid version conflicts.
104+
This approach ensures we have explicit control over all dependencies used in the build.
105+
106+
###### General Guidelines
107+
108+
1. **Avoid unused transitive dependencies** - Dependencies that are not actually used by our code should be excluded to reduce the attack surface and avoid potential conflicts.
109+
110+
2. **Prefer versions declared in `build-tools-internal/version.properties`** - All dependency versions should be centrally managed in this file to ensure consistency across the entire build.
111+
112+
3. **Libraries required to compile our code should be direct dependencies** - If we directly use a library in our source code, it should be declared as a direct dependency rather than relying on it being transitively available.
113+
114+
###### Component Metadata Rules
115+
116+
We use two main types of component metadata rules at this point to manage transitive dependencies:
117+
118+
- **`ExcludeAllTransitivesRule`** - Excludes all transitive dependencies for libraries where we want complete control over dependencies or the transitive dependencies are unused.
119+
120+
- **`ExcludeOtherGroupsTransitiveRule`** - Excludes transitive dependencies that don't belong to the same group as the direct dependency, while keeping same-group dependencies.
121+
-
122+
- **`ExcludeByGroup`** - Excludes transitive dependencies that match a specific groupId while keeping all other transitive dependencies with different groupIds.
123+
124+
Examples from the `ComponentMetadataRulesPlugin`:
125+
126+
```gradle
127+
// Exclude all transitives - used when transitive deps are unused or problematic
128+
components.withModule("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor", ExcludeAllTransitivesRule.class);
129+
130+
// Exclude other groups - used when we want same-group deps but not external ones
131+
components.withModule("com.azure:azure-core", ExcludeOtherGroupsTransitiveRule.class);
132+
133+
// Exclude only specific groups - used when we want exclude specific group of transitive deps.
134+
components.withModule("org.apache.logging.log4j:log4j-api", ExcludeByGroup.class, rule -> {
135+
rule.params(List.of("biz.aQute.bnd", "org.osgi"));
136+
});
137+
```
138+
139+
###### Common Scenarios
140+
141+
**Version Conflicts**: When a transitive dependency brings in a different version than what we use:
142+
```gradle
143+
// brings in jackson-databind and jackson-annotations not used
144+
components.withModule("com.fasterxml.jackson.dataformat:jackson-dataformat-cbor", ExcludeAllTransitivesRule.class);
145+
```
146+
147+
**Unused Dependencies**: When transitive dependencies are not actually used:
148+
```gradle
149+
// brings in azure-core-http-netty. not used
150+
components.withModule("com.azure:azure-core-http-netty", ExcludeAllTransitivesRule.class);
151+
```
152+
153+
**Mismatching Version Dependencies**: When other versions are required:
154+
```gradle
155+
// brings in org.slf4j:slf4j-api:1.7.25. We use 2.0.6
156+
components.withModule("org.apache.directory.api:api-asn1-ber", ExcludeOtherGroupsTransitiveRule.class);
157+
```
158+
159+
When adding or updating dependencies, ensure that any required transitive dependencies are either:
160+
1. Already available as direct dependencies with compatible versions
161+
2. Added as direct dependencies if they're actually used by our code
162+
3. Properly excluded if they're not needed
163+
100164
#### Custom plugin and task implementations
101165

102166
Build logic that is used across multiple subprojects should be considered to be moved into a Gradle plugin with according Gradle task implementation.

build-conventions/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ repositories {
7272
}
7373

7474
dependencies {
75+
constraints {
76+
api("org.slf4j:slf4j-api:2.0.6")
77+
}
7578
api buildLibs.maven.model
7679
api buildLibs.shadow.plugin
7780
api buildLibs.apache.rat

build-tools-internal/build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ gradlePlugin {
4040
id = 'elasticsearch.build-complete'
4141
implementationClass = 'org.elasticsearch.gradle.internal.ElasticsearchBuildCompletePlugin'
4242
}
43+
componentMetadataRules {
44+
id = 'elasticsearch.component-metadata-rules'
45+
implementationClass = 'org.elasticsearch.gradle.internal.dependencies.rules.ComponentMetadataRulesPlugin'
46+
}
4347
distro {
4448
id = 'elasticsearch.distro'
4549
implementationClass = 'org.elasticsearch.gradle.internal.distribution.ElasticsearchDistributionPlugin'
@@ -281,6 +285,9 @@ dependencies {
281285
testImplementation buildLibs.asm
282286
integTestImplementation buildLibs.asm
283287
api(buildLibs.snakeyaml)
288+
api("org.slf4j:slf4j-api:2.0.6") {
289+
because("Align with what we use in production")
290+
}
284291
}
285292
// Forcefully downgrade the jackson platform as used in production
286293
api enforcedPlatform(buildLibs.jackson.platform)

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchJavaBasePlugin.java

Lines changed: 0 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,14 @@
1616
import org.elasticsearch.gradle.internal.test.MutedTestPlugin;
1717
import org.elasticsearch.gradle.internal.test.TestUtil;
1818
import org.elasticsearch.gradle.test.SystemPropertyCommandLineArgumentProvider;
19-
import org.elasticsearch.gradle.util.GradleUtils;
2019
import org.gradle.api.JavaVersion;
2120
import org.gradle.api.Plugin;
2221
import org.gradle.api.Project;
2322
import org.gradle.api.artifacts.Configuration;
24-
import org.gradle.api.artifacts.ResolutionStrategy;
2523
import org.gradle.api.file.FileCollection;
2624
import org.gradle.api.plugins.JavaBasePlugin;
2725
import org.gradle.api.plugins.JavaPluginExtension;
2826
import org.gradle.api.provider.Provider;
29-
import org.gradle.api.tasks.SourceSet;
30-
import org.gradle.api.tasks.SourceSetContainer;
3127
import org.gradle.api.tasks.compile.AbstractCompile;
3228
import org.gradle.api.tasks.compile.CompileOptions;
3329
import org.gradle.api.tasks.compile.GroovyCompile;
@@ -67,8 +63,6 @@ public void apply(Project project) {
6763
project.getPluginManager().apply(ElasticsearchTestBasePlugin.class);
6864
project.getPluginManager().apply(PrecommitTaskPlugin.class);
6965
project.getPluginManager().apply(MutedTestPlugin.class);
70-
71-
configureConfigurations(project);
7266
configureCompile(project);
7367
configureInputNormalization(project);
7468
configureNativeLibraryPath(project);
@@ -77,54 +71,6 @@ public void apply(Project project) {
7771
project.getExtensions().getExtraProperties().set("versions", VersionProperties.getVersions());
7872
}
7973

80-
/**
81-
* Makes dependencies non-transitive.
82-
* <p>
83-
* Gradle allows setting all dependencies as non-transitive very easily.
84-
* Sadly this mechanism does not translate into maven pom generation. In order
85-
* to effectively make the pom act as if it has no transitive dependencies,
86-
* we must exclude each transitive dependency of each direct dependency.
87-
* <p>
88-
* Determining the transitive deps of a dependency which has been resolved as
89-
* non-transitive is difficult because the process of resolving removes the
90-
* transitive deps. To sidestep this issue, we create a configuration per
91-
* direct dependency version. This specially named and unique configuration
92-
* will contain all of the transitive dependencies of this particular
93-
* dependency. We can then use this configuration during pom generation
94-
* to iterate the transitive dependencies and add excludes.
95-
*/
96-
public static void configureConfigurations(Project project) {
97-
// we are not shipping these jars, we act like dumb consumers of these things
98-
if (project.getPath().startsWith(":test:fixtures") || project.getPath().equals(":build-tools")) {
99-
return;
100-
}
101-
// fail on any conflicting dependency versions
102-
project.getConfigurations().all(configuration -> {
103-
if (configuration.getName().endsWith("Fixture")) {
104-
// just a self contained test-fixture configuration, likely transitive and hellacious
105-
return;
106-
}
107-
configuration.resolutionStrategy(ResolutionStrategy::failOnVersionConflict);
108-
});
109-
110-
// disable transitive dependency management
111-
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
112-
sourceSets.all(sourceSet -> disableTransitiveDependenciesForSourceSet(project, sourceSet));
113-
}
114-
115-
private static void disableTransitiveDependenciesForSourceSet(Project project, SourceSet sourceSet) {
116-
List<String> sourceSetConfigurationNames = List.of(
117-
sourceSet.getApiConfigurationName(),
118-
sourceSet.getImplementationConfigurationName(),
119-
sourceSet.getCompileOnlyConfigurationName(),
120-
sourceSet.getRuntimeOnlyConfigurationName()
121-
);
122-
123-
project.getConfigurations()
124-
.matching(c -> sourceSetConfigurationNames.contains(c.getName()))
125-
.configureEach(GradleUtils::disableTransitiveDependencies);
126-
}
127-
12874
/**
12975
* Adds compiler settings to the project
13076
*/

0 commit comments

Comments
 (0)