Skip to content

Commit 4270848

Browse files
Validate all APIs in PRs (#5341) (#5345)
* Validate all APIs in PRs The current code tries to guess which APIs could be affected by the PR, but it does miss things. Now that full validation takes two minutes, we can always use it. * Fix lint * Fix working directory before calling glob * Fix detection of global APIs (cherry picked from commit 4516b79) Co-authored-by: Quentin Pradet <quentin.pradet@elastic.co>
1 parent d5dfbcf commit 4270848

File tree

2 files changed

+33
-60
lines changed

2 files changed

+33
-60
lines changed

.github/validate-pr/index.js

Lines changed: 28 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@
2222
import { dirname } from 'path'
2323
import { fileURLToPath } from 'url'
2424
import 'zx/globals'
25-
import assert from 'assert'
2625
import * as core from '@actions/core'
2726
import { copyFile } from 'fs/promises'
28-
import * as github from '@actions/github'
2927
import specification from '../../output/schema/schema.json' with { type: 'json' }
3028
import baselineValidation from '../../../clients-flight-recorder/recordings/types-validation/types-validation.json' with { type: 'json' }
3129
import { run as getReport } from '../../../clients-flight-recorder/scripts/types-validator/index.js'
@@ -36,7 +34,6 @@ import {
3634

3735
const __dirname = dirname(fileURLToPath(import.meta.url))
3836

39-
const octokit = github.getOctokit(argv.token)
4037

4138
const privateNames = ['_global']
4239
const tick = '`'
@@ -55,51 +52,16 @@ async function run() {
5552
path.join(__dirname, '..', '..', 'output', 'typescript', 'types.ts'),
5653
path.join(tsValidationPath, 'types.ts')
5754
)
58-
const context = github.context
59-
assert(context.payload.pull_request, 'We should be in a PR context')
60-
const files = []
61-
let page = 1
62-
while (true) {
63-
const { data } = await octokit.rest.pulls.listFiles({
64-
owner: 'elastic',
65-
repo: 'elasticsearch-specification',
66-
pull_number: context.payload.pull_request.number,
67-
page,
68-
per_page: 100
69-
})
70-
if (data.length > 0) {
71-
files.push(
72-
...data
73-
.filter((entry) => entry.status !== 'deleted')
74-
.map((entry) => entry.filename)
75-
)
76-
page += 1
77-
} else {
78-
break
79-
}
80-
}
81-
82-
const specFiles = files.filter(
83-
(file) => file.includes('specification') && !file.includes('compiler/test')
84-
)
8555
const reports = new Map()
8656

87-
cd(tsValidationPath)
8857

8958
// Collect all APIs to validate
9059
const apisToValidate = new Set()
9160

92-
for (const file of specFiles) {
61+
cd(path.join(__dirname, '..', '..'))
62+
for (const file of await glob('specification/**/*.ts')) {
9363
if (file.startsWith('specification/_types')) continue
94-
if (file.startsWith('specification/_spec_utils')) continue
95-
if (file.startsWith('specification/_doc_ids')) continue
96-
if (file.startsWith('specification/_json_spec')) continue
9764
if (file.startsWith('specification/node_modules')) continue
98-
if (file.endsWith('tsconfig.json')) continue
99-
if (file.endsWith('eslint.config.js')) continue
100-
if (file.endsWith('package.json')) continue
101-
if (file.endsWith('package-lock.json')) continue
102-
if (file.endsWith('.md')) continue
10365
if (getApi(file).endsWith('_types')) {
10466
const apis = specification.endpoints
10567
.filter(endpoint => endpoint.name.split('.').filter(s => !privateNames.includes(s))[0] === getApi(file).split('.')[0])
@@ -113,26 +75,27 @@ async function run() {
11375
}
11476
}
11577

78+
cd(tsValidationPath)
79+
console.log(`Validating ${apisToValidate.size} APIs...`)
80+
11681
// Call getReport once with all APIs
117-
if (apisToValidate.size > 0) {
118-
const allApis = Array.from(apisToValidate).join(',')
119-
const report = await getReport({
120-
api: allApis,
121-
'generate-report': false,
122-
request: true,
123-
response: true,
124-
ci: false,
125-
verbose: false
126-
})
127-
128-
// Extract individual API reports from the combined result
129-
for (const api of apisToValidate) {
130-
const namespace = getNamespace(api)
131-
if (report.has(namespace)) {
132-
const namespaceReport = report.get(namespace).find(r => r.api === getName(api))
133-
if (namespaceReport) {
134-
reports.set(api, namespaceReport)
135-
}
82+
const allApis = Array.from(apisToValidate).join(',')
83+
const report = await getReport({
84+
api: allApis,
85+
'generate-report': false,
86+
request: true,
87+
response: true,
88+
ci: false,
89+
verbose: false
90+
})
91+
92+
// Extract individual API reports from the combined result
93+
for (const api of apisToValidate) {
94+
const namespace = getNamespace(api)
95+
if (report.has(namespace)) {
96+
const namespaceReport = report.get(namespace).find(r => r.api === getName(api))
97+
if (namespaceReport) {
98+
reports.set(api, namespaceReport)
13699
}
137100
}
138101
}
@@ -170,7 +133,12 @@ function getApi (file) {
170133
}
171134

172135
function findBaselineReport(apiName, baselineValidation) {
173-
const [namespace, method] = apiName.split('.')
136+
let namespace, method = [null, null]
137+
if (!apiName.includes('.')) {
138+
[namespace, method] = ['global', apiName]
139+
} else {
140+
[namespace, method] = apiName.split('.')
141+
}
174142

175143
if (!baselineValidation.namespaces[namespace]) {
176144
return null

specification/_types/Base.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* under the License.
1818
*/
1919

20+
import { FailureStoreStatus } from '@global/bulk/types'
2021
import { CommonQueryParameters } from '@spec_utils/behaviors'
2122
import {
2223
Id,
@@ -63,6 +64,10 @@ export class WriteResponseBase {
6364
* The document version, which is incremented each time the document is updated.
6465
*/
6566
_version: VersionNumber
67+
/**
68+
* The role of the failure store in this document response
69+
*/
70+
failure_store?: FailureStoreStatus
6671
forced_refresh?: boolean
6772
}
6873

0 commit comments

Comments
 (0)