Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to consider reactions #1086

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Next Next commit
Add updates on reactions
gorzelinski committed Jun 19, 2023
commit 1f507bdb42723c5179df6804bed61b1ffc48c4ff
63 changes: 61 additions & 2 deletions dist/index.js
Original file line number Diff line number Diff line change
@@ -654,6 +654,38 @@ class IssuesProcessor {
}
});
}
// Grab reactions for an issue since a given date
listIssueReactions(issue, sinceDate) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
try {
this._consumeIssueOperation(issue);
(_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsReactionsCount();
let reactions = [];
let currentReactions = [];
let iterator = 1;
const daysSinceLastUpdated = (new Date().getTime() - new Date(sinceDate).getTime()) /
(1000 * 60 * 60 * 24);
do {
const response = yield this.client.rest.reactions.listForIssue({
owner: github_1.context.repo.owner,
repo: github_1.context.repo.repo,
issue_number: issue.number,
per_page: 100,
page: iterator
});
currentReactions = response.data;
reactions = [...reactions, ...currentReactions];
iterator++;
} while (currentReactions.length !== 0);
return reactions.filter(reaction => IssuesProcessor._updatedSince(reaction.created_at, daysSinceLastUpdated));
}
catch (error) {
this._logger.error(`List issue reactions error: ${error.message}`);
return Promise.resolve([]);
}
});
}
// grab issues from github in batches of 100
getIssues(page) {
var _a;
@@ -729,6 +761,8 @@ class IssuesProcessor {
issueLogger.info(`$$type marked stale on: ${logger_service_1.LoggerService.cyan(markedStaleOn)}`);
const issueHasCommentsSinceStale = yield this._hasCommentsSince(issue, markedStaleOn, staleMessage);
issueLogger.info(`$$type has been commented on: ${logger_service_1.LoggerService.cyan(issueHasCommentsSinceStale)}`);
const issueHasReactionsSinceStale = yield this._hasReactionsSince(issue, markedStaleOn);
issueLogger.info(`$$type had a reaction: ${logger_service_1.LoggerService.cyan(issueHasReactionsSinceStale)}`);
const daysBeforeClose = issue.isPullRequest
? this._getDaysBeforePrClose()
: this._getDaysBeforeIssueClose();
@@ -751,7 +785,9 @@ class IssuesProcessor {
issueLogger.info(`$$type has been updated since it was marked stale: ${logger_service_1.LoggerService.cyan(issueHasUpdateSinceStale)}`);
// Should we un-stale this issue?
if (shouldRemoveStaleWhenUpdated &&
(issueHasUpdateSinceStale || issueHasCommentsSinceStale) &&
(issueHasUpdateSinceStale ||
issueHasCommentsSinceStale ||
issueHasReactionsSinceStale) &&
!issue.markedStaleThisRun) {
issueLogger.info(`Remove the stale label since the $$type has been updated and the workflow should remove the stale label when updated`);
yield this._removeStaleLabel(issue, staleLabel);
@@ -767,7 +803,9 @@ class IssuesProcessor {
}
const issueHasUpdateInCloseWindow = IssuesProcessor._updatedSince(issue.updated_at, daysBeforeClose);
issueLogger.info(`$$type has been updated in the last ${daysBeforeClose} days: ${logger_service_1.LoggerService.cyan(issueHasUpdateInCloseWindow)}`);
if (!issueHasCommentsSinceStale && !issueHasUpdateInCloseWindow) {
if (!issueHasCommentsSinceStale &&
!issueHasUpdateInCloseWindow &&
!issueHasReactionsSinceStale) {
issueLogger.info(`Closing $$type because it was last updated on: ${logger_service_1.LoggerService.cyan(issue.updated_at)}`);
yield this._closeIssue(issue, closeMessage, closeLabel);
if (this.options.deleteBranch && issue.pull_request) {
@@ -801,6 +839,18 @@ class IssuesProcessor {
return filteredComments.length > 0;
});
}
// find any reactions since the date
_hasReactionsSince(issue, sinceDate) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Checking for reactions on $$type since: ${logger_service_1.LoggerService.cyan(sinceDate)}`);
if (!sinceDate) {
return true;
}
const reactions = yield this.listIssueReactions(issue, sinceDate);
return reactions.length > 0;
});
}
// Mark an issue as stale with a comment and a label
_markStale(issue, staleMessage, staleLabel, skipMessage) {
var _a, _b, _c;
@@ -1529,6 +1579,7 @@ class Statistics {
this.fetchedItemsCount = 0;
this.fetchedItemsEventsCount = 0;
this.fetchedItemsCommentsCount = 0;
this.fetchedItemsReactionsCount = 0;
this.fetchedPullRequestsCount = 0;
}
incrementProcessedItemsCount(issue, increment = 1) {
@@ -1599,6 +1650,10 @@ class Statistics {
this.fetchedItemsCommentsCount += increment;
return this;
}
incrementFetchedItemsReactionsCount(increment = 1) {
this.fetchedItemsReactionsCount += increment;
return this;
}
incrementFetchedPullRequestsCount(increment = 1) {
this.fetchedPullRequestsCount += increment;
return this;
@@ -1617,6 +1672,7 @@ class Statistics {
this._logFetchedItemsCount();
this._logFetchedItemsEventsCount();
this._logFetchedItemsCommentsCount();
this._logFetchedItemsReactionsCount();
this._logFetchedPullRequestsCount();
this._logOperationsCount();
return this;
@@ -1793,6 +1849,9 @@ class Statistics {
_logFetchedItemsCommentsCount() {
this._logCount('Fetched items comments', this.fetchedItemsCommentsCount);
}
_logFetchedItemsReactionsCount() {
this._logCount('Fetched items reactions', this.fetchedItemsReactionsCount);
}
_logFetchedPullRequestsCount() {
this._logCount('Fetched pull requests', this.fetchedPullRequestsCount);
}
76 changes: 74 additions & 2 deletions src/classes/issues-processor.ts
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ import {IComment} from '../interfaces/comment';
import {IIssueEvent} from '../interfaces/issue-event';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {IPullRequest} from '../interfaces/pull-request';
import {IReaction} from '../interfaces/reaction';
import {Assignees} from './assignees';
import {IgnoreUpdates} from './ignore-updates';
import {ExemptDraftPullRequest} from './exempt-draft-pull-request';
@@ -546,6 +547,41 @@ export class IssuesProcessor {
}
}

// Grab reactions for an issue since a given date
async listIssueReactions(
issue: Readonly<Issue>,
sinceDate: Readonly<string>
): Promise<IReaction[]> {
try {
this._consumeIssueOperation(issue);
this.statistics?.incrementFetchedItemsReactionsCount();
let reactions: IReaction[] = [];
let currentReactions: IReaction[] = [];
let iterator = 1;
const daysSinceLastUpdated =
(new Date().getTime() - new Date(sinceDate).getTime()) /
(1000 * 60 * 60 * 24);
do {
const response = await this.client.rest.reactions.listForIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
per_page: 100,
page: iterator
});
currentReactions = response.data;
reactions = [...reactions, ...currentReactions];
iterator++;
} while (currentReactions.length !== 0);
return reactions.filter(reaction =>
IssuesProcessor._updatedSince(reaction.created_at, daysSinceLastUpdated)
);
} catch (error) {
this._logger.error(`List issue reactions error: ${error.message}`);
return Promise.resolve([]);
}
}

// grab issues from github in batches of 100
async getIssues(page: number): Promise<Issue[]> {
try {
@@ -652,6 +688,16 @@ export class IssuesProcessor {
)}`
);

const issueHasReactionsSinceStale: boolean = await this._hasReactionsSince(
issue,
markedStaleOn
);
issueLogger.info(
`$$type had a reaction: ${LoggerService.cyan(
issueHasReactionsSinceStale
)}`
);

const daysBeforeClose: number = issue.isPullRequest
? this._getDaysBeforePrClose()
: this._getDaysBeforeIssueClose();
@@ -703,7 +749,9 @@ export class IssuesProcessor {
// Should we un-stale this issue?
if (
shouldRemoveStaleWhenUpdated &&
(issueHasUpdateSinceStale || issueHasCommentsSinceStale) &&
(issueHasUpdateSinceStale ||
issueHasCommentsSinceStale ||
issueHasReactionsSinceStale) &&
!issue.markedStaleThisRun
) {
issueLogger.info(
@@ -739,7 +787,11 @@ export class IssuesProcessor {
)}`
);

if (!issueHasCommentsSinceStale && !issueHasUpdateInCloseWindow) {
if (
!issueHasCommentsSinceStale &&
!issueHasUpdateInCloseWindow &&
!issueHasReactionsSinceStale
) {
issueLogger.info(
`Closing $$type because it was last updated on: ${LoggerService.cyan(
issue.updated_at
@@ -798,6 +850,26 @@ export class IssuesProcessor {
return filteredComments.length > 0;
}

// find any reactions since the date
private async _hasReactionsSince(
issue: Issue,
sinceDate: string
): Promise<boolean> {
const issueLogger: IssueLogger = new IssueLogger(issue);

issueLogger.info(
`Checking for reactions on $$type since: ${LoggerService.cyan(sinceDate)}`
);

if (!sinceDate) {
return true;
}

const reactions = await this.listIssueReactions(issue, sinceDate);

return reactions.length > 0;
}

// Mark an issue as stale with a comment and a label
private async _markStale(
issue: Issue,
14 changes: 14 additions & 0 deletions src/classes/statistics.ts
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ export class Statistics {
fetchedItemsCount = 0;
fetchedItemsEventsCount = 0;
fetchedItemsCommentsCount = 0;
fetchedItemsReactionsCount = 0;
fetchedPullRequestsCount = 0;

incrementProcessedItemsCount(
@@ -154,6 +155,14 @@ export class Statistics {
return this;
}

incrementFetchedItemsReactionsCount(
increment: Readonly<number> = 1
): Statistics {
this.fetchedItemsReactionsCount += increment;

return this;
}

incrementFetchedPullRequestsCount(
increment: Readonly<number> = 1
): Statistics {
@@ -176,6 +185,7 @@ export class Statistics {
this._logFetchedItemsCount();
this._logFetchedItemsEventsCount();
this._logFetchedItemsCommentsCount();
this._logFetchedItemsReactionsCount();
this._logFetchedPullRequestsCount();
this._logOperationsCount();

@@ -430,6 +440,10 @@ export class Statistics {
this._logCount('Fetched items comments', this.fetchedItemsCommentsCount);
}

private _logFetchedItemsReactionsCount(): void {
this._logCount('Fetched items reactions', this.fetchedItemsReactionsCount);
}

private _logFetchedPullRequestsCount(): void {
this._logCount('Fetched pull requests', this.fetchedPullRequestsCount);
}
2 changes: 2 additions & 0 deletions src/interfaces/issue.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import {IsoDateString} from '../types/iso-date-string';
import {Assignee} from './assignee';
import {ILabel} from './label';
import {IMilestone} from './milestone';
import {IReaction} from './reaction';
import {components} from '@octokit/openapi-types';
export interface IIssue {
title: string;
@@ -14,6 +15,7 @@ export interface IIssue {
locked: boolean;
milestone?: IMilestone | null;
assignees?: Assignee[] | null;
reactions?: IReaction[] | null;
}

export type OctokitIssue = components['schemas']['issue'];
4 changes: 4 additions & 0 deletions src/interfaces/reaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface IReaction {
content: string;
created_at: string;
}