mirror of
https://github.com/mshick/add-pr-comment.git
synced 2025-12-31 14:20:32 +11:00
parent
ef723874d4
commit
a251f051d3
9 changed files with 154 additions and 85 deletions
1
.github/workflows/ci.yml
vendored
1
.github/workflows/ci.yml
vendored
|
|
@ -62,6 +62,7 @@ jobs:
|
|||
|
||||
- uses: ./
|
||||
with:
|
||||
preformatted: true
|
||||
message-id: path
|
||||
message-path: |
|
||||
.github/test/file-*.txt
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ jobs:
|
|||
| issue | with | Optional issue number override. | no | |
|
||||
| update-only | with | Only update the comment if it already exists. | no | false |
|
||||
| GITHUB_TOKEN | env | Valid GitHub token, can alternatively be defined in the env. | no | |
|
||||
| preformatted | with | Treat message text as pre-formatted and place it in a codeblock | no | |
|
||||
|
||||
## Advanced Uses
|
||||
|
||||
|
|
@ -169,7 +170,6 @@ jobs:
|
|||
message-part-*.txt
|
||||
```
|
||||
|
||||
|
||||
### Bring your own issues
|
||||
|
||||
You can set an issue id explicitly. Helpful for cases where you want to post
|
||||
|
|
@ -202,7 +202,7 @@ jobs:
|
|||
issue: ${{ steps.pr.outputs.issue }}
|
||||
message: |
|
||||
**Howdie!**
|
||||
````
|
||||
```
|
||||
|
||||
## Contributors ✨
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ type Inputs = {
|
|||
'message-cancelled'?: string
|
||||
'message-skipped'?: string
|
||||
'update-only'?: string
|
||||
preformatted?: string
|
||||
status?: 'success' | 'failure' | 'cancelled' | 'skipped'
|
||||
}
|
||||
|
||||
|
|
@ -41,6 +42,7 @@ const defaultInputs: Inputs = {
|
|||
'repo-token': repoToken,
|
||||
'message-id': 'add-pr-comment',
|
||||
'allow-repeats': 'false',
|
||||
status: 'success',
|
||||
}
|
||||
|
||||
const defaultIssueNumber = 1
|
||||
|
|
@ -95,10 +97,10 @@ const server = setupServer(...handlers)
|
|||
|
||||
describe('add-pr-comment action', () => {
|
||||
beforeAll(() => {
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
vi.spyOn(core, 'debug').mockImplementation(() => {})
|
||||
vi.spyOn(core, 'info').mockImplementation(() => {})
|
||||
vi.spyOn(core, 'warning').mockImplementation(() => {})
|
||||
// vi.spyOn(console, 'log').mockImplementation(() => {})
|
||||
// vi.spyOn(core, 'debug').mockImplementation(() => {})
|
||||
// vi.spyOn(core, 'info').mockImplementation(() => {})
|
||||
// vi.spyOn(core, 'warning').mockImplementation(() => {})
|
||||
server.listen({ onUnhandledRequest: 'error' })
|
||||
})
|
||||
afterAll(() => server.close())
|
||||
|
|
@ -392,4 +394,17 @@ describe('add-pr-comment action', () => {
|
|||
await run()
|
||||
expect(messagePayload?.body).toContain('666')
|
||||
})
|
||||
|
||||
it('wraps a message in a codeblock if preformatted is true', async () => {
|
||||
inputs.message = undefined
|
||||
inputs['preformatted'] = 'true'
|
||||
inputs['message-path'] = messagePath1Fixture
|
||||
|
||||
await expect(run()).resolves.not.toThrow()
|
||||
expect(
|
||||
`<!-- add-pr-comment:add-pr-comment -->\n\n\`\`\`\n${messagePath1FixturePayload}\n\`\`\``,
|
||||
).toEqual(messagePayload?.body)
|
||||
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
|
||||
expect(core.setOutput).toHaveBeenCalledWith('comment-id', postIssueCommentsResponse.id)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ inputs:
|
|||
update-only:
|
||||
description: "Only update the comment if it already exists."
|
||||
required: false
|
||||
preformatted:
|
||||
description: "Treat message text (from a file or input) as pre-formatted and place it in a codeblock."
|
||||
required: false
|
||||
outputs:
|
||||
comment-created:
|
||||
description: "Whether a comment was created."
|
||||
|
|
|
|||
|
|
@ -1,27 +1,6 @@
|
|||
import * as core from '@actions/core'
|
||||
import * as github from '@actions/github'
|
||||
import { getMessageFromPaths } from './util'
|
||||
|
||||
interface Inputs {
|
||||
allowRepeats: boolean
|
||||
attachPath?: string[]
|
||||
commitSha: string
|
||||
issue?: number
|
||||
message?: string
|
||||
messageId: string
|
||||
messagePath?: string
|
||||
messageSuccess?: string
|
||||
messageFailure?: string
|
||||
messageCancelled?: string
|
||||
proxyUrl?: string
|
||||
pullRequestNumber?: number
|
||||
refreshMessagePosition: boolean
|
||||
repo: string
|
||||
repoToken: string
|
||||
status?: string
|
||||
owner: string
|
||||
updateOnly: boolean
|
||||
}
|
||||
import { Inputs } from './types'
|
||||
|
||||
export async function getInputs(): Promise<Inputs> {
|
||||
const messageIdInput = core.getInput('message-id', { required: false })
|
||||
|
|
@ -38,52 +17,31 @@ export async function getInputs(): Promise<Inputs> {
|
|||
const refreshMessagePosition =
|
||||
core.getInput('refresh-message-position', { required: false }) === 'true'
|
||||
const updateOnly = core.getInput('update-only', { required: false }) === 'true'
|
||||
const preformatted = core.getInput('preformatted', { required: false }) === 'true'
|
||||
|
||||
if (messageInput && messagePath) {
|
||||
throw new Error('must specify only one, message or message-path')
|
||||
}
|
||||
|
||||
let message
|
||||
|
||||
if (messagePath) {
|
||||
message = await getMessageFromPaths(messagePath)
|
||||
} else {
|
||||
message = messageInput
|
||||
}
|
||||
|
||||
const messageSuccess = core.getInput(`message-success`)
|
||||
const messageFailure = core.getInput(`message-failure`)
|
||||
const messageCancelled = core.getInput(`message-cancelled`)
|
||||
const messageSkipped = core.getInput(`message-skipped`)
|
||||
|
||||
if (status === 'success' && messageSuccess) {
|
||||
message = messageSuccess
|
||||
}
|
||||
|
||||
if (status === 'failure' && messageFailure) {
|
||||
message = messageFailure
|
||||
}
|
||||
|
||||
if (status === 'cancelled' && messageCancelled) {
|
||||
message = messageCancelled
|
||||
}
|
||||
|
||||
if (status === 'skipped' && messageSkipped) {
|
||||
message = messageSkipped
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
throw new Error('no message, check your message inputs')
|
||||
}
|
||||
|
||||
const { payload } = github.context
|
||||
|
||||
return {
|
||||
allowRepeats,
|
||||
commitSha: github.context.sha,
|
||||
issue: issue ? Number(issue) : payload.issue?.number,
|
||||
message,
|
||||
messageInput,
|
||||
messageId: `<!-- ${messageId} -->`,
|
||||
messageSuccess,
|
||||
messageFailure,
|
||||
messageCancelled,
|
||||
messageSkipped,
|
||||
messagePath,
|
||||
preformatted,
|
||||
proxyUrl,
|
||||
pullRequestNumber: payload.pull_request?.number,
|
||||
refreshMessagePosition,
|
||||
|
|
|
|||
|
|
@ -2,36 +2,13 @@ import * as core from '@actions/core'
|
|||
import * as glob from '@actions/glob'
|
||||
import fs from 'node:fs/promises'
|
||||
|
||||
export async function getMessageFromPaths(searchPath: string) {
|
||||
let message = ''
|
||||
|
||||
const files = await findFiles(searchPath)
|
||||
|
||||
for (const [index, path] of files.entries()) {
|
||||
if (index > 0) {
|
||||
message += '\n'
|
||||
}
|
||||
|
||||
message += await fs.readFile(path, { encoding: 'utf8' })
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
function getDefaultGlobOptions(): glob.GlobOptions {
|
||||
return {
|
||||
export async function findFiles(searchPath: string): Promise<string[]> {
|
||||
const searchResults: string[] = []
|
||||
const globber = await glob.create(searchPath, {
|
||||
followSymbolicLinks: true,
|
||||
implicitDescendants: true,
|
||||
omitBrokenSymbolicLinks: true,
|
||||
}
|
||||
}
|
||||
|
||||
export async function findFiles(
|
||||
searchPath: string,
|
||||
globOptions?: glob.GlobOptions,
|
||||
): Promise<string[]> {
|
||||
const searchResults: string[] = []
|
||||
const globber = await glob.create(searchPath, globOptions || getDefaultGlobOptions())
|
||||
})
|
||||
const rawSearchResults: string[] = await globber.glob()
|
||||
|
||||
for (const searchResult of rawSearchResults) {
|
||||
21
src/main.ts
21
src/main.ts
|
|
@ -9,13 +9,15 @@ import {
|
|||
} from './comments'
|
||||
import { getInputs } from './config'
|
||||
import { getIssueNumberFromCommitPullsList } from './issues'
|
||||
import { getMessage } from './message'
|
||||
import { createCommentProxy } from './proxy'
|
||||
|
||||
const run = async (): Promise<void> => {
|
||||
try {
|
||||
const {
|
||||
allowRepeats,
|
||||
message,
|
||||
messagePath,
|
||||
messageInput,
|
||||
messageId,
|
||||
refreshMessagePosition,
|
||||
repoToken,
|
||||
|
|
@ -26,10 +28,27 @@ const run = async (): Promise<void> => {
|
|||
repo,
|
||||
owner,
|
||||
updateOnly,
|
||||
messageCancelled,
|
||||
messageFailure,
|
||||
messageSuccess,
|
||||
messageSkipped,
|
||||
preformatted,
|
||||
status,
|
||||
} = await getInputs()
|
||||
|
||||
const octokit = github.getOctokit(repoToken)
|
||||
|
||||
const message = await getMessage({
|
||||
messagePath,
|
||||
messageInput,
|
||||
messageSkipped,
|
||||
messageCancelled,
|
||||
messageSuccess,
|
||||
messageFailure,
|
||||
preformatted,
|
||||
status,
|
||||
})
|
||||
|
||||
let issueNumber
|
||||
|
||||
if (issue) {
|
||||
|
|
|
|||
74
src/message.ts
Normal file
74
src/message.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import fs from 'node:fs/promises'
|
||||
import { findFiles } from './files'
|
||||
import { Inputs } from './types'
|
||||
|
||||
export async function getMessage({
|
||||
messageInput,
|
||||
messagePath,
|
||||
messageCancelled,
|
||||
messageSkipped,
|
||||
messageFailure,
|
||||
messageSuccess,
|
||||
preformatted,
|
||||
status,
|
||||
}: Pick<
|
||||
Inputs,
|
||||
| 'messageInput'
|
||||
| 'messageCancelled'
|
||||
| 'messageSuccess'
|
||||
| 'messageFailure'
|
||||
| 'messageSkipped'
|
||||
| 'messagePath'
|
||||
| 'preformatted'
|
||||
| 'status'
|
||||
>) {
|
||||
let message
|
||||
|
||||
if (status === 'success') {
|
||||
if (messageSuccess) {
|
||||
message = messageSuccess
|
||||
} else if (messagePath) {
|
||||
message = await getMessageFromPath(messagePath)
|
||||
} else {
|
||||
message = messageInput
|
||||
}
|
||||
}
|
||||
|
||||
if (status === 'failure' && messageFailure) {
|
||||
message = messageFailure
|
||||
}
|
||||
|
||||
if (status === 'cancelled' && messageCancelled) {
|
||||
message = messageCancelled
|
||||
}
|
||||
|
||||
if (status === 'skipped' && messageSkipped) {
|
||||
message = messageSkipped
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
throw new Error('no message, check your message inputs')
|
||||
}
|
||||
|
||||
if (preformatted) {
|
||||
message = `\`\`\`\n${message}\n\`\`\``
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
export async function getMessageFromPath(searchPath: string) {
|
||||
let message = ''
|
||||
|
||||
const files = await findFiles(searchPath)
|
||||
|
||||
for (const [index, path] of files.entries()) {
|
||||
if (index > 0) {
|
||||
message += '\n'
|
||||
}
|
||||
|
||||
message += await fs.readFile(path, { encoding: 'utf8' })
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
22
src/types.ts
Normal file
22
src/types.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export interface Inputs {
|
||||
allowRepeats: boolean
|
||||
attachPath?: string[]
|
||||
commitSha: string
|
||||
issue?: number
|
||||
messageInput?: string
|
||||
messageId: string
|
||||
messagePath?: string
|
||||
messageSuccess?: string
|
||||
messageFailure?: string
|
||||
messageCancelled?: string
|
||||
messageSkipped?: string
|
||||
preformatted: boolean
|
||||
proxyUrl?: string
|
||||
pullRequestNumber?: number
|
||||
refreshMessagePosition: boolean
|
||||
repo: string
|
||||
repoToken: string
|
||||
status: string
|
||||
owner: string
|
||||
updateOnly: boolean
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue