Skip to content

Commit

Permalink
Init with version 0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
vloddi committed Aug 21, 2022
1 parent f295a20 commit 57cf219
Show file tree
Hide file tree
Showing 14 changed files with 21,247 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.idea/
/node_modules/

61 changes: 59 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,59 @@
# changed-lines-count-labeler
An action for automatically labelling pull requests based on the changed lines count
# Changed Lines Count Labeler

Automatically label new pull requests based on the changed lines count.

## Usage

### Create `.github/changed-lines-count-labeler.yml`

Create a `.github/changed-lines-count-labeler.yml` file with a list of labels and [minimatch](https://github.com/isaacs/minimatch) globs to match to apply the label.

The key is the name of the label in your repository that you want to add (eg: "small", "large") and the value is the minimum and maximum count of lines.

#### Examples

```yml
# Add 'small' to any changes below 10 lines
small:
max: 9

# Add 'medium' to any changes between 10 and 100 lines
medium:
min: 10
max: 99

# Add 'large' to any changes for more than 100 lines
large:
min: 100
```
### Create Workflow
Create a workflow (eg: `.github/workflows/labeler.yml` see [Creating a Workflow file](https://help.github.com/en/articles/configuring-a-workflow#creating-a-workflow-file)) to utilize the labeler action with content:

```yml
name: "Pull Request Labeler"
on: [pull_request]
jobs:
changed-lines-count-labeler:
runs-on: ubuntu-latest
name: An action for automatically labelling pull requests based on the changed lines count
steps:
- name: Set a label
uses: vkirilichev/[email protected]
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
configuration-path: .github/changed-lines-count-labeler.yml
```

_Note: This grants access to the `GITHUB_TOKEN` so the action can make calls to GitHub's rest API_

#### Inputs

Various inputs are defined in [`action.yml`](action.yml) to let you configure the labeler:

| Name | Description | Default |
| - | - | - |
| `repo-token` | Token to use to authorize label changes. Typically the GITHUB_TOKEN secret, with `contents:read` and `pull-requests:write` access | N/A |
| `configuration-path` | The path to the label configuration file | `.github/changed-lines-count-labeler.yml` |
34 changes: 34 additions & 0 deletions __mocks__/@actions/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const context = {
payload: {
pull_request: {
number: 1,
},
},
repo: {
owner: "vkirilichev",
repo: "changed-lines-count-labeler",
},
};

const mockApi = {
rest: {
issues: {
addLabels: jest.fn(),
removeLabel: jest.fn(),
},
pulls: {
get: jest.fn().mockResolvedValue({}),
listFiles: {
endpoint: {
merge: jest.fn().mockReturnValue({}),
},
},
},
repos: {
getContent: jest.fn(),
},
},
paginate: jest.fn(),
};

export const getOctokit = jest.fn().mockImplementation(() => mockApi);
6 changes: 6 additions & 0 deletions __tests__/fixtures/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
petit:
min: 0
max: 5
grande:
min: 100
max: 500
30 changes: 30 additions & 0 deletions __tests__/labeler.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {checkBoundaries} from "../src/labeler";

import * as core from "@actions/core";

jest.mock("@actions/core");

beforeAll(() => {
jest.spyOn(core, "getInput").mockImplementation((name, options) => {
return jest.requireActual("@actions/core").getInput(name, options);
});
});

const config = { min: 2, max: 5 };

describe("checkBoundaries", () => {
it("returns true when our boundaries include the number of changed files", () => {
const result = checkBoundaries(2, config);
expect(result).toBeTruthy();
});

it("returns false when our boundaries does not include the number of changed files", () => {
const result = checkBoundaries(1, config);
expect(result).toBeFalsy();
});

it("returns false when our boundaries does not include the number of changed files", () => {
const result = checkBoundaries(6, config);
expect(result).toBeFalsy();
});
});
98 changes: 98 additions & 0 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { run } from "../src/labeler";
import * as github from "@actions/github";
import * as core from "@actions/core";

const fs = jest.requireActual("fs");

jest.mock("@actions/core");
jest.mock("@actions/github");

const gh = github.getOctokit("_");
const addLabelsMock = jest.spyOn(gh.rest.issues, "addLabels");
const removeLabelMock = jest.spyOn(gh.rest.issues, "removeLabel");
const reposMock = jest.spyOn(gh.rest.repos, "getContent");
const getPullMock = jest.spyOn(gh.rest.pulls, "get");

const yamlFixtures = {
"config.yml": fs.readFileSync("__tests__/fixtures/config.yml"),
};

afterAll(() => jest.restoreAllMocks());

describe("run", () => {
it("adds labels to PRs which changed file size is inside configured boundaries", async () => {
usingLabelerConfigYaml("config.yml");
getPullMock.mockResolvedValue(<any>{
data: {
additions: 1,
deletions: 0,
labels: [],
},
});

await run();

expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(1);
expect(addLabelsMock).toHaveBeenCalledWith({
owner: "vkirilichev",
repo: "changed-lines-count-labeler",
issue_number: 1,
labels: ["petit"],
});
});

it("does not add labels to PRs which changed file size is outside of configured boundaries", async () => {
usingLabelerConfigYaml("config.yml");
getPullMock.mockResolvedValue(<any>{
data: {
additions: 5,
deletions: 1,
labels: [],
},
});

await run();

expect(removeLabelMock).toHaveBeenCalledTimes(0);
expect(addLabelsMock).toHaveBeenCalledTimes(0);
});

it("deletes existing PR labels that is not longer insode of configured boundaries", async () => {
let mockInput = {
"repo-token": "foo",
"configuration-path": "bar"
};

jest
.spyOn(core, "getInput")
.mockImplementation((name: string, ...opts) => mockInput[name]);

usingLabelerConfigYaml("config.yml");
getPullMock.mockResolvedValue(<any>{
data: {
additions: 1,
deletions: 0,
labels: [{ name: "grande" }],
},
});

await run();

expect(addLabelsMock).toHaveBeenCalledTimes(1);
expect(removeLabelMock).toHaveBeenCalledTimes(1);
expect(removeLabelMock).toHaveBeenCalledWith({
owner: "vkirilichev",
repo: "changed-lines-count-labeler",
issue_number: 1,
name: "grande",
});
});
});

function usingLabelerConfigYaml(fixtureName: keyof typeof yamlFixtures): void {
reposMock.mockResolvedValue(<any>{
data: { content: yamlFixtures[fixtureName], encoding: "utf8" },
});
}

12 changes: 12 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: 'Changed Lines Count Labeler'
description: 'Set a label based on the number of lines changed'
inputs:
repo-token:
description: 'The GITHUB_TOKEN secret'
configuration-path:
description: 'The path for the label configurations'
default: '.github/changed-lines-count-labeler.yml'
required: false
runs:
using: 'node16'
main: 'dist/index.js'
Loading

0 comments on commit 57cf219

Please sign in to comment.