diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..6b523eb --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,24 @@ +name: Lint PR +on: + pull_request: + branches: [ master ] + +jobs: + label: + runs-on: ubuntu-latest + name: A job to say hello + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'yarn' + - run: yarn + - run: yarn build + - name: label + uses: ./ + with: + access_token: ${{ secrets.GITHUB_TOKEN }} + - name: Get the output + run: echo "The labels were ${{ steps.label.outputs.labels }}" \ No newline at end of file diff --git a/action.yml b/action.yml index 107b6ed..594c3ea 100644 --- a/action.yml +++ b/action.yml @@ -2,7 +2,7 @@ name: 'Conventional Labeler' description: 'A Pull request labeler using conventional commit standard' inputs: access_token: - description: 'Github Access Token to access and modify your pr's label' + description: Github Access Token to access and modify your pr's label required: true outputs: labels: diff --git a/dist/index.js b/dist/index.js index 9150f7e..005a99e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -102,6 +102,25 @@ exports.ConventionalCommit = ConventionalCommit; "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -111,12 +130,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.GithubClient = void 0; -const github_1 = __importDefault(__nccwpck_require__(5438)); +const github = __importStar(__nccwpck_require__(5438)); /** * Github client is a wrapper for the Github API. */ @@ -126,11 +142,11 @@ class GithubClient { } addLabel(pr, labels) { return __awaiter(this, void 0, void 0, function* () { - const client = github_1.default.getOctokit(this.token); + const client = github.getOctokit(this.token); try { yield client.rest.issues.addLabels({ - owner: github_1.default.context.repo.owner, - repo: github_1.default.context.repo.repo, + owner: github.context.repo.owner, + repo: github.context.repo.repo, issue_number: pr, labels: labels, }); @@ -149,11 +165,11 @@ class GithubClient { */ removeLabels(pr, labels) { return __awaiter(this, void 0, void 0, function* () { - const client = github_1.default.getOctokit(this.token); + const client = github.getOctokit(this.token); try { yield Promise.all(labels.map((label) => client.rest.issues.removeLabel({ - owner: github_1.default.context.repo.owner, - repo: github_1.default.context.repo.repo, + owner: github.context.repo.owner, + repo: github.context.repo.repo, issue_number: pr, name: label, }))); @@ -171,10 +187,10 @@ class GithubClient { getLabels(pr) { return __awaiter(this, void 0, void 0, function* () { try { - const client = github_1.default.getOctokit(this.token); + const client = github.getOctokit(this.token); const labels = yield client.rest.issues.listLabelsOnIssue({ - owner: github_1.default.context.repo.owner, - repo: github_1.default.context.repo.repo, + owner: github.context.repo.owner, + repo: github.context.repo.repo, issue_number: pr, }); return { @@ -193,7 +209,7 @@ class GithubClient { */ getTitle() { // use github api to get pr's title - const pullRequest = github_1.default.context.payload.pull_request; + const pullRequest = github.context.payload.pull_request; return pullRequest === null || pullRequest === void 0 ? void 0 : pullRequest.title; } /** @@ -202,7 +218,7 @@ class GithubClient { */ getPr() { var _a; - return (_a = github_1.default.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.number; + return (_a = github.context.payload.pull_request) === null || _a === void 0 ? void 0 : _a.number; } } exports.GithubClient = GithubClient; @@ -239,6 +255,25 @@ const labeler_1 = __nccwpck_require__(8389); "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -248,17 +283,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; Object.defineProperty(exports, "__esModule", ({ value: true })); exports.ConventionalLabeler = void 0; const conventional_commit_1 = __nccwpck_require__(6382); const github_1 = __nccwpck_require__(3412); -const core_1 = __importDefault(__nccwpck_require__(2186)); +const core = __importStar(__nccwpck_require__(2186)); class ConventionalLabeler { constructor() { - const token = core_1.default.getInput("access_token", { required: true }); + const token = core.getInput("access_token", { required: true }); this.githubClient = new github_1.GithubClient(token); this.conventionalCommit = new conventional_commit_1.ConventionalCommit(); } @@ -269,50 +301,50 @@ class ConventionalLabeler { var _a; return __awaiter(this, void 0, void 0, function* () { // get pr's number - core_1.default.info("Getting PR number"); + core.info("Getting PR number"); const pr = this.githubClient.getPr(); if (!pr) { - core_1.default.error("No pull request found"); + core.error("No pull request found"); return; } // get pr's existing labels - core_1.default.info("Getting PR labels"); + core.info("Getting PR labels"); const labels = yield this.githubClient.getLabels(pr); if (labels.error) { - core_1.default.error(labels.error); + core.error(labels.error); return; } // get list of preset labels - core_1.default.info("Getting preset labels"); + core.info("Getting preset labels"); const presetLabels = this.conventionalCommit.getValidLabels((_a = labels.labels) !== null && _a !== void 0 ? _a : []); // remove them - core_1.default.info("Removing preset labels"); + core.info("Removing preset labels"); const removeError = yield this.githubClient.removeLabels(pr, presetLabels); if (removeError) { - core_1.default.error(removeError); + core.error(removeError); return; } // get the pr title const title = this.githubClient.getTitle(); if (!title || title.length === 0) { - core_1.default.error("Failed to get the pr title"); + core.error("Failed to get the pr title"); return; } // get the label - core_1.default.info("Getting conventional label"); + core.info("Getting conventional label"); const label = this.conventionalCommit.getLabel(title); if (label.error) { - core_1.default.error(label.error); + core.error(label.error); return; } // add the label - core_1.default.info("Adding label to PR"); + core.info("Adding label to PR"); const error = yield this.githubClient.addLabel(pr, [label.label]); if (error) { - core_1.default.error(error); + core.error(error); return; } - core_1.default.setOutput("labels", labels.labels); + core.setOutput("labels", labels.labels); }); } } diff --git a/readme.md b/readme.md index b6fae6f..7599599 100644 --- a/readme.md +++ b/readme.md @@ -6,4 +6,4 @@ Conventional labeler will label your PR based on your PR's feature if it follows ## Required input -- access_token: can be set by using ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file +- access_token: can be set by using `${{ secrets.GITHUB_TOKEN }}` \ No newline at end of file diff --git a/src/client/conventional_commit.ts b/src/client/conventional_commit.ts index af17c46..f134614 100644 --- a/src/client/conventional_commit.ts +++ b/src/client/conventional_commit.ts @@ -91,4 +91,17 @@ export class ConventionalCommit { } return validLabels; } + + /** + * Given two labels array labels1 and labels2, return the labels that are not in labels2 + */ + getDiffLabels(labels: string[], labels2: string[]): string[] { + const diffLabels = []; + for (const label of labels) { + if (!labels2.includes(label)) { + diffLabels.push(label); + } + } + return diffLabels; + } } diff --git a/src/client/github.ts b/src/client/github.ts index aa9e93b..4ca2fe0 100644 --- a/src/client/github.ts +++ b/src/client/github.ts @@ -1,4 +1,4 @@ -import github from "@actions/github"; +import * as github from "@actions/github"; /** * Github client is a wrapper for the Github API. diff --git a/src/labeler.ts b/src/labeler.ts index bf6e01f..c3bf299 100644 --- a/src/labeler.ts +++ b/src/labeler.ts @@ -1,6 +1,6 @@ import { ConventionalCommit } from "./client/conventional_commit"; import { GithubClient } from "./client/github"; -import core from "@actions/core"; +import * as core from "@actions/core"; export class ConventionalLabeler { private githubClient: GithubClient; @@ -32,19 +32,6 @@ export class ConventionalLabeler { return; } - // get list of preset labels - core.info("Getting preset labels"); - const presetLabels = this.conventionalCommit.getValidLabels( - labels.labels ?? [] - ); - // remove them - core.info("Removing preset labels"); - const removeError = await this.githubClient.removeLabels(pr, presetLabels); - if (removeError) { - core.error(removeError); - return; - } - // get the pr title const title = this.githubClient.getTitle(); if (!title || title.length === 0) { @@ -53,21 +40,43 @@ export class ConventionalLabeler { } // get the label - core.info("Getting conventional label"); - const label = this.conventionalCommit.getLabel(title); - if (label.error) { - core.error(label.error); + core.info(`Getting conventional label`); + const generatedLabel = this.conventionalCommit.getLabel(title); + if (generatedLabel.error) { + core.error(generatedLabel.error); + return; + } + + // get list of preset labels + core.info("Getting preset labels"); + const presetLabels = this.conventionalCommit.getValidLabels( + labels.labels ?? [] + ); + + const differentLabels = this.conventionalCommit.getDiffLabels( + presetLabels, + [generatedLabel.label!] + ); + + // remove them + core.info("Removing different label"); + const removeError = await this.githubClient.removeLabels( + pr, + differentLabels + ); + if (removeError) { + core.error(removeError); return; } // add the label - core.info("Adding label to PR"); - const error = await this.githubClient.addLabel(pr, [label.label!]); + core.info(`Adding label ${generatedLabel.label} to PR`); + const error = await this.githubClient.addLabel(pr, [generatedLabel.label!]); if (error) { core.error(error); return; } - core.setOutput("labels", labels.labels); + core.setOutput("labels", generatedLabel.label); } } diff --git a/src/tests/covnentioanl_commit.test.ts b/src/tests/covnentioanl_commit.test.ts index f507d0b..c6b6432 100644 --- a/src/tests/covnentioanl_commit.test.ts +++ b/src/tests/covnentioanl_commit.test.ts @@ -72,4 +72,36 @@ describe("Given a conventional commit client", () => { const labels = client.getValidLabels([]); expect(labels.length).toBe(0); }); + + it("Should return different labels", () => { + const diff = client.getDiffLabels( + ["enhancement", "bugfix"], + ["enhancement", "bugfix"] + ); + expect(diff.length).toBe(0); + }); + + it("Should return different labels", () => { + const diff = client.getDiffLabels( + ["enhancement", "bug"], + ["enhancement", "bugfix"] + ); + expect(diff).toEqual(["bug"]); + }); + + it("Should return different labels", () => { + const diff = client.getDiffLabels( + ["enhancement"], + ["enhancement", "bugfix"] + ); + expect(diff.length).toEqual(0); + }); + + it("Should return different labels", () => { + const diff = client.getDiffLabels( + ["enhancement", "bug", "bugfix"], + ["enhancement", "bugfix"] + ); + expect(diff).toEqual(["bug"]); + }); }); diff --git a/src/tests/github.test.ts b/src/tests/github.test.ts index d5d97d3..0ba7910 100644 --- a/src/tests/github.test.ts +++ b/src/tests/github.test.ts @@ -1,5 +1,5 @@ import { GithubClient } from "../client/github"; -import github from "@actions/github"; +import * as github from "@actions/github"; jest.mock("@actions/core"); jest.mock("@actions/github", () => ({