Skip to content

Commit 1e1bfee

Browse files
author
John Doe
committed
Merge remote-tracking branch 'origin/main' into plugin-bundle-stats-poc
# Conflicts: # nx.json # package-lock.json # package.json # packages/models/src/index.ts # packages/models/src/lib/configuration.ts
2 parents 19054d5 + 068984b commit 1e1bfee

620 files changed

Lines changed: 32516 additions & 19480 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
# for uploading to portal
2-
CP_SERVER=
32
CP_API_KEY=
4-
CP_ORGANIZATION=
5-
CP_PROJECT=
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Code PushUp
2+
description: Minimalist GitHub Action that executes Code PushUp using local @code-pushup/ci source code
3+
4+
inputs:
5+
token:
6+
description: GitHub token for API access
7+
required: true
8+
default: ${{ github.token }}
9+
mode:
10+
description: Is `standalone` or `monorepo` mode?
11+
required: true
12+
13+
runs:
14+
using: composite
15+
steps:
16+
- name: Run Node script
17+
run: npx tsx .github/actions/code-pushup/src/runner.ts
18+
shell: bash
19+
env:
20+
TSX_TSCONFIG_PATH: .github/actions/code-pushup/tsconfig.json
21+
GH_TOKEN: ${{ inputs.token }}
22+
MODE: ${{ inputs.mode }}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"name": "@code-pushup/local-action",
3+
"version": "0.0.0",
4+
"private": true,
5+
"type": "module",
6+
"description": "Minimalist GitHub Action that executes Code PushUp using local @code-pushup/ci source code for testing CI changes"
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "local-action",
3+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": ".github/actions/code-pushup/src",
5+
"projectType": "application",
6+
"targets": {},
7+
"tags": ["type:app"]
8+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import * as core from '@actions/core';
2+
import * as github from '@actions/github';
3+
import type { WebhookPayload } from '@actions/github/lib/interfaces';
4+
import type { components } from '@octokit/openapi-types';
5+
import {
6+
type Comment,
7+
type GitBranch,
8+
type Options,
9+
type ProviderAPIClient,
10+
type SourceFileIssue,
11+
runInCI,
12+
} from '@code-pushup/ci';
13+
import { DEFAULT_PERSIST_CONFIG } from '@code-pushup/models';
14+
import {
15+
CODE_PUSHUP_UNICODE_LOGO,
16+
logger,
17+
stringifyError,
18+
} from '@code-pushup/utils';
19+
20+
type GitHubRefs = {
21+
head: GitBranch;
22+
base?: GitBranch;
23+
};
24+
25+
type PullRequestPayload = NonNullable<WebhookPayload['pull_request']> &
26+
components['schemas']['pull-request-minimal'];
27+
28+
const LOG_PREFIX = '[Code PushUp GitHub action]';
29+
30+
const MAX_COMMENT_CHARS = 65_536;
31+
32+
function convertComment(
33+
comment: Pick<components['schemas']['issue-comment'], 'id' | 'body' | 'url'>,
34+
): Comment {
35+
const { id, body = '', url } = comment;
36+
return { id, body, url };
37+
}
38+
39+
function isPullRequest(
40+
payload: WebhookPayload['pull_request'],
41+
): payload is PullRequestPayload {
42+
return payload != null;
43+
}
44+
45+
function parseBranchRef({ ref, sha }: GitBranch): GitBranch {
46+
return {
47+
ref: ref.split('/').at(-1) ?? ref,
48+
sha,
49+
};
50+
}
51+
52+
function parseGitRefs(): GitHubRefs {
53+
if (isPullRequest(github.context.payload.pull_request)) {
54+
const { head, base } = github.context.payload.pull_request;
55+
return { head: parseBranchRef(head), base: parseBranchRef(base) };
56+
}
57+
return { head: parseBranchRef(github.context) };
58+
}
59+
60+
function createAnnotationsFromIssues(issues: SourceFileIssue[]): void {
61+
if (issues.length > 0) {
62+
core.info(`Creating annotations for ${issues.length} issues:`);
63+
}
64+
// eslint-disable-next-line functional/no-loop-statements
65+
for (const issue of issues) {
66+
const message = issue.message;
67+
const properties: core.AnnotationProperties = {
68+
title: `${CODE_PUSHUP_UNICODE_LOGO} ${issue.plugin.title} | ${issue.audit.title}`,
69+
file: issue.source.file,
70+
startLine: issue.source.position?.startLine,
71+
startColumn: issue.source.position?.startColumn,
72+
endLine: issue.source.position?.endLine,
73+
endColumn: issue.source.position?.endColumn,
74+
};
75+
switch (issue.severity) {
76+
case 'error':
77+
core.error(message, properties);
78+
break;
79+
case 'warning':
80+
core.warning(message, properties);
81+
break;
82+
case 'info':
83+
core.notice(message, properties);
84+
break;
85+
}
86+
}
87+
}
88+
89+
function createGitHubApiClient(): ProviderAPIClient {
90+
const token = process.env['GH_TOKEN'];
91+
92+
if (!token) {
93+
throw new Error('No GitHub token found');
94+
}
95+
96+
const octokit = github.getOctokit(token);
97+
98+
return {
99+
maxCommentChars: MAX_COMMENT_CHARS,
100+
101+
listComments: async (): Promise<Comment[]> => {
102+
const comments = await octokit.paginate(
103+
octokit.rest.issues.listComments,
104+
{
105+
...github.context.repo,
106+
issue_number: github.context.issue.number,
107+
},
108+
);
109+
return comments.map(convertComment);
110+
},
111+
112+
createComment: async (body: string): Promise<Comment> => {
113+
const { data } = await octokit.rest.issues.createComment({
114+
...github.context.repo,
115+
issue_number: github.context.issue.number,
116+
body,
117+
});
118+
return convertComment(data);
119+
},
120+
121+
updateComment: async (id: number, body: string): Promise<Comment> => {
122+
const { data } = await octokit.rest.issues.updateComment({
123+
...github.context.repo,
124+
comment_id: id,
125+
body,
126+
});
127+
return convertComment(data);
128+
},
129+
};
130+
}
131+
132+
async function run(): Promise<void> {
133+
try {
134+
if (core.isDebug()) {
135+
logger.setVerbose(true);
136+
}
137+
138+
const isMonorepo = process.env['MODE'] === 'monorepo';
139+
140+
const options: Options = isMonorepo
141+
? {
142+
jobId: 'monorepo-mode',
143+
monorepo: 'nx',
144+
nxProjectsFilter: '--with-target=code-pushup --exclude=workspace',
145+
configPatterns: {
146+
persist: {
147+
...DEFAULT_PERSIST_CONFIG,
148+
outputDir: '.code-pushup/{projectName}',
149+
},
150+
...(process.env['CP_API_KEY'] && {
151+
upload: {
152+
server: 'https://api.staging.code-pushup.dev/graphql',
153+
apiKey: process.env['CP_API_KEY'],
154+
organization: 'code-pushup',
155+
project: 'cli-{projectName}',
156+
},
157+
}),
158+
},
159+
}
160+
: {
161+
jobId: 'standalone-mode',
162+
bin: 'npx nx code-pushup --',
163+
};
164+
165+
const gitRefs = parseGitRefs();
166+
167+
const apiClient = createGitHubApiClient();
168+
169+
const result = await runInCI(gitRefs, apiClient, options);
170+
171+
const issues =
172+
result.mode === 'standalone'
173+
? (result.newIssues ?? [])
174+
: result.projects.flatMap(project => project.newIssues ?? []);
175+
176+
if (issues.length > 0) {
177+
core.info(
178+
`Found ${issues.length} new issues, creating GitHub annotations`,
179+
);
180+
createAnnotationsFromIssues(issues);
181+
}
182+
183+
core.info(`${LOG_PREFIX} Finished running successfully`);
184+
} catch (error) {
185+
const message = stringifyError(error);
186+
core.error(`${LOG_PREFIX} Failed: ${message}`);
187+
core.setFailed(message);
188+
}
189+
}
190+
191+
await run();
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"include": ["src/**/*"]
4+
}

.github/workflows/ci.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ on:
88

99
env:
1010
NX_NON_NATIVE_HASHER: true
11+
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
1112

1213
jobs:
1314
format:
@@ -21,7 +22,7 @@ jobs:
2122
- name: Set up Node.js
2223
uses: actions/setup-node@v4
2324
with:
24-
node-version-file: .nvmrc
25+
node-version-file: .node-version
2526
cache: npm
2627
- name: Set base and head for Nx affected commands
2728
uses: nrwl/nx-set-shas@v4
@@ -41,14 +42,14 @@ jobs:
4142
- name: Set up Node.js
4243
uses: actions/setup-node@v4
4344
with:
44-
node-version-file: .nvmrc
45+
node-version-file: .node-version
4546
cache: npm
4647
- name: Set base and head for Nx affected commands
4748
uses: nrwl/nx-set-shas@v4
4849
- name: Install dependencies
4950
run: npm ci
5051
- name: Lint affected projects
51-
run: npx nx affected:lint --parallel=3
52+
run: npx nx affected -t lint --parallel=3
5253

5354
unit-test:
5455
strategy:
@@ -65,14 +66,14 @@ jobs:
6566
- name: Set up Node.js
6667
uses: actions/setup-node@v4
6768
with:
68-
node-version-file: .nvmrc
69+
node-version-file: .node-version
6970
cache: npm
7071
- name: Set base and head for Nx affected commands
7172
uses: nrwl/nx-set-shas@v4
7273
- name: Install dependencies
7374
run: npm ci
7475
- name: Unit test affected projects
75-
run: npx nx affected -t unit-test --parallel=3 --coverage.enabled
76+
run: npx nx affected -t unit-test --parallel=3
7677

7778
integration-test:
7879
strategy:
@@ -89,14 +90,14 @@ jobs:
8990
- name: Set up Node.js
9091
uses: actions/setup-node@v4
9192
with:
92-
node-version-file: .nvmrc
93+
node-version-file: .node-version
9394
cache: npm
9495
- name: Set base and head for Nx affected commands
9596
uses: nrwl/nx-set-shas@v4
9697
- name: Install dependencies
9798
run: npm ci
9899
- name: Integration test affected projects
99-
run: npx nx affected -t int-test --parallel=3 --coverage.enabled
100+
run: npx nx affected -t int-test --parallel=3
100101

101102
e2e:
102103
strategy:
@@ -113,7 +114,7 @@ jobs:
113114
- name: Set up Node.js
114115
uses: actions/setup-node@v4
115116
with:
116-
node-version-file: .nvmrc
117+
node-version-file: .node-version
117118
cache: npm
118119
- name: Set base and head for Nx affected commands
119120
uses: nrwl/nx-set-shas@v4
@@ -133,7 +134,7 @@ jobs:
133134
- name: Set up Node.js
134135
uses: actions/setup-node@v4
135136
with:
136-
node-version-file: .nvmrc
137+
node-version-file: .node-version
137138
cache: npm
138139
- name: Set base and head for Nx affected commands
139140
uses: nrwl/nx-set-shas@v4

0 commit comments

Comments
 (0)