Skip to content

Commit b5adceb

Browse files
committed
fix(ci): make generation comment clearer
1 parent 8bc743e commit b5adceb

File tree

9 files changed

+284
-113
lines changed

9 files changed

+284
-113
lines changed

.github/actions/setup/action.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ name: Setup
22

33
description: Setup CI environment.
44

5+
inputs:
6+
type:
7+
description: Type of setup, `minimal` will only run the JavaScript installation.
8+
required: false
9+
510
runs:
611
using: composite
712
steps:
@@ -10,13 +15,15 @@ runs:
1015
run: echo "CACHE_VERSION=$(< .github/.cache_version)" >> $GITHUB_ENV
1116

1217
- name: Install Java
18+
if: inputs.type != 'minimal'
1319
uses: actions/setup-java@v2
1420
with:
1521
distribution: zulu
1622
java-version: 11.0.4
1723
cache: gradle
1824

1925
- name: Validate gradle wrapper
26+
if: inputs.type != 'minimal'
2027
uses: gradle/wrapper-validation-action@v1
2128

2229
- name: Install Node
@@ -29,6 +36,7 @@ runs:
2936
uses: ./.github/actions/cache
3037

3138
- name: Setting diff outputs variables
39+
if: inputs.type != 'minimal'
3240
id: diff
3341
shell: bash
3442
run: |
@@ -61,6 +69,7 @@ runs:
6169
echo "::set-output name=ORIGIN_BRANCH::$origin"
6270
6371
- name: Compute specs matrix
72+
if: inputs.type != 'minimal'
6473
id: spec-matrix
6574
shell: bash
6675
run: |
@@ -81,6 +90,7 @@ runs:
8190
echo "::set-output name=RUN_SPECS::$run"
8291
8392
- name: Compute the JS client build matrix
93+
if: inputs.type != 'minimal'
8494
id: js-matrix
8595
shell: bash
8696
run: |
@@ -117,6 +127,7 @@ runs:
117127
fi
118128
119129
- name: Compute the Java client build matrix
130+
if: inputs.type != 'minimal'
120131
id: java-matrix
121132
shell: bash
122133
run: |
@@ -137,6 +148,7 @@ runs:
137148
echo "::set-output name=RUN_CLIENT::$run"
138149
139150
- name: Compute the PHP client build matrix
151+
if: inputs.type != 'minimal'
140152
id: php-matrix
141153
shell: bash
142154
run: |

.github/workflows/codegen-cleanup.yml

Lines changed: 0 additions & 21 deletions
This file was deleted.

.github/workflows/codegen.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Codegen
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, closed]
6+
7+
jobs:
8+
notification:
9+
runs-on: ubuntu-20.04
10+
timeout-minutes: 10
11+
if: (github.event.action == 'opened' || github.event.action == 'synchronize') && github.event.number
12+
steps:
13+
- uses: actions/checkout@v2
14+
with:
15+
fetch-depth: 0
16+
ref: ${{ github.event.pull_request.head.ref }}
17+
18+
- name: Setup
19+
uses: ./.github/actions/setup
20+
with:
21+
type: minimal
22+
23+
- name: Add notification comment
24+
run: yarn workspace scripts upsertGenerationComment notification
25+
env:
26+
GITHUB_TOKEN: ${{ secrets.TOKEN_GENERATE_BOT }}
27+
PR_NUMBER: ${{ github.event.number }}
28+
29+
cleanup:
30+
runs-on: ubuntu-20.04
31+
timeout-minutes: 10
32+
if: github.event.action == 'closed'
33+
steps:
34+
- uses: actions/checkout@v2
35+
with:
36+
fetch-depth: 0
37+
ref: main
38+
39+
- name: Setup
40+
uses: ./.github/actions/setup
41+
with:
42+
type: minimal
43+
44+
- name: Clean previously generated branch
45+
run: yarn workspace scripts cleanGeneratedBranch ${{ github.head_ref }}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { cleanGeneratedBranch } from '../cleanGeneratedBranch';
2+
import { pushGeneratedCode } from '../pushGeneratedCode';
3+
import commentText from '../text';
4+
import {
5+
getCommentBody,
6+
upsertGenerationComment,
7+
} from '../upsertGenerationComment';
8+
9+
describe('codegen', () => {
10+
describe('cleanGeneratedBranch', () => {
11+
it('throws without parameters', async () => {
12+
await expect(
13+
// @ts-expect-error a parameter is required
14+
cleanGeneratedBranch()
15+
).rejects.toThrow(
16+
'The base branch should be passed as a cli parameter of the `cleanGeneratedBranch` script.'
17+
);
18+
});
19+
});
20+
21+
describe('pushGeneratedCode', () => {
22+
it('throws without GITHUB_TOKEN environment variable', async () => {
23+
await expect(pushGeneratedCode()).rejects.toThrow(
24+
'Environment variable `GITHUB_TOKEN` does not exist.'
25+
);
26+
});
27+
});
28+
29+
describe('upsertGenerationComment', () => {
30+
it('throws without parameter', async () => {
31+
await expect(
32+
// @ts-expect-error a parameter is required
33+
upsertGenerationComment()
34+
).rejects.toThrow(
35+
'`upsertGenerationComment` requires a `trigger` parameter (`codegen` | `notification`).'
36+
);
37+
});
38+
39+
it('throws without PR_NUMBER environment variable', async () => {
40+
process.env.GITHUB_TOKEN = 'foo';
41+
42+
await expect(upsertGenerationComment('codegen')).rejects.toThrow(
43+
'`upsertGenerationComment` requires a `PR_NUMBER` environment variable.'
44+
);
45+
});
46+
});
47+
48+
describe('getCommentBody', () => {
49+
it('returns the right comment for a `notification` trigger', async () => {
50+
expect(await getCommentBody('notification')).toMatchInlineSnapshot(`
51+
"🔨 The codegen job will run at the end of the CI.
52+
53+
_Make sure your last commit does not contains generated code, it will be automatically pushed by our CI._"
54+
`);
55+
});
56+
57+
it('returns the right comment for a `noGen` trigger', async () => {
58+
expect(await getCommentBody('noGen')).toMatchInlineSnapshot(`
59+
"✗ No code generated.
60+
61+
_If you believe this is an issue on our side, please [open an issue](https://github.com/shortcuts/api-clients-automation/issues/new)_"
62+
`);
63+
});
64+
65+
describe('text', () => {
66+
it('creates a comment body for the parameters', () => {
67+
expect(
68+
commentText.codegen.body(
69+
'myBranch',
70+
'myCommit',
71+
42,
72+
'theGeneratedCommit'
73+
)
74+
).toMatchInlineSnapshot(`
75+
"🔨 Triggered by commit [myCommit](https://github.com/shortcuts/api-clients-automation/pull/42/commits/myCommit).
76+
🔍 Browse the generated code on branch [myBranch](https://github.com/shortcuts/api-clients-automation/tree/myBranch): [theGeneratedCommit](https://github.com/shortcuts/api-clients-automation/commit/theGeneratedCommit)."
77+
`);
78+
});
79+
});
80+
});
81+
});

scripts/ci/codegen/cleanGeneratedBranch.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import { run } from '../../common';
44
/**
55
* Deletes a branch for its `generated/${headRef}` name on origin.
66
*/
7-
async function cleanGeneratedBranch(headRef: string): Promise<void> {
7+
export async function cleanGeneratedBranch(headRef: string): Promise<void> {
8+
if (!headRef) {
9+
throw new Error(
10+
'The base branch should be passed as a cli parameter of the `cleanGeneratedBranch` script.'
11+
);
12+
}
13+
814
const generatedCodeBranch = `generated/${headRef}`;
915

1016
if (!(await run(`git ls-remote --heads origin ${generatedCodeBranch}`))) {
@@ -22,10 +28,4 @@ async function cleanGeneratedBranch(headRef: string): Promise<void> {
2228

2329
const args = process.argv.slice(2);
2430

25-
if (!args || args.length === 0) {
26-
throw new Error(
27-
'The base branch should be passed as a cli parameter of the `cleanGeneratedBranch` script.'
28-
);
29-
}
30-
3131
cleanGeneratedBranch(args[0]);

scripts/ci/codegen/pushGeneratedCode.ts

Lines changed: 15 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,42 @@
11
/* eslint-disable no-console */
2-
import { Octokit } from '@octokit/rest';
3-
42
import { run } from '../../common';
5-
import { configureGitHubAuthor, OWNER, REPO } from '../../release/common';
6-
7-
if (!process.env.GITHUB_TOKEN) {
8-
throw new Error('Environment variable `GITHUB_TOKEN` does not exist.');
9-
}
3+
import { configureGitHubAuthor } from '../../release/common';
104

115
const PR_NUMBER = parseInt(process.env.PR_NUMBER || '0', 10);
12-
const FOLDERS_TO_CHECK = ['clients', 'specs/bundled'];
13-
// this should be changed to the bot name once we have the logs
14-
const BOT_NAME = 'shortcuts';
15-
16-
const octokit = new Octokit({
17-
auth: `token ${process.env.GITHUB_TOKEN}`,
18-
});
19-
20-
async function getCommentBody(commit: string, branch: string): Promise<string> {
21-
const repoUrl = `https://github.com/${OWNER}/${REPO}`;
22-
const generatedCommit = await run('git show -s --format=%H');
23-
const header = `✔️ codegen triggered on commit [${commit}](${repoUrl}/pull/${PR_NUMBER}/commits/${commit}).`;
24-
const body = `🔍 Browse the generated code on branch [${branch}](${repoUrl}/tree/${branch}): [${generatedCommit}](${repoUrl}/commit/${generatedCommit}).`;
25-
26-
return `${header}
27-
28-
${body}`;
29-
}
6+
const FOLDERS_TO_CHECK = 'clients specs/bundled';
307

318
/**
32-
* Add or update comment to the current `PR_NUMBER`.
9+
* Push generated code for the current `JOB` and `CLIENT` on a `generated/` branch.
3310
*/
34-
async function upsertCommentToPullRequest(
35-
baseCommit: string,
36-
generatedCodeBranch: string
37-
): Promise<void> {
38-
const baseOctokitConfig = {
39-
owner: OWNER,
40-
repo: REPO,
41-
issue_number: PR_NUMBER,
42-
};
43-
44-
try {
45-
// Search for a previous comment from our bot.
46-
const previousComment = await octokit.rest.issues
47-
.listComments(baseOctokitConfig)
48-
.then(
49-
(res) =>
50-
res.data.filter(
51-
(comment) =>
52-
comment.user?.login === BOT_NAME &&
53-
// this shouldn't be needed once we have a proper bot running
54-
comment.body?.startsWith('✔️ codegen triggered on commit')
55-
)[0]
56-
);
57-
const commentBody = await getCommentBody(baseCommit, generatedCodeBranch);
58-
59-
if (previousComment?.id) {
60-
console.log(`Previous bot comment found ${previousComment.id}.`);
61-
62-
await octokit.rest.issues.updateComment({
63-
...baseOctokitConfig,
64-
body: commentBody,
65-
comment_id: previousComment.id,
66-
});
67-
68-
return;
69-
}
70-
71-
console.log('Creating new comment.');
72-
await octokit.rest.issues.createComment({
73-
...baseOctokitConfig,
74-
body: commentBody,
75-
});
76-
} catch (e) {
77-
throw new Error(`Error with GitHub API: ${e}`);
11+
export async function pushGeneratedCode(): Promise<void> {
12+
if (!process.env.GITHUB_TOKEN) {
13+
throw new Error('Environment variable `GITHUB_TOKEN` does not exist.');
7814
}
79-
}
8015

81-
/**
82-
* Push generated code for the current `JOB` and `CLIENT` on a `generated/` branch.
83-
*/
84-
async function pushGeneratedCode(): Promise<void> {
8516
await configureGitHubAuthor();
8617

8718
const baseBranch = await run('git branch --show-current');
8819
console.log(`Checking codegen status on '${baseBranch}'.`);
8920

9021
// determine generated branch name based on current branch
9122
const generatedCodeBranch = `generated/${baseBranch}`;
92-
const generatedFolders = FOLDERS_TO_CHECK.join(' ');
9323

9424
if (
9525
(await run(
96-
`git status --porcelain ${generatedFolders} | wc -l | tr -d ' '`
26+
`git status --porcelain ${FOLDERS_TO_CHECK} | wc -l | tr -d ' '`
9727
)) === '0'
9828
) {
9929
console.log(`No generated code changes found for '${baseBranch}'.`);
10030

31+
if (PR_NUMBER) {
32+
await run(`yarn workspace scripts upsertGenerationComment noGen`);
33+
}
34+
10135
return;
10236
}
10337

10438
await run(`yarn workspace scripts cleanGeneratedBranch ${baseBranch}`);
10539

106-
const baseCommit = await run(`git show ${baseBranch} -s --format=%H`);
107-
console.log(
108-
`Codegen triggered on branch '${baseBranch}' for commit ${baseCommit}.`
109-
);
110-
11140
console.log(`Creating branch for generated code: '${generatedCodeBranch}'`);
11241
await run(`git branch ${generatedCodeBranch}`);
11342
const commitMessage =
@@ -116,15 +45,16 @@ async function pushGeneratedCode(): Promise<void> {
11645
Co-authored-by: %an <%ae>"`);
11746

11847
console.log(
119-
`Pushing code for folders '${generatedFolders}' to generated branch: ${generatedCodeBranch}`
48+
`Pushing code for folders '${FOLDERS_TO_CHECK}' to generated branch: ${generatedCodeBranch}`
12049
);
12150
await run(`git checkout ${generatedCodeBranch}`);
122-
await run(`git add ${generatedFolders}`);
51+
await run(`git add ${FOLDERS_TO_CHECK}`);
12352
await run(`git commit -m "${commitMessage}"`);
12453
await run(`git push origin ${generatedCodeBranch}`);
54+
await run(`git checkout ${baseBranch}`);
12555

12656
if (PR_NUMBER) {
127-
await upsertCommentToPullRequest(baseCommit, generatedCodeBranch);
57+
await run(`yarn workspace scripts upsertGenerationComment codegen`);
12858
}
12959
}
13060

0 commit comments

Comments
 (0)