Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/ci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ If only the `head` is supplied, then Code PushUp will collect a new report and o
If triggered by a pull request, then specify the `base` ref as well.
This will additionally compare reports from both source and target branches and post a comment to the PR.

| Property | Required | Type | Description |
| :------- | :------: | :----------------------------- | :-------------------- |
| `head` | yes | `{ ref: string, sha: string }` | Current branch/commit |
| `base` | no | `{ ref: string, sha: string }` | Branch targeted by PR |
| Property | Required | Type | Description |
| :------- | :------: | :--------------------------------------- | :-------------------- |
| `head` | yes | `string \| { ref: string, sha: string }` | Current branch/commit |
| `base` | no | `string \| { ref: string, sha: string }` | Branch targeted by PR |

### Provider API client

Expand Down
26 changes: 25 additions & 1 deletion packages/ci/src/lib/git.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DiffNameStatus, simpleGit } from 'simple-git';
import { DiffNameStatus, GitError, simpleGit } from 'simple-git';
import type { GitBranch } from './models.js';

export type ChangedFiles = Record<string, ChangedFile>;

Expand All @@ -12,6 +13,29 @@
curr: { line: number; count: number };
};

export async function normalizeGitRef(

Check warning on line 16 in packages/ci/src/lib/git.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> JSDoc coverage | Functions coverage

Missing functions documentation for normalizeGitRef
ref: string | GitBranch,
git = simpleGit(),
): Promise<GitBranch> {
if (typeof ref === 'object') {
return ref;
}

Check failure on line 22 in packages/ci/src/lib/git.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> Code coverage | Branch coverage

1st branch is not taken in any test case.
try {
const sha = await git.revparse(ref);
return { ref, sha };
} catch (error) {
if (
error instanceof GitError &&
error.message.includes(`fatal: ambiguous argument '${ref}'`)
) {
await git.fetch(['origin', ref, '--depth=1']);
const sha = await git.revparse('FETCH_HEAD');
return { ref, sha };
}
throw error;
}

Check warning on line 36 in packages/ci/src/lib/git.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> Code coverage | Line coverage

Lines 23-36 are not covered in any test case.
}

export async function listChangedFiles(
refs: {
base: string;
Expand Down
6 changes: 3 additions & 3 deletions packages/ci/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export type Options = {
export type Settings = Required<Options>;

/**
* Branches/commits for {@link runInCI}
* Branches/tags for {@link runInCI}
*/
export type GitRefs = {
head: GitBranch;
base?: GitBranch;
head: string | GitBranch;
base?: string | GitBranch;
};

/**
Expand Down
3 changes: 0 additions & 3 deletions packages/ci/src/lib/run-monorepo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
type RunEnv,
checkPrintConfig,
compareReports,
ensureHeadBranch,
loadCachedBaseReport,
printPersistConfig,
runInBaseBranch,
Expand All @@ -48,8 +47,6 @@ export async function runInMonorepoMode(

logger.info('Running Code PushUp in monorepo mode');

await ensureHeadBranch(env);

const { projects, runManyCommand } = await listMonorepoProjects(settings);
const projectResults = runManyCommand
? await runProjectsInBulk(projects, runManyCommand, env)
Expand Down
4 changes: 1 addition & 3 deletions packages/ci/src/lib/run-standalone.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { commentOnPR } from './comment.js';
import type { StandaloneRunResult } from './models.js';
import { type RunEnv, ensureHeadBranch, runOnProject } from './run-utils.js';
import { type RunEnv, runOnProject } from './run-utils.js';

export async function runInStandaloneMode(
env: RunEnv,
Expand All @@ -10,8 +10,6 @@ export async function runInStandaloneMode(

logger.info('Running Code PushUp in standalone project mode');

await ensureHeadBranch(env);

const { files, newIssues } = await runOnProject(null, env);

const commentMdPath = files.diff?.md;
Expand Down
49 changes: 36 additions & 13 deletions packages/ci/src/lib/run-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
import path from 'node:path';
import type { SimpleGit } from 'simple-git';
import type { CoreConfig, Report, ReportsDiff } from '@code-pushup/models';
import { stringifyError } from '@code-pushup/utils';
import {
removeUndefinedAndEmptyProps,
stringifyError,
} from '@code-pushup/utils';
import {
type CommandContext,
createCommandContext,
Expand All @@ -12,12 +15,14 @@
runPrintConfig,
} from './cli/index.js';
import { parsePersistConfig } from './cli/persist.js';
import { listChangedFiles } from './git.js';
import { DEFAULT_SETTINGS } from './constants.js';
import { listChangedFiles, normalizeGitRef } from './git.js';
import { type SourceFileIssue, filterRelevantIssues } from './issues.js';
import type {
GitBranch,
GitRefs,
Logger,
Options,
OutputFiles,
ProjectRunResult,
ProviderAPIClient,
Expand All @@ -26,12 +31,17 @@
import type { ProjectConfig } from './monorepo/index.js';

export type RunEnv = {
refs: GitRefs;
refs: NormalizedGitRefs;
api: ProviderAPIClient;
settings: Settings;
git: SimpleGit;
};

type NormalizedGitRefs = {

Check warning on line 40 in packages/ci/src/lib/run-utils.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> JSDoc coverage | Types coverage

Missing types documentation for NormalizedGitRefs
head: GitBranch;
base?: GitBranch;
};

export type CompareReportsArgs = {
project: ProjectConfig | null;
env: RunEnv;
Expand All @@ -53,6 +63,28 @@
ctx: CommandContext;
};

export async function createRunEnv(

Check warning on line 66 in packages/ci/src/lib/run-utils.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> JSDoc coverage | Functions coverage

Missing functions documentation for createRunEnv
refs: GitRefs,
api: ProviderAPIClient,
options: Options | undefined,
git: SimpleGit,
): Promise<RunEnv> {
const [head, base] = await Promise.all([
normalizeGitRef(refs.head, git),
refs.base && normalizeGitRef(refs.base, git),
]);

return {
refs: { head, ...(base && { base }) },
api,
settings: {
...DEFAULT_SETTINGS,
...(options && removeUndefinedAndEmptyProps(options)),
},
git,
};
}

export async function runOnProject(
project: ProjectConfig | null,
env: RunEnv,
Expand Down Expand Up @@ -81,9 +113,7 @@

const noDiffOutput = {
name: project?.name ?? '-',
files: {
report: reportFiles,
},
files: { report: reportFiles },
} satisfies ProjectRunResult;

if (base == null) {
Expand Down Expand Up @@ -223,13 +253,6 @@
return null;
}

export async function ensureHeadBranch({ refs, git }: RunEnv): Promise<void> {
const { head } = refs;
if (head.sha !== (await git.revparse('HEAD'))) {
await git.checkout(['-f', head.ref]);
}
}

export async function runInBaseBranch<T>(
base: GitBranch,
env: RunEnv,
Expand Down
13 changes: 3 additions & 10 deletions packages/ci/src/lib/run.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { type SimpleGit, simpleGit } from 'simple-git';
import { DEFAULT_SETTINGS } from './constants.js';
import type {
GitRefs,
Options,
ProviderAPIClient,
RunResult,
Settings,
} from './models.js';
import { runInMonorepoMode } from './run-monorepo.js';
import { runInStandaloneMode } from './run-standalone.js';
import type { RunEnv } from './run-utils.js';
import { createRunEnv } from './run-utils.js';

/**
* Runs Code PushUp in CI environment.
Expand All @@ -25,14 +23,9 @@ export async function runInCI(
options?: Options,
git: SimpleGit = simpleGit(),
): Promise<RunResult> {
const settings: Settings = {
...DEFAULT_SETTINGS,
...options,
};
const env = await createRunEnv(refs, api, options, git);

const env: RunEnv = { refs, api, settings, git };

if (settings.monorepo) {
if (env.settings.monorepo) {
return runInMonorepoMode(env);
}

Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export {
objectToCliArgs,
objectToEntries,
objectToKeys,
removeUndefinedAndEmptyProps,
toArray,
toJsonLines,
toNumberPrecision,
Expand Down
8 changes: 8 additions & 0 deletions packages/utils/src/lib/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,11 @@

return `${value}th`;
}

export function removeUndefinedAndEmptyProps<T extends object>(obj: T): T {

Check warning on line 155 in packages/utils/src/lib/transform.ts

View workflow job for this annotation

GitHub Actions / Code PushUp

<✓> JSDoc coverage | Functions coverage

Missing functions documentation for removeUndefinedAndEmptyProps
return Object.fromEntries(
Object.entries(obj).filter(
([, value]) => value !== undefined && value !== '',
),
) as T;
}
14 changes: 14 additions & 0 deletions packages/utils/src/lib/transform.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
objectToCliArgs,
objectToEntries,
objectToKeys,
removeUndefinedAndEmptyProps,
toArray,
toJsonLines,
toNumberPrecision,
Expand Down Expand Up @@ -303,3 +304,16 @@ describe('toOrdinal', () => {
expect(toOrdinal(value)).toBe(ordinalValue);
});
});

describe('removeUndefinedAndEmptyProps', () => {
it('should omit empty strings and undefined', () => {
expect(
removeUndefinedAndEmptyProps({ foo: '', bar: undefined }),
).toStrictEqual({});
});

it('should preserve other values', () => {
const obj = { a: 'hello', b: 42, c: [], d: {}, e: null };
expect(removeUndefinedAndEmptyProps(obj)).toStrictEqual(obj);
});
});