Skip to content

Commit

Permalink
Added configuration parameters (#6)
Browse files Browse the repository at this point in the history
Added configuration parameter to enable to update every branch and not
only PRs that have auto-merge enabled.

It will also skip `draft` pull requests (which would not in the case
that the auto-merge requirement is set to disabled).

Resolves #3
  • Loading branch information
Bullrich authored Jan 9, 2024
1 parent 83c26a5 commit d8554d7
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 20 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
uses: paritytech/up-to-date-action@main
with:
GITHUB_TOKEN: ${{ secret.PAT }}
REQUIRE_AUTO_MERGE: true
```
### Inputs
Expand Down Expand Up @@ -66,6 +67,12 @@ Because this project is intended to be used with a token we need to do an extra
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
```

### REQUIRE_AUTO_MERGE

If **only** Pull Request that have the [`auto-merge`](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/automatically-merging-a-pull-request) feature enabled should be updated.

It defaults to `true`.

## Development
To work on this app, you require
- `Node 18.x`
Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ inputs:
GITHUB_TOKEN:
required: true
description: The token to access the repo
REQUIRE_AUTO_MERGE:
required: false
default: "true"
description: "If only PRs with auto-merge should be updated."
outputs:
repo:
description: 'The name of the repo in owner/repo pattern'
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@types/jest": "^29.5.5",
"@vercel/ncc": "^0.38.0",
"jest": "^29.7.0",
"jest-mock-extended": "^3.0.5",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
}
Expand Down
29 changes: 19 additions & 10 deletions src/github/pullRequest.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
import { GitHubClient } from "./types";
import { ActionLogger, GitHubClient } from "./types";

type PullData = { number: number; title: string };

/** API class that uses the default token to access the data from the pull request and the repository */
export class PullRequestApi {
constructor(
private readonly api: GitHubClient,
private readonly repo: { owner: string; repo: string },
private readonly logger: ActionLogger,
) {}

async listPRs(
onlyAutoMerge: boolean,
): Promise<{ number: number; title: string }[]> {
async listPRs(onlyAutoMerge: boolean): Promise<PullData[]> {
const openPRs = await this.api.paginate(this.api.rest.pulls.list, {
...this.repo,
state: "open",
});

if (onlyAutoMerge) {
return openPRs
.filter((pr) => pr.auto_merge)
.map(({ number, title }) => ({ number, title }) as const);
} else {
return openPRs.map(({ number, title }) => ({ number, title }) as const);
const prs: PullData[] = [];
for (const pr of openPRs) {
const { number, title } = pr;

if (pr.draft) {
this.logger.debug(`❕ - Ignoring #${number} because it is a draft`);
} else if (!pr.auto_merge && onlyAutoMerge) {
this.logger.debug(
`❗️ - Ignoring #${number} because auto-merge is not enabled`,
);
} else {
prs.push({ number, title });
}
}
return prs;
}

async update(number: number): Promise<string | undefined> {
Expand Down
22 changes: 15 additions & 7 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getInput, setFailed, setOutput, summary } from "@actions/core";
import { getInput, setFailed, summary } from "@actions/core";
import { SummaryTableRow } from "@actions/core/lib/summary";
import { context, getOctokit } from "@actions/github";
import { Context } from "@actions/github/lib/context";
Expand All @@ -20,16 +20,15 @@ const getRepo = (ctx: Context) => {
return { repo, owner };
};

const repo = getRepo(context);

setOutput("repo", `${repo.owner}/${repo.repo}`);
const logger = generateCoreLogger();

const action = async () => {
const token = getInput("GITHUB_TOKEN", { required: true });
const repoInfo = getRepo(context);
const api = new PullRequestApi(getOctokit(token), repoInfo);
const prs = await api.listPRs(false);
const requireAutoMerge: boolean =
getInput("REQUIRE_AUTO_MERGE", { required: false }) !== "false";
const api = new PullRequestApi(getOctokit(token), repoInfo, logger);
const prs = await api.listPRs(requireAutoMerge);
if (prs.length > 0) {
logger.info(`About to update ${prs.length} PRs 🗄️`);
const rows: SummaryTableRow[] = [
Expand All @@ -39,6 +38,12 @@ const action = async () => {
{ data: "Result", header: true },
],
];

// JSON array with all the PRs numbers
const prsNumbers = JSON.stringify(prs.map(({ number }) => number));

logger.info(`About to update PRs: ${prsNumbers}`);

for (const { number, title } of prs.sort((a, b) => a.number - b.number)) {
logger.info(`📡 - Updating '${title}' #${number}`);
const repoTxt = `${repoInfo.owner}/${repoInfo.repo}#${number}`;
Expand All @@ -59,7 +64,10 @@ const action = async () => {
.write();
} else {
logger.info("No matching PRs found. Aborting");
summary.addHeading("Up to date", 1).addHeading("No matching PRs found");
await summary
.addHeading("Up to date", 1)
.addHeading("No matching PRs found")
.write();
}
};

Expand Down
3 changes: 0 additions & 3 deletions src/test/index.test.ts

This file was deleted.

70 changes: 70 additions & 0 deletions src/test/pullRequest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { DeepMockProxy, mock, mockDeep, MockProxy } from "jest-mock-extended";

import { PullRequestApi } from "../github/pullRequest";
import { ActionLogger, GitHubClient } from "../github/types";

describe("Pull Request API Tests", () => {
let api: PullRequestApi;
let logger: MockProxy<ActionLogger>;
let client: DeepMockProxy<GitHubClient>;
beforeEach(() => {
logger = mock<ActionLogger>();
client = mockDeep<GitHubClient>();

api = new PullRequestApi(
client,
{ owner: "owner", repo: "example" },
logger,
);
});

test("Should filter prs without auto-merge", async () => {
const mockedPrs = [
{ number: 1, auto_merge: true, title: "one" },
{ number: 2, auto_merge: false, title: "two" },
];
client.paginate.mockResolvedValue(mockedPrs);
const prs = await api.listPRs(true);
expect(prs).toHaveLength(1);
expect(prs).toContainEqual({
number: mockedPrs[0].number,
title: mockedPrs[0].title,
});
expect(prs).not.toContainEqual({
number: mockedPrs[1].number,
title: mockedPrs[1].title,
});
});

test("Should return all prs without filter", async () => {
const mockedPrs = [
{ number: 1, auto_merge: true, title: "one" },
{ number: 2, auto_merge: false, title: "two" },
];
client.paginate.mockResolvedValue(mockedPrs);
const prs = await api.listPRs(false);
expect(prs).toHaveLength(2);
expect(prs).toEqual([
{ number: mockedPrs[0].number, title: mockedPrs[0].title },
{ number: mockedPrs[1].number, title: mockedPrs[1].title },
]);
});

test("Should filter drafts PRs", async () => {
const mockedPrs = [
{ number: 1, auto_merge: false, title: "one" },
{ number: 2, auto_merge: false, draft: true, title: "two" },
];
client.paginate.mockResolvedValue(mockedPrs);
const prs = await api.listPRs(false);
expect(prs).toHaveLength(1);
expect(prs).toContainEqual({
number: mockedPrs[0].number,
title: mockedPrs[0].title,
});
expect(prs).not.toContainEqual({
number: mockedPrs[1].number,
title: mockedPrs[1].title,
});
});
});
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2675,6 +2675,13 @@ jest-message-util@^29.7.0:
slash "^3.0.0"
stack-utils "^2.0.3"

jest-mock-extended@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/jest-mock-extended/-/jest-mock-extended-3.0.5.tgz#ebf208e363f4f1db603b81fb005c4055b7c1c8b7"
integrity sha512-/eHdaNPUAXe7f65gHH5urc8SbRVWjYxBqmCgax2uqOBJy8UUcCBMN1upj1eZ8y/i+IqpyEm4Kq0VKss/GCCTdw==
dependencies:
ts-essentials "^7.0.3"

jest-mock@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347"
Expand Down Expand Up @@ -3747,6 +3754,11 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"

ts-essentials@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38"
integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==

ts-jest@^29.1.1:
version "29.1.1"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b"
Expand Down

0 comments on commit d8554d7

Please sign in to comment.