Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the option to configure when the action should start reporting a new version #910

Merged
merged 31 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7cf8835
Using the version-check api
marekdedic Apr 9, 2023
1607548
Parsing RC version if available
marekdedic Apr 9, 2023
70d0ec8
Build artifact sync
marekdedic Apr 9, 2023
157e430
Fixed test setup
marekdedic Apr 9, 2023
10605d2
Fixed test names
marekdedic Apr 9, 2023
0eba982
Merge branch 'master' into configurable-channel
marekdedic Apr 9, 2023
822223f
Added channel to config
marekdedic Apr 9, 2023
743cbd0
Added switching logic for different variants
marekdedic Apr 9, 2023
dc60023
Merge branch 'master' into configurable-channel
marekdedic Apr 9, 2023
9c66531
Split tests to reflect code changes
marekdedic Apr 9, 2023
5d6f5eb
Added a new test with invalid config
marekdedic Apr 9, 2023
a42b180
Testing run function
marekdedic Apr 10, 2023
434c65e
Added default assignees to config
marekdedic Apr 10, 2023
9434fab
Added default channel to config
marekdedic Apr 10, 2023
f0eaadf
Merge branch 'master' into configurable-channel
marekdedic Apr 10, 2023
4c16031
VersionOffers -> WordpressVersions
marekdedic Apr 10, 2023
1dc1fad
Removed central existing issue retrieval
marekdedic Apr 10, 2023
d9879ac
Simplified version logic
marekdedic Apr 10, 2023
925452e
Split issue commenting from closing
marekdedic Apr 11, 2023
e0e99db
Split issue creating from content generating
marekdedic Apr 11, 2023
70a6762
updateIssue comapring whole contents
marekdedic Apr 11, 2023
22a5b39
Passing all versions to outdatedStable
marekdedic Apr 11, 2023
9e97c39
Revert "Passing all versions to outdatedStable"
marekdedic Apr 11, 2023
6b07b2c
Implemented outdatedRC
marekdedic Apr 11, 2023
3657976
variable renames
marekdedic Apr 11, 2023
fb8ea20
Implemented outdatedBeta
marekdedic Apr 11, 2023
74132f1
Tweaked issue wording
marekdedic Apr 11, 2023
1cadaf7
Build artifact sync
marekdedic Apr 11, 2023
228b4bf
Documented configuration options
marekdedic Apr 11, 2023
eaea4ff
Temporarily disabled the option to specify the beta channel.
marekdedic Apr 11, 2023
f7337cd
Typo fix
marekdedic Apr 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,48 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
```

By default, the app checks for readme in `readme.txt` and `plugin/readme.txt`. If the readme of your plugin is not in one of these locations, you can configure the app to look somewhere else by creating a file called `.wordpress-version-checker.json` in the root of your repo with the contents:
## Configuration

The app doesn't stricly require any configuration, however you can configure some aspects of its function by placing a file named `.wordpress-version-checker.json` in the root of your repository. The file may contain any of the following configuration options:

### Plugin readme location.

By default, the app checks for readme in `readme.txt` and `plugin/readme.txt`. If the readme of your plugin is not in one of these locations, you can configure the app to look somewhere else with the `readme` value in the configuration. The value can be either a single location or an array of locations to check - if multiple locations are provided, they will be checked in the given order until the first match.

#### Examples

```json
{
"readme": "path/to/your/readme.txt"
}
```

If you want the issues to be automatically assigned to someone, you can put their GitHub usernames in the config as well:
```json
{
"readme": ["path/to/first/readme.txt", "path/to/second/readme.txt"]
}
```

### WordPress release channel

By default, the app will only notify you once the new WordPress version is released (**This will change** - starting from version 2.0, the default value will be changed to `rc`). By setting the `channel` value to one of `stable` or `rc`, you can choose to be notified when the new version is fully release, is in the release candidate (RC) stage of development or when the first beta versions are released.
marekdedic marked this conversation as resolved.
Show resolved Hide resolved

#### Example

```json
{
"channel": "rc"
}
```

### Issue assignees

By default, the issue will have no assignees. If you want the issues to be automatically assigned to someone, you can put their GitHub usernames in the config as the `assignees` value.

#### Example

```json
{
"readme": "path/to/your/readme.txt",
"assignees": ["alice", "bob"]
}
```
196 changes: 98 additions & 98 deletions __tests__/issue-management.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { mocked } from "jest-mock";
import mockedEnv from "mocked-env";
import nock from "nock";

import { ExistingIssueFormatError } from "../src/exceptions/ExistingIssueFormatError";
import { GetIssueError } from "../src/exceptions/GetIssueError";
import { IssueCommentError } from "../src/exceptions/IssueCommentError";
import { IssueCreationError } from "../src/exceptions/IssueCreationError";
import { IssueListError } from "../src/exceptions/IssueListError";
import { IssueUpdateError } from "../src/exceptions/IssueUpdateError";
import {
closeIssue,
commentOnIssue,
createIssue,
getIssue,
updateIssue,
Expand Down Expand Up @@ -65,176 +65,198 @@ describe("[env variable mock]", () => {
await expect(getIssue()).rejects.toThrow(IssueListError);
});

test("closeIssue works correctly", async () => {
expect.assertions(1);
nock("https://api.github.com")
test("commentOnIssue works correctly", async () => {
expect.assertions(2);
const issueBody = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues/123/comments", {
body: 'The "Tested up to" version in the readme matches the latest version now, closing this issue.',
})
.reply(200)
.patch("/repos/OWNER/REPO/issues/123", {
state: "closed",
body: issueBody,
})
.reply(200);

await expect(closeIssue(123)).resolves.toBeUndefined();
await expect(commentOnIssue(123, issueBody)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("closeIssue fails gracefully on connection issues when commenting", async () => {
test("commentOnIssue fails gracefully on connection issues", async () => {
expect.assertions(1);
await expect(closeIssue(123)).rejects.toThrow(IssueCommentError);
await expect(commentOnIssue(123, "ISSUE_BODY")).rejects.toThrow(
IssueCommentError
);
});

test("closeIssue fails gracefully on nonexistent repo when commenting", async () => {
expect.assertions(1);
nock("https://api.github.com")
test("commentOnIssue fails gracefully on nonexistent repo", async () => {
expect.assertions(2);
const issueBody = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues/123/comments", {
body: 'The "Tested up to" version in the readme matches the latest version now, closing this issue.',
body: issueBody,
})
.reply(404)
.reply(404);

await expect(commentOnIssue(123, issueBody)).rejects.toThrow(
IssueCommentError
);
expect(scope.isDone()).toBe(true);
});

test("closeIssue works correctly", async () => {
expect.assertions(2);
const scope = nock("https://api.github.com")
.patch("/repos/OWNER/REPO/issues/123", {
state: "closed",
})
.reply(404);
.reply(200);

await expect(closeIssue(123)).rejects.toThrow(IssueCommentError);
await expect(closeIssue(123)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("closeIssue fails gracefully on connection issues when closing", async () => {
test("closeIssue fails gracefully on connection issues", async () => {
expect.assertions(1);
nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues/123/comments", {
body: 'The "Tested up to" version in the readme matches the latest version now, closing this issue.',
})
.reply(200);
await expect(closeIssue(123)).rejects.toThrow(IssueUpdateError);
});

test("closeIssue fails gracefully on nonexistent repo when closing", async () => {
expect.assertions(1);
nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues/123/comments", {
body: 'The "Tested up to" version in the readme matches the latest version now, closing this issue.',
})
.reply(200)
test("closeIssue fails gracefully on nonexistent repo", async () => {
expect.assertions(2);
const scope = nock("https://api.github.com")
.patch("/repos/OWNER/REPO/issues/123", {
state: "closed",
})
.reply(404);

await expect(closeIssue(123)).rejects.toThrow(IssueUpdateError);
expect(scope.isDone()).toBe(true);
});

test("createIssue works correctly", async () => {
expect.assertions(2);
const config = {
readme: ["readme.txt"],
assignees: [],
};
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";
const assignees: Array<string> = [];

const scope = nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues", {
title:
"The plugin hasn't been tested with the latest version of WordPress",
body: /.*/g,
title,
body,
labels: ["wpvc"],
assignees: [],
assignees,
})
.reply(201);

await expect(createIssue(config, "0.41", "0.42")).resolves.toBeUndefined();
await expect(createIssue(title, body, assignees)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("createIssue works correctly with assignees", async () => {
expect.assertions(2);
const config = {
readme: ["readme.txt"],
assignees: ["PERSON1", "PERSON2"],
};
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";
const assignees = ["PERSON1", "PERSON2"];

const scope = nock("https://api.github.com")
.post("/repos/OWNER/REPO/issues", {
title:
"The plugin hasn't been tested with the latest version of WordPress",
body: /.*/g,
title,
body,
labels: ["wpvc"],
assignees: ["PERSON1", "PERSON2"],
assignees,
})
.reply(201);

await expect(createIssue(config, "0.41", "0.42")).resolves.toBeUndefined();
await expect(createIssue(title, body, assignees)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("createIssue fails gracefully on connection issues", async () => {
expect.assertions(1);
const config = {
readme: ["readme.txt"],
assignees: ["PERSON1", "PERSON2"],
};

await expect(createIssue(config, "0.41", "0.42")).rejects.toThrow(
await expect(createIssue("ISSUE_TITLE", "ISSUE_BODY", [])).rejects.toThrow(
IssueCreationError
);
});

test("createIssue fails gracefully on nonexistent repo", async () => {
expect.assertions(1);
const config = {
readme: ["readme.txt"],
assignees: ["PERSON1", "PERSON2"],
};

nock("https://api.github.com").post("/repos/OWNER/REPO/issues").reply(404);

await expect(createIssue(config, "0.41", "0.42")).rejects.toThrow(
await expect(createIssue("ISSUE_TITLE", "ISSUE_BODY", [])).rejects.toThrow(
IssueCreationError
);
});

test("updateIssue works correctly", async () => {
test("updateIssue works correctly with an up-to-date-issue", async () => {
expect.assertions(2);
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, { body: "**Latest version:** 0.42" })
.patch("/repos/OWNER/REPO/issues/123")
.reply(200, { title, body });
//.patch("/repos/OWNER/REPO/issues/123")
//.reply(200);

await expect(updateIssue(123, title, body)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("updateIssue works correctly with an issue with outdated title", async () => {
expect.assertions(2);
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, { title: "WRONG_TITLE", body })
.patch("/repos/OWNER/REPO/issues/123", { title, body })
.reply(200);

await expect(updateIssue(123, "0.41", "0.43")).resolves.toBeUndefined();
await expect(updateIssue(123, title, body)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("updateIssue correctly does not update the issue if it isn't needed", async () => {
test("updateIssue works correctly with an issue with outdated body", async () => {
expect.assertions(2);
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, { body: "**Latest version:** 0.42" });
.reply(200, { title, body: "WRONG_BODY" })
.patch("/repos/OWNER/REPO/issues/123", { title, body })
.reply(200);

await expect(updateIssue(123, "0.41", "0.42")).resolves.toBeUndefined();
await expect(updateIssue(123, title, body)).resolves.toBeUndefined();
expect(scope.isDone()).toBe(true);
});

test("updateIssue fails gracefully on connection issues on getting the existing issue", async () => {
expect.assertions(1);
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";

nock("https://api.github.com")
.patch("/repos/OWNER/REPO/issues/123")
.patch("/repos/OWNER/REPO/issues/123", { title, body })
.reply(200);

await expect(updateIssue(123, "0.41", "0.43")).rejects.toThrow(
GetIssueError
);
await expect(updateIssue(123, title, body)).rejects.toThrow(GetIssueError);
});

test("updateIssue fails gracefully on connection issues on updating the existing issue", async () => {
expect.assertions(1);
nock("https://api.github.com")
expect.assertions(2);
const title = "ISSUE_TITLE";
const body = "ISSUE_BODY";

const scope = nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, { body: "**Latest version:** 0.42" });
.reply(200, { title: "WRONG_TITLE", body });

await expect(updateIssue(123, "0.41", "0.43")).rejects.toThrow(
await expect(updateIssue(123, title, body)).rejects.toThrow(
IssueUpdateError
);
expect(scope.isDone()).toBe(true);
});

test("updateIssue fails gracefully on nonexistent repo", async () => {
Expand All @@ -245,30 +267,8 @@ describe("[env variable mock]", () => {
.patch("/repos/OWNER/REPO/issues/123")
.reply(404);

await expect(updateIssue(123, "0.41", "0.43")).rejects.toThrow(
await expect(updateIssue(123, "ISSUE_TITLE", "ISSUE_BODY")).rejects.toThrow(
GetIssueError
);
});

test("updateIssue fails gracefully on malformed issue 1", async () => {
expect.assertions(1);
nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, {});

await expect(updateIssue(123, "0.41", "0.43")).rejects.toThrow(
ExistingIssueFormatError
);
});

test("updateIssue fails gracefully on malformed issue 2", async () => {
expect.assertions(1);
nock("https://api.github.com")
.get("/repos/OWNER/REPO/issues/123")
.reply(200, { body: "**Latest NOT version:** 0.42" });

await expect(updateIssue(123, "0.41", "0.43")).rejects.toThrow(
ExistingIssueFormatError
);
});
});
Loading