-
Notifications
You must be signed in to change notification settings - Fork 47
/
octokit.ts
116 lines (104 loc) · 3.41 KB
/
octokit.ts
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
import { GitHub } from '@actions/github';
import * as TE from 'fp-ts/lib/TaskEither';
import * as E from 'fp-ts/lib/Either';
import * as D from 'io-ts/lib/Decoder';
import { draw } from 'io-ts/lib/Tree';
import { Do } from 'fp-ts-contrib/lib/Do';
import { ChecksCreateResponse, ChecksUpdateParamsOutputAnnotations, ChecksUpdateParams, Response } from '@octokit/rest';
import { pipe } from 'fp-ts/lib/pipeable';
const EventDecoder = D.type({
after: D.string,
repository: D.type({
name: D.string,
owner: D.type({
login: D.string,
}),
}),
});
type Event = D.TypeOf<typeof EventDecoder>;
export const createOctokitInstance = (token: string) => TE.fromEither(E.tryCatch(() => new GitHub(token), E.toError));
export const createGithubCheck = (octokit: GitHub, event: IRepositoryInfo, name: string) =>
TE.tryCatch(
() =>
octokit.checks.create({
owner: event.owner,
repo: event.repo,
name,
head_sha: event.sha,
status: 'in_progress',
}),
E.toError
);
export interface IRepositoryInfo {
owner: string;
repo: string;
eventName: string;
sha: string;
}
const extractSha = (eventName: string, event: any): E.Either<Error, string> => {
switch (eventName) {
case 'pull_request':
return E.right(event.pull_request.head.sha);
case 'push':
return E.right(event.after);
default:
return E.left(Error(`Unsupported event '${eventName}'`));
}
};
function buildRepositoryInfoFrom(event: Event, eventName: string, sha: string): IRepositoryInfo {
const { repository } = event;
const {
owner: { login: owner },
} = repository;
const { name: repo } = repository;
return { owner, repo, eventName, sha };
}
const parseEventFile = (eventPath: string) =>
pipe(
E.tryCatch<Error, unknown>(() => require(eventPath), E.toError),
E.chain(event =>
pipe(
EventDecoder.decode(event),
E.mapLeft(errors => new Error(draw(errors)))
)
)
);
export const getRepositoryInfoFromEvent = (eventPath: string, eventName: string): E.Either<Error, IRepositoryInfo> =>
Do(E.either)
.bind('event', parseEventFile(eventPath))
.bindL('sha', ({ event }) => extractSha(eventName, event))
.return(({ event, sha }) => buildRepositoryInfoFrom(event, eventName, sha));
export const updateGithubCheck = (
octokit: GitHub,
check: Response<ChecksCreateResponse>,
event: IRepositoryInfo,
annotations: ChecksUpdateParamsOutputAnnotations[],
conclusion: ChecksUpdateParams['conclusion'],
message?: string
) =>
TE.tryCatch(
() =>
octokit.checks.update({
check_run_id: check.data.id,
owner: event.owner,
name: check.data.name,
repo: event.repo,
status: 'completed',
conclusion,
completed_at: new Date().toISOString(),
output: {
title: check.data.name,
summary: message
? message
: conclusion === 'success'
? 'Lint completed successfully'
: 'Lint completed with some errors',
// TODO: Split calls when annotations.length > 50
// From https://octokit.github.io/rest.js/v17#checks-update
// => "The Checks API limits the number of annotations to a maximum of 50 per API request.
// To create more than 50 annotations, you have to make multiple requests to the Update a check run endpoint."
annotations,
},
}),
E.toError
);