Skip to content
This repository was archived by the owner on Nov 18, 2024. It is now read-only.

Commit 187335e

Browse files
authored
Example issueSummaryOnlyOnEvent & reportWarningsAsErrors (#16)
* test: issueSummaryOnlyOnEvent * log context * log env * get current workflow context on first run * log state diff * move userid to workflow state * add issueSummaryOnlyOnEvent to action.yml * cause event * fix event * report severity level properly
1 parent 2f71c79 commit 187335e

17 files changed

+311
-61
lines changed

Diff for: .github/workflows/test.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,6 @@ jobs:
1818
- uses: actions/checkout@v2
1919
- uses: ./
2020
with:
21-
reportIgnoredFiles: true
21+
reportIgnoredFiles: true
22+
reportWarningsAsErrors: true
23+
issueSummaryOnlyOnEvent: true

Diff for: action.yml

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ inputs:
3030
issueSummaryMethod:
3131
description: 'When issueSummary is enabled, allows having the bot edit or refresh the comment on each new push'
3232
required: false
33+
issueSummaryOnlyOnEvent:
34+
description: 'Should an issue comment only occur when there are warnings or errors?'
35+
required: false
3336
extensions:
3437
description: 'Optionally provide a comma-separated list of extensions (checks js, jsx, ts, tsx by default)'
3538
required: false

Diff for: lib/api.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
3-
exports.updateCheck = exports.createCheck = exports.fetchFilesBatchCommit = exports.fetchFilesBatchPR = void 0;
3+
exports.getCurrentWorkflow = exports.updateCheck = exports.createCheck = exports.fetchFilesBatchCommit = exports.fetchFilesBatchPR = void 0;
44
const tslib_1 = require("tslib");
55
const core = tslib_1.__importStar(require("@actions/core"));
66
const constants_1 = require("./constants");
@@ -86,3 +86,14 @@ function updateCheck(createCheckResult, data, client, owner, repo, nextParams) {
8686
});
8787
}
8888
exports.updateCheck = updateCheck;
89+
function getCurrentWorkflow(client, data, owner = constants_1.OWNER, repo = constants_1.REPO) {
90+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
91+
const workflows = yield client.actions.listRepoWorkflows({
92+
owner,
93+
repo,
94+
});
95+
const currentWorkflow = workflows.data.workflows.find((workflow) => workflow.name === data.name);
96+
return currentWorkflow;
97+
});
98+
}
99+
exports.getCurrentWorkflow = getCurrentWorkflow;

Diff for: lib/artifacts.js

+15-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const artifact = tslib_1.__importStar(require("@actions/artifact"));
99
const constants_1 = require("./constants");
1010
const fs_2 = require("./fs");
1111
const utils_1 = require("./utils");
12+
const api_1 = require("./api");
1213
const defaultArtifactFilter = (artifacts) => artifacts.filter((artifact) => artifact.name.startsWith(constants_1.ARTIFACT_KEY));
1314
function getArtifactsForRepo(client) {
1415
return client.actions.listArtifactsForRepo({
@@ -102,23 +103,31 @@ function getIssueState(client, data, _artifacts) {
102103
if (!artifact) {
103104
const state = lodash_clonedeep_1.default(constants_1.DEFAULT_ISSUE_STATE);
104105
state.issue.id = data.issueNumber;
105-
state.workflow = Object.freeze(workflowState);
106+
state.workflow = workflowState;
106107
return state;
107108
}
108109
const state = JSON.parse(artifact);
109-
state.workflow = Object.freeze(workflowState);
110+
state.workflow = workflowState;
110111
return state;
111112
});
112113
}
113114
exports.getIssueState = getIssueState;
114115
function getWorkflowState(client, data, _artifacts) {
115116
return tslib_1.__awaiter(this, void 0, void 0, function* () {
116117
const [artifact] = yield downloadArtifacts(client, (artifactList) => artifactList.filter((a) => a.name === utils_1.getWorkflowStateName(data)), _artifacts || (yield getArtifactsForRepo(client)));
117-
if (!artifact) {
118-
console.warn('No Workflow State Found, Using Default');
119-
return lodash_clonedeep_1.default(constants_1.DEFAULT_WORKFLOW_STATE);
118+
const state = artifact
119+
? JSON.parse(artifact)
120+
: lodash_clonedeep_1.default(constants_1.DEFAULT_WORKFLOW_STATE);
121+
if (!state.id) {
122+
console.log('Getting Current Workflow Information');
123+
const currentWorkflow = yield api_1.getCurrentWorkflow(client, data);
124+
if (currentWorkflow) {
125+
state.id = currentWorkflow.id;
126+
state.path = currentWorkflow.path;
127+
yield updateWorkflowState(client, data, state);
128+
}
120129
}
121-
return JSON.parse(artifact);
130+
return state;
122131
});
123132
}
124133
exports.getWorkflowState = getWorkflowState;

Diff for: lib/constants.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ const github = tslib_1.__importStar(require("@actions/github"));
77
const guards_1 = require("./guards");
88
const context = github.context;
99
exports.DEFAULT_ISSUE_STATE = Object.freeze({
10-
action: Object.freeze({
11-
userId: undefined,
12-
}),
1310
issue: Object.freeze({
1411
id: undefined,
1512
summaryId: undefined,
1613
}),
1714
});
1815
exports.DEFAULT_WORKFLOW_STATE = Object.freeze({
16+
id: undefined,
17+
path: undefined,
18+
userId: undefined,
1919
scheduler: Object.freeze({
2020
lastRunAt: undefined,
2121
}),

Diff for: lib/issues.js

+38-8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,35 @@ exports.handleIssueComment = void 0;
44
const tslib_1 = require("tslib");
55
const constants_1 = require("./constants");
66
const markdown_1 = require("./utils/markdown");
7+
function removeIssueSummary(client, data) {
8+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
9+
if (data.issueNumber && data.persist.workflow.userId) {
10+
const comments = yield client.issues.listComments({
11+
owner: constants_1.OWNER,
12+
repo: constants_1.REPO,
13+
issue_number: data.issueNumber,
14+
});
15+
yield Promise.all(comments.data.reduce((arr, comment) => {
16+
if (comment.user.id === data.persist.workflow.userId) {
17+
arr.push(client.issues.deleteComment({
18+
owner: constants_1.OWNER,
19+
repo: constants_1.REPO,
20+
comment_id: comment.id,
21+
}));
22+
}
23+
return arr;
24+
}, []));
25+
}
26+
else if (data.persist.issue.summaryId) {
27+
yield client.issues.deleteComment({
28+
owner: constants_1.OWNER,
29+
repo: constants_1.REPO,
30+
comment_id: data.persist.issue.summaryId,
31+
});
32+
}
33+
data.persist.issue.summaryId = undefined;
34+
});
35+
}
736
function handleIssueComment(client, data) {
837
return tslib_1.__awaiter(this, void 0, void 0, function* () {
938
const { state } = data;
@@ -14,21 +43,19 @@ function handleIssueComment(client, data) {
1443
state.fixableErrorCount > 0 ||
1544
state.fixableWarningCount > 0) {
1645
if (data.persist.issue.summaryId && data.issueSummaryMethod === 'edit') {
17-
yield client.issues.updateComment({
46+
const result = yield client.issues.updateComment({
1847
owner: constants_1.OWNER,
1948
repo: constants_1.REPO,
2049
comment_id: data.persist.issue.summaryId,
2150
body: markdown_1.getResultMarkdownBody(data),
2251
});
52+
if (!data.persist.workflow.userId) {
53+
data.persist.workflow.userId = result.data.user.id;
54+
}
2355
}
2456
else if (data.persist.issue.summaryId &&
2557
data.issueSummaryMethod === 'refresh') {
26-
yield client.issues.deleteComment({
27-
owner: constants_1.OWNER,
28-
repo: constants_1.REPO,
29-
comment_id: data.persist.issue.summaryId,
30-
});
31-
data.persist.issue.summaryId = undefined;
58+
yield removeIssueSummary(client, data);
3259
}
3360
if (!data.persist.issue.summaryId) {
3461
const commentResult = yield client.issues.createComment({
@@ -38,9 +65,12 @@ function handleIssueComment(client, data) {
3865
body: markdown_1.getResultMarkdownBody(data),
3966
});
4067
data.persist.issue.summaryId = commentResult.data.id;
41-
data.persist.action.userId = commentResult.data.user.id;
68+
data.persist.workflow.userId = commentResult.data.user.id;
4269
}
4370
}
71+
else if (data.issueSummaryOnlyOnEvent && data.persist.issue.summaryId) {
72+
yield removeIssueSummary(client, data);
73+
}
4474
}
4575
});
4676
}

Diff for: lib/quick.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ function arrayBufferToString(buffer) {
1111
exports.default = arrayBufferToString;
1212
function run() {
1313
return tslib_1.__awaiter(this, void 0, void 0, function* () {
14-
const artifacts = yield client.actions.listArtifactsForRepo({
14+
const workflows = yield client.actions.listRepoWorkflows({
1515
owner: 'bradennapier',
1616
repo: 'eslint-plus-action',
1717
});
18-
console.log(JSON.stringify(artifacts.data, null, 2));
18+
const currentWorkflow = workflows.data.workflows.find((workflow) => workflow.name === 'lint');
19+
console.log(JSON.stringify(currentWorkflow, null, 2));
1920
});
2021
}
2122
run();

Diff for: lib/run.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const constants_1 = require("./constants");
99
const octokit_1 = require("./utils/octokit");
1010
const artifacts_1 = require("./artifacts");
1111
const issues_1 = require("./issues");
12+
const lodash_clonedeep_1 = tslib_1.__importDefault(require("lodash.clonedeep"));
1213
function run() {
1314
var _a, _b, _c;
1415
return tslib_1.__awaiter(this, void 0, void 0, function* () {
@@ -93,7 +94,8 @@ function run() {
9394
case 'synchronize':
9495
default: {
9596
data.persist = yield artifacts_1.getIssueState(client, data);
96-
core.info(`Context:\n ${JSON.stringify(data, null, 2)}`);
97+
const startState = lodash_clonedeep_1.default(data.persist);
98+
core.info(`Data:\n ${JSON.stringify(data, null, 2)}`);
9799
if (data.isReadOnly && !utils_1.isSchedulerActive(data)) {
98100
console.warn(`[WARN] | Read Only & schedule not found, we will not run on this PR.`);
99101
return;
@@ -105,8 +107,9 @@ function run() {
105107
}
106108
else {
107109
yield issues_1.handleIssueComment(client, data);
108-
yield artifacts_1.updateIssueState(client, data);
110+
yield utils_1.updateIssueStateIfNeeded(client, startState, data);
109111
}
112+
yield utils_1.updateWorkflowStateIfNeeded(client, startState, data);
110113
break;
111114
}
112115
}

Diff for: lib/utils.js

+28-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
3-
exports.processLintResults = exports.processInput = exports.processBooleanInput = exports.processEnumInput = exports.processArrayInput = exports.isSchedulerActive = exports.getIssueLintResultsName = exports.getIssueStateName = exports.getWorkflowStateName = void 0;
3+
exports.updateWorkflowStateIfNeeded = exports.updateIssueStateIfNeeded = exports.processLintResults = exports.processInput = exports.processBooleanInput = exports.processEnumInput = exports.processArrayInput = exports.isSchedulerActive = exports.getIssueLintResultsName = exports.getIssueStateName = exports.getWorkflowStateName = void 0;
44
const tslib_1 = require("tslib");
5+
const util_1 = require("util");
56
const dayjs_1 = tslib_1.__importDefault(require("dayjs"));
67
const core = tslib_1.__importStar(require("@actions/core"));
78
const constants_1 = require("./constants");
9+
const artifacts_1 = require("./artifacts");
810
exports.getWorkflowStateName = (data) => `${constants_1.ARTIFACT_KEY_ISSUE_STATE}-${data.name}`;
911
exports.getIssueStateName = (data) => `${constants_1.ARTIFACT_KEY_ISSUE_STATE}-${data.name}-${data.issueNumber}`;
1012
exports.getIssueLintResultsName = (data) => `${constants_1.ARTIFACT_KEY_LINT_RESULTS}-${data.name}-${data.issueNumber}`;
@@ -116,7 +118,7 @@ function processLintResults(engine, report, data) {
116118
ruleUrl: ruleDocs === null || ruleDocs === void 0 ? void 0 : ruleDocs.url,
117119
ruleId,
118120
message: (ruleDocs === null || ruleDocs === void 0 ? void 0 : ruleDocs.description) || '',
119-
level: severity === 2 ? 'failure' : 'warning',
121+
level,
120122
annotations: [annotation],
121123
});
122124
}
@@ -132,3 +134,27 @@ function processLintResults(engine, report, data) {
132134
};
133135
}
134136
exports.processLintResults = processLintResults;
137+
function updateIssueStateIfNeeded(client, prevState, data) {
138+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
139+
const promises = [];
140+
const prevIssueState = Object.assign(Object.assign({}, prevState), { workflow: undefined });
141+
const nextIssueState = Object.assign(Object.assign({}, data.persist), { workflow: undefined });
142+
if (!util_1.isDeepStrictEqual(prevIssueState, nextIssueState)) {
143+
console.log('Issue State Updating');
144+
console.log(JSON.stringify(prevIssueState, null, 2), JSON.stringify(nextIssueState, null, 2));
145+
promises.push(artifacts_1.updateIssueState(client, data));
146+
}
147+
yield Promise.all(promises);
148+
});
149+
}
150+
exports.updateIssueStateIfNeeded = updateIssueStateIfNeeded;
151+
function updateWorkflowStateIfNeeded(client, prevState, data) {
152+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
153+
if (!util_1.isDeepStrictEqual(prevState.workflow, data.persist.workflow)) {
154+
console.log('Workflow State Updating');
155+
console.log(JSON.stringify(prevState.workflow, null, 2), JSON.stringify(data.persist.workflow, null, 2));
156+
yield artifacts_1.updateWorkflowState(client, data, data.persist.workflow);
157+
}
158+
});
159+
}
160+
exports.updateWorkflowStateIfNeeded = updateWorkflowStateIfNeeded;

Diff for: src/api.ts

+24-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
OctokitCreateChecksParams,
99
OctokitUpdateChecksParams,
1010
CheckUpdaterFn,
11+
GitHubWorkflow,
1112
} from './types';
1213
import { NAME, OWNER, REPO } from './constants';
1314

@@ -117,7 +118,6 @@ export async function createCheck(
117118
};
118119

119120
const createCheckResult = await client.checks.create(params);
120-
121121
data.state.checkId = createCheckResult.data.id;
122122

123123
return (nextParams: Partial<OctokitUpdateChecksParams>) =>
@@ -146,3 +146,26 @@ export async function updateCheck(
146146

147147
return result;
148148
}
149+
150+
/**
151+
* Since the github action context does not provide the necessary information
152+
* to know what our workflow id is, we will capture it and save to our workflow level
153+
* state.
154+
*/
155+
export async function getCurrentWorkflow(
156+
client: Octokit,
157+
data: ActionData,
158+
owner: string = OWNER,
159+
repo: string = REPO,
160+
): Promise<GitHubWorkflow | undefined> {
161+
const workflows = await client.actions.listRepoWorkflows({
162+
owner,
163+
repo,
164+
});
165+
166+
const currentWorkflow = workflows.data.workflows.find(
167+
(workflow) => workflow.name === data.name,
168+
);
169+
170+
return currentWorkflow;
171+
}

Diff for: src/artifacts.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
getIssueLintResultsName,
2626
getWorkflowStateName,
2727
} from './utils';
28+
import { getCurrentWorkflow } from './api';
2829

2930
type ArtifactFilter =
3031
| null
@@ -179,14 +180,14 @@ export async function getIssueState(
179180
const state = cloneDeep(DEFAULT_ISSUE_STATE);
180181
state.issue.id = data.issueNumber;
181182
// eslint-disable-next-line @typescript-eslint/no-explicit-any
182-
(state as any).workflow = Object.freeze(workflowState);
183+
(state as any).workflow = workflowState;
183184
return state as IssuePersistentState;
184185
}
185186

186187
const state = JSON.parse(artifact);
187188

188189
// eslint-disable-next-line @typescript-eslint/no-explicit-any
189-
(state as any).workflow = Object.freeze(workflowState);
190+
(state as any).workflow = workflowState;
190191

191192
return state as IssuePersistentState;
192193
}
@@ -203,12 +204,21 @@ export async function getWorkflowState(
203204
_artifacts || (await getArtifactsForRepo(client)),
204205
);
205206

206-
if (!artifact) {
207-
console.warn('No Workflow State Found, Using Default');
208-
return cloneDeep(DEFAULT_WORKFLOW_STATE);
207+
const state: WorkflowPersistentState = artifact
208+
? JSON.parse(artifact)
209+
: cloneDeep(DEFAULT_WORKFLOW_STATE);
210+
211+
if (!state.id) {
212+
console.log('Getting Current Workflow Information');
213+
const currentWorkflow = await getCurrentWorkflow(client, data);
214+
if (currentWorkflow) {
215+
state.id = currentWorkflow.id;
216+
state.path = currentWorkflow.path;
217+
await updateWorkflowState(client, data, state);
218+
}
209219
}
210220

211-
return JSON.parse(artifact);
221+
return state;
212222
}
213223

214224
/**

Diff for: src/constants.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ export const DEFAULT_ISSUE_STATE: Omit<
1818
IssuePersistentState,
1919
'workflow'
2020
> = Object.freeze({
21-
action: Object.freeze({
22-
userId: undefined,
23-
}),
2421
issue: Object.freeze({
2522
id: undefined,
2623
summaryId: undefined,
2724
}),
2825
});
2926

3027
export const DEFAULT_WORKFLOW_STATE: WorkflowPersistentState = Object.freeze({
28+
id: undefined,
29+
path: undefined,
30+
userId: undefined,
3131
scheduler: Object.freeze({
3232
lastRunAt: undefined,
3333
}),

0 commit comments

Comments
 (0)