-
Notifications
You must be signed in to change notification settings - Fork 4
153 lines (138 loc) · 5.43 KB
/
check-todo-fixme.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
name: Check todo and fixme
on:
pull_request:
branches:
- '**'
jobs:
check:
runs-on: ubuntu-latest
steps:
- name: Checkout patomic
uses: actions/checkout@v4
with:
path: patomic
- name: Get Open Issues
id: get-open-issues
uses: actions/github-script@v7
with:
script: |
// get repository details
const [owner, repo] = "${{ github.repository }}".split("/");
// make graphql query
const graphql = `query listOpenIssues($repository: String!, $owner: String!, $cursor: String) {
repository(name: $repository, owner: $owner) {
issues(first: 100, states: OPEN, after: $cursor) {
nodes {
number
}
pageInfo {
endCursor
hasNextPage
}
}
}
}`;
// get information from graphql api
let cursor;
let openIssueNumbers = [];
do {
const response = await github.graphql(graphql, { repository: repo, owner: owner, cursor });
response.repository.issues.nodes.forEach(({ number }) => openIssueNumbers.push(number));
cursor = response.repository.issues.pageInfo.endCursor;
} while (cursor);
// save data as json by returning
console.log(openIssueNumbers);
return openIssueNumbers;
- name: Scan Files for Fixme and Todo
id: scan-files
env:
BASE_PATH: './patomic'
uses: actions/github-script@v7
with:
script: |
// dependencies
const fs = require('fs');
const path = require('path');
// get issue id if line contains todo or fixme
// return: null | { issueId: null } | { issueId: 'number' }
function parseLine(line) {
const regex = /(fixme|todo)/i;
const issueIdRegex = /ghi\s#(\d+)/i;
if (regex.test(line)) {
const match = line.match(issueIdRegex);
const issueId = match ? match[1] : null;
return { issueId };
} else {
return null;
}
}
// list all files in directory (except excluded ones)
// return: [ path1, path2, ... ]
const excludedDirs = ['.git'];
const excludedFiles = ['check-todo-fixme.yml'];
function listFiles(dir) {
let result = [];
fs.readdirSync(dir).forEach(file => {
// base set up
let fullPath = path.join(dir, file);
let stat = fs.statSync(fullPath);
// path is a directory
if (stat && stat.isDirectory()) {
if (!excludedDirs.includes(file)) {
result = result.concat(listFiles(fullPath));
}
// path is a file
} else if (!excludedFiles.includes(file)) {
result.push(fullPath)
}
});
return result;
}
// parse all lines in all files
// return: [ { filePath: <path>, lineNum: <num>, issueId: <id> }, ... ]
function parseAll(dir) {
const files = listFiles(dir);
const items = []
files.forEach(file => {
const content = fs.readFileSync(file, 'utf-8');
const lines = content.split('\n');
lines.forEach((line, index) => {
const item = parseLine(line);
if (item) {
item.filePath = file;
item.lineNum = index + 1;
items.push(item);
}
});
});
return items;
}
// save data as json by returning
const ret = parseAll('${{ env.BASE_PATH }}');
console.log(ret);
return ret;
- name: Check Issues
uses: actions/github-script@v7
with:
script: |
// get outputs
const openIssueIds = ${{ steps.get-open-issues.outputs.result }};
const parsedItems = ${{ steps.scan-files.outputs.result }};
// go through all parsed items
let errorCount = 0;
parsedItems.forEach(item => {
const filePath = item.filePath.replace('patomic/', '');
if (item.issueId === null) {
++errorCount;
const msg = "No GitHub issue mentioned in todo/fixme comment (must match pattern '/ghi\\s#(\\d+)/i').";
console.error(`::error file=${filePath},line=${item.lineNum}::${msg}`);
} else if (!openIssueIds.includes(parseInt(item.issueId))) {
++errorCount;
const msg = `GitHub issue #${item.issueId} does not correspond to an open issue number for GitHub repository ${{ github.repository }} (maybe it was resolved and closed).`
console.error(`::error file=${filePath},line=${item.lineNum}::${msg}`);
}
});
// fail if error was printed
if (errorCount > 0) {
process.exit(1);
}