Skip to content

Commit a73bf21

Browse files
committed
feat(ci): parse upload along with persist in print-config commands
1 parent d35cd7a commit a73bf21

File tree

5 files changed

+80
-21
lines changed

5 files changed

+80
-21
lines changed

packages/ci/src/lib/cli/index.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,8 @@ export { runCompare } from './commands/compare.js';
33
export { runMergeDiffs } from './commands/merge-diffs.js';
44
export { runPrintConfig } from './commands/print-config.js';
55
export { createCommandContext, type CommandContext } from './context.js';
6-
export { persistedFilesFromConfig } from './persist.js';
6+
export {
7+
parsePersistConfig,
8+
persistedFilesFromConfig,
9+
type EnhancedPersistConfig,
10+
} from './persist.js';

packages/ci/src/lib/cli/persist.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ import {
77
DEFAULT_PERSIST_OUTPUT_DIR,
88
type Format,
99
persistConfigSchema,
10+
uploadConfigSchema,
1011
} from '@code-pushup/models';
11-
import { objectFromEntries, stringifyError } from '@code-pushup/utils';
12+
import { objectFromEntries } from '@code-pushup/utils';
13+
14+
export type EnhancedPersistConfig = Pick<CoreConfig, 'persist' | 'upload'>;
1215

1316
export function persistedFilesFromConfig(
14-
config: Pick<CoreConfig, 'persist'>,
17+
config: EnhancedPersistConfig,
1518
{ isDiff, directory }: { isDiff?: boolean; directory: string },
1619
): Record<Format, string> {
1720
const {
@@ -36,11 +39,16 @@ export function persistedFilesFromConfig(
3639

3740
export async function parsePersistConfig(
3841
json: unknown,
39-
): Promise<Pick<CoreConfig, 'persist'>> {
40-
const schema = z.object({ persist: persistConfigSchema.optional() });
42+
): Promise<EnhancedPersistConfig> {
43+
const schema = z.object({
44+
persist: persistConfigSchema.optional(),
45+
upload: uploadConfigSchema.optional(),
46+
});
4147
const result = await schema.safeParseAsync(json);
4248
if (result.error) {
43-
throw new Error(`Invalid persist config - ${stringifyError(result.error)}`);
49+
throw new Error(
50+
`Code PushUp config is invalid:\n${z.prettifyError(result.error)}`,
51+
);
4452
}
4553
return result.data;
4654
}

packages/ci/src/lib/cli/persist.unit.test.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import path from 'node:path';
22
import type { CoreConfig } from '@code-pushup/models';
3-
import { parsePersistConfig, persistedFilesFromConfig } from './persist.js';
3+
import {
4+
type EnhancedPersistConfig,
5+
parsePersistConfig,
6+
persistedFilesFromConfig,
7+
} from './persist.js';
48

59
describe('persistedFilesFromConfig', () => {
610
it('should return default report paths when no config is set', () => {
@@ -72,17 +76,47 @@ describe('persistedFilesFromConfig', () => {
7276
});
7377

7478
describe('parsePersistConfig', () => {
75-
it('should validate only persist config', async () => {
79+
it('should validate only persist and upload config', async () => {
7680
await expect(
7781
parsePersistConfig({
7882
persist: {
7983
outputDir: '.code-pushup',
8084
filename: 'report',
8185
format: ['json', 'md'],
8286
},
87+
upload: {
88+
server: 'https://code-pushup-api.dunder-mifflin.org/graphql',
89+
apiKey: 'cp_abcdef0123456789',
90+
organization: 'dunder-mifflin',
91+
project: 'website',
92+
},
8393
// missing props (slug, etc.)
8494
plugins: [{ title: 'some plugin', audits: [{ title: 'some audit' }] }],
8595
} as CoreConfig),
96+
).resolves.toEqual({
97+
persist: {
98+
outputDir: '.code-pushup',
99+
filename: 'report',
100+
format: ['json', 'md'],
101+
},
102+
upload: {
103+
server: 'https://code-pushup-api.dunder-mifflin.org/graphql',
104+
apiKey: 'cp_abcdef0123456789',
105+
organization: 'dunder-mifflin',
106+
project: 'website',
107+
},
108+
} satisfies EnhancedPersistConfig);
109+
});
110+
111+
it('should accept missing upload config', async () => {
112+
await expect(
113+
parsePersistConfig({
114+
persist: {
115+
outputDir: '.code-pushup',
116+
filename: 'report',
117+
format: ['json', 'md'],
118+
},
119+
}),
86120
).resolves.toEqual({
87121
persist: {
88122
outputDir: '.code-pushup',
@@ -114,7 +148,20 @@ describe('parsePersistConfig', () => {
114148
await expect(
115149
parsePersistConfig({ persist: { format: ['json', 'html'] } }),
116150
).rejects.toThrow(
117-
/^Invalid persist config - ZodError:.*Invalid option: expected one of \\"json\\"\|\\"md\\"/s,
151+
/^Code PushUp config is invalid.*Invalid option: expected one of "json"\|"md".*at persist\.format\[1]/s,
152+
);
153+
});
154+
155+
it('should error if upload config is invalid', async () => {
156+
await expect(
157+
parsePersistConfig({
158+
upload: {
159+
organization: 'dunder-mifflin',
160+
project: 'website',
161+
},
162+
}),
163+
).rejects.toThrow(
164+
/^Code PushUp config is invalid.*Invalid input: expected string, received undefined.*at upload\.server.*at upload\.apiKey/s,
118165
);
119166
});
120167
});

packages/ci/src/lib/run-monorepo.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { readFile } from 'node:fs/promises';
2-
import type { CoreConfig } from '@code-pushup/models';
32
import {
43
type ExcludeNullableProps,
54
asyncSequential,
65
hasNoNullableProps,
76
} from '@code-pushup/utils';
87
import {
98
type CommandContext,
9+
type EnhancedPersistConfig,
1010
createCommandContext,
1111
persistedFilesFromConfig,
1212
runCollect,
@@ -88,7 +88,7 @@ export async function runInMonorepoMode(
8888
type ProjectReport = {
8989
project: ProjectConfig;
9090
reports: OutputFiles;
91-
config: Pick<CoreConfig, 'persist'>;
91+
config: EnhancedPersistConfig;
9292
ctx: CommandContext;
9393
};
9494

@@ -125,7 +125,7 @@ async function runProjectsInBulk(
125125
const hasFormats = allProjectsHaveDefaultPersistFormats(currProjectConfigs);
126126
logger.debug(
127127
[
128-
`Loaded ${currProjectConfigs.length} persist configs by running print-config command for each project.`,
128+
`Loaded ${currProjectConfigs.length} persist and upload configs by running print-config command for each project.`,
129129
hasFormats
130130
? 'Every project has default persist formats.'
131131
: 'Not all projects have default persist formats.',
@@ -279,7 +279,7 @@ async function collectPreviousReports(
279279
async function savePreviousProjectReport(args: {
280280
name: string;
281281
ctx: CommandContext;
282-
config: Pick<CoreConfig, 'persist'>;
282+
config: EnhancedPersistConfig;
283283
settings: Settings;
284284
}): Promise<[string, ReportData<'previous'>]> {
285285
const { name, ctx, config, settings } = args;
@@ -320,7 +320,7 @@ async function collectMany(
320320
}
321321

322322
export function allProjectsHaveDefaultPersistFormats(
323-
projects: { config: Pick<CoreConfig, 'persist'> }[],
323+
projects: { config: EnhancedPersistConfig }[],
324324
): boolean {
325325
return projects.every(({ config }) => hasDefaultPersistFormats(config));
326326
}

packages/ci/src/lib/run-utils.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import { readFile } from 'node:fs/promises';
33
import type { SimpleGit } from 'simple-git';
44
import {
5-
type CoreConfig,
65
DEFAULT_PERSIST_FORMAT,
76
type Report,
87
type ReportsDiff,
@@ -13,13 +12,14 @@ import {
1312
} from '@code-pushup/utils';
1413
import {
1514
type CommandContext,
15+
type EnhancedPersistConfig,
1616
createCommandContext,
17+
parsePersistConfig,
1718
persistedFilesFromConfig,
1819
runCollect,
1920
runCompare,
2021
runPrintConfig,
2122
} from './cli/index.js';
22-
import { parsePersistConfig } from './cli/persist.js';
2323
import { DEFAULT_SETTINGS } from './constants.js';
2424
import { listChangedFiles, normalizeGitRef } from './git.js';
2525
import { type SourceFileIssue, filterRelevantIssues } from './issues.js';
@@ -53,7 +53,7 @@ export type CompareReportsArgs = {
5353
base: GitBranch;
5454
currReport: ReportData<'current'>;
5555
prevReport: ReportData<'previous'>;
56-
config: Pick<CoreConfig, 'persist'>;
56+
config: EnhancedPersistConfig;
5757
};
5858

5959
export type BaseReportArgs = {
@@ -114,7 +114,7 @@ export async function runOnProject(
114114

115115
const config = await printPersistConfig(ctx);
116116
logger.debug(
117-
`Loaded persist config from print-config command - ${JSON.stringify(config.persist)}`,
117+
`Loaded persist and upload configs from print-config command - ${JSON.stringify(config)}`,
118118
);
119119

120120
await runCollect(ctx, { hasFormats: hasDefaultPersistFormats(config) });
@@ -300,7 +300,7 @@ export async function runInBaseBranch<T>(
300300

301301
export async function checkPrintConfig(
302302
args: BaseReportArgs,
303-
): Promise<Pick<CoreConfig, 'persist'> | null> {
303+
): Promise<EnhancedPersistConfig | null> {
304304
const {
305305
project,
306306
ctx,
@@ -329,13 +329,13 @@ export async function checkPrintConfig(
329329

330330
export async function printPersistConfig(
331331
ctx: CommandContext,
332-
): Promise<Pick<CoreConfig, 'persist'>> {
332+
): Promise<EnhancedPersistConfig> {
333333
const json = await runPrintConfig(ctx);
334334
return parsePersistConfig(json);
335335
}
336336

337337
export function hasDefaultPersistFormats(
338-
config: Pick<CoreConfig, 'persist'>,
338+
config: EnhancedPersistConfig,
339339
): boolean {
340340
const formats = config.persist?.format;
341341
return (

0 commit comments

Comments
 (0)