bktide 1.0.1755559112 ā 1.0.1755639164
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/commands/ShowBuild.js +31 -5
- package/dist/commands/ShowBuild.js.map +1 -1
- package/dist/formatters/build-detail/PlainTextFormatter.js +533 -180
- package/dist/formatters/build-detail/PlainTextFormatter.js.map +1 -1
- package/dist/formatters/builds/PlainTextFormatter.js +4 -2
- package/dist/formatters/builds/PlainTextFormatter.js.map +1 -1
- package/dist/formatters/pipelines/PlainTextFormatter.js +3 -6
- package/dist/formatters/pipelines/PlainTextFormatter.js.map +1 -1
- package/dist/graphql/fragments/index.js +3 -0
- package/dist/graphql/fragments/index.js.map +1 -0
- package/dist/graphql/fragments/jobs.js +112 -0
- package/dist/graphql/fragments/jobs.js.map +1 -0
- package/dist/graphql/queries.js +35 -53
- package/dist/graphql/queries.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/scripts/extract-data-patterns.js +118 -0
- package/dist/scripts/extract-data-patterns.js.map +1 -0
- package/dist/services/BuildkiteClient.js +109 -32
- package/dist/services/BuildkiteClient.js.map +1 -1
- package/dist/services/BuildkiteRestClient.js +8 -7
- package/dist/services/BuildkiteRestClient.js.map +1 -1
- package/dist/test-helpers/DataProfiler.js +307 -0
- package/dist/test-helpers/DataProfiler.js.map +1 -0
- package/dist/test-helpers/PatternMockGenerator.js +590 -0
- package/dist/test-helpers/PatternMockGenerator.js.map +1 -0
- package/dist/ui/theme.js +193 -8
- package/dist/ui/theme.js.map +1 -1
- package/dist/utils/terminal-links.js +165 -0
- package/dist/utils/terminal-links.js.map +1 -0
- package/package.json +19 -3
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { gql } from 'graphql-request';
|
|
2
|
+
/**
|
|
3
|
+
* Fragment for basic job fields used in summary views
|
|
4
|
+
* This is the minimal set of fields needed for job lists
|
|
5
|
+
*/
|
|
6
|
+
export const JOB_SUMMARY_FIELDS = gql `
|
|
7
|
+
fragment JobSummaryFields on JobInterface {
|
|
8
|
+
... on JobTypeCommand {
|
|
9
|
+
id
|
|
10
|
+
uuid
|
|
11
|
+
label
|
|
12
|
+
state
|
|
13
|
+
exitStatus
|
|
14
|
+
startedAt
|
|
15
|
+
finishedAt
|
|
16
|
+
passed
|
|
17
|
+
parallelGroupIndex
|
|
18
|
+
parallelGroupTotal
|
|
19
|
+
}
|
|
20
|
+
... on JobTypeWait {
|
|
21
|
+
id
|
|
22
|
+
label
|
|
23
|
+
}
|
|
24
|
+
... on JobTypeTrigger {
|
|
25
|
+
id
|
|
26
|
+
label
|
|
27
|
+
state
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`;
|
|
31
|
+
/**
|
|
32
|
+
* Fragment for detailed job fields used in full views
|
|
33
|
+
* Includes all summary fields plus additional details
|
|
34
|
+
*/
|
|
35
|
+
export const JOB_DETAIL_FIELDS = gql `
|
|
36
|
+
fragment JobDetailFields on JobInterface {
|
|
37
|
+
... on JobTypeCommand {
|
|
38
|
+
id
|
|
39
|
+
uuid
|
|
40
|
+
label
|
|
41
|
+
command
|
|
42
|
+
state
|
|
43
|
+
exitStatus
|
|
44
|
+
startedAt
|
|
45
|
+
finishedAt
|
|
46
|
+
passed
|
|
47
|
+
retried
|
|
48
|
+
parallelGroupIndex
|
|
49
|
+
parallelGroupTotal
|
|
50
|
+
retrySource {
|
|
51
|
+
... on JobTypeCommand {
|
|
52
|
+
id
|
|
53
|
+
uuid
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
agent {
|
|
57
|
+
... on Agent {
|
|
58
|
+
id
|
|
59
|
+
name
|
|
60
|
+
hostname
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
... on JobTypeWait {
|
|
65
|
+
id
|
|
66
|
+
label
|
|
67
|
+
}
|
|
68
|
+
... on JobTypeTrigger {
|
|
69
|
+
id
|
|
70
|
+
label
|
|
71
|
+
state
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
/**
|
|
76
|
+
* Fragment for jobs connection with pagination info
|
|
77
|
+
* Can be used with either summary or detail fields
|
|
78
|
+
*/
|
|
79
|
+
export const JOBS_CONNECTION = gql `
|
|
80
|
+
fragment JobsConnection on JobConnection {
|
|
81
|
+
edges {
|
|
82
|
+
node {
|
|
83
|
+
...JobSummaryFields
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
pageInfo {
|
|
87
|
+
hasNextPage
|
|
88
|
+
endCursor
|
|
89
|
+
}
|
|
90
|
+
count
|
|
91
|
+
}
|
|
92
|
+
${JOB_SUMMARY_FIELDS}
|
|
93
|
+
`;
|
|
94
|
+
/**
|
|
95
|
+
* Fragment for detailed jobs connection
|
|
96
|
+
*/
|
|
97
|
+
export const JOBS_CONNECTION_DETAILED = gql `
|
|
98
|
+
fragment JobsConnectionDetailed on JobConnection {
|
|
99
|
+
edges {
|
|
100
|
+
node {
|
|
101
|
+
...JobDetailFields
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
pageInfo {
|
|
105
|
+
hasNextPage
|
|
106
|
+
endCursor
|
|
107
|
+
}
|
|
108
|
+
count
|
|
109
|
+
}
|
|
110
|
+
${JOB_DETAIL_FIELDS}
|
|
111
|
+
`;
|
|
112
|
+
//# sourceMappingURL=jobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs.js","sourceRoot":"/","sources":["graphql/fragments/jobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAEtC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwBpC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCnC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAA;;;;;;;;;;;;;IAa9B,kBAAkB;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAG,CAAA;;;;;;;;;;;;;IAavC,iBAAiB;CACpB,CAAC","sourcesContent":["import { gql } from 'graphql-request';\n\n/**\n * Fragment for basic job fields used in summary views\n * This is the minimal set of fields needed for job lists\n */\nexport const JOB_SUMMARY_FIELDS = gql`\n fragment JobSummaryFields on JobInterface {\n ... on JobTypeCommand {\n id\n uuid\n label\n state\n exitStatus\n startedAt\n finishedAt\n passed\n parallelGroupIndex\n parallelGroupTotal\n }\n ... on JobTypeWait {\n id\n label\n }\n ... on JobTypeTrigger {\n id\n label\n state\n }\n }\n`;\n\n/**\n * Fragment for detailed job fields used in full views\n * Includes all summary fields plus additional details\n */\nexport const JOB_DETAIL_FIELDS = gql`\n fragment JobDetailFields on JobInterface {\n ... on JobTypeCommand {\n id\n uuid\n label\n command\n state\n exitStatus\n startedAt\n finishedAt\n passed\n retried\n parallelGroupIndex\n parallelGroupTotal\n retrySource {\n ... on JobTypeCommand {\n id\n uuid\n }\n }\n agent {\n ... on Agent {\n id\n name\n hostname\n }\n }\n }\n ... on JobTypeWait {\n id\n label\n }\n ... on JobTypeTrigger {\n id\n label\n state\n }\n }\n`;\n\n/**\n * Fragment for jobs connection with pagination info\n * Can be used with either summary or detail fields\n */\nexport const JOBS_CONNECTION = gql`\n fragment JobsConnection on JobConnection {\n edges {\n node {\n ...JobSummaryFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n count\n }\n ${JOB_SUMMARY_FIELDS}\n`;\n\n/**\n * Fragment for detailed jobs connection\n */\nexport const JOBS_CONNECTION_DETAILED = gql`\n fragment JobsConnectionDetailed on JobConnection {\n edges {\n node {\n ...JobDetailFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n count\n }\n ${JOB_DETAIL_FIELDS}\n`;\n"]}
|
package/dist/graphql/queries.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Common GraphQL queries for the Buildkite API
|
|
3
3
|
*/
|
|
4
4
|
import { gql } from 'graphql-request';
|
|
5
|
+
import { JOB_SUMMARY_FIELDS, JOB_DETAIL_FIELDS } from './fragments/index.js';
|
|
5
6
|
export const GET_VIEWER = gql `
|
|
6
7
|
query GetViewer {
|
|
7
8
|
viewer {
|
|
@@ -177,27 +178,14 @@ export const GET_BUILD_SUMMARY = gql `
|
|
|
177
178
|
jobs(first: 100) {
|
|
178
179
|
edges {
|
|
179
180
|
node {
|
|
180
|
-
...
|
|
181
|
-
id
|
|
182
|
-
uuid
|
|
183
|
-
label
|
|
184
|
-
state
|
|
185
|
-
exitStatus
|
|
186
|
-
startedAt
|
|
187
|
-
finishedAt
|
|
188
|
-
passed
|
|
189
|
-
}
|
|
190
|
-
... on JobTypeWait {
|
|
191
|
-
id
|
|
192
|
-
label
|
|
193
|
-
}
|
|
194
|
-
... on JobTypeTrigger {
|
|
195
|
-
id
|
|
196
|
-
label
|
|
197
|
-
state
|
|
198
|
-
}
|
|
181
|
+
...JobSummaryFields
|
|
199
182
|
}
|
|
200
183
|
}
|
|
184
|
+
pageInfo {
|
|
185
|
+
hasNextPage
|
|
186
|
+
endCursor
|
|
187
|
+
}
|
|
188
|
+
count
|
|
201
189
|
}
|
|
202
190
|
annotations(first: 50) {
|
|
203
191
|
edges {
|
|
@@ -213,6 +201,7 @@ export const GET_BUILD_SUMMARY = gql `
|
|
|
213
201
|
}
|
|
214
202
|
}
|
|
215
203
|
}
|
|
204
|
+
${JOB_SUMMARY_FIELDS}
|
|
216
205
|
`;
|
|
217
206
|
export const GET_BUILD_FULL = gql `
|
|
218
207
|
query GetBuildFull($slug: ID!) {
|
|
@@ -262,42 +251,14 @@ export const GET_BUILD_FULL = gql `
|
|
|
262
251
|
jobs(first: 100) {
|
|
263
252
|
edges {
|
|
264
253
|
node {
|
|
265
|
-
...
|
|
266
|
-
id
|
|
267
|
-
uuid
|
|
268
|
-
label
|
|
269
|
-
command
|
|
270
|
-
state
|
|
271
|
-
exitStatus
|
|
272
|
-
startedAt
|
|
273
|
-
finishedAt
|
|
274
|
-
passed
|
|
275
|
-
retried
|
|
276
|
-
retrySource {
|
|
277
|
-
... on JobTypeCommand {
|
|
278
|
-
id
|
|
279
|
-
uuid
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
agent {
|
|
283
|
-
... on Agent {
|
|
284
|
-
id
|
|
285
|
-
name
|
|
286
|
-
hostname
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
... on JobTypeWait {
|
|
291
|
-
id
|
|
292
|
-
label
|
|
293
|
-
}
|
|
294
|
-
... on JobTypeTrigger {
|
|
295
|
-
id
|
|
296
|
-
label
|
|
297
|
-
state
|
|
298
|
-
}
|
|
254
|
+
...JobDetailFields
|
|
299
255
|
}
|
|
300
256
|
}
|
|
257
|
+
pageInfo {
|
|
258
|
+
hasNextPage
|
|
259
|
+
endCursor
|
|
260
|
+
}
|
|
261
|
+
count
|
|
301
262
|
}
|
|
302
263
|
annotations(first: 100) {
|
|
303
264
|
edges {
|
|
@@ -315,5 +276,26 @@ export const GET_BUILD_FULL = gql `
|
|
|
315
276
|
}
|
|
316
277
|
}
|
|
317
278
|
}
|
|
279
|
+
${JOB_DETAIL_FIELDS}
|
|
280
|
+
`;
|
|
281
|
+
export const GET_BUILD_JOBS_PAGE = gql `
|
|
282
|
+
query GetBuildJobsPage($slug: ID!, $first: Int!, $after: String) {
|
|
283
|
+
build(slug: $slug) {
|
|
284
|
+
id
|
|
285
|
+
jobs(first: $first, after: $after) {
|
|
286
|
+
edges {
|
|
287
|
+
node {
|
|
288
|
+
...JobSummaryFields
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
pageInfo {
|
|
292
|
+
hasNextPage
|
|
293
|
+
endCursor
|
|
294
|
+
}
|
|
295
|
+
count
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
${JOB_SUMMARY_FIELDS}
|
|
318
300
|
`;
|
|
319
301
|
//# sourceMappingURL=queries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sourceRoot":"/","sources":["graphql/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"/","sources":["graphql/queries.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE7E,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;CAY5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;CAcnC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;CAwB/B,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B5B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BnC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;CAgBvC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiEhC,kBAAkB;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyE7B,iBAAiB;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;IAkBlC,kBAAkB;CACrB,CAAC","sourcesContent":["/**\n * Common GraphQL queries for the Buildkite API\n */\nimport { gql } from 'graphql-request';\nimport { JOB_SUMMARY_FIELDS, JOB_DETAIL_FIELDS } from './fragments/index.js';\n\nexport const GET_VIEWER = gql`\n query GetViewer {\n viewer {\n id\n user {\n id\n uuid\n name\n email\n }\n }\n }\n`;\n\nexport const GET_ORGANIZATIONS = gql`\n query GetOrganizations {\n viewer {\n organizations {\n edges {\n node {\n id\n name\n slug\n }\n }\n }\n }\n }\n`;\n\nexport const GET_PIPELINES = gql`\n query GetPipelines($organizationSlug: ID!, $first: Int, $after: String) {\n organization(slug: $organizationSlug) {\n pipelines(first: $first, after: $after, archived: false) {\n edges {\n node {\n uuid\n id\n name\n slug\n description\n url\n repository {\n url\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILDS = gql`\n query GetBuilds($pipelineSlug: String!, $organizationSlug: ID!, $first: Int) {\n organization(slug: $organizationSlug) {\n pipelines(first: 1, search: $pipelineSlug) {\n edges {\n node {\n builds(first: $first) {\n edges {\n node {\n id\n number\n url\n state\n message\n commit\n branch\n createdAt\n startedAt\n finishedAt\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_VIEWER_BUILDS = gql`\n query GetViewerBuilds($first: Int!) {\n viewer {\n builds(first: $first) {\n edges {\n node {\n id\n number\n state\n url\n createdAt\n branch\n message\n pipeline {\n name\n slug\n }\n organization {\n name\n slug\n }\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_ANNOTATIONS = gql`\n query GetBuildAnnotations($buildSlug: ID!) {\n build(slug: $buildSlug) {\n annotations(first: 100) {\n edges {\n node {\n context\n style\n body {\n html\n }\n }\n }\n }\n }\n }\n`;\n\nexport const GET_BUILD_SUMMARY = gql`\n query GetBuildSummary($slug: ID!) {\n build(slug: $slug) {\n id\n number\n state\n branch\n message\n commit\n createdAt\n startedAt\n finishedAt\n canceledAt\n url\n blockedState\n createdBy {\n ... on User {\n id\n name\n email\n avatar {\n url\n }\n }\n ... on UnregisteredUser {\n name\n email\n }\n }\n pipeline {\n id\n name\n slug\n }\n organization {\n id\n name\n slug\n }\n jobs(first: 100) {\n edges {\n node {\n ...JobSummaryFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n count\n }\n annotations(first: 50) {\n edges {\n node {\n id\n style\n context\n body {\n html\n }\n }\n }\n }\n }\n }\n ${JOB_SUMMARY_FIELDS}\n`;\n\nexport const GET_BUILD_FULL = gql`\n query GetBuildFull($slug: ID!) {\n build(slug: $slug) {\n id\n number\n state\n branch\n message\n commit\n createdAt\n startedAt\n finishedAt\n canceledAt\n url\n blockedState\n createdBy {\n ... on User {\n id\n name\n email\n avatar {\n url\n }\n }\n ... on UnregisteredUser {\n name\n email\n }\n }\n pipeline {\n id\n name\n slug\n repository {\n url\n }\n }\n organization {\n id\n name\n slug\n }\n pullRequest {\n id\n }\n jobs(first: 100) {\n edges {\n node {\n ...JobDetailFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n count\n }\n annotations(first: 100) {\n edges {\n node {\n id\n style\n context\n body {\n html\n }\n createdAt\n updatedAt\n }\n }\n }\n }\n }\n ${JOB_DETAIL_FIELDS}\n`;\n\nexport const GET_BUILD_JOBS_PAGE = gql`\n query GetBuildJobsPage($slug: ID!, $first: Int!, $after: String) {\n build(slug: $slug) {\n id\n jobs(first: $first, after: $after) {\n edges {\n node {\n ...JobSummaryFields\n }\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n count\n }\n }\n }\n ${JOB_SUMMARY_FIELDS}\n`; "]}
|
package/dist/index.js
CHANGED
|
@@ -275,6 +275,7 @@ program
|
|
|
275
275
|
.argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')
|
|
276
276
|
.option('--jobs', 'Show job summary and details')
|
|
277
277
|
.option('--failed', 'Show only failed job details (implies --jobs)')
|
|
278
|
+
.option('--all-jobs', 'Show all jobs without grouping limit')
|
|
278
279
|
.option('--annotations', 'Show annotation details with context')
|
|
279
280
|
.option('--annotations-full', 'Show complete annotation content')
|
|
280
281
|
.option('--full', 'Show all available information')
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport {\n BaseCommand,\n ShowViewer,\n ListOrganizations,\n ListBuilds,\n ListPipelines,\n ManageToken,\n ListAnnotations,\n GenerateCompletions,\n ShowBuild\n} from './commands/index.js';\nimport { initializeErrorHandling } from './utils/errorUtils.js';\nimport { displayCLIError, setErrorFormat } from './utils/cli-error-handler.js';\nimport { logger, setLogLevel } from './services/logger.js';\nimport { WidthAwareHelp } from './ui/help.js';\n\n// Set a global error handler for uncaught exceptions\nconst uncaughtExceptionHandler = (err: Error) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('uncaughtException');\n handlers.forEach(listener => {\n if (listener !== uncaughtExceptionHandler) {\n process.removeListener('uncaughtException', listener);\n }\n });\n \n displayCLIError(\n err, \n process.argv.includes('--debug')\n );\n};\nprocess.on('uncaughtException', uncaughtExceptionHandler);\n\n// Set a global error handler for unhandled promise rejections\nconst unhandledRejectionHandler = (reason: unknown) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('unhandledRejection');\n handlers.forEach(listener => {\n if (listener !== unhandledRejectionHandler) {\n process.removeListener('unhandledRejection', listener);\n }\n });\n \n displayCLIError(\n reason, \n process.argv.includes('--debug')\n );\n};\nprocess.on('unhandledRejection', unhandledRejectionHandler);\n\n// Initialize error handling after our handlers are registered\ninitializeErrorHandling();\n\nconst program = new Command();\n\n// Define a generic interface for the command classes that includes the execute method\ninterface CommandWithExecute {\n execute(options: any): Promise<number>;\n}\n\n// Define a type for the constructor that includes static properties\ntype CommandConstructor = {\n new (options?: any): BaseCommand & CommandWithExecute;\n requiresToken: boolean;\n}\n\n// Extend the Command type to include our custom properties\ninterface ExtendedCommand extends Command {\n mergedOptions?: any;\n pipelineOptions?: {\n organization?: string;\n count?: number;\n filter?: string;\n };\n buildOptions?: {\n organization?: string;\n pipeline?: string;\n branch?: string;\n state?: string;\n count: number;\n page: number;\n filter?: string;\n };\n}\n\n// Handler for executing commands with proper option handling\nconst createCommandHandler = (CommandClass: CommandConstructor) => {\n return async function(this: ExtendedCommand) {\n try {\n const options = this.mergedOptions || this.opts();\n const cacheOptions = { enabled: options.cache !== false, ttl: options.cacheTtl, clear: options.clearCache };\n\n if (CommandClass.requiresToken) {\n const token = await BaseCommand.getToken(options);\n options.token = token;\n }\n \n const handler = new CommandClass({\n ...cacheOptions,\n token: options.token,\n debug: options.debug,\n format: options.format,\n quiet: options.quiet,\n tips: options.tips,\n });\n \n // Pass command-specific options if available\n const commandName = this.name();\n if (commandName === 'pipelines' && this.pipelineOptions) {\n logger.debug('Using pipeline options:', this.pipelineOptions);\n }\n else if (commandName === 'builds' && this.buildOptions) {\n logger.debug('Using build options:', this.buildOptions);\n }\n \n const exitCode = await handler.execute(options);\n // Set process.exitCode to propagate the exit code\n process.exitCode = exitCode;\n } catch (error) {\n const debug = this.mergedOptions?.debug || this.opts().debug || false;\n // No need to pass format - will use global format set in preAction hook\n displayCLIError(error, debug);\n process.exitCode = 1; // Set error exit code\n }\n };\n};\n\nfunction resolveAppVersion(): string {\n // Prefer environment-provided version (set in CI before publish)\n if (process.env.BKTIDE_VERSION && process.env.BKTIDE_VERSION.trim().length > 0) {\n return process.env.BKTIDE_VERSION.trim();\n }\n\n try {\n // Attempt to read package.json near compiled dist/index.js\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidatePaths = [\n path.resolve(__dirname, '..', 'package.json'), // when running from dist/\n path.resolve(__dirname, '..', '..', 'package.json'), // fallback\n ];\n for (const pkgPath of candidatePaths) {\n if (fs.existsSync(pkgPath)) {\n const raw = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string };\n if (pkg.version) return pkg.version;\n }\n }\n } catch {\n // ignore\n }\n\n // Last resort\n return '0.0.0';\n}\n\n// Create custom help instance\nconst customHelp = new WidthAwareHelp();\n\nprogram\n .name('bktide')\n .description('Buildkite CLI tool')\n .version(resolveAppVersion())\n .configureHelp(customHelp)\n .showSuggestionAfterError()\n .option('--log-level <level>', 'Set logging level (trace, debug, info, warn, error, fatal)', 'info')\n .option('-d, --debug', 'Show debug information for errors')\n .option('--no-cache', 'Disable caching of API responses')\n .option('--cache-ttl <milliseconds>', 'Set cache time-to-live in milliseconds', parseInt)\n .option('--clear-cache', 'Clear all cached data before executing command')\n .option('-t, --token <token>', 'Buildkite API token (set BUILDKITE_API_TOKEN or BK_TOKEN env var)', process.env.BUILDKITE_API_TOKEN || process.env.BK_TOKEN)\n .option('--save-token', 'Save the token to system keychain for future use')\n .option('-f, --format <format>', 'Output format for results and errors (plain, json, alfred)', 'plain')\n .option('--color <mode>', 'Color output: auto|always|never', 'auto')\n .option('-q, --quiet', 'Suppress non-error output (plain format only)')\n .option('--tips', 'Show helpful tips and suggestions')\n .option('--no-tips', 'Hide helpful tips and suggestions')\n .option('--ascii', 'Use ASCII symbols instead of Unicode');\n\n// Add hooks for handling options\nprogram\n .hook('preAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Merge global options with command-specific options\n const globalOpts = program.opts();\n const commandOpts = cmd.opts();\n const mergedOptions = { ...globalOpts, ...commandOpts };\n \n // Set the global error format from the command line options\n if (mergedOptions.format) {\n setErrorFormat(mergedOptions.format);\n }\n\n // Apply color mode\n if (mergedOptions.color) {\n const mode = String(mergedOptions.color).toLowerCase();\n // Respect NO_COLOR when mode is never; clear when always\n if (mode === 'never') {\n process.env.NO_COLOR = '1';\n } else if (mode === 'always') {\n // Explicitly enable color by unsetting NO_COLOR; downstream code should still TTY-check\n if (process.env.NO_COLOR) {\n delete process.env.NO_COLOR;\n }\n process.env.BKTIDE_COLOR_MODE = 'always';\n } else {\n // auto\n process.env.BKTIDE_COLOR_MODE = 'auto';\n }\n }\n \n if (mergedOptions.cacheTtl && (isNaN(mergedOptions.cacheTtl) || mergedOptions.cacheTtl <= 0)) {\n logger.error('cache-ttl must be a positive number');\n process.exitCode = 1;\n return;\n }\n \n if (mergedOptions.cache === false && mergedOptions.cacheTtl) {\n logger.warn('--no-cache and --cache-ttl used together. Cache will be disabled regardless of TTL setting.');\n }\n \n // Validate count options\n if (mergedOptions.count && (isNaN(parseInt(mergedOptions.count)) || parseInt(mergedOptions.count) <= 0)) {\n logger.error('count must be a positive number');\n process.exitCode = 1;\n return;\n }\n\n cmd.mergedOptions = mergedOptions;\n\n const commandName = cmd.name();\n\n if (commandName === 'pipelines') {\n // Create pipeline-specific options structure\n cmd.pipelineOptions = {\n organization: mergedOptions.org,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : undefined,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Pipeline options:', cmd.pipelineOptions);\n }\n }\n else if (commandName === 'builds') {\n // Create builds-specific options structure\n cmd.buildOptions = {\n organization: mergedOptions.org,\n pipeline: mergedOptions.pipeline,\n branch: mergedOptions.branch,\n state: mergedOptions.state,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : 10,\n page: mergedOptions.page ? parseInt(mergedOptions.page) : 1,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Build options:', cmd.buildOptions);\n }\n }\n else if (commandName === 'annotations') {\n // Attach the build argument to options\n cmd.mergedOptions.buildArg = cmd.args?.[0];\n \n if (mergedOptions.debug) {\n logger.debug('Annotations build arg:', cmd.mergedOptions.buildArg);\n logger.debug('Annotations context filter:', mergedOptions.context);\n }\n }\n else if (commandName === 'build') {\n // Attach the build argument to options\n cmd.mergedOptions.buildArg = cmd.args?.[0];\n \n if (mergedOptions.debug) {\n logger.debug('Build arg:', cmd.mergedOptions.buildArg);\n logger.debug('Build options:', mergedOptions);\n }\n }\n \n if (mergedOptions.debug) {\n logger.debug(`Executing command: ${commandName}`);\n logger.debug('Options:', mergedOptions);\n }\n })\n .hook('postAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Accessing the custom property\n const options = cmd.mergedOptions || {};\n if (options.debug) {\n logger.debug(`Command ${cmd.name()} completed`);\n }\n });\n\nprogram\n .command('viewer')\n .description('Show logged in user information')\n .action(createCommandHandler(ShowViewer));\n\nprogram\n .command('orgs')\n .description('List organizations')\n .action(createCommandHandler(ListOrganizations));\n\nprogram\n .command('pipelines')\n .description('List pipelines for an organization')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-n, --count <count>', 'Limit to specified number of pipelines per organization')\n .option('--filter <name>', 'Filter pipelines by name (case insensitive)')\n .action(createCommandHandler(ListPipelines));\n\n// Update the builds command to include REST API filtering options\nprogram\n .command('builds')\n .description('List builds for the current user')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-p, --pipeline <pipeline>', 'Filter by pipeline slug')\n .option('-b, --branch <branch>', 'Filter by branch name')\n .option('-s, --state <state>', 'Filter by build state (running, scheduled, passed, failing, failed, canceled, etc.)')\n .option('-n, --count <count>', 'Number of builds per page', '10')\n .option('--page <page>', 'Page number', '1')\n .option('--filter <filter>', 'Fuzzy filter builds by name or other properties')\n .action(createCommandHandler(ListBuilds));\n\n// Add token management command\nprogram\n .command('token')\n .description('Manage API tokens')\n .option('--check', 'Check if a token is stored in the system keychain')\n .option('--store', 'Store a token in the system keychain')\n .option('--reset', 'Delete the stored token from system keychain')\n .action(createCommandHandler(ManageToken));\n\n// Add annotations command\nprogram\n .command('annotations')\n .description('Show annotations for a build')\n .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')\n .option('--context <context>', 'Filter annotations by context (e.g., rspec, build-resources)')\n .action(createCommandHandler(ListAnnotations));\n\n// Add build command\nprogram\n .command('build')\n .description('Show details for a specific build')\n .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')\n .option('--jobs', 'Show job summary and details')\n .option('--failed', 'Show only failed job details (implies --jobs)')\n .option('--annotations', 'Show annotation details with context')\n .option('--annotations-full', 'Show complete annotation content')\n .option('--full', 'Show all available information')\n .option('--summary', 'Single-line summary only (for scripts)')\n .action(createCommandHandler(ShowBuild));\n\n// Add completions command\nprogram\n .command('completions [shell]')\n .description('Generate shell completions')\n .action(async (shell) => {\n const handler = new GenerateCompletions();\n const exitCode = await handler.execute({ shell, quiet: program.opts().quiet, debug: program.opts().debug });\n process.exitCode = exitCode;\n });\n\nprogram\n .command('boom')\n .description('Test error handling')\n .option('--type <type>', 'Type of error to throw (basic, api, object)', 'basic')\n .option('--format <format>', 'Output format (plain, json, alfred)', 'plain')\n .action((options) => {\n switch (options.type) {\n case 'api':\n const apiError = new Error('API request failed');\n (apiError as any).response = {\n errors: [\n { message: 'Invalid token', path: ['viewer'] }\n ]\n };\n throw apiError;\n \n case 'object':\n throw {\n message: 'This is not an Error instance',\n code: 'CUSTOM_ERROR'\n };\n \n case 'basic':\n default:\n throw new Error('Boom! This is a test error');\n }\n });\n\nprogram.parse();\n\n// Apply log level from command line options\nconst options = program.opts();\nif (options.debug) {\n // Debug mode takes precedence over log-level\n setLogLevel('debug');\n logger.debug('Debug mode enabled via --debug flag');\n} else if (options.logLevel) {\n setLogLevel(options.logLevel);\n logger.debug(`Log level set to ${options.logLevel} via --log-level option`);\n}\n\nlogger.debug({ \n pid: process.pid, \n}, 'Buildkite CLI started'); "]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport fs from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nimport {\n BaseCommand,\n ShowViewer,\n ListOrganizations,\n ListBuilds,\n ListPipelines,\n ManageToken,\n ListAnnotations,\n GenerateCompletions,\n ShowBuild\n} from './commands/index.js';\nimport { initializeErrorHandling } from './utils/errorUtils.js';\nimport { displayCLIError, setErrorFormat } from './utils/cli-error-handler.js';\nimport { logger, setLogLevel } from './services/logger.js';\nimport { WidthAwareHelp } from './ui/help.js';\n\n// Set a global error handler for uncaught exceptions\nconst uncaughtExceptionHandler = (err: Error) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('uncaughtException');\n handlers.forEach(listener => {\n if (listener !== uncaughtExceptionHandler) {\n process.removeListener('uncaughtException', listener);\n }\n });\n \n displayCLIError(\n err, \n process.argv.includes('--debug')\n );\n};\nprocess.on('uncaughtException', uncaughtExceptionHandler);\n\n// Set a global error handler for unhandled promise rejections\nconst unhandledRejectionHandler = (reason: unknown) => {\n // Remove any existing handlers to avoid duplicates\n const handlers = process.listeners('unhandledRejection');\n handlers.forEach(listener => {\n if (listener !== unhandledRejectionHandler) {\n process.removeListener('unhandledRejection', listener);\n }\n });\n \n displayCLIError(\n reason, \n process.argv.includes('--debug')\n );\n};\nprocess.on('unhandledRejection', unhandledRejectionHandler);\n\n// Initialize error handling after our handlers are registered\ninitializeErrorHandling();\n\nconst program = new Command();\n\n// Define a generic interface for the command classes that includes the execute method\ninterface CommandWithExecute {\n execute(options: any): Promise<number>;\n}\n\n// Define a type for the constructor that includes static properties\ntype CommandConstructor = {\n new (options?: any): BaseCommand & CommandWithExecute;\n requiresToken: boolean;\n}\n\n// Extend the Command type to include our custom properties\ninterface ExtendedCommand extends Command {\n mergedOptions?: any;\n pipelineOptions?: {\n organization?: string;\n count?: number;\n filter?: string;\n };\n buildOptions?: {\n organization?: string;\n pipeline?: string;\n branch?: string;\n state?: string;\n count: number;\n page: number;\n filter?: string;\n };\n}\n\n// Handler for executing commands with proper option handling\nconst createCommandHandler = (CommandClass: CommandConstructor) => {\n return async function(this: ExtendedCommand) {\n try {\n const options = this.mergedOptions || this.opts();\n const cacheOptions = { enabled: options.cache !== false, ttl: options.cacheTtl, clear: options.clearCache };\n\n if (CommandClass.requiresToken) {\n const token = await BaseCommand.getToken(options);\n options.token = token;\n }\n \n const handler = new CommandClass({\n ...cacheOptions,\n token: options.token,\n debug: options.debug,\n format: options.format,\n quiet: options.quiet,\n tips: options.tips,\n });\n \n // Pass command-specific options if available\n const commandName = this.name();\n if (commandName === 'pipelines' && this.pipelineOptions) {\n logger.debug('Using pipeline options:', this.pipelineOptions);\n }\n else if (commandName === 'builds' && this.buildOptions) {\n logger.debug('Using build options:', this.buildOptions);\n }\n \n const exitCode = await handler.execute(options);\n // Set process.exitCode to propagate the exit code\n process.exitCode = exitCode;\n } catch (error) {\n const debug = this.mergedOptions?.debug || this.opts().debug || false;\n // No need to pass format - will use global format set in preAction hook\n displayCLIError(error, debug);\n process.exitCode = 1; // Set error exit code\n }\n };\n};\n\nfunction resolveAppVersion(): string {\n // Prefer environment-provided version (set in CI before publish)\n if (process.env.BKTIDE_VERSION && process.env.BKTIDE_VERSION.trim().length > 0) {\n return process.env.BKTIDE_VERSION.trim();\n }\n\n try {\n // Attempt to read package.json near compiled dist/index.js\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n const candidatePaths = [\n path.resolve(__dirname, '..', 'package.json'), // when running from dist/\n path.resolve(__dirname, '..', '..', 'package.json'), // fallback\n ];\n for (const pkgPath of candidatePaths) {\n if (fs.existsSync(pkgPath)) {\n const raw = fs.readFileSync(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { version?: string };\n if (pkg.version) return pkg.version;\n }\n }\n } catch {\n // ignore\n }\n\n // Last resort\n return '0.0.0';\n}\n\n// Create custom help instance\nconst customHelp = new WidthAwareHelp();\n\nprogram\n .name('bktide')\n .description('Buildkite CLI tool')\n .version(resolveAppVersion())\n .configureHelp(customHelp)\n .showSuggestionAfterError()\n .option('--log-level <level>', 'Set logging level (trace, debug, info, warn, error, fatal)', 'info')\n .option('-d, --debug', 'Show debug information for errors')\n .option('--no-cache', 'Disable caching of API responses')\n .option('--cache-ttl <milliseconds>', 'Set cache time-to-live in milliseconds', parseInt)\n .option('--clear-cache', 'Clear all cached data before executing command')\n .option('-t, --token <token>', 'Buildkite API token (set BUILDKITE_API_TOKEN or BK_TOKEN env var)', process.env.BUILDKITE_API_TOKEN || process.env.BK_TOKEN)\n .option('--save-token', 'Save the token to system keychain for future use')\n .option('-f, --format <format>', 'Output format for results and errors (plain, json, alfred)', 'plain')\n .option('--color <mode>', 'Color output: auto|always|never', 'auto')\n .option('-q, --quiet', 'Suppress non-error output (plain format only)')\n .option('--tips', 'Show helpful tips and suggestions')\n .option('--no-tips', 'Hide helpful tips and suggestions')\n .option('--ascii', 'Use ASCII symbols instead of Unicode');\n\n// Add hooks for handling options\nprogram\n .hook('preAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Merge global options with command-specific options\n const globalOpts = program.opts();\n const commandOpts = cmd.opts();\n const mergedOptions = { ...globalOpts, ...commandOpts };\n \n // Set the global error format from the command line options\n if (mergedOptions.format) {\n setErrorFormat(mergedOptions.format);\n }\n\n // Apply color mode\n if (mergedOptions.color) {\n const mode = String(mergedOptions.color).toLowerCase();\n // Respect NO_COLOR when mode is never; clear when always\n if (mode === 'never') {\n process.env.NO_COLOR = '1';\n } else if (mode === 'always') {\n // Explicitly enable color by unsetting NO_COLOR; downstream code should still TTY-check\n if (process.env.NO_COLOR) {\n delete process.env.NO_COLOR;\n }\n process.env.BKTIDE_COLOR_MODE = 'always';\n } else {\n // auto\n process.env.BKTIDE_COLOR_MODE = 'auto';\n }\n }\n \n if (mergedOptions.cacheTtl && (isNaN(mergedOptions.cacheTtl) || mergedOptions.cacheTtl <= 0)) {\n logger.error('cache-ttl must be a positive number');\n process.exitCode = 1;\n return;\n }\n \n if (mergedOptions.cache === false && mergedOptions.cacheTtl) {\n logger.warn('--no-cache and --cache-ttl used together. Cache will be disabled regardless of TTL setting.');\n }\n \n // Validate count options\n if (mergedOptions.count && (isNaN(parseInt(mergedOptions.count)) || parseInt(mergedOptions.count) <= 0)) {\n logger.error('count must be a positive number');\n process.exitCode = 1;\n return;\n }\n\n cmd.mergedOptions = mergedOptions;\n\n const commandName = cmd.name();\n\n if (commandName === 'pipelines') {\n // Create pipeline-specific options structure\n cmd.pipelineOptions = {\n organization: mergedOptions.org,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : undefined,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Pipeline options:', cmd.pipelineOptions);\n }\n }\n else if (commandName === 'builds') {\n // Create builds-specific options structure\n cmd.buildOptions = {\n organization: mergedOptions.org,\n pipeline: mergedOptions.pipeline,\n branch: mergedOptions.branch,\n state: mergedOptions.state,\n count: mergedOptions.count ? parseInt(mergedOptions.count) : 10,\n page: mergedOptions.page ? parseInt(mergedOptions.page) : 1,\n filter: mergedOptions.filter\n };\n \n if (mergedOptions.debug) {\n logger.debug('Build options:', cmd.buildOptions);\n }\n }\n else if (commandName === 'annotations') {\n // Attach the build argument to options\n cmd.mergedOptions.buildArg = cmd.args?.[0];\n \n if (mergedOptions.debug) {\n logger.debug('Annotations build arg:', cmd.mergedOptions.buildArg);\n logger.debug('Annotations context filter:', mergedOptions.context);\n }\n }\n else if (commandName === 'build') {\n // Attach the build argument to options\n cmd.mergedOptions.buildArg = cmd.args?.[0];\n \n if (mergedOptions.debug) {\n logger.debug('Build arg:', cmd.mergedOptions.buildArg);\n logger.debug('Build options:', mergedOptions);\n }\n }\n \n if (mergedOptions.debug) {\n logger.debug(`Executing command: ${commandName}`);\n logger.debug('Options:', mergedOptions);\n }\n })\n .hook('postAction', (_thisCommand, actionCommand) => {\n // Cast to our extended command type\n const cmd = actionCommand as unknown as ExtendedCommand;\n \n // Accessing the custom property\n const options = cmd.mergedOptions || {};\n if (options.debug) {\n logger.debug(`Command ${cmd.name()} completed`);\n }\n });\n\nprogram\n .command('viewer')\n .description('Show logged in user information')\n .action(createCommandHandler(ShowViewer));\n\nprogram\n .command('orgs')\n .description('List organizations')\n .action(createCommandHandler(ListOrganizations));\n\nprogram\n .command('pipelines')\n .description('List pipelines for an organization')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-n, --count <count>', 'Limit to specified number of pipelines per organization')\n .option('--filter <name>', 'Filter pipelines by name (case insensitive)')\n .action(createCommandHandler(ListPipelines));\n\n// Update the builds command to include REST API filtering options\nprogram\n .command('builds')\n .description('List builds for the current user')\n .option('-o, --org <org>', 'Organization slug (optional - will search all your orgs if not specified)')\n .option('-p, --pipeline <pipeline>', 'Filter by pipeline slug')\n .option('-b, --branch <branch>', 'Filter by branch name')\n .option('-s, --state <state>', 'Filter by build state (running, scheduled, passed, failing, failed, canceled, etc.)')\n .option('-n, --count <count>', 'Number of builds per page', '10')\n .option('--page <page>', 'Page number', '1')\n .option('--filter <filter>', 'Fuzzy filter builds by name or other properties')\n .action(createCommandHandler(ListBuilds));\n\n// Add token management command\nprogram\n .command('token')\n .description('Manage API tokens')\n .option('--check', 'Check if a token is stored in the system keychain')\n .option('--store', 'Store a token in the system keychain')\n .option('--reset', 'Delete the stored token from system keychain')\n .action(createCommandHandler(ManageToken));\n\n// Add annotations command\nprogram\n .command('annotations')\n .description('Show annotations for a build')\n .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')\n .option('--context <context>', 'Filter annotations by context (e.g., rspec, build-resources)')\n .action(createCommandHandler(ListAnnotations));\n\n// Add build command\nprogram\n .command('build')\n .description('Show details for a specific build')\n .argument('<build>', 'Build reference (org/pipeline/number or @https://buildkite.com/org/pipeline/builds/number)')\n .option('--jobs', 'Show job summary and details')\n .option('--failed', 'Show only failed job details (implies --jobs)')\n .option('--all-jobs', 'Show all jobs without grouping limit')\n .option('--annotations', 'Show annotation details with context')\n .option('--annotations-full', 'Show complete annotation content')\n .option('--full', 'Show all available information')\n .option('--summary', 'Single-line summary only (for scripts)')\n .action(createCommandHandler(ShowBuild));\n\n// Add completions command\nprogram\n .command('completions [shell]')\n .description('Generate shell completions')\n .action(async (shell) => {\n const handler = new GenerateCompletions();\n const exitCode = await handler.execute({ shell, quiet: program.opts().quiet, debug: program.opts().debug });\n process.exitCode = exitCode;\n });\n\nprogram\n .command('boom')\n .description('Test error handling')\n .option('--type <type>', 'Type of error to throw (basic, api, object)', 'basic')\n .option('--format <format>', 'Output format (plain, json, alfred)', 'plain')\n .action((options) => {\n switch (options.type) {\n case 'api':\n const apiError = new Error('API request failed');\n (apiError as any).response = {\n errors: [\n { message: 'Invalid token', path: ['viewer'] }\n ]\n };\n throw apiError;\n \n case 'object':\n throw {\n message: 'This is not an Error instance',\n code: 'CUSTOM_ERROR'\n };\n \n case 'basic':\n default:\n throw new Error('Boom! This is a test error');\n }\n });\n\nprogram.parse();\n\n// Apply log level from command line options\nconst options = program.opts();\nif (options.debug) {\n // Debug mode takes precedence over log-level\n setLogLevel('debug');\n logger.debug('Debug mode enabled via --debug flag');\n} else if (options.logLevel) {\n setLogLevel(options.logLevel);\n logger.debug(`Log level set to ${options.logLevel} via --log-level option`);\n}\n\nlogger.debug({ \n pid: process.pid, \n}, 'Buildkite CLI started'); "]}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Extract statistical patterns from real Buildkite data
|
|
4
|
+
* This script analyzes real data to extract patterns without storing sensitive information
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npm run test:extract-patterns
|
|
8
|
+
*
|
|
9
|
+
* Environment variables:
|
|
10
|
+
* BUILDKITE_API_TOKEN - Required for API access
|
|
11
|
+
* PATTERN_SAMPLE_SIZE - Number of items to sample (default: 100 for builds, 50 for pipelines)
|
|
12
|
+
*/
|
|
13
|
+
import { BuildkiteClient } from '../services/BuildkiteClient.js';
|
|
14
|
+
import { DataProfiler } from '../test-helpers/DataProfiler.js';
|
|
15
|
+
import { promises as fs } from 'fs';
|
|
16
|
+
import { dirname } from 'path';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
import { resolve } from 'path';
|
|
19
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const __dirname = dirname(__filename);
|
|
21
|
+
async function extractPatterns() {
|
|
22
|
+
const token = process.env.BUILDKITE_API_TOKEN;
|
|
23
|
+
if (!token) {
|
|
24
|
+
console.error('ā BUILDKITE_API_TOKEN environment variable is required');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
console.log('š Extracting data patterns from Buildkite...');
|
|
28
|
+
try {
|
|
29
|
+
const client = new BuildkiteClient(token, {
|
|
30
|
+
caching: false, // Don't cache during extraction
|
|
31
|
+
debug: false
|
|
32
|
+
});
|
|
33
|
+
const profiler = new DataProfiler();
|
|
34
|
+
// Sample sizes (can be overridden with env vars)
|
|
35
|
+
const buildSampleSize = parseInt(process.env.PATTERN_SAMPLE_SIZE || '100', 10);
|
|
36
|
+
const pipelineSampleSize = parseInt(process.env.PIPELINE_SAMPLE_SIZE || '50', 10);
|
|
37
|
+
console.log(`š Sampling ${buildSampleSize} builds from viewer...`);
|
|
38
|
+
const buildsResponse = await client.getViewerBuilds(buildSampleSize);
|
|
39
|
+
const builds = buildsResponse.viewer?.builds?.edges?.map(edge => edge?.node).filter(Boolean) || [];
|
|
40
|
+
console.log(` ā Collected ${builds.length} builds`);
|
|
41
|
+
console.log('š Sampling organizations...');
|
|
42
|
+
const organizations = await client.getOrganizations();
|
|
43
|
+
console.log(` ā Collected ${organizations.length} organizations`);
|
|
44
|
+
// Get pipelines from the first organization
|
|
45
|
+
let pipelines = [];
|
|
46
|
+
if (organizations.length > 0) {
|
|
47
|
+
console.log(`š Sampling ${pipelineSampleSize} pipelines from ${organizations[0].slug}...`);
|
|
48
|
+
try {
|
|
49
|
+
const pipelinesResponse = await client.getPipelines(organizations[0].slug, pipelineSampleSize);
|
|
50
|
+
pipelines = pipelinesResponse.organization?.pipelines?.edges?.map(edge => edge?.node).filter(Boolean) || [];
|
|
51
|
+
console.log(` ā Collected ${pipelines.length} pipelines`);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn(` ā ļø Could not fetch pipelines: ${error instanceof Error ? error.message : String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Extract jobs from builds (Note: viewer builds don't include jobs by default)
|
|
58
|
+
// For now, we'll skip job extraction or fetch from a specific build
|
|
59
|
+
console.log(`š Job extraction skipped (not included in viewer builds query)`);
|
|
60
|
+
const jobs = [];
|
|
61
|
+
// Profile the data
|
|
62
|
+
console.log('š¬ Analyzing patterns...');
|
|
63
|
+
const patterns = {
|
|
64
|
+
builds: profiler.profileBuilds(builds),
|
|
65
|
+
pipelines: profiler.profilePipelines(pipelines),
|
|
66
|
+
jobs: profiler.profileJobs(jobs),
|
|
67
|
+
organizations: profiler.profileOrganizations(organizations),
|
|
68
|
+
extracted: new Date().toISOString(),
|
|
69
|
+
sampleSize: {
|
|
70
|
+
builds: builds.length,
|
|
71
|
+
pipelines: pipelines.length,
|
|
72
|
+
jobs: jobs.length,
|
|
73
|
+
organizations: organizations.length
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
// Ensure output directory exists
|
|
77
|
+
const outputPath = resolve(__dirname, '../../test/fixtures/data-patterns.json');
|
|
78
|
+
const outputDir = dirname(outputPath);
|
|
79
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
80
|
+
// Save patterns
|
|
81
|
+
await fs.writeFile(outputPath, JSON.stringify(patterns, null, 2));
|
|
82
|
+
console.log(`ā
Successfully extracted patterns to ${outputPath}`);
|
|
83
|
+
// Print summary statistics
|
|
84
|
+
console.log('\nš Pattern Summary:');
|
|
85
|
+
console.log(' Builds:');
|
|
86
|
+
if (patterns.builds.states.values.length > 0) {
|
|
87
|
+
console.log(` - States: ${patterns.builds.states.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);
|
|
88
|
+
}
|
|
89
|
+
console.log(` - Branch formats: feature (${(patterns.builds.branches.formats.feature * 100).toFixed(1)}%), main (${(patterns.builds.branches.formats.main * 100).toFixed(1)}%)`);
|
|
90
|
+
console.log(` - Conventional commits: ${(patterns.builds.messagePatterns.conventionalCommits * 100).toFixed(1)}%`);
|
|
91
|
+
console.log(` - Build number range: ${patterns.builds.numberRange.min} - ${patterns.builds.numberRange.max}`);
|
|
92
|
+
if (patterns.pipelines.defaultBranches.values.length > 0) {
|
|
93
|
+
console.log(' Pipelines:');
|
|
94
|
+
console.log(` - Default branches: ${patterns.pipelines.defaultBranches.values.slice(0, 3).map(v => v.value).join(', ')}`);
|
|
95
|
+
console.log(` - Repository providers: ${patterns.pipelines.repositoryProviders.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);
|
|
96
|
+
}
|
|
97
|
+
if (patterns.jobs.exitStatusDistribution.values.length > 0) {
|
|
98
|
+
console.log(' Jobs:');
|
|
99
|
+
console.log(` - Retry rates: automatic (${(patterns.jobs.retryRates.automatic * 100).toFixed(1)}%), manual (${(patterns.jobs.retryRates.manual * 100).toFixed(1)}%)`);
|
|
100
|
+
console.log(` - Exit status distribution: ${patterns.jobs.exitStatusDistribution.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
console.error('ā Error extracting patterns:', error);
|
|
105
|
+
if (error instanceof Error) {
|
|
106
|
+
console.error(' ', error.message);
|
|
107
|
+
if (error.stack) {
|
|
108
|
+
console.debug(error.stack);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Run if executed directly
|
|
115
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
116
|
+
extractPatterns();
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=extract-data-patterns.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-data-patterns.js","sourceRoot":"/","sources":["scripts/extract-data-patterns.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\n/**\n * Extract statistical patterns from real Buildkite data\n * This script analyzes real data to extract patterns without storing sensitive information\n * \n * Usage:\n * npm run test:extract-patterns\n * \n * Environment variables:\n * BUILDKITE_API_TOKEN - Required for API access\n * PATTERN_SAMPLE_SIZE - Number of items to sample (default: 100 for builds, 50 for pipelines)\n */\n\nimport { BuildkiteClient } from '../services/BuildkiteClient.js';\nimport { DataProfiler } from '../test-helpers/DataProfiler.js';\nimport { promises as fs } from 'fs';\nimport { dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { resolve } from 'path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nasync function extractPatterns() {\n const token = process.env.BUILDKITE_API_TOKEN;\n if (!token) {\n console.error('ā BUILDKITE_API_TOKEN environment variable is required');\n process.exit(1);\n }\n\n console.log('š Extracting data patterns from Buildkite...');\n \n try {\n const client = new BuildkiteClient(token, { \n caching: false, // Don't cache during extraction\n debug: false \n });\n \n const profiler = new DataProfiler();\n \n // Sample sizes (can be overridden with env vars)\n const buildSampleSize = parseInt(process.env.PATTERN_SAMPLE_SIZE || '100', 10);\n const pipelineSampleSize = parseInt(process.env.PIPELINE_SAMPLE_SIZE || '50', 10);\n \n console.log(`š Sampling ${buildSampleSize} builds from viewer...`);\n const buildsResponse = await client.getViewerBuilds(buildSampleSize);\n const builds = buildsResponse.viewer?.builds?.edges?.map(edge => edge?.node).filter(Boolean) || [];\n console.log(` ā Collected ${builds.length} builds`);\n \n console.log('š Sampling organizations...');\n const organizations = await client.getOrganizations();\n console.log(` ā Collected ${organizations.length} organizations`);\n \n // Get pipelines from the first organization\n let pipelines: any[] = [];\n if (organizations.length > 0) {\n console.log(`š Sampling ${pipelineSampleSize} pipelines from ${organizations[0].slug}...`);\n try {\n const pipelinesResponse = await client.getPipelines(organizations[0].slug, pipelineSampleSize);\n pipelines = pipelinesResponse.organization?.pipelines?.edges?.map(edge => edge?.node).filter(Boolean) || [];\n console.log(` ā Collected ${pipelines.length} pipelines`);\n } catch (error) {\n console.warn(` ā ļø Could not fetch pipelines: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n \n // Extract jobs from builds (Note: viewer builds don't include jobs by default)\n // For now, we'll skip job extraction or fetch from a specific build\n console.log(`š Job extraction skipped (not included in viewer builds query)`);\n const jobs: any[] = [];\n \n // Profile the data\n console.log('š¬ Analyzing patterns...');\n \n const patterns = {\n builds: profiler.profileBuilds(builds as any),\n pipelines: profiler.profilePipelines(pipelines as any),\n jobs: profiler.profileJobs(jobs as any),\n organizations: profiler.profileOrganizations(organizations as any),\n extracted: new Date().toISOString(),\n sampleSize: {\n builds: builds.length,\n pipelines: pipelines.length,\n jobs: jobs.length,\n organizations: organizations.length\n }\n };\n \n // Ensure output directory exists\n const outputPath = resolve(__dirname, '../../test/fixtures/data-patterns.json');\n const outputDir = dirname(outputPath);\n await fs.mkdir(outputDir, { recursive: true });\n \n // Save patterns\n await fs.writeFile(\n outputPath,\n JSON.stringify(patterns, null, 2)\n );\n \n console.log(`ā
Successfully extracted patterns to ${outputPath}`);\n \n // Print summary statistics\n console.log('\\nš Pattern Summary:');\n console.log(' Builds:');\n if (patterns.builds.states.values.length > 0) {\n console.log(` - States: ${patterns.builds.states.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);\n }\n console.log(` - Branch formats: feature (${(patterns.builds.branches.formats.feature * 100).toFixed(1)}%), main (${(patterns.builds.branches.formats.main * 100).toFixed(1)}%)`);\n console.log(` - Conventional commits: ${(patterns.builds.messagePatterns.conventionalCommits * 100).toFixed(1)}%`);\n console.log(` - Build number range: ${patterns.builds.numberRange.min} - ${patterns.builds.numberRange.max}`);\n \n if (patterns.pipelines.defaultBranches.values.length > 0) {\n console.log(' Pipelines:');\n console.log(` - Default branches: ${patterns.pipelines.defaultBranches.values.slice(0, 3).map(v => v.value).join(', ')}`);\n console.log(` - Repository providers: ${patterns.pipelines.repositoryProviders.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);\n }\n \n if (patterns.jobs.exitStatusDistribution.values.length > 0) {\n console.log(' Jobs:');\n console.log(` - Retry rates: automatic (${(patterns.jobs.retryRates.automatic * 100).toFixed(1)}%), manual (${(patterns.jobs.retryRates.manual * 100).toFixed(1)}%)`);\n console.log(` - Exit status distribution: ${patterns.jobs.exitStatusDistribution.values.slice(0, 3).map(v => `${v.value} (${(v.frequency * 100).toFixed(1)}%)`).join(', ')}`);\n }\n \n } catch (error) {\n console.error('ā Error extracting patterns:', error);\n if (error instanceof Error) {\n console.error(' ', error.message);\n if (error.stack) {\n console.debug(error.stack);\n }\n }\n process.exit(1);\n }\n}\n\n// Run if executed directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n extractPatterns();\n}"]}
|