Skip to content

Commit 3a8c89b

Browse files
committed
Merge branch 'main' into ts-in-generative-tests
2 parents 820f4b7 + a521e13 commit 3a8c89b

File tree

948 files changed

+32969
-21166
lines changed

Some content is hidden

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

948 files changed

+32969
-21166
lines changed
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
steps: []
1+
steps:
2+
- label: update-transport-versions
3+
command: '.buildkite/scripts/update-transport-versions.sh'
4+
# New transport versions are always added via the main branch
5+
if: build.env('BUILDKITE_PULL_REQUEST_BASE_BRANCH') == 'main'
6+
agents:
7+
provider: gcp
8+
image: family/elasticsearch-ubuntu-2404
9+
machineType: custom-16-32768
10+
buildDirectory: /dev/shm/bk
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
config:
2+
skip-target-branches: "main"
3+
steps:
4+
- label: validate-transport-version-backport
5+
command: .buildkite/scripts/validate-transport-version-backport.sh

.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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
if [[ -z "${BUILDKITE_PULL_REQUEST:-}" ]]; then
5+
echo "Not a pull request, skipping transport version update"
6+
exit 0
7+
fi
8+
9+
if ! git diff --exit-code; then
10+
echo "Changes are present before updating transport versions, not running"
11+
git status
12+
exit 0
13+
fi
14+
15+
NEW_COMMIT_MESSAGE="[CI] Update transport version definitions"
16+
17+
echo "--- Generating updated transport version definitions"
18+
# Calculate backport branches based on pull request version labels
19+
backport_branches=$(
20+
echo "${GITHUB_PR_LABELS}" \
21+
| tr ',' '\n' \
22+
| grep -E "v[0-9]+\.[0-9]+\.[0-9]+" \
23+
| sed -E 's/^v([0-9]+)\.([0-9]+)\.[0-9]+$/\1.\2/' \
24+
| paste -sd, -
25+
)
26+
27+
if [[ -z "${backport_branches}" ]]; then
28+
echo "Skipping as pull request contains no version labels"
29+
exit 0
30+
fi
31+
32+
.ci/scripts/run-gradle.sh generateTransportVersion --backport-branches="${backport_branches}"
33+
34+
if git diff --exit-code; then
35+
echo "No changes found after updating transport versions. Don't need to auto commit."
36+
exit 0
37+
fi
38+
39+
git config --global user.name elasticsearchmachine
40+
git config --global user.email '[email protected]'
41+
42+
gh pr checkout "${BUILDKITE_PULL_REQUEST}"
43+
git add -A .
44+
git commit -m "$NEW_COMMIT_MESSAGE"
45+
git push
46+
47+
# After the git push, the new commit will trigger a new build within a few seconds and this build should get cancelled
48+
# So, let's just sleep to give the build time to cancel itself without an error
49+
# If it doesn't get cancelled for some reason, then exit with an error, because we don't want this build to be green (we just don't want it to generate an error either)
50+
sleep 300
51+
exit 1
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
if [[ "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" == "main" ]]; then
5+
# Don't run on PRs targeting main
6+
exit 0
7+
fi
8+
9+
echo "--- Looking for transport version changes"
10+
11+
# Get any changes in this pull request to transport definitions
12+
git fetch origin "${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" --quiet
13+
changed_files=$(git diff --name-only "origin/${BUILDKITE_PULL_REQUEST_BASE_BRANCH}" | grep -E "server/src/main/resources/transport/definitions/.*\.csv" || true)
14+
15+
if [[ -z "${changed_files}" ]]; then
16+
echo "No transport version changes detected."
17+
exit 0
18+
fi
19+
20+
# Compare those files against the main branch to ensure they are the same
21+
git fetch origin main --quiet
22+
while IFS= read -r file; do
23+
if ! git diff --quiet origin/main -- "${file}"; then
24+
echo "Changes to transport definition [${file}] missing from main branch."
25+
echo "Transport changes must first be merged to main before being backported."
26+
exit 1
27+
fi
28+
done <<< "${changed_files}"
29+
30+
echo "All transport changes exist in main branch."

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.

0 commit comments

Comments
 (0)