mirror of
https://github.com/actions/labeler.git
synced 2025-12-11 12:07:32 +00:00
Add .prettierrc.json to configure Prettier, reformat code
This commit is contained in:
12
.prettierrc.json
Normal file
12
.prettierrc.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"parser": "typescript",
|
||||||
|
"endOfLine": "auto"
|
||||||
|
}
|
||||||
@@ -1,34 +1,34 @@
|
|||||||
export const context = {
|
export const context = {
|
||||||
payload: {
|
payload: {
|
||||||
pull_request: {
|
pull_request: {
|
||||||
number: 123,
|
number: 123
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
repo: {
|
repo: {
|
||||||
owner: "monalisa",
|
owner: 'monalisa',
|
||||||
repo: "helloworld",
|
repo: 'helloworld'
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockApi = {
|
const mockApi = {
|
||||||
rest: {
|
rest: {
|
||||||
issues: {
|
issues: {
|
||||||
addLabels: jest.fn(),
|
addLabels: jest.fn(),
|
||||||
removeLabel: jest.fn(),
|
removeLabel: jest.fn()
|
||||||
},
|
},
|
||||||
pulls: {
|
pulls: {
|
||||||
get: jest.fn().mockResolvedValue({}),
|
get: jest.fn().mockResolvedValue({}),
|
||||||
listFiles: {
|
listFiles: {
|
||||||
endpoint: {
|
endpoint: {
|
||||||
merge: jest.fn().mockReturnValue({}),
|
merge: jest.fn().mockReturnValue({})
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
repos: {
|
repos: {
|
||||||
getContent: jest.fn(),
|
getContent: jest.fn()
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
paginate: jest.fn(),
|
paginate: jest.fn()
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getOctokit = jest.fn().mockImplementation(() => mockApi);
|
export const getOctokit = jest.fn().mockImplementation(() => mockApi);
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
import { checkGlobs } from "../src/labeler";
|
import {checkGlobs} from '../src/labeler';
|
||||||
|
|
||||||
import * as core from "@actions/core";
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
jest.mock("@actions/core");
|
jest.mock('@actions/core');
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
jest.spyOn(core, "getInput").mockImplementation((name, options) => {
|
jest.spyOn(core, 'getInput').mockImplementation((name, options) => {
|
||||||
return jest.requireActual("@actions/core").getInput(name, options);
|
return jest.requireActual('@actions/core').getInput(name, options);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const matchConfig = [{ any: ["*.txt"] }];
|
const matchConfig = [{any: ['*.txt']}];
|
||||||
|
|
||||||
describe("checkGlobs", () => {
|
describe('checkGlobs', () => {
|
||||||
it("returns true when our pattern does match changed files", () => {
|
it('returns true when our pattern does match changed files', () => {
|
||||||
const changedFiles = ["foo.txt", "bar.txt"];
|
const changedFiles = ['foo.txt', 'bar.txt'];
|
||||||
const result = checkGlobs(changedFiles, matchConfig);
|
const result = checkGlobs(changedFiles, matchConfig);
|
||||||
|
|
||||||
expect(result).toBeTruthy();
|
expect(result).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns false when our pattern does not match changed files", () => {
|
it('returns false when our pattern does not match changed files', () => {
|
||||||
const changedFiles = ["foo.docx"];
|
const changedFiles = ['foo.docx'];
|
||||||
const result = checkGlobs(changedFiles, matchConfig);
|
const result = checkGlobs(changedFiles, matchConfig);
|
||||||
|
|
||||||
expect(result).toBeFalsy();
|
expect(result).toBeFalsy();
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
import { run } from "../src/labeler";
|
import {run} from '../src/labeler';
|
||||||
import * as github from "@actions/github";
|
import * as github from '@actions/github';
|
||||||
import * as core from "@actions/core";
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
const fs = jest.requireActual("fs");
|
const fs = jest.requireActual('fs');
|
||||||
|
|
||||||
jest.mock("@actions/core");
|
jest.mock('@actions/core');
|
||||||
jest.mock("@actions/github");
|
jest.mock('@actions/github');
|
||||||
|
|
||||||
const gh = github.getOctokit("_");
|
const gh = github.getOctokit('_');
|
||||||
const addLabelsMock = jest.spyOn(gh.rest.issues, "addLabels");
|
const addLabelsMock = jest.spyOn(gh.rest.issues, 'addLabels');
|
||||||
const removeLabelMock = jest.spyOn(gh.rest.issues, "removeLabel");
|
const removeLabelMock = jest.spyOn(gh.rest.issues, 'removeLabel');
|
||||||
const reposMock = jest.spyOn(gh.rest.repos, "getContent");
|
const reposMock = jest.spyOn(gh.rest.repos, 'getContent');
|
||||||
const paginateMock = jest.spyOn(gh, "paginate");
|
const paginateMock = jest.spyOn(gh, 'paginate');
|
||||||
const getPullMock = jest.spyOn(gh.rest.pulls, "get");
|
const getPullMock = jest.spyOn(gh.rest.pulls, 'get');
|
||||||
|
|
||||||
const yamlFixtures = {
|
const yamlFixtures = {
|
||||||
"only_pdfs.yml": fs.readFileSync("__tests__/fixtures/only_pdfs.yml"),
|
'only_pdfs.yml': fs.readFileSync('__tests__/fixtures/only_pdfs.yml')
|
||||||
};
|
};
|
||||||
|
|
||||||
afterAll(() => jest.restoreAllMocks());
|
afterAll(() => jest.restoreAllMocks());
|
||||||
|
|
||||||
describe("run", () => {
|
describe('run', () => {
|
||||||
it("adds labels to PRs that match our glob patterns", async () => {
|
it('adds labels to PRs that match our glob patterns', async () => {
|
||||||
usingLabelerConfigYaml("only_pdfs.yml");
|
usingLabelerConfigYaml('only_pdfs.yml');
|
||||||
mockGitHubResponseChangedFiles("foo.pdf");
|
mockGitHubResponseChangedFiles('foo.pdf');
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
|
|
||||||
expect(removeLabelMock).toHaveBeenCalledTimes(0);
|
expect(removeLabelMock).toHaveBeenCalledTimes(0);
|
||||||
expect(addLabelsMock).toHaveBeenCalledTimes(1);
|
expect(addLabelsMock).toHaveBeenCalledTimes(1);
|
||||||
expect(addLabelsMock).toHaveBeenCalledWith({
|
expect(addLabelsMock).toHaveBeenCalledWith({
|
||||||
owner: "monalisa",
|
owner: 'monalisa',
|
||||||
repo: "helloworld",
|
repo: 'helloworld',
|
||||||
issue_number: 123,
|
issue_number: 123,
|
||||||
labels: ["touched-a-pdf-file"],
|
labels: ['touched-a-pdf-file']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not add labels to PRs that do not match our glob patterns", async () => {
|
it('does not add labels to PRs that do not match our glob patterns', async () => {
|
||||||
usingLabelerConfigYaml("only_pdfs.yml");
|
usingLabelerConfigYaml('only_pdfs.yml');
|
||||||
mockGitHubResponseChangedFiles("foo.txt");
|
mockGitHubResponseChangedFiles('foo.txt');
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
|
|
||||||
@@ -47,23 +47,23 @@ describe("run", () => {
|
|||||||
expect(addLabelsMock).toHaveBeenCalledTimes(0);
|
expect(addLabelsMock).toHaveBeenCalledTimes(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("(with sync-labels: true) it deletes preexisting PR labels that no longer match the glob pattern", async () => {
|
it('(with sync-labels: true) it deletes preexisting PR labels that no longer match the glob pattern', async () => {
|
||||||
let mockInput = {
|
let mockInput = {
|
||||||
"repo-token": "foo",
|
'repo-token': 'foo',
|
||||||
"configuration-path": "bar",
|
'configuration-path': 'bar',
|
||||||
"sync-labels": true,
|
'sync-labels': true
|
||||||
};
|
};
|
||||||
|
|
||||||
jest
|
jest
|
||||||
.spyOn(core, "getInput")
|
.spyOn(core, 'getInput')
|
||||||
.mockImplementation((name: string, ...opts) => mockInput[name]);
|
.mockImplementation((name: string, ...opts) => mockInput[name]);
|
||||||
|
|
||||||
usingLabelerConfigYaml("only_pdfs.yml");
|
usingLabelerConfigYaml('only_pdfs.yml');
|
||||||
mockGitHubResponseChangedFiles("foo.txt");
|
mockGitHubResponseChangedFiles('foo.txt');
|
||||||
getPullMock.mockResolvedValue(<any>{
|
getPullMock.mockResolvedValue(<any>{
|
||||||
data: {
|
data: {
|
||||||
labels: [{ name: "touched-a-pdf-file" }],
|
labels: [{name: 'touched-a-pdf-file'}]
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
@@ -71,30 +71,30 @@ describe("run", () => {
|
|||||||
expect(addLabelsMock).toHaveBeenCalledTimes(0);
|
expect(addLabelsMock).toHaveBeenCalledTimes(0);
|
||||||
expect(removeLabelMock).toHaveBeenCalledTimes(1);
|
expect(removeLabelMock).toHaveBeenCalledTimes(1);
|
||||||
expect(removeLabelMock).toHaveBeenCalledWith({
|
expect(removeLabelMock).toHaveBeenCalledWith({
|
||||||
owner: "monalisa",
|
owner: 'monalisa',
|
||||||
repo: "helloworld",
|
repo: 'helloworld',
|
||||||
issue_number: 123,
|
issue_number: 123,
|
||||||
name: "touched-a-pdf-file",
|
name: 'touched-a-pdf-file'
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("(with sync-labels: false) it issues no delete calls even when there are preexisting PR labels that no longer match the glob pattern", async () => {
|
it('(with sync-labels: false) it issues no delete calls even when there are preexisting PR labels that no longer match the glob pattern', async () => {
|
||||||
let mockInput = {
|
let mockInput = {
|
||||||
"repo-token": "foo",
|
'repo-token': 'foo',
|
||||||
"configuration-path": "bar",
|
'configuration-path': 'bar',
|
||||||
"sync-labels": false,
|
'sync-labels': false
|
||||||
};
|
};
|
||||||
|
|
||||||
jest
|
jest
|
||||||
.spyOn(core, "getInput")
|
.spyOn(core, 'getInput')
|
||||||
.mockImplementation((name: string, ...opts) => mockInput[name]);
|
.mockImplementation((name: string, ...opts) => mockInput[name]);
|
||||||
|
|
||||||
usingLabelerConfigYaml("only_pdfs.yml");
|
usingLabelerConfigYaml('only_pdfs.yml');
|
||||||
mockGitHubResponseChangedFiles("foo.txt");
|
mockGitHubResponseChangedFiles('foo.txt');
|
||||||
getPullMock.mockResolvedValue(<any>{
|
getPullMock.mockResolvedValue(<any>{
|
||||||
data: {
|
data: {
|
||||||
labels: [{ name: "touched-a-pdf-file" }],
|
labels: [{name: 'touched-a-pdf-file'}]
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await run();
|
await run();
|
||||||
@@ -106,11 +106,11 @@ describe("run", () => {
|
|||||||
|
|
||||||
function usingLabelerConfigYaml(fixtureName: keyof typeof yamlFixtures): void {
|
function usingLabelerConfigYaml(fixtureName: keyof typeof yamlFixtures): void {
|
||||||
reposMock.mockResolvedValue(<any>{
|
reposMock.mockResolvedValue(<any>{
|
||||||
data: { content: yamlFixtures[fixtureName], encoding: "utf8" },
|
data: {content: yamlFixtures[fixtureName], encoding: 'utf8'}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function mockGitHubResponseChangedFiles(...files: string[]): void {
|
function mockGitHubResponseChangedFiles(...files: string[]): void {
|
||||||
const returnValue = files.map((f) => ({ filename: f }));
|
const returnValue = files.map(f => ({filename: f}));
|
||||||
paginateMock.mockReturnValue(<any>returnValue);
|
paginateMock.mockReturnValue(<any>returnValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import * as core from "@actions/core";
|
import * as core from '@actions/core';
|
||||||
import * as github from "@actions/github";
|
import * as github from '@actions/github';
|
||||||
import * as yaml from "js-yaml";
|
import * as yaml from 'js-yaml';
|
||||||
import { Minimatch, IMinimatch } from "minimatch";
|
import {Minimatch, IMinimatch} from 'minimatch';
|
||||||
|
|
||||||
interface MatchConfig {
|
interface MatchConfig {
|
||||||
all?: string[];
|
all?: string[];
|
||||||
@@ -13,22 +13,22 @@ type ClientType = ReturnType<typeof github.getOctokit>;
|
|||||||
|
|
||||||
export async function run() {
|
export async function run() {
|
||||||
try {
|
try {
|
||||||
const token = core.getInput("repo-token", { required: true });
|
const token = core.getInput('repo-token', {required: true});
|
||||||
const configPath = core.getInput("configuration-path", { required: true });
|
const configPath = core.getInput('configuration-path', {required: true});
|
||||||
const syncLabels = !!core.getInput("sync-labels", { required: false });
|
const syncLabels = !!core.getInput('sync-labels', {required: false});
|
||||||
|
|
||||||
const prNumber = getPrNumber();
|
const prNumber = getPrNumber();
|
||||||
if (!prNumber) {
|
if (!prNumber) {
|
||||||
console.log("Could not get pull request number from context, exiting");
|
console.log('Could not get pull request number from context, exiting');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const client: ClientType = github.getOctokit(token);
|
const client: ClientType = github.getOctokit(token);
|
||||||
|
|
||||||
const { data: pullRequest } = await client.rest.pulls.get({
|
const {data: pullRequest} = await client.rest.pulls.get({
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
pull_number: prNumber,
|
pull_number: prNumber
|
||||||
});
|
});
|
||||||
|
|
||||||
core.debug(`fetching changed files for pr #${prNumber}`);
|
core.debug(`fetching changed files for pr #${prNumber}`);
|
||||||
@@ -44,7 +44,7 @@ export async function run() {
|
|||||||
core.debug(`processing ${label}`);
|
core.debug(`processing ${label}`);
|
||||||
if (checkGlobs(changedFiles, globs)) {
|
if (checkGlobs(changedFiles, globs)) {
|
||||||
labels.push(label);
|
labels.push(label);
|
||||||
} else if (pullRequest.labels.find((l) => l.name === label)) {
|
} else if (pullRequest.labels.find(l => l.name === label)) {
|
||||||
labelsToRemove.push(label);
|
labelsToRemove.push(label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,15 @@ async function getChangedFiles(
|
|||||||
const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({
|
const listFilesOptions = client.rest.pulls.listFiles.endpoint.merge({
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
pull_number: prNumber,
|
pull_number: prNumber
|
||||||
});
|
});
|
||||||
|
|
||||||
const listFilesResponse = await client.paginate(listFilesOptions);
|
const listFilesResponse = await client.paginate(listFilesOptions);
|
||||||
const changedFiles = listFilesResponse.map((f: any) => f.filename);
|
const changedFiles = listFilesResponse.map((f: any) => f.filename);
|
||||||
|
|
||||||
core.debug("found changed files:");
|
core.debug('found changed files:');
|
||||||
for (const file of changedFiles) {
|
for (const file of changedFiles) {
|
||||||
core.debug(" " + file);
|
core.debug(' ' + file);
|
||||||
}
|
}
|
||||||
|
|
||||||
return changedFiles;
|
return changedFiles;
|
||||||
@@ -116,7 +116,7 @@ async function fetchContent(
|
|||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
path: repoPath,
|
path: repoPath,
|
||||||
ref: github.context.sha,
|
ref: github.context.sha
|
||||||
});
|
});
|
||||||
|
|
||||||
return Buffer.from(response.data.content, response.data.encoding).toString();
|
return Buffer.from(response.data.content, response.data.encoding).toString();
|
||||||
@@ -127,7 +127,7 @@ function getLabelGlobMapFromObject(
|
|||||||
): Map<string, StringOrMatchConfig[]> {
|
): Map<string, StringOrMatchConfig[]> {
|
||||||
const labelGlobs: Map<string, StringOrMatchConfig[]> = new Map();
|
const labelGlobs: Map<string, StringOrMatchConfig[]> = new Map();
|
||||||
for (const label in configObject) {
|
for (const label in configObject) {
|
||||||
if (typeof configObject[label] === "string") {
|
if (typeof configObject[label] === 'string') {
|
||||||
labelGlobs.set(label, [configObject[label]]);
|
labelGlobs.set(label, [configObject[label]]);
|
||||||
} else if (configObject[label] instanceof Array) {
|
} else if (configObject[label] instanceof Array) {
|
||||||
labelGlobs.set(label, configObject[label]);
|
labelGlobs.set(label, configObject[label]);
|
||||||
@@ -142,9 +142,9 @@ function getLabelGlobMapFromObject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toMatchConfig(config: StringOrMatchConfig): MatchConfig {
|
function toMatchConfig(config: StringOrMatchConfig): MatchConfig {
|
||||||
if (typeof config === "string") {
|
if (typeof config === 'string') {
|
||||||
return {
|
return {
|
||||||
any: [config],
|
any: [config]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ function toMatchConfig(config: StringOrMatchConfig): MatchConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function printPattern(matcher: IMinimatch): string {
|
function printPattern(matcher: IMinimatch): string {
|
||||||
return (matcher.negate ? "!" : "") + matcher.pattern;
|
return (matcher.negate ? '!' : '') + matcher.pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function checkGlobs(
|
export function checkGlobs(
|
||||||
@@ -185,7 +185,7 @@ function isMatch(changedFile: string, matchers: IMinimatch[]): boolean {
|
|||||||
|
|
||||||
// equivalent to "Array.some()" but expanded for debugging and clarity
|
// equivalent to "Array.some()" but expanded for debugging and clarity
|
||||||
function checkAny(changedFiles: string[], globs: string[]): boolean {
|
function checkAny(changedFiles: string[], globs: string[]): boolean {
|
||||||
const matchers = globs.map((g) => new Minimatch(g));
|
const matchers = globs.map(g => new Minimatch(g));
|
||||||
core.debug(` checking "any" patterns`);
|
core.debug(` checking "any" patterns`);
|
||||||
for (const changedFile of changedFiles) {
|
for (const changedFile of changedFiles) {
|
||||||
if (isMatch(changedFile, matchers)) {
|
if (isMatch(changedFile, matchers)) {
|
||||||
@@ -200,7 +200,7 @@ function checkAny(changedFiles: string[], globs: string[]): boolean {
|
|||||||
|
|
||||||
// equivalent to "Array.every()" but expanded for debugging and clarity
|
// equivalent to "Array.every()" but expanded for debugging and clarity
|
||||||
function checkAll(changedFiles: string[], globs: string[]): boolean {
|
function checkAll(changedFiles: string[], globs: string[]): boolean {
|
||||||
const matchers = globs.map((g) => new Minimatch(g));
|
const matchers = globs.map(g => new Minimatch(g));
|
||||||
core.debug(` checking "all" patterns`);
|
core.debug(` checking "all" patterns`);
|
||||||
for (const changedFile of changedFiles) {
|
for (const changedFile of changedFiles) {
|
||||||
if (!isMatch(changedFile, matchers)) {
|
if (!isMatch(changedFile, matchers)) {
|
||||||
@@ -238,7 +238,7 @@ async function addLabels(
|
|||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
labels: labels,
|
labels: labels
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,12 +248,12 @@ async function removeLabels(
|
|||||||
labels: string[]
|
labels: string[]
|
||||||
) {
|
) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
labels.map((label) =>
|
labels.map(label =>
|
||||||
client.rest.issues.removeLabel({
|
client.rest.issues.removeLabel({
|
||||||
owner: github.context.repo.owner,
|
owner: github.context.repo.owner,
|
||||||
repo: github.context.repo.repo,
|
repo: github.context.repo.repo,
|
||||||
issue_number: prNumber,
|
issue_number: prNumber,
|
||||||
name: label,
|
name: label
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import { run } from "./labeler";
|
import {run} from './labeler';
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
|||||||
Reference in New Issue
Block a user