Skip to content

Commit 5a8460e

Browse files
authored
feat: add .reference-ignore file support (#41)
This also fixes a small regex error where `-` in the repo name was not matched. Further, the output markdown of the opened issue got improved.
1 parent 03ef659 commit 5a8460e

11 files changed

+96
-46
lines changed

.github/workflows/release-tagger.yml

-15
This file was deleted.

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,5 @@ typings/
103103

104104
# TernJS port file
105105
.tern-port
106+
107+
dist

.reference-ignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
dist*
2+
src/*.test.ts

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ All other inputs are optional.
4848
| issueLabels | the labels to create issues with, comma seperated list | closed reference |
4949
| issueLimit | the maximum number of issues to create, supposed to catch bugs | 5 |
5050
51+
Additionally to setting `ignore` as an input, you can also place a `.reference-ignore` file in the root of your repo (entries should be `\n` separated).
52+
Both, the input and the file will be concatenated.
53+
5154
Note that the action fails when there are more issues to be created than the limit allows. This is because GitHub Actions
5255
do not have manual approval.
5356

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
"version": "1.1.0",
44
"description": "A GitHub action to open an issue when GitHub references in your code are closed.",
55
"bin": "distCli/index.js",
6+
"prettier": "ory-prettier-styles",
67
"scripts": {
78
"build": "npm-run-all build:*",
89
"build:cli": "ncc build src/runInCli.ts -o distCli && echo -e \"#!/usr/bin/env node\\n$(cat distCli/index.js)\" > distCli/index.js",
910
"build:action": "ncc build src/runInAction.ts -o distAction",
1011
"watch": "tsc -w",
1112
"test": "jest",
1213
"test:watch": "jest --watch",
13-
"format": "prettier --single-quote --no-semi --trailing-comma none --write '{src/*.ts,*.md}'",
14-
"format:check": "prettier --check --single-quote --no-semi --trailing-comma none '{src/*.ts,*.md}'"
14+
"format": "prettier --write '{src/*.ts,*.md}'",
15+
"format:check": "prettier --check '{src/*.ts,*.md}'"
1516
},
1617
"repository": {
1718
"type": "git",
@@ -36,6 +37,7 @@
3637
"@actions/core": "^1.2.6",
3738
"@actions/github": "^2.1.1",
3839
"ignore": "^5.1.4",
40+
"ory-prettier-styles": "^1.0.1",
3941
"walkdir": "^0.4.1"
4042
}
4143
}

src/helpers.ts

+24-4
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import { GitHub } from '@actions/github'
1717
import { Octokit } from '@octokit/rest'
1818
import ignore, { Ignore } from 'ignore'
1919
import { Reference } from './mainRunner'
20+
import * as fs from 'fs'
21+
import * as path from 'path'
2022

2123
let client: GitHub
2224
const getClient = () => client || (client = new GitHub(getInput('token')))
@@ -31,10 +33,13 @@ export const issueBody = (
3133
thisRepo: string,
3234
foundIn: Reference['foundIn']
3335
) =>
34-
`The upstream [${type}](https://${upstreamReference}) got closed. It is referenced in: ${foundIn.map(
35-
([file, line]) =>
36-
`[${file}#L${line}](https://github.com/${thisOwner}/${thisRepo}/blob/master/${file}#L${line})`
37-
)}`
36+
`The upstream [${type}](https://${upstreamReference}) got closed. It is referenced in:
37+
- [ ] ${foundIn
38+
.map(
39+
([file, line]) =>
40+
`[${file}#L${line}](https://github.com/${thisOwner}/${thisRepo}/blob/master/${file}#L${line})`
41+
)
42+
.join('\n- [ ] ')}`
3843

3944
export const createIssue = (params: Octokit.IssuesCreateParams) =>
4045
getClient()
@@ -88,6 +93,21 @@ export const issueIsClosed = (reference: Reference): Promise<boolean> => {
8893
.then((issue) => issue.data.state === 'closed')
8994
}
9095

96+
export const readIgnoreFiles = (dir: string = '.'): Promise<string[]> =>
97+
Promise.allSettled(
98+
['.reference-ignore', '.gitignore'].map((fn) =>
99+
fs.promises.readFile(path.join(dir, fn))
100+
)
101+
).then((files) =>
102+
files
103+
.filter<PromiseFulfilledResult<Buffer>>(
104+
(file): file is PromiseFulfilledResult<Buffer> =>
105+
file.status === 'fulfilled'
106+
)
107+
.map((fulFilled) => fulFilled.value.toString().split('\n'))
108+
.flat(1)
109+
)
110+
91111
export default {
92112
issueExists,
93113
exitWithReason,

src/mainRunner.test.ts

+39-13
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@ const mockDependencies = ({
3939
})
4040

4141
const createFiles = (dirPath: string, files: { [path: string]: string }) =>
42-
Promise.all(
43-
Object.entries(files).map(([name, data]) =>
44-
fs.promises
45-
.mkdir(path.dirname(path.join(dirPath, name)), { recursive: true })
46-
.then(() => fs.promises.writeFile(path.join(dirPath, name), data))
47-
)
48-
)
42+
Object.entries(files).forEach(([name, data]) => {
43+
const filePath = path.join(dirPath, name)
44+
fs.mkdirSync(path.dirname(filePath), { recursive: true })
45+
fs.writeFileSync(filePath, data)
46+
})
4947

5048
const expectCreated = (
5149
deps: ReturnType<typeof mockDependencies>,
5250
created: string[],
5351
notCreated: string[]
5452
) => {
53+
if (deps.exitWithReason.mock.calls.length != 0) {
54+
console.log(deps.exitWithReason.mock.calls)
55+
}
5556
expect(deps.exitWithReason).toBeCalledTimes(0)
5657
expect(deps.createIssue).toBeCalledTimes(created.length)
5758
expect(deps.issueIsClosed).toBeCalledTimes(created.length + notCreated.length)
@@ -90,16 +91,16 @@ const expectFail = (
9091
describe('mainRunner works', () => {
9192
let dir: string
9293

93-
beforeEach(async () => {
94-
await fs.promises.mkdtemp('test').then((path) => (dir = path))
95-
await createFiles(dir, {
94+
beforeEach(() => {
95+
dir = fs.mkdtempSync('test')
96+
createFiles(dir, {
9697
'src/index.js': 'github.com/testUser/testRepo/issues/1337',
9798
'foo.txt': 'github.com/testUser/testRepo/pull/42'
9899
})
99100
})
100101

101-
afterEach(async () => {
102-
await fs.promises.rmdir(dir, { recursive: true })
102+
afterEach(() => {
103+
fs.rmdirSync(dir, { recursive: true })
103104
})
104105

105106
it('should create issues for closed references', async () => {
@@ -212,7 +213,7 @@ describe('mainRunner works', () => {
212213
path: dir,
213214
issueLimit: 2
214215
})
215-
await createFiles(dir, {
216+
createFiles(dir, {
216217
'bar.txt': 'github.com/testUser/testRepo/pull/42'
217218
})
218219
await mainRunner(deps)
@@ -231,4 +232,29 @@ describe('mainRunner works', () => {
231232
['foo.txt', 1]
232233
])
233234
})
235+
236+
it('should find multiple references in one file', async () => {
237+
const deps = mockDependencies({
238+
issueExists: false,
239+
referenceClosed: true,
240+
path: dir,
241+
issueLimit: 4
242+
})
243+
createFiles(dir, {
244+
'bar.txt':
245+
'github.com/testUser/testRepo/pull/420\ngithub.com/ory/closed-reference-notifier/issues/13'
246+
})
247+
await mainRunner(deps)
248+
249+
expectCreated(
250+
deps,
251+
[
252+
'github.com/testUser/testRepo/pull/42',
253+
'github.com/testUser/testRepo/issues/1337',
254+
'github.com/testUser/testRepo/pull/420',
255+
'github.com/ory/closed-reference-notifier/issues/13'
256+
],
257+
[]
258+
)
259+
})
234260
})

src/mainRunner.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import fs from 'fs'
1717
import walkdir from 'walkdir'
1818
import path from 'path'
1919

20-
const referenceRegex = /github\.com\/([a-zA-Z\d-]+)\/([a-zA-Z\d.-_]+)\/(pull|issues)\/(\d+)/gm
20+
const referenceRegex = /github\.com\/([a-zA-Z\d-]+)\/([a-zA-Z\d._-]+)\/(pull|issues)\/(\d+)/gm
2121

2222
export type Dependencies = typeof helpers & {
2323
labels: Array<string>

src/runInAction.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414

1515
import { getInput } from '@actions/core'
1616
import fs from 'fs'
17-
import nodePath from 'path'
18-
import helpers from './helpers'
17+
import helpers, { readIgnoreFiles } from './helpers'
1918
import mainRunner from './mainRunner'
2019

2120
const [thisOwner, thisRepo] = process.env.GITHUB_REPOSITORY.split('/', 2)
@@ -27,7 +26,10 @@ const [thisOwner, thisRepo] = process.env.GITHUB_REPOSITORY.split('/', 2)
2726
thisOwner,
2827
thisRepo,
2928
labels: getInput('issueLabels').split(','),
30-
ignorePaths: getInput('ignore').split(','),
29+
ignorePaths: [
30+
...getInput('ignore').split(','),
31+
...(await readIgnoreFiles())
32+
],
3133
directory: '.',
3234
issueLimit: parseInt(getInput('issueLimit')) || 5
3335
})

src/runInCli.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import mainRunner from './mainRunner'
2-
import { shouldIgnore } from './helpers'
3-
import * as fs from 'fs'
2+
import { readIgnoreFiles, shouldIgnore } from './helpers'
3+
import fs from 'fs'
44

5-
switch (process.argv[2]) {
5+
const [dir = '-h', ignore = '.git'] = process.argv.slice(2)
6+
7+
switch (dir) {
68
case '-help':
79
case '-h':
810
case '--help':
911
console.log(`Usage:
1012
npx closed-reference-notifier <dir> <ignore>
1113
1214
<dir>: the directory to traverse
13-
<ignore>: comma separated list of gitignore style entries to ignore
15+
<ignore>: comma separated list of gitignore style entries to ignore, defaults to '.git'
1416
`)
1517
process.exit(0)
1618
}
@@ -21,16 +23,17 @@ npx closed-reference-notifier <dir> <ignore>
2123
thisOwner: '',
2224
issueExists: () => Promise.resolve(false),
2325
issueTitle: () => '',
24-
issueBody: (ref, type, thisOwner, thisRepo, file) =>
25-
`Found reference "${ref}" in file ${file}`,
26+
issueBody: (ref, type, thisOwner, thisRepo, files) =>
27+
`Found reference "${ref}" in files
28+
${files.map((file) => file.join('#')).join('\n ')}`,
2629
issueIsClosed: () => Promise.resolve(true),
27-
ignorePaths: process.argv[3] ? process.argv[3].split(',') : [],
30+
ignorePaths: [...ignore.split(','), ...(await readIgnoreFiles(dir))],
2831
createIssue: (issue) => {
2932
console.log(issue.body)
3033
return Promise.resolve()
3134
},
3235
shouldIgnore,
33-
directory: process.argv[2],
36+
directory: dir,
3437
exitWithReason: (err: any) => {
3538
console.log('unexpected error:', err)
3639
process.exit(1)

0 commit comments

Comments
 (0)