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
package/README.md
CHANGED
|
@@ -50,10 +50,25 @@ See [Shell Completions Guide](docs/shell-completions.md) for detailed installati
|
|
|
50
50
|
- [Development Guide](docs/development.md) - Information about running and developing the CLI
|
|
51
51
|
- [Authentication](docs/authentication.md) - How to authenticate with Buildkite
|
|
52
52
|
- [Caching](docs/caching.md) - Information about the CLI's caching system
|
|
53
|
+
- [Testing Guide](docs/testing-guide.md) - Running tests and testing strategy
|
|
54
|
+
- [API Reference](docs/api-reference.md) - Complete command reference
|
|
55
|
+
- [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
|
|
53
56
|
- [Alfred Integration (Overview)](docs/alfred.md) - What the Alfred integration does and quick usage
|
|
54
57
|
- [Alfred Installation](docs/alfred-installation.md) - End-user install, configuration, and troubleshooting
|
|
55
58
|
- [Alfred Development](docs/alfred-development.md) - Packaging, wrapper behavior, metadata, and workflow wiring
|
|
56
59
|
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
Run the test suite with:
|
|
63
|
+
```bash
|
|
64
|
+
npm test # Run all tests
|
|
65
|
+
npm run test:watch # Watch mode for development
|
|
66
|
+
npm run test:coverage # Generate coverage report
|
|
67
|
+
npm run test:extract-patterns # Extract patterns from real data (requires token)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
See [Testing Guide](docs/testing/README.md) for details on the hybrid testing strategy.
|
|
71
|
+
|
|
57
72
|
## Usage
|
|
58
73
|
|
|
59
74
|
### Show Your Login Information
|
|
@@ -141,6 +156,33 @@ bktide annotations https://buildkite.com/gusto/zenpayroll/builds/1287418 --forma
|
|
|
141
156
|
bktide annotations gusto/zenpayroll/1287418 --context build-resources --format json
|
|
142
157
|
```
|
|
143
158
|
|
|
159
|
+
### Show Build Details
|
|
160
|
+
|
|
161
|
+
View detailed information about a specific build including jobs and annotations.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# View build by slug format
|
|
165
|
+
bktide build org/pipeline/123
|
|
166
|
+
|
|
167
|
+
# View build by URL format
|
|
168
|
+
bktide build @https://buildkite.com/org/pipeline/builds/123
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Additional options:
|
|
172
|
+
```bash
|
|
173
|
+
# Fetch all jobs (handles pagination for large builds)
|
|
174
|
+
bktide build org/pipeline/123 --jobs
|
|
175
|
+
|
|
176
|
+
# Show failure details and error summaries
|
|
177
|
+
bktide build org/pipeline/123 --failed
|
|
178
|
+
|
|
179
|
+
# Include full annotation content
|
|
180
|
+
bktide build org/pipeline/123 --annotations
|
|
181
|
+
|
|
182
|
+
# Combine options for comprehensive view
|
|
183
|
+
bktide build org/pipeline/123 --jobs --failed --annotations
|
|
184
|
+
```
|
|
185
|
+
|
|
144
186
|
### Generate Shell Completions
|
|
145
187
|
|
|
146
188
|
```bash
|
|
@@ -21,10 +21,14 @@ export class ShowBuild extends BaseCommand {
|
|
|
21
21
|
if (options.annotationsFull) {
|
|
22
22
|
adjustedOptions.annotations = true; // --annotations-full implies --annotations
|
|
23
23
|
}
|
|
24
|
+
if (options.allJobs) {
|
|
25
|
+
adjustedOptions.jobs = true; // --all-jobs implies --jobs
|
|
26
|
+
}
|
|
24
27
|
if (options.full) {
|
|
25
28
|
// --full shows everything
|
|
26
29
|
adjustedOptions.jobs = true;
|
|
27
30
|
adjustedOptions.annotations = true;
|
|
31
|
+
adjustedOptions.allJobs = true; // --full shows all jobs
|
|
28
32
|
}
|
|
29
33
|
// Initialize spinner early
|
|
30
34
|
const format = options.format || 'plain';
|
|
@@ -66,21 +70,43 @@ export class ShowBuild extends BaseCommand {
|
|
|
66
70
|
}
|
|
67
71
|
async fetchBuildData(buildSlug, options) {
|
|
68
72
|
// Determine what data we need to fetch based on options
|
|
69
|
-
const
|
|
73
|
+
const needsAllJobs = options.jobs || options.failed || options.full;
|
|
70
74
|
const needsAnnotations = options.annotations || options.annotationsFull || options.full;
|
|
71
75
|
if (options.debug) {
|
|
72
76
|
logger.debug('Fetching build data', {
|
|
73
77
|
buildSlug,
|
|
74
|
-
|
|
78
|
+
needsAllJobs,
|
|
75
79
|
needsAnnotations,
|
|
76
80
|
full: options.full
|
|
77
81
|
});
|
|
78
82
|
}
|
|
79
|
-
//
|
|
80
|
-
if (
|
|
81
|
-
|
|
83
|
+
// Use the new pagination-aware method when we need all jobs
|
|
84
|
+
if (needsAllJobs) {
|
|
85
|
+
// Show progress when fetching many jobs (only in plain format)
|
|
86
|
+
const progressCallback = options.format === 'plain' || !options.format
|
|
87
|
+
? (fetched, total) => {
|
|
88
|
+
const totalStr = total ? `/${total}` : '';
|
|
89
|
+
process.stderr.write(`\rFetching jobs: ${fetched}${totalStr}...`);
|
|
90
|
+
}
|
|
91
|
+
: undefined;
|
|
92
|
+
const buildData = await this.client.getBuildSummaryWithAllJobs(buildSlug, {
|
|
93
|
+
fetchAllJobs: true,
|
|
94
|
+
onProgress: progressCallback
|
|
95
|
+
});
|
|
96
|
+
// Clear the progress line
|
|
97
|
+
if (progressCallback) {
|
|
98
|
+
process.stderr.write('\r\x1b[K'); // Clear the line
|
|
99
|
+
}
|
|
100
|
+
// If we need full details (like command text), fetch that separately
|
|
101
|
+
if (options.full) {
|
|
102
|
+
// For now, getBuildFull still provides more detailed fields
|
|
103
|
+
// In the future, we could enhance the pagination query to include these
|
|
104
|
+
return await this.client.getBuildFull(buildSlug);
|
|
105
|
+
}
|
|
106
|
+
return buildData;
|
|
82
107
|
}
|
|
83
108
|
else {
|
|
109
|
+
// Just get the summary with first 100 jobs
|
|
84
110
|
return await this.client.getBuildSummary(buildSlug);
|
|
85
111
|
}
|
|
86
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShowBuild.js","sourceRoot":"/","sources":["commands/ShowBuild.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ShowBuild.js","sourceRoot":"/","sources":["commands/ShowBuild.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseCommand, BaseCommandOptions } from './BaseCommand.js';\nimport { logger } from '../services/logger.js';\nimport { parseBuildRef } from '../utils/parseBuildRef.js';\nimport { FormatterFactory, FormatterType } from '../formatters/index.js';\nimport { Progress } from '../ui/progress.js';\n\nexport interface ShowBuildOptions extends BaseCommandOptions {\n jobs?: boolean;\n failed?: boolean;\n annotations?: boolean;\n annotationsFull?: boolean;\n full?: boolean;\n summary?: boolean;\n allJobs?: boolean;\n buildArg?: string;\n}\n\nexport class ShowBuild extends BaseCommand {\n static requiresToken = true;\n\n async execute(options: ShowBuildOptions): Promise<number> {\n if (options.debug) {\n logger.debug('Starting ShowBuild command execution', options);\n }\n \n if (!options.buildArg) {\n logger.error('Build reference is required');\n return 1;\n }\n \n // Adjust options based on implications\n const adjustedOptions = { ...options };\n if (options.failed) {\n adjustedOptions.jobs = true; // --failed implies --jobs\n }\n if (options.annotationsFull) {\n adjustedOptions.annotations = true; // --annotations-full implies --annotations\n }\n if (options.allJobs) {\n adjustedOptions.jobs = true; // --all-jobs implies --jobs\n }\n if (options.full) {\n // --full shows everything\n adjustedOptions.jobs = true;\n adjustedOptions.annotations = true;\n adjustedOptions.allJobs = true; // --full shows all jobs\n }\n \n // Initialize spinner early\n const format = options.format || 'plain';\n const spinner = Progress.spinner('Fetching build details…', { format });\n \n try {\n // Ensure the command is initialized\n await this.ensureInitialized();\n \n // Parse build reference\n const buildRef = parseBuildRef(options.buildArg);\n if (options.debug) {\n logger.debug('Parsed build reference:', buildRef);\n }\n \n // Construct build slug for GraphQL\n const buildSlug = `${buildRef.org}/${buildRef.pipeline}/${buildRef.number}`;\n \n // Fetch build data based on what's needed\n const buildData = await this.fetchBuildData(buildSlug, adjustedOptions);\n spinner.stop();\n \n // Get the appropriate formatter\n const formatter = FormatterFactory.getFormatter(\n FormatterType.BUILD_DETAIL,\n options.format || 'plain'\n ) as any;\n \n // Format and output the results\n const output = formatter.formatBuildDetail(buildData, adjustedOptions);\n \n logger.console(output);\n \n return 0;\n } catch (error) {\n spinner.stop();\n logger.error('Failed to fetch build:', error);\n \n // Handle the error with the formatter\n const formatter = FormatterFactory.getFormatter(\n FormatterType.BUILD_DETAIL,\n options.format || 'plain'\n ) as any;\n \n const errorOutput = formatter.formatBuildDetail(null, {\n ...adjustedOptions,\n hasError: true,\n errorMessage: error instanceof Error ? error.message : 'Unknown error occurred',\n errorType: 'api',\n });\n \n logger.console(errorOutput);\n return 1;\n }\n }\n \n private async fetchBuildData(buildSlug: string, options: ShowBuildOptions): Promise<any> {\n // Determine what data we need to fetch based on options\n const needsAllJobs = options.jobs || options.failed || options.full;\n const needsAnnotations = options.annotations || options.annotationsFull || options.full;\n \n if (options.debug) {\n logger.debug('Fetching build data', {\n buildSlug,\n needsAllJobs,\n needsAnnotations,\n full: options.full\n });\n }\n \n // Use the new pagination-aware method when we need all jobs\n if (needsAllJobs) {\n // Show progress when fetching many jobs (only in plain format)\n const progressCallback = options.format === 'plain' || !options.format\n ? (fetched: number, total?: number) => {\n const totalStr = total ? `/${total}` : '';\n process.stderr.write(`\\rFetching jobs: ${fetched}${totalStr}...`);\n }\n : undefined;\n \n const buildData = await this.client.getBuildSummaryWithAllJobs(buildSlug, {\n fetchAllJobs: true,\n onProgress: progressCallback\n });\n \n // Clear the progress line\n if (progressCallback) {\n process.stderr.write('\\r\\x1b[K'); // Clear the line\n }\n \n // If we need full details (like command text), fetch that separately\n if (options.full) {\n // For now, getBuildFull still provides more detailed fields\n // In the future, we could enhance the pagination query to include these\n return await this.client.getBuildFull(buildSlug);\n }\n \n return buildData;\n } else {\n // Just get the summary with first 100 jobs\n return await this.client.getBuildSummary(buildSlug);\n }\n }\n}\n"]}
|