Skip to content

Commit 5670a23

Browse files
authored
Changeset checker (#3554)
1 parent c6abcd8 commit 5670a23

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

.github/workflows/check-changeset.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Check Changeset
2+
3+
on: pull_request
4+
5+
jobs:
6+
check_changeset:
7+
name: Check changeset vs changed files
8+
runs-on: ubuntu-latest
9+
10+
steps:
11+
- name: Checkout Repo
12+
uses: actions/checkout@master
13+
with:
14+
# This makes Actions fetch all Git history so check_changeset script can diff properly.
15+
- name: Set up Node (10)
16+
uses: actions/setup-node@v1
17+
with:
18+
node-version: 10.x
19+
- name: Yarn install
20+
run: yarn
21+
- name: Run changeset script
22+
run: yarn ts-node-script scripts/check_changeset.ts
23+
id: check-changeset
24+
- name: Read output
25+
run: echo "${{steps.check-changeset.outputs.MISSING_PACKAGES}}"
26+
- name: Find Comment
27+
uses: peter-evans/find-comment@v1
28+
id: fc
29+
with:
30+
issue-number: ${{github.event.number}}
31+
body-includes: Changeset File Check
32+
- name: Create comment (missing packages)
33+
if: ${{!steps.fc.outputs.comment-id && steps.check-changeset.outputs.MISSING_PACKAGES}}
34+
uses: peter-evans/create-or-update-comment@v1
35+
with:
36+
issue-number: ${{github.event.number}}
37+
body: |
38+
### Changeset File Check :warning:
39+
Warning: This PR modifies files in the following packages but they have not been included in the changeset file:
40+
${{steps.check-changeset.outputs.MISSING_PACKAGES}}
41+
42+
Make sure this was intentional.
43+
- name: Update comment (missing packages)
44+
if: ${{steps.fc.outputs.comment-id}}
45+
uses: peter-evans/create-or-update-comment@v1
46+
with:
47+
comment-id: ${{steps.fc.outputs.comment-id}} && steps.check-changeset.outputs.MISSING_PACKAGES}}
48+
edit-mode: replace
49+
body: |
50+
### Changeset File Check :warning:
51+
Warning: This PR modifies files in the following packages but they have not been included in the changeset file:
52+
${{steps.check-changeset.outputs.MISSING_PACKAGES}}
53+
54+
Make sure this was intentional.
55+
- name: Update comment (no missing packages)
56+
if: ${{steps.fc.outputs.comment-id && !steps.check-changeset.outputs.MISSING_PACKAGES}}
57+
uses: peter-evans/create-or-update-comment@v1
58+
with:
59+
comment-id: ${{steps.fc.outputs.comment-id}}
60+
edit-mode: replace
61+
body: |
62+
### Changeset File Check :white_check_mark:
63+
No modified packages are missing from the changeset file.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
"@types/listr": "0.14.2",
7777
"@types/long": "4.0.1",
7878
"@types/mocha": "7.0.2",
79+
"@types/mz": "2.7.1",
7980
"@types/node": "12.12.53",
8081
"@types/sinon": "9.0.4",
8182
"@types/sinon-chai": "3.2.4",

scripts/check_changeset.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { resolve } from 'path';
19+
import chalk from 'chalk';
20+
import simpleGit from 'simple-git/promise';
21+
import fs from 'mz/fs';
22+
23+
const root = resolve(__dirname, '..');
24+
const git = simpleGit(root);
25+
26+
/**
27+
* Identify modified packages.
28+
*/
29+
async function getDiffData(): Promise<{
30+
changedPackages: Set<string>;
31+
changesetFile: string;
32+
} | null> {
33+
const diff = await git.diff(['--name-only', 'origin/master...HEAD']);
34+
const changedFiles = diff.split('\n');
35+
let changesetFile = '';
36+
const changedPackages = new Set<string>();
37+
for (const filename of changedFiles) {
38+
// Check for an existing .changeset
39+
const changesetMatch = filename.match(/^\.changeset\/[a-zA-Z-]+\.md/);
40+
if (changesetMatch) {
41+
changesetFile = changesetMatch[0];
42+
}
43+
// Check for changed files inside package dirs.
44+
const pkgMatch = filename.match('^(packages(-exp)?/[a-zA-Z0-9-]+)/.*');
45+
if (pkgMatch && pkgMatch[1]) {
46+
const changedPackage = require(resolve(
47+
root,
48+
pkgMatch[1],
49+
'package.json'
50+
));
51+
if (changedPackage) {
52+
// Add the package itself.
53+
changedPackages.add(changedPackage.name);
54+
}
55+
}
56+
}
57+
if (!changesetFile || changedPackages.size === 0) {
58+
return null;
59+
}
60+
return { changedPackages, changesetFile };
61+
}
62+
63+
async function parseChangesetFile(changesetFile: string) {
64+
const fileExists = await fs.exists(changesetFile);
65+
if (!fileExists) {
66+
process.exit();
67+
}
68+
const fileText: string = await fs.readFile(changesetFile, 'utf8');
69+
const fileParts = fileText.split('---\n');
70+
const packageLines = fileParts[1].split('\n');
71+
const changesetPackages = packageLines
72+
.filter(line => line)
73+
.map(line => {
74+
const [packageName] = line.split(':');
75+
return packageName.replace(/'/g, '');
76+
});
77+
return changesetPackages;
78+
}
79+
80+
async function main() {
81+
try {
82+
const diffData = await getDiffData();
83+
if (diffData == null) {
84+
process.exit();
85+
} else {
86+
const { changedPackages, changesetFile } = diffData;
87+
const changesetPackages = await parseChangesetFile(changesetFile);
88+
const missingPackages = [...changedPackages].filter(
89+
changedPkg => !changesetPackages.includes(changedPkg)
90+
);
91+
if (missingPackages.length > 0) {
92+
/**
93+
* Sets Github Actions output for a step. Pass missing package list to next
94+
* step. See:
95+
* https://github.com/actions/toolkit/blob/master/docs/commands.md#set-outputs
96+
*/
97+
console.log(
98+
`::set-output name=MISSING_PACKAGES::${missingPackages
99+
.map(pkg => `- ${pkg}`)
100+
.join('%0A')}`
101+
);
102+
}
103+
process.exit();
104+
}
105+
} catch (e) {
106+
console.error(chalk`{red ${e}}`);
107+
process.exit(1);
108+
}
109+
}
110+
111+
main();

0 commit comments

Comments
 (0)