blob: 6c321615b17f8ce173d69b0cc09eca900beca427 [file] [log] [blame]
import * as core from '@actions/core';
import * as github from '@actions/github';
import * as octokitTypes from '@octokit/types';
import { Label, IssueEvent } from './types';
import { Quiet } from './enums';
import {
formatStrArray,
validateEnum,
parseOffsetString,
getOffsetDate,
isLabelEvent,
isCreatedByUser,
removeDuplicates,
} from './utils';
import { formatLabel, extractLabels, getName } from './labels';
import { Logger, LoggingLevel } from './logger';
async function processIssue(
octokit: ReturnType<typeof github.getOctokit>,
repo: string,
owner: string,
issue_number: number,
htmlUrl: string,
description: string,
labelPattern: string,
logger: Logger,
): Promise<void> {
logger.debug(`--- ${htmlUrl} ---`);
// Labels extracted from an issue description
const labels = extractLabels(description, labelPattern);
if (labels.length === 0) {
logger.debug('No labels found');
return;
}
octokit.issues.listEvents({
owner,
repo,
issue_number,
});
const listEventsData: IssueEvent[] = await octokit.paginate(
octokit.issues.listEvents,
{
owner,
repo,
issue_number,
},
);
// Labels added or removed by users
const labelsToIgnore = removeDuplicates(
listEventsData
.filter(event => isLabelEvent(event) && isCreatedByUser(event))
.map(({ label }) => label && label.name),
);
logger.debug('Labels to ignore:');
logger.debug(formatStrArray(labelsToIgnore));
// Labels registered in a repository
const labelsForRepoData = await octokit.paginate(
octokit.issues.listLabelsForRepo,
{
owner,
repo,
},
);
const labelsForRepo = labelsForRepoData.map(getName);
const labelsToProcess = labels.filter(
({ name }) =>
labelsForRepo.includes(name) && !labelsToIgnore.includes(name),
);
if (labelsToProcess.length === 0) {
logger.debug('No labels to process');
return;
}
// Labels that are already applied on an issue
const labelsOnIssueResp = await octokit.issues.listLabelsOnIssue({
owner,
repo,
issue_number,
});
const labelsOnIssue = labelsOnIssueResp.data.map(getName);
logger.debug('Labels to process:');
logger.debug(formatStrArray(labelsToProcess.map(formatLabel)));
// Remove labels
const shouldRemove = ({ name, checked }: Label): boolean =>
!checked && labelsOnIssue.includes(name);
const labelsToRemove = labelsToProcess.filter(shouldRemove).map(getName);
logger.debug('Labels to remove:');
logger.debug(formatStrArray(labelsToRemove));
logger.debug("ffffffff")
logger.debug(octokit)
if (labelsToRemove.length > 0) {
labelsToRemove.forEach(async name => {
await octokit.issues.removeLabel({
owner,
repo,
issue_number,
name,
});
});
}
// Add labels
const shouldAdd = ({ name, checked }: Label): boolean =>
checked && !labelsOnIssue.includes(name);
const labelsToAdd = labelsToProcess.filter(shouldAdd).map(getName);
logger.debug('Labels to add:');
logger.debug(formatStrArray(labelsToAdd));
if (labelsToAdd.length > 0) {
await octokit.issues.addLabels({
owner,
repo,
issue_number,
labels: labelsToAdd,
});
}
}
async function main(): Promise<void> {
try {
const token = core.getInput('github-token', { required: true });
const labelPattern = core.getInput('label-pattern', { required: true });
const quiet = core.getInput('quiet', { required: false });
const offset = core.getInput('offset', { required: false });
validateEnum('quiet', quiet, Quiet);
const logger = new Logger(
quiet === Quiet.TRUE ? LoggingLevel.SILENT : LoggingLevel.DEBUG,
);
const octokit = github.getOctokit(token);
logger.debug("ffffffff")
logger.debug(octokit)
const { repo, owner } = github.context.repo;
const { eventName } = github.context;
switch (eventName) {
case 'issues': {
const { issue } = github.context.payload;
if (issue === undefined) {
return;
}
const { body, html_url, number: issue_number } = issue;
if (body === undefined || html_url === undefined) {
return;
}
await processIssue(
octokit,
repo,
owner,
issue_number,
html_url,
body,
labelPattern,
logger,
);
break;
}
case 'pull_request':
case 'pull_request_target': {
const { pull_request } = github.context.payload;
if (pull_request === undefined) {
return;
}
const { body, html_url, number: issue_number } = pull_request;
if (body === undefined || html_url === undefined) {
return;
}
await processIssue(
octokit,
repo,
owner,
issue_number,
html_url,
body,
labelPattern,
logger,
);
break;
}
case 'schedule': {
const parsed = parseOffsetString(offset);
const offsetDate = getOffsetDate(new Date(), ...parsed);
// Iterate through all open issues and pull requests
for await (const page of octokit.paginate.iterator(
octokit.issues.listForRepo,
{ owner, repo, since: offsetDate.toISOString() },
)) {
for (const issue of page.data) {
const {
body,
number,
html_url,
} = issue as octokitTypes.IssuesGetResponseData;
await processIssue(
octokit,
repo,
owner,
number,
html_url,
body,
labelPattern,
logger,
);
}
const rateLimitResp = await octokit.rateLimit.get();
logger.debug(rateLimitResp.data);
}
break;
}
default: {
return;
}
}
} catch (error) {
core.setFailed(error.message);
}
}
main().catch(err => {
throw err;
});