mirror of
https://github.com/marocchino/sticky-pull-request-comment.git
synced 2026-03-29 18:49:26 +00:00
Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a61de79c6 | ||
|
|
7cb1e16d25 | ||
|
|
14d4f1e429 |
11 changed files with 374 additions and 446 deletions
17
README.md
17
README.md
|
|
@ -91,6 +91,19 @@ If for some reason, triggering on pr is not possible, you can use push.
|
|||
This message is from a push.
|
||||
```
|
||||
|
||||
### Override pull request number
|
||||
|
||||
Use `number_force` to comment on a different pull request than the one that triggered the event.
|
||||
|
||||
```yaml
|
||||
- uses: marocchino/sticky-pull-request-comment@v2
|
||||
with:
|
||||
number_force: 123
|
||||
message: |
|
||||
This comment will be posted to PR #123,
|
||||
regardless of which PR triggered this workflow.
|
||||
```
|
||||
|
||||
### Read comment from a file
|
||||
|
||||
```yaml
|
||||
|
|
@ -217,6 +230,10 @@ For more detailed information about permissions, you can read from the link belo
|
|||
|
||||
**Optional** Pull request number for push event. Note that this has a **lower priority** than the number of a pull_request event.
|
||||
|
||||
### `number_force`
|
||||
|
||||
**Optional** Pull request number for any event. Note that this has the **highest priority** and will override the number from a pull_request event.
|
||||
|
||||
### `owner`
|
||||
|
||||
**Optional** Another repository owner, If not set, the current repository owner is used by default. Note that when you trying changing a repo, be aware that `GITHUB_TOKEN` should also have permission for that repository.
|
||||
|
|
|
|||
|
|
@ -1,430 +1,213 @@
|
|||
import { beforeEach, afterEach, test, expect, vi, describe } from 'vitest'
|
||||
import {afterEach, describe, expect, test, vi} from "vitest"
|
||||
import {resolve} from "node:path"
|
||||
|
||||
const mockConfig = {
|
||||
pullRequestNumber: 123,
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false,
|
||||
getBody: vi.fn().mockResolvedValue("")
|
||||
}
|
||||
vi.mock("@actions/core", () => ({
|
||||
getInput: vi.fn().mockReturnValue(""),
|
||||
getBooleanInput: vi.fn().mockReturnValue(false),
|
||||
getMultilineInput: vi.fn().mockReturnValue([]),
|
||||
setFailed: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('../src/config', () => {
|
||||
return mockConfig
|
||||
})
|
||||
const mockContext = vi.hoisted(() => ({
|
||||
repo: {owner: "marocchino", repo: "sticky-pull-request-comment"},
|
||||
payload: {} as Record<string, unknown>,
|
||||
}))
|
||||
|
||||
beforeEach(() => {
|
||||
// Set up default environment variables for each test
|
||||
process.env["GITHUB_REPOSITORY"] = "marocchino/stick-pull-request-comment"
|
||||
process.env["INPUT_NUMBER"] = "123"
|
||||
process.env["INPUT_APPEND"] = "false"
|
||||
process.env["INPUT_RECREATE"] = "false"
|
||||
process.env["INPUT_DELETE"] = "false"
|
||||
process.env["INPUT_ONLY_CREATE"] = "false"
|
||||
process.env["INPUT_ONLY_UPDATE"] = "false"
|
||||
process.env["INPUT_HIDE"] = "false"
|
||||
process.env["INPUT_HIDE_AND_RECREATE"] = "false"
|
||||
process.env["INPUT_HIDE_CLASSIFY"] = "OUTDATED"
|
||||
process.env["INPUT_HIDE_DETAILS"] = "false"
|
||||
process.env["INPUT_GITHUB_TOKEN"] = "some-token"
|
||||
process.env["INPUT_IGNORE_EMPTY"] = "false"
|
||||
process.env["INPUT_SKIP_UNCHANGED"] = "false"
|
||||
process.env["INPUT_FOLLOW_SYMBOLIC_LINKS"] = "false"
|
||||
|
||||
// 모킹된 값 초기화
|
||||
mockConfig.pullRequestNumber = 123
|
||||
mockConfig.repo = {owner: "marocchino", repo: "stick-pull-request-comment"}
|
||||
mockConfig.header = ""
|
||||
mockConfig.append = false
|
||||
mockConfig.recreate = false
|
||||
mockConfig.deleteOldComment = false
|
||||
mockConfig.hideOldComment = false
|
||||
mockConfig.hideAndRecreate = false
|
||||
mockConfig.hideClassify = "OUTDATED"
|
||||
mockConfig.hideDetails = false
|
||||
mockConfig.githubToken = "some-token"
|
||||
mockConfig.ignoreEmpty = false
|
||||
mockConfig.skipUnchanged = false
|
||||
mockConfig.getBody.mockResolvedValue("")
|
||||
})
|
||||
vi.mock("@actions/github", () => ({
|
||||
context: mockContext,
|
||||
}))
|
||||
|
||||
const mockGlobCreate = vi.hoisted(() => vi.fn())
|
||||
|
||||
vi.mock("@actions/glob", () => ({
|
||||
create: mockGlobCreate,
|
||||
}))
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetModules()
|
||||
delete process.env["GITHUB_REPOSITORY"]
|
||||
delete process.env["INPUT_OWNER"]
|
||||
delete process.env["INPUT_REPO"]
|
||||
delete process.env["INPUT_HEADER"]
|
||||
delete process.env["INPUT_MESSAGE"]
|
||||
delete process.env["INPUT_NUMBER"]
|
||||
delete process.env["INPUT_APPEND"]
|
||||
delete process.env["INPUT_RECREATE"]
|
||||
delete process.env["INPUT_DELETE"]
|
||||
delete process.env["INPUT_ONLY_CREATE"]
|
||||
delete process.env["INPUT_ONLY_UPDATE"]
|
||||
delete process.env["INPUT_HIDE"]
|
||||
delete process.env["INPUT_HIDE_AND_RECREATE"]
|
||||
delete process.env["INPUT_HIDE_CLASSIFY"]
|
||||
delete process.env["INPUT_HIDE_DETAILS"]
|
||||
delete process.env["INPUT_GITHUB_TOKEN"]
|
||||
delete process.env["INPUT_PATH"]
|
||||
delete process.env["INPUT_IGNORE_EMPTY"]
|
||||
delete process.env["INPUT_SKIP_UNCHANGED"]
|
||||
delete process.env["INPUT_FOLLOW_SYMBOLIC_LINKS"]
|
||||
mockContext.payload = {}
|
||||
mockContext.repo = {owner: "marocchino", repo: "sticky-pull-request-comment"}
|
||||
mockGlobCreate.mockReset()
|
||||
})
|
||||
|
||||
test("repo", async () => {
|
||||
process.env["INPUT_OWNER"] = "jin"
|
||||
process.env["INPUT_REPO"] = "other"
|
||||
|
||||
mockConfig.repo = {owner: "jin", repo: "other"}
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "jin", repo: "other"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
async function loadConfig(
|
||||
setup?: (mocks: {core: typeof import("@actions/core")}) => void,
|
||||
) {
|
||||
vi.resetModules()
|
||||
const core = await import("@actions/core")
|
||||
// vi.resetModules clears the config module cache but not mock instances,
|
||||
// so reset core back to default values before each test.
|
||||
vi.mocked(core.getInput).mockReturnValue("")
|
||||
vi.mocked(core.getBooleanInput).mockReturnValue(false)
|
||||
vi.mocked(core.getMultilineInput).mockReturnValue([])
|
||||
setup?.({core})
|
||||
const config = await import("../src/config")
|
||||
return {config, core}
|
||||
}
|
||||
|
||||
describe("pullRequestNumber", () => {
|
||||
test("number_force takes highest priority", async () => {
|
||||
mockContext.payload = {pull_request: {number: 789}}
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => {
|
||||
if (name === "number_force") return "456"
|
||||
if (name === "number") return "123"
|
||||
return ""
|
||||
})
|
||||
})
|
||||
expect(config.pullRequestNumber).toBe(456)
|
||||
})
|
||||
|
||||
test("falls back to context.payload.pull_request.number", async () => {
|
||||
mockContext.payload = {pull_request: {number: 789}}
|
||||
const {config} = await loadConfig()
|
||||
expect(config.pullRequestNumber).toBe(789)
|
||||
})
|
||||
|
||||
test("falls back to number input", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => (name === "number" ? "123" : ""))
|
||||
})
|
||||
expect(config.pullRequestNumber).toBe(123)
|
||||
})
|
||||
})
|
||||
|
||||
describe("repo", () => {
|
||||
test("defaults to context.repo", async () => {
|
||||
const {config} = await loadConfig()
|
||||
expect(config.repo).toEqual({owner: "marocchino", repo: "sticky-pull-request-comment"})
|
||||
})
|
||||
|
||||
test("uses owner and repo inputs when provided", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => {
|
||||
if (name === "owner") return "jin"
|
||||
if (name === "repo") return "other"
|
||||
return ""
|
||||
})
|
||||
})
|
||||
expect(config.repo).toEqual({owner: "jin", repo: "other"})
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
})
|
||||
|
||||
test("header", async () => {
|
||||
process.env["INPUT_HEADER"] = "header"
|
||||
mockConfig.header = "header"
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "header",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => (name === "header" ? "my-header" : ""))
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.header).toBe("my-header")
|
||||
})
|
||||
|
||||
test("append", async () => {
|
||||
process.env["INPUT_APPEND"] = "true"
|
||||
mockConfig.append = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: true,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "append")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.append).toBe(true)
|
||||
})
|
||||
|
||||
test("recreate", async () => {
|
||||
process.env["INPUT_RECREATE"] = "true"
|
||||
mockConfig.recreate = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: true,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "recreate")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.recreate).toBe(true)
|
||||
})
|
||||
|
||||
test("delete", async () => {
|
||||
process.env["INPUT_DELETE"] = "true"
|
||||
mockConfig.deleteOldComment = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: true,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
test("deleteOldComment", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "delete")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.deleteOldComment).toBe(true)
|
||||
})
|
||||
|
||||
test("hideOldComment", async () => {
|
||||
process.env["INPUT_HIDE"] = "true"
|
||||
mockConfig.hideOldComment = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: true,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.hideOldComment).toBe(true)
|
||||
})
|
||||
|
||||
test("hideAndRecreate", async () => {
|
||||
process.env["INPUT_HIDE_AND_RECREATE"] = "true"
|
||||
mockConfig.hideAndRecreate = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: true,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide_and_recreate")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.hideAndRecreate).toBe(true)
|
||||
})
|
||||
|
||||
test("hideClassify", async () => {
|
||||
process.env["INPUT_HIDE_CLASSIFY"] = "OFF_TOPIC"
|
||||
mockConfig.hideClassify = "OFF_TOPIC"
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OFF_TOPIC",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => (name === "hide_classify" ? "OFF_TOPIC" : ""))
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.hideClassify).toBe("OFF_TOPIC")
|
||||
})
|
||||
|
||||
test("hideDetails", async () => {
|
||||
process.env["INPUT_HIDE_DETAILS"] = "true"
|
||||
mockConfig.hideDetails = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: true,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "hide_details")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
expect(config.hideDetails).toBe(true)
|
||||
})
|
||||
|
||||
describe("path", () => {
|
||||
test("when exists return content of a file", async () => {
|
||||
process.env["INPUT_PATH"] = "./__tests__/assets/result"
|
||||
mockConfig.getBody.mockResolvedValue("hi there\n")
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
test("ignoreEmpty", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "ignore_empty")
|
||||
})
|
||||
expect(config.ignoreEmpty).toBe(true)
|
||||
})
|
||||
|
||||
test("skipUnchanged", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getBooleanInput).mockImplementation(name => name === "skip_unchanged")
|
||||
})
|
||||
expect(config.skipUnchanged).toBe(true)
|
||||
})
|
||||
|
||||
test("githubToken", async () => {
|
||||
const {config} = await loadConfig(({core}) => {
|
||||
vi.mocked(core.getInput).mockImplementation(name => (name === "GITHUB_TOKEN" ? "my-token" : ""))
|
||||
})
|
||||
expect(config.githubToken).toBe("my-token")
|
||||
})
|
||||
|
||||
describe("getBody", () => {
|
||||
test("returns message when no path is provided", async () => {
|
||||
const {config, core} = await loadConfig()
|
||||
vi.mocked(core.getInput).mockImplementation(name => (name === "message" ? "hello there" : ""))
|
||||
expect(await config.getBody()).toBe("hello there")
|
||||
})
|
||||
|
||||
test("returns file content when path exists", async () => {
|
||||
const {config, core} = await loadConfig()
|
||||
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/result"])
|
||||
mockGlobCreate.mockResolvedValue({
|
||||
glob: vi.fn().mockResolvedValue([resolve("__tests__/assets/result")]),
|
||||
})
|
||||
expect(await config.getBody()).toEqual("hi there\n")
|
||||
expect(await config.getBody()).toBe("hi there\n")
|
||||
})
|
||||
|
||||
test("glob match files", async () => {
|
||||
process.env["INPUT_PATH"] = "./__tests__/assets/*"
|
||||
mockConfig.getBody.mockResolvedValue("hi there\n\nhey there\n")
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
test("glob matches multiple files", async () => {
|
||||
const {config, core} = await loadConfig()
|
||||
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/*"])
|
||||
mockGlobCreate.mockResolvedValue({
|
||||
glob: vi
|
||||
.fn()
|
||||
.mockResolvedValue([
|
||||
resolve("__tests__/assets/result"),
|
||||
resolve("__tests__/assets/result2"),
|
||||
]),
|
||||
})
|
||||
expect(await config.getBody()).toEqual("hi there\n\nhey there\n")
|
||||
expect(await config.getBody()).toBe("hi there\n\nhey there\n")
|
||||
})
|
||||
|
||||
test("when not exists return null string", async () => {
|
||||
process.env["INPUT_PATH"] = "./__tests__/assets/not_exists"
|
||||
mockConfig.getBody.mockResolvedValue("")
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
test("returns empty string when path matches no files", async () => {
|
||||
const {config, core} = await loadConfig()
|
||||
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/not_exists"])
|
||||
mockGlobCreate.mockResolvedValue({glob: vi.fn().mockResolvedValue([])})
|
||||
expect(await config.getBody()).toBe("")
|
||||
})
|
||||
})
|
||||
|
||||
test("message", async () => {
|
||||
process.env["INPUT_MESSAGE"] = "hello there"
|
||||
mockConfig.getBody.mockResolvedValue("hello there")
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: false
|
||||
test("returns empty string and calls setFailed when glob throws", async () => {
|
||||
const {config, core} = await loadConfig()
|
||||
vi.mocked(core.getMultilineInput).mockReturnValue(["__tests__/assets/result"])
|
||||
mockGlobCreate.mockRejectedValue(new Error("glob error"))
|
||||
expect(await config.getBody()).toBe("")
|
||||
expect(core.setFailed).toHaveBeenCalledWith("glob error")
|
||||
})
|
||||
expect(await config.getBody()).toEqual("hello there")
|
||||
})
|
||||
|
||||
test("ignore_empty", async () => {
|
||||
process.env["INPUT_IGNORE_EMPTY"] = "true"
|
||||
mockConfig.ignoreEmpty = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: true,
|
||||
skipUnchanged: false
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
})
|
||||
|
||||
test("skip_unchanged", async () => {
|
||||
process.env["INPUT_SKIP_UNCHANGED"] = "true"
|
||||
mockConfig.skipUnchanged = true
|
||||
|
||||
const config = await import('../src/config')
|
||||
expect(config).toMatchObject({
|
||||
pullRequestNumber: expect.any(Number),
|
||||
repo: {owner: "marocchino", repo: "stick-pull-request-comment"},
|
||||
header: "",
|
||||
append: false,
|
||||
recreate: false,
|
||||
deleteOldComment: false,
|
||||
hideOldComment: false,
|
||||
hideAndRecreate: false,
|
||||
hideClassify: "OUTDATED",
|
||||
hideDetails: false,
|
||||
githubToken: "some-token",
|
||||
ignoreEmpty: false,
|
||||
skipUnchanged: true
|
||||
})
|
||||
expect(await config.getBody()).toEqual("")
|
||||
})
|
||||
|
|
|
|||
|
|
@ -115,8 +115,9 @@ describe("run", () => {
|
|||
mockConfig.recreate = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"delete and recreate cannot be both set to true",
|
||||
"delete and recreate cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("fails when deleteOldComment and onlyCreateComment are both true", async () => {
|
||||
|
|
@ -124,8 +125,9 @@ describe("run", () => {
|
|||
mockConfig.onlyCreateComment = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"delete and only_create cannot be both set to true",
|
||||
"delete and only_create cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("fails when deleteOldComment and hideOldComment are both true", async () => {
|
||||
|
|
@ -133,8 +135,9 @@ describe("run", () => {
|
|||
mockConfig.hideOldComment = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"delete and hide cannot be both set to true",
|
||||
"delete and hide cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("fails when onlyCreateComment and onlyUpdateComment are both true", async () => {
|
||||
|
|
@ -142,8 +145,9 @@ describe("run", () => {
|
|||
mockConfig.onlyUpdateComment = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"only_create and only_update cannot be both set to true",
|
||||
"only_create and only_update cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("fails when hideOldComment and hideAndRecreate are both true", async () => {
|
||||
|
|
@ -151,8 +155,19 @@ describe("run", () => {
|
|||
mockConfig.hideAndRecreate = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"hide and hide_and_recreate cannot be both set to true",
|
||||
"hide and hide_and_recreate cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("fails when deleteOldComment and hideAndRecreate are both true", async () => {
|
||||
mockConfig.deleteOldComment = true
|
||||
mockConfig.hideAndRecreate = true
|
||||
const {core} = await runMain()
|
||||
expect(core.setFailed).toHaveBeenCalledWith(
|
||||
"delete and hide_and_recreate cannot be set to true simultaneously",
|
||||
)
|
||||
expect(mockConfig.getBody).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
test("deletes previous comment when deleteOldComment is true and previous comment exists", async () => {
|
||||
|
|
|
|||
85
__tests__/validate.test.ts
Normal file
85
__tests__/validate.test.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import {describe, expect, test} from "vitest"
|
||||
import {validateBody, validateExclusiveModes} from "../src/validate"
|
||||
|
||||
describe("validateBody", () => {
|
||||
test("throws when body is empty and neither delete nor hide is set", () => {
|
||||
expect(() => validateBody("", false, false)).toThrow(
|
||||
"Either message or path input is required",
|
||||
)
|
||||
})
|
||||
|
||||
test("does not throw when body is provided", () => {
|
||||
expect(() => validateBody("some body", false, false)).not.toThrow()
|
||||
})
|
||||
|
||||
test("does not throw when body is empty but deleteOldComment is true", () => {
|
||||
expect(() => validateBody("", true, false)).not.toThrow()
|
||||
})
|
||||
|
||||
test("does not throw when body is empty but hideOldComment is true", () => {
|
||||
expect(() => validateBody("", false, true)).not.toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
describe("validateExclusiveModes", () => {
|
||||
test("does not throw when no modes are enabled", () => {
|
||||
expect(() => validateExclusiveModes(false, false, false, false, false, false)).not.toThrow()
|
||||
})
|
||||
|
||||
test("does not throw when exactly one mode is enabled", () => {
|
||||
expect(() => validateExclusiveModes(true, false, false, false, false, false)).not.toThrow()
|
||||
expect(() => validateExclusiveModes(false, true, false, false, false, false)).not.toThrow()
|
||||
expect(() => validateExclusiveModes(false, false, true, false, false, false)).not.toThrow()
|
||||
expect(() => validateExclusiveModes(false, false, false, true, false, false)).not.toThrow()
|
||||
expect(() => validateExclusiveModes(false, false, false, false, true, false)).not.toThrow()
|
||||
expect(() => validateExclusiveModes(false, false, false, false, false, true)).not.toThrow()
|
||||
})
|
||||
|
||||
test("throws when delete and recreate are both true", () => {
|
||||
expect(() => validateExclusiveModes(true, true, false, false, false, false)).toThrow(
|
||||
"delete and recreate cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when delete and only_create are both true", () => {
|
||||
expect(() => validateExclusiveModes(true, false, true, false, false, false)).toThrow(
|
||||
"delete and only_create cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when delete and only_update are both true", () => {
|
||||
expect(() => validateExclusiveModes(true, false, false, true, false, false)).toThrow(
|
||||
"delete and only_update cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when delete and hide are both true", () => {
|
||||
expect(() => validateExclusiveModes(true, false, false, false, true, false)).toThrow(
|
||||
"delete and hide cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when delete and hide_and_recreate are both true", () => {
|
||||
expect(() => validateExclusiveModes(true, false, false, false, false, true)).toThrow(
|
||||
"delete and hide_and_recreate cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when only_create and only_update are both true", () => {
|
||||
expect(() => validateExclusiveModes(false, false, true, true, false, false)).toThrow(
|
||||
"only_create and only_update cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("throws when hide and hide_and_recreate are both true", () => {
|
||||
expect(() => validateExclusiveModes(false, false, false, false, true, true)).toThrow(
|
||||
"hide and hide_and_recreate cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
|
||||
test("uses Oxford comma when three or more modes are enabled", () => {
|
||||
expect(() => validateExclusiveModes(true, true, true, false, false, false)).toThrow(
|
||||
"delete, recreate, and only_create cannot be set to true simultaneously",
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
@ -72,6 +72,9 @@ inputs:
|
|||
number:
|
||||
description: "pull request number for push event"
|
||||
required: false
|
||||
number_force:
|
||||
description: "pull request number for any event"
|
||||
required: false
|
||||
owner:
|
||||
description: "Another repo owner, If not set, the current repo owner is used by default. Note that when you trying changing a repo, be aware that GITHUB_TOKEN should also have permission for that repository."
|
||||
required: false
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.6/schema.json",
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
|
||||
"files": {
|
||||
"includes": ["src/**/*.ts"]
|
||||
},
|
||||
|
|
|
|||
72
package-lock.json
generated
72
package-lock.json
generated
|
|
@ -15,7 +15,7 @@
|
|||
"@octokit/graphql-schema": "^15.26.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.4.6",
|
||||
"@biomejs/biome": "2.4.7",
|
||||
"@rollup/plugin-commonjs": "^29.0.2",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@rollup/plugin-typescript": "^12.3.0",
|
||||
|
|
@ -98,9 +98,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@biomejs/biome": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.6.tgz",
|
||||
"integrity": "sha512-QnHe81PMslpy3mnpL8DnO2M4S4ZnYPkjlGCLWBZT/3R9M6b5daArWMMtEfP52/n174RKnwRIf3oT8+wc9ihSfQ==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.7.tgz",
|
||||
"integrity": "sha512-vXrgcmNGZ4lpdwZSpMf1hWw1aWS6B+SyeSYKTLrNsiUsAdSRN0J4d/7mF3ogJFbIwFFSOL3wT92Zzxia/d5/ng==",
|
||||
"dev": true,
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"bin": {
|
||||
|
|
@ -114,20 +114,20 @@
|
|||
"url": "https://opencollective.com/biome"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@biomejs/cli-darwin-arm64": "2.4.6",
|
||||
"@biomejs/cli-darwin-x64": "2.4.6",
|
||||
"@biomejs/cli-linux-arm64": "2.4.6",
|
||||
"@biomejs/cli-linux-arm64-musl": "2.4.6",
|
||||
"@biomejs/cli-linux-x64": "2.4.6",
|
||||
"@biomejs/cli-linux-x64-musl": "2.4.6",
|
||||
"@biomejs/cli-win32-arm64": "2.4.6",
|
||||
"@biomejs/cli-win32-x64": "2.4.6"
|
||||
"@biomejs/cli-darwin-arm64": "2.4.7",
|
||||
"@biomejs/cli-darwin-x64": "2.4.7",
|
||||
"@biomejs/cli-linux-arm64": "2.4.7",
|
||||
"@biomejs/cli-linux-arm64-musl": "2.4.7",
|
||||
"@biomejs/cli-linux-x64": "2.4.7",
|
||||
"@biomejs/cli-linux-x64-musl": "2.4.7",
|
||||
"@biomejs/cli-win32-arm64": "2.4.7",
|
||||
"@biomejs/cli-win32-x64": "2.4.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-darwin-arm64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.6.tgz",
|
||||
"integrity": "sha512-NW18GSyxr+8sJIqgoGwVp5Zqm4SALH4b4gftIA0n62PTuBs6G2tHlwNAOj0Vq0KKSs7Sf88VjjmHh0O36EnzrQ==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.7.tgz",
|
||||
"integrity": "sha512-Oo0cF5mHzmvDmTXw8XSjhCia8K6YrZnk7aCS54+/HxyMdZMruMO3nfpDsrlar/EQWe41r1qrwKiCa2QDYHDzWA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -142,9 +142,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-darwin-x64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.6.tgz",
|
||||
"integrity": "sha512-4uiE/9tuI7cnjtY9b07RgS7gGyYOAfIAGeVJWEfeCnAarOAS7qVmuRyX6d7JTKw28/mt+rUzMasYeZ+0R/U1Mw==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.7.tgz",
|
||||
"integrity": "sha512-I+cOG3sd/7HdFtvDSnF9QQPrWguUH7zrkIMMykM3PtfWU9soTcS2yRb9Myq6MHmzbeCT08D1UmY+BaiMl5CcoQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -159,9 +159,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-linux-arm64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.6.tgz",
|
||||
"integrity": "sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.7.tgz",
|
||||
"integrity": "sha512-om6FugwmibzfP/6ALj5WRDVSND4H2G9X0nkI1HZpp2ySf9lW2j0X68oQSaHEnls6666oy4KDsc5RFjT4m0kV0w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -176,9 +176,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-linux-arm64-musl": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.6.tgz",
|
||||
"integrity": "sha512-F/JdB7eN22txiTqHM5KhIVt0jVkzZwVYrdTR1O3Y4auBOQcXxHK4dxULf4z43QyZI5tsnQJrRBHZy7wwtL+B3A==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.7.tgz",
|
||||
"integrity": "sha512-I2NvM9KPb09jWml93O2/5WMfNR7Lee5Latag1JThDRMURVhPX74p9UDnyTw3Ae6cE1DgXfw7sqQgX7rkvpc0vw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -193,9 +193,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-linux-x64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.6.tgz",
|
||||
"integrity": "sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.7.tgz",
|
||||
"integrity": "sha512-bV8/uo2Tj+gumnk4sUdkerWyCPRabaZdv88IpbmDWARQQoA/Q0YaqPz1a+LSEDIL7OfrnPi9Hq1Llz4ZIGyIQQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -210,9 +210,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-linux-x64-musl": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.6.tgz",
|
||||
"integrity": "sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.7.tgz",
|
||||
"integrity": "sha512-00kx4YrBMU8374zd2wHuRV5wseh0rom5HqRND+vDldJPrWwQw+mzd/d8byI9hPx926CG+vWzq6AeiT7Yi5y59g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -227,9 +227,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-win32-arm64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.6.tgz",
|
||||
"integrity": "sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.7.tgz",
|
||||
"integrity": "sha512-hOUHBMlFCvDhu3WCq6vaBoG0dp0LkWxSEnEEsxxXvOa9TfT6ZBnbh72A/xBM7CBYB7WgwqboetzFEVDnMxelyw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -244,9 +244,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@biomejs/cli-win32-x64": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.6.tgz",
|
||||
"integrity": "sha512-7++XhnsPlr1HDbor5amovPjOH6vsrFOCdp93iKXhFn6bcMUI6soodj3WWKfgEO6JosKU1W5n3uky3WW9RlRjTg==",
|
||||
"version": "2.4.7",
|
||||
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.7.tgz",
|
||||
"integrity": "sha512-qEpGjSkPC3qX4ycbMUthXvi9CkRq7kZpkqMY1OyhmYlYLnANnooDQ7hDerM8+0NJ+DZKVnsIc07h30XOpt7LtQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"@octokit/graphql-schema": "^15.26.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "2.4.6",
|
||||
"@biomejs/biome": "2.4.7",
|
||||
"@rollup/plugin-commonjs": "^29.0.2",
|
||||
"@rollup/plugin-node-resolve": "^16.0.3",
|
||||
"@rollup/plugin-typescript": "^12.3.0",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ import {create} from "@actions/glob"
|
|||
import type {ReportedContentClassifiers} from "@octokit/graphql-schema"
|
||||
|
||||
export const pullRequestNumber =
|
||||
context?.payload?.pull_request?.number || +core.getInput("number", {required: false})
|
||||
+core.getInput("number_force", {required: false}) ||
|
||||
context?.payload?.pull_request?.number ||
|
||||
+core.getInput("number", {required: false})
|
||||
|
||||
export const repo = buildRepo()
|
||||
export const header = core.getInput("header", {required: false})
|
||||
|
|
|
|||
34
src/main.ts
34
src/main.ts
|
|
@ -27,6 +27,7 @@ import {
|
|||
repo,
|
||||
skipUnchanged,
|
||||
} from "./config"
|
||||
import {validateBody, validateExclusiveModes} from "./validate"
|
||||
|
||||
async function run(): Promise<undefined> {
|
||||
if (Number.isNaN(pullRequestNumber) || pullRequestNumber < 1) {
|
||||
|
|
@ -35,6 +36,15 @@ async function run(): Promise<undefined> {
|
|||
}
|
||||
|
||||
try {
|
||||
validateExclusiveModes(
|
||||
deleteOldComment,
|
||||
recreate,
|
||||
onlyCreateComment,
|
||||
onlyUpdateComment,
|
||||
hideOldComment,
|
||||
hideAndRecreate,
|
||||
)
|
||||
|
||||
const body = await getBody()
|
||||
|
||||
if (!body && ignoreEmpty) {
|
||||
|
|
@ -42,29 +52,7 @@ async function run(): Promise<undefined> {
|
|||
return
|
||||
}
|
||||
|
||||
if (!deleteOldComment && !hideOldComment && !body) {
|
||||
throw new Error("Either message or path input is required")
|
||||
}
|
||||
|
||||
if (deleteOldComment && recreate) {
|
||||
throw new Error("delete and recreate cannot be both set to true")
|
||||
}
|
||||
|
||||
if (deleteOldComment && onlyCreateComment) {
|
||||
throw new Error("delete and only_create cannot be both set to true")
|
||||
}
|
||||
|
||||
if (deleteOldComment && hideOldComment) {
|
||||
throw new Error("delete and hide cannot be both set to true")
|
||||
}
|
||||
|
||||
if (onlyCreateComment && onlyUpdateComment) {
|
||||
throw new Error("only_create and only_update cannot be both set to true")
|
||||
}
|
||||
|
||||
if (hideOldComment && hideAndRecreate) {
|
||||
throw new Error("hide and hide_and_recreate cannot be both set to true")
|
||||
}
|
||||
validateBody(body, deleteOldComment, hideOldComment)
|
||||
|
||||
const octokit = github.getOctokit(githubToken)
|
||||
const previous = await findPreviousComment(octokit, repo, pullRequestNumber, header)
|
||||
|
|
|
|||
35
src/validate.ts
Normal file
35
src/validate.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
export function validateBody(
|
||||
body: string,
|
||||
deleteOldComment: boolean,
|
||||
hideOldComment: boolean,
|
||||
): void {
|
||||
if (!deleteOldComment && !hideOldComment && !body) {
|
||||
throw new Error("Either message or path input is required")
|
||||
}
|
||||
}
|
||||
|
||||
export function validateExclusiveModes(
|
||||
deleteOldComment: boolean,
|
||||
recreate: boolean,
|
||||
onlyCreateComment: boolean,
|
||||
onlyUpdateComment: boolean,
|
||||
hideOldComment: boolean,
|
||||
hideAndRecreate: boolean,
|
||||
): void {
|
||||
const exclusiveModes: [string, boolean][] = [
|
||||
["delete", deleteOldComment],
|
||||
["recreate", recreate],
|
||||
["only_create", onlyCreateComment],
|
||||
["only_update", onlyUpdateComment],
|
||||
["hide", hideOldComment],
|
||||
["hide_and_recreate", hideAndRecreate],
|
||||
]
|
||||
const enabledModes = exclusiveModes.filter(([, flag]) => flag).map(([name]) => name)
|
||||
if (enabledModes.length > 1) {
|
||||
const last = enabledModes[enabledModes.length - 1]
|
||||
const rest = enabledModes.slice(0, -1)
|
||||
const joined =
|
||||
enabledModes.length === 2 ? `${rest[0]} and ${last}` : `${rest.join(", ")}, and ${last}`
|
||||
throw new Error(`${joined} cannot be set to true simultaneously`)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue