Skip to content

Commit b743fd2

Browse files
Merge branch 'main' into 249382_Fix-monospace-fonts-applied-outside-Lens
2 parents f80eb8c + 39763e5 commit b743fd2

4,080 files changed

Lines changed: 96680 additions & 105304 deletions

File tree

Some content is hidden

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

.buildkite/ftr_platform_stateful_configs.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,7 @@ enabled:
479479
- x-pack/platform/test/api_integration/apis/watcher/config.ts
480480
- x-pack/platform/test/api_integration_basic/apis/aiops/config.ts
481481
- x-pack/platform/test/api_integration_basic/apis/security/config.ts
482-
- x-pack/platform/test/automatic_import_api_integration/apis/config_basic.ts
483-
- x-pack/platform/test/automatic_import_api_integration/apis/config_graphs.ts
484-
- x-pack/platform/test/automatic_import_v2_api_integration/configs/config.stateful.ts
482+
- x-pack/platform/test/automatic_import_api_integration/configs/config.stateful.ts
485483
- x-pack/platform/test/encrypted_saved_objects_api_integration/config.ts
486484
- x-pack/platform/test/fleet_multi_cluster/config.ts
487485
- x-pack/platform/test/monitoring_api_integration/config.ts

.buildkite/pipelines/artifacts.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,5 @@ steps:
157157
imageProject: elastic-images-prod
158158
provider: gcp
159159
machineType: n2-standard-2
160+
diskSizeGb: 180
160161
timeout_in_minutes: 30

.buildkite/pipelines/pull_request/security_solution/automatic_import.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.buildkite/scout_ci_config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins:
55
- alerting
66
- alerting_v2
77
- apm
8-
- automatic_import_v2
8+
- automatic_import
99
- banners
1010
- cloud_security_posture
1111
- console

.buildkite/scripts/common/env.sh

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,7 @@ if is_pr; then
9292
if is_pr_with_label "ci:security-genai-run-evals-local-prompts"; then
9393
export IS_SECURITY_AI_PROMPT_TEST=true
9494
fi
95-
96-
# These can be removed once we're not supporting Jenkins and Buildkite at the same time
97-
# These are primarily used by github checks reporter and can be configured via /github_checks_api.json
98-
export ghprbGhRepository="elastic/kibana"
99-
export ghprbActualCommit="$BUILDKITE_COMMIT"
95+
10096
export BUILD_URL="$BUILDKITE_BUILD_URL"
10197

10298
set_git_merge_base

.buildkite/scripts/common/setup_job_env.sh

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ EOF
8989

9090
# Set up misc keys
9191
{
92-
KIBANA_CI_REPORTER_KEY=$(vault_get kibanamachine-reporter value)
93-
export KIBANA_CI_REPORTER_KEY
94-
9592
EC_API_KEY="$(vault_get kibana-ci-cloud-deploy pr_deploy_api_key)"
9693
export EC_API_KEY
9794

@@ -101,24 +98,6 @@ EOF
10198
PROJECT_API_DOMAIN="$(vault_get kibana-ci-project-deploy pr_deploy_domain)"
10299
export PROJECT_API_DOMAIN
103100

104-
SYNTHETICS_SERVICE_USERNAME="$(vault_get kibana-ci-synthetics-credentials username)"
105-
export SYNTHETICS_SERVICE_USERNAME
106-
107-
SYNTHETICS_SERVICE_PASSWORD="$(vault_get kibana-ci-synthetics-credentials password)"
108-
export SYNTHETICS_SERVICE_PASSWORD
109-
110-
SYNTHETICS_SERVICE_MANIFEST="$(vault_get kibana-ci-synthetics-credentials manifest)"
111-
export SYNTHETICS_SERVICE_MANIFEST
112-
113-
SYNTHETICS_REMOTE_KIBANA_USERNAME="$(vault_get kibana-ci-synthetics-remote-credentials username)"
114-
export SYNTHETICS_REMOTE_KIBANA_USERNAME
115-
116-
SYNTHETICS_REMOTE_KIBANA_PASSWORD="$(vault_get kibana-ci-synthetics-remote-credentials password)"
117-
export SYNTHETICS_REMOTE_KIBANA_PASSWORD
118-
119-
SYNTHETICS_REMOTE_KIBANA_URL=${SYNTHETICS_REMOTE_KIBANA_URL-"$(vault_get kibana-ci-synthetics-remote-credentials url)"}
120-
export SYNTHETICS_REMOTE_KIBANA_URL
121-
122101
DEPLOY_TAGGER_SLACK_WEBHOOK_URL=${DEPLOY_TAGGER_SLACK_WEBHOOK_URL:-"$(vault_get kibana-serverless-release-tools DEPLOY_TAGGER_SLACK_WEBHOOK_URL)"}
123102
export DEPLOY_TAGGER_SLACK_WEBHOOK_URL
124103

.buildkite/scripts/pipelines/pull_request/pipeline.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,7 @@ const SKIPPABLE_PR_MATCHERS = prConfig.skip_ci_on_only_changed!.map((r) => new R
7171

7272
// Register steps from base.yml that should still be canceled on gate failure.
7373
// base.yml itself is not loaded with cancelOnGateFailure because it contains the gate steps.
74-
for (const stepKey of [
75-
'pick_test_group_run_order',
76-
'build_scout_tests',
77-
'check_oas_snapshot',
78-
'build_api_docs',
79-
]) {
74+
for (const stepKey of ['pick_test_group_run_order', 'build_scout_tests', 'build_api_docs']) {
8075
execFileSync('buildkite-agent', [
8176
'meta-data',
8277
'set',
@@ -354,7 +349,6 @@ const SKIPPABLE_PR_MATCHERS = prConfig.skip_ci_on_only_changed!.map((r) => new R
354349
/^x-pack\/solutions\/security\/test\/security_solution_cypress/,
355350
/^\.buildkite\/pipelines\/pull_request\/security_solution\/ai_assistant\.yml/,
356351
/^\.buildkite\/pipelines\/pull_request\/security_solution\/ai4dsoc\.yml/,
357-
/^\.buildkite\/pipelines\/pull_request\/security_solution\/automatic_import\.yml/,
358352
/^\.buildkite\/pipelines\/pull_request\/security_solution\/detection_engine\.yml/,
359353
/^\.buildkite\/pipelines\/pull_request\/security_solution\/entity_analytics\.yml/,
360354
/^\.buildkite\/pipelines\/pull_request\/security_solution\/rule_management\.yml/,
@@ -371,12 +365,6 @@ const SKIPPABLE_PR_MATCHERS = prConfig.skip_ci_on_only_changed!.map((r) => new R
371365
pipeline.push(
372366
getPipeline('.buildkite/pipelines/pull_request/security_solution/ai4dsoc.yml', cancelable)
373367
);
374-
pipeline.push(
375-
getPipeline(
376-
'.buildkite/pipelines/pull_request/security_solution/automatic_import.yml',
377-
cancelable
378-
)
379-
);
380368
pipeline.push(
381369
getPipeline(
382370
'.buildkite/pipelines/pull_request/security_solution/detection_engine.yml',

.buildkite/scripts/steps/checks/api_contracts.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@ if [[ -n "${GITHUB_PR_MERGE_BASE:-}" ]]; then
1616
MERGE_BASE_ARGS=(--mergeBase "$GITHUB_PR_MERGE_BASE")
1717
fi
1818

19+
REPORT_DIR="packages/kbn-api-contracts/target/reports"
20+
STACK_REPORT="$REPORT_DIR/stack-impact.json"
21+
SERVERLESS_REPORT="$REPORT_DIR/serverless-impact.json"
22+
rm -f "$STACK_REPORT" "$SERVERLESS_REPORT"
23+
1924
echo "Checking stack API contracts..."
2025
node scripts/check_api_contracts.js \
2126
--distribution stack \
2227
--specPath oas_docs/output/kibana.yaml \
2328
--baseBranch "$BASE_BRANCH" \
29+
--reportPath "$STACK_REPORT" \
2430
"${MERGE_BASE_ARGS[@]+"${MERGE_BASE_ARGS[@]}"}" &
2531
STACK_PID=$!
2632

@@ -29,6 +35,7 @@ node scripts/check_api_contracts.js \
2935
--distribution serverless \
3036
--specPath oas_docs/output/kibana.serverless.yaml \
3137
--baseBranch "$BASE_BRANCH" \
38+
--reportPath "$SERVERLESS_REPORT" \
3239
"${MERGE_BASE_ARGS[@]+"${MERGE_BASE_ARGS[@]}"}" &
3340
SERVERLESS_PID=$!
3441

@@ -38,5 +45,10 @@ wait $STACK_PID || STACK_EXIT=$?
3845
wait $SERVERLESS_PID || SERVERLESS_EXIT=$?
3946

4047
if [ $STACK_EXIT -ne 0 ] || [ $SERVERLESS_EXIT -ne 0 ]; then
48+
echo --- Notify API owners
49+
if [[ "${BUILDKITE_PULL_REQUEST:-false}" != "false" ]]; then
50+
ts-node .buildkite/scripts/steps/checks/notify_api_contract_owners.ts \
51+
"$STACK_REPORT" "$SERVERLESS_REPORT" || echo "Warning: failed to post PR notification"
52+
fi
4153
exit 1
4254
fi
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
jest.mock('#pipeline-utils', () => ({
11+
upsertComment: jest.fn(),
12+
}));
13+
14+
import { buildCommentBody, type ImpactEntry } from './notify_api_contract_owners';
15+
16+
const entry = (overrides: Partial<ImpactEntry> = {}): ImpactEntry => ({
17+
path: '/api/spaces/space',
18+
method: 'GET',
19+
reason: 'Endpoint removed',
20+
terraformResource: 'elasticstack_kibana_space',
21+
owners: ['@elastic/kibana-security'],
22+
...overrides,
23+
});
24+
25+
describe('buildCommentBody', () => {
26+
it('renders a markdown table with one entry', () => {
27+
const body = buildCommentBody([entry()]);
28+
29+
expect(body).toContain('## API Contract Breaking Changes');
30+
expect(body).toContain('| `/api/spaces/space` `GET`');
31+
expect(body).toContain('elasticstack_kibana_space');
32+
expect(body).toContain('@elastic/kibana-security');
33+
});
34+
35+
it('deduplicates owners in the cc line', () => {
36+
const entries = [
37+
entry({ owners: ['@elastic/kibana-security'] }),
38+
entry({ path: '/api/spaces/space/{id}', owners: ['@elastic/kibana-security'] }),
39+
];
40+
const body = buildCommentBody(entries);
41+
42+
const ccLine = body.split('\n').find((l) => l.startsWith('cc '))!;
43+
const mentions = ccLine.replace('cc ', '').trim().split(' ');
44+
expect(mentions).toEqual(['@elastic/kibana-security']);
45+
});
46+
47+
it('aggregates multiple distinct owners', () => {
48+
const entries = [
49+
entry({ owners: ['@elastic/kibana-security'] }),
50+
entry({
51+
path: '/api/fleet/agent_policies',
52+
method: 'POST',
53+
terraformResource: 'elasticstack_fleet_agent_policy',
54+
owners: ['@elastic/fleet'],
55+
}),
56+
];
57+
const body = buildCommentBody(entries);
58+
59+
expect(body).toContain('@elastic/kibana-security');
60+
expect(body).toContain('@elastic/fleet');
61+
});
62+
63+
it('shows _unknown_ when no owners exist', () => {
64+
const body = buildCommentBody([entry({ owners: [] })]);
65+
66+
expect(body).toContain('cc _unknown_');
67+
});
68+
69+
it('escapes pipe characters in the reason field', () => {
70+
const body = buildCommentBody([entry({ reason: 'field|was|removed' })]);
71+
72+
expect(body).toContain('field\\|was\\|removed');
73+
expect(body).not.toContain('field|was|removed');
74+
});
75+
76+
it('escapes newlines in the reason field', () => {
77+
const body = buildCommentBody([entry({ reason: 'line1\nline2' })]);
78+
79+
expect(body).toContain('line1 line2');
80+
expect(body).not.toContain('line1\nline2');
81+
});
82+
83+
it('omits method badge when method is undefined', () => {
84+
const body = buildCommentBody([entry({ method: undefined })]);
85+
86+
expect(body).toContain('| `/api/spaces/space` |');
87+
expect(body).not.toMatch(/`GET`|`POST`|`PUT`|`DELETE`/);
88+
});
89+
});
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
import { readFileSync, existsSync } from 'fs';
11+
import { upsertComment } from '#pipeline-utils';
12+
13+
export interface ImpactEntry {
14+
path: string;
15+
method?: string;
16+
reason: string;
17+
terraformResource: string;
18+
owners: string[];
19+
}
20+
21+
interface ImpactReport {
22+
impactedChanges: ImpactEntry[];
23+
}
24+
25+
const COMMENT_CONTEXT = 'api-contracts-tf-breaking';
26+
27+
const ALLOWLIST_PATH = 'packages/kbn-api-contracts/allowlist.json';
28+
const README_PATH = 'packages/kbn-api-contracts/README.md';
29+
30+
export const buildCommentBody = (entries: ImpactEntry[]): string => {
31+
const allOwners = [...new Set(entries.flatMap((e) => e.owners || []))];
32+
const ownerMentions = allOwners.length > 0 ? allOwners.join(' ') : '_unknown_';
33+
34+
const escapeCell = (text: string): string => text.replace(/\|/g, '\\|').replace(/\n/g, ' ');
35+
36+
const rows = entries
37+
.map((e) => {
38+
const method = e.method ? ` \`${e.method.toUpperCase()}\`` : '';
39+
return `| \`${e.path}\`${method} | ${escapeCell(e.terraformResource)} | ${escapeCell(
40+
e.reason
41+
)} | ${(e.owners || []).join(', ')} |`;
42+
})
43+
.join('\n');
44+
45+
return `## API Contract Breaking Changes — Terraform Provider Impact
46+
47+
cc ${ownerMentions}
48+
49+
The following breaking change(s) affect APIs consumed by the [Elastic Terraform Provider](https://github.com/elastic/terraform-provider-elasticstack).
50+
51+
| Endpoint | Terraform Resource | Reason | Owners |
52+
|----------|--------------------|--------|--------|
53+
${rows}
54+
55+
### What to do
56+
57+
1. **Fix the breaking change** if it was unintentional.
58+
2. **If intentional**, add an approved entry to [\`${ALLOWLIST_PATH}\`](https://github.com/elastic/kibana/blob/main/${ALLOWLIST_PATH}) and coordinate with \`@elastic/terraform-provider\`.
59+
60+
See the [\`@kbn/api-contracts\` README](https://github.com/elastic/kibana/blob/main/${README_PATH}) for details on the allowlist schema and workflow.`;
61+
};
62+
63+
async function main() {
64+
const reportPaths = process.argv.slice(2);
65+
66+
const allEntries: ImpactEntry[] = [];
67+
for (const reportPath of reportPaths) {
68+
if (!existsSync(reportPath)) {
69+
continue;
70+
}
71+
try {
72+
const report: ImpactReport = JSON.parse(readFileSync(reportPath, 'utf-8'));
73+
if (!Array.isArray(report.impactedChanges)) {
74+
console.error(`Report at ${reportPath} has no impactedChanges array, skipping`);
75+
continue;
76+
}
77+
allEntries.push(...report.impactedChanges);
78+
} catch {
79+
console.error(`Failed to parse report at ${reportPath}, skipping`);
80+
}
81+
}
82+
83+
if (allEntries.length === 0) {
84+
console.log('No TF-impacting breaking changes to report');
85+
return;
86+
}
87+
88+
const deduped = Array.from(
89+
new Map(allEntries.map((e) => [`${e.path}::${e.method ?? ''}`, e])).values()
90+
);
91+
92+
const body = buildCommentBody(deduped);
93+
console.log('Posting PR comment notifying API owners...');
94+
95+
await upsertComment({
96+
commentBody: body,
97+
commentContext: COMMENT_CONTEXT,
98+
clearPrevious: true,
99+
});
100+
101+
console.log('PR comment posted successfully');
102+
}
103+
104+
if (require.main === module) {
105+
main().catch((error) => {
106+
console.error('Failed to post API contract notification:', error);
107+
process.exit(1);
108+
});
109+
}

0 commit comments

Comments
 (0)