Multiline message-path and concatenation (#88)

This commit is contained in:
Michael Shick 2023-05-04 17:25:26 -04:00 committed by GitHub
parent a0c6c0cbf4
commit 4a541a260f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 249 additions and 54 deletions

1
.github/test/file-1.txt vendored Normal file
View file

@ -0,0 +1 @@
Hello

1
.github/test/file-2.txt vendored Normal file
View file

@ -0,0 +1 @@
Goodbye

BIN
.github/test/image.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View file

@ -62,7 +62,14 @@ jobs:
- uses: ./ - uses: ./
with: with:
message-id: path
message-path: |
.github/test/file-*.txt
- uses: ./
with:
message-id: text
message: | message: |
**Hello ${{ github.run_number }}** **Hello**
🌏 🌏
! !

View file

@ -1,6 +1,9 @@
# add-pr-comment # add-pr-comment
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --> <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-) [![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END --> <!-- ALL-CONTRIBUTORS-BADGE:END -->
A GitHub Action which adds a comment to a pull request's issue. A GitHub Action which adds a comment to a pull request's issue.
@ -65,25 +68,25 @@ jobs:
## Configuration options ## Configuration options
| Input | Location | Description | Required | Default | | Input | Location | Description | Required | Default |
|--------------------------|----------|------------------------------------------------------------------------------------------------------|----------|------------------------------------| | ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------- |
| message | with | The message you'd like displayed, supports Markdown and all valid Unicode characters. | maybe | | | message | with | The message you'd like displayed, supports Markdown and all valid Unicode characters. | maybe | |
| message-path | with | Path to a message you'd like displayed. Will be read and displayed just like a normal message. | maybe | | | message-path | with | Path to a message you'd like displayed. Will be read and displayed just like a normal message. Supports multi-line input and globs. Multiple messages will be concatenated. | maybe | |
| message-success | with | A message override, printed in case of success. | no | | | message-success | with | A message override, printed in case of success. | no | |
| message-failure | with | A message override, printed in case of failure. | no | | | message-failure | with | A message override, printed in case of failure. | no | |
| message-cancelled | with | A message override, printed in case of cancelled. | no | | | message-cancelled | with | A message override, printed in case of cancelled. | no | |
| message-skipped | with | A message override, printed in case of skipped. | no | | | message-skipped | with | A message override, printed in case of skipped. | no | |
| status | with | Required if you want to use message status overrides. | no | {{ job.status }} | | status | with | Required if you want to use message status overrides. | no | {{ job.status }} |
| repo-owner | with | Owner of the repo. | no | {{ github.repository_owner }} | | repo-owner | with | Owner of the repo. | no | {{ github.repository_owner }} |
| repo-name | with | Name of the repo. | no | {{ github.event.repository.name }} | | repo-name | with | Name of the repo. | no | {{ github.event.repository.name }} |
| repo-token | with | Valid GitHub token, either the temporary token GitHub provides or a personal access token. | no | {{ github.token }} | | repo-token | with | Valid GitHub token, either the temporary token GitHub provides or a personal access token. | no | {{ github.token }} |
| message-id | with | Message id to use when searching existing comments. If found, updates the existing (sticky comment). | no | | | message-id | with | Message id to use when searching existing comments. If found, updates the existing (sticky comment). | no | |
| refresh-message-position | with | Should the sticky message be the last one in the PR's feed. | no | false | | refresh-message-position | with | Should the sticky message be the last one in the PR's feed. | no | false |
| allow-repeats | with | Boolean flag to allow identical messages to be posted each time this action is run. | no | false | | allow-repeats | with | Boolean flag to allow identical messages to be posted each time this action is run. | no | false |
| proxy-url | with | String for your proxy service URL if you'd like this to work with fork-based PRs. | no | | | proxy-url | with | String for your proxy service URL if you'd like this to work with fork-based PRs. | no | |
| issue | with | Optional issue number override. | no | | | issue | with | Optional issue number override. | no | |
| update-only | with | Only update the comment if it already exists. | no | false | | 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 | | | GITHUB_TOKEN | env | Valid GitHub token, can alternatively be defined in the env. | no | |
## Advanced Uses ## Advanced Uses
@ -141,6 +144,31 @@ jobs:
Uh oh! Uh oh!
``` ```
### Multiple Message Files
Instead of directly setting the message you can also load a file with the text
of your message using `message-path`. `message-path` supports loading multiple
files and files on multiple lines, the contents of which will be concatenated.
**Example**
````yaml
on:
pull_request:
jobs:
pr:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: mshick/add-pr-comment@v2
if: always()
with:
message-path: |
message-part-*.txt
```
### Bring your own issues ### Bring your own issues
You can set an issue id explicitly. Helpful for cases where you want to post You can set an issue id explicitly. Helpful for cases where you want to post
@ -173,7 +201,7 @@ jobs:
issue: ${{ steps.pr.outputs.issue }} issue: ${{ steps.pr.outputs.issue }}
message: | message: |
**Howdie!** **Howdie!**
``` ````
## Contributors ✨ ## Contributors ✨

View file

@ -3,11 +3,16 @@ import * as github from '@actions/github'
import { WebhookPayload } from '@actions/github/lib/interfaces' import { WebhookPayload } from '@actions/github/lib/interfaces'
import { rest } from 'msw' import { rest } from 'msw'
import { setupServer } from 'msw/node' import { setupServer } from 'msw/node'
import * as fs from 'node:fs/promises'
import * as path from 'node:path' import * as path from 'node:path'
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import run from '../src/main' import run from '../src/main'
import apiResponse from './sample-pulls-api-response.json' import apiResponse from './sample-pulls-api-response.json'
const messagePath1Fixture = path.resolve(__dirname, './message-part-1.txt')
const messagePath1FixturePayload = await fs.readFile(messagePath1Fixture, 'utf-8')
const messagePath2Fixture = path.resolve(__dirname, './message-part-2.txt')
const repoToken = '12345' const repoToken = '12345'
const commitSha = 'abc123' const commitSha = 'abc123'
const simpleMessage = 'hello world' const simpleMessage = 'hello world'
@ -89,12 +94,19 @@ const handlers = [
const server = setupServer(...handlers) const server = setupServer(...handlers)
describe('add-pr-comment action', () => { describe('add-pr-comment action', () => {
beforeAll(() => server.listen({ onUnhandledRequest: 'error' })) beforeAll(() => {
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()) afterAll(() => server.close())
beforeEach(() => { beforeEach(() => {
inputs = { ...defaultInputs } inputs = { ...defaultInputs }
issueNumber = defaultIssueNumber issueNumber = defaultIssueNumber
messagePayload = undefined
vi.resetModules() vi.resetModules()
@ -141,17 +153,46 @@ describe('add-pr-comment action', () => {
it('creates a comment with a message-path', async () => { it('creates a comment with a message-path', async () => {
inputs.message = undefined inputs.message = undefined
inputs['message-path'] = path.resolve(__dirname, './message.txt') inputs['message-path'] = messagePath1Fixture
inputs['allow-repeats'] = 'true' inputs['allow-repeats'] = 'true'
await expect(run()).resolves.not.toThrow() await expect(run()).resolves.not.toThrow()
expect(`<!-- add-pr-comment:add-pr-comment -->\n\n${messagePath1FixturePayload}`).toEqual(
messagePayload?.body,
)
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
expect(core.setOutput).toHaveBeenCalledWith('comment-id', postIssueCommentsResponse.id)
})
it('creates a comment with multiple message-paths concatenated', async () => {
inputs.message = undefined
inputs['message-path'] = `${messagePath1Fixture}\n${messagePath2Fixture}`
inputs['allow-repeats'] = 'true'
await expect(run()).resolves.not.toThrow()
expect(
`<!-- add-pr-comment:add-pr-comment -->\n\n${messagePath1FixturePayload}\n${messagePath1FixturePayload}`,
).toEqual(messagePayload?.body)
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
expect(core.setOutput).toHaveBeenCalledWith('comment-id', postIssueCommentsResponse.id)
})
it('supports globs in message paths', async () => {
inputs.message = undefined
inputs['message-path'] = `${path.resolve(__dirname)}/message-part-*.txt`
inputs['allow-repeats'] = 'true'
await expect(run()).resolves.not.toThrow()
expect(
`<!-- add-pr-comment:add-pr-comment -->\n\n${messagePath1FixturePayload}\n${messagePath1FixturePayload}`,
).toEqual(messagePayload?.body)
expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true') expect(core.setOutput).toHaveBeenCalledWith('comment-created', 'true')
expect(core.setOutput).toHaveBeenCalledWith('comment-id', postIssueCommentsResponse.id) expect(core.setOutput).toHaveBeenCalledWith('comment-id', postIssueCommentsResponse.id)
}) })
it('fails when both message and message-path are defined', async () => { it('fails when both message and message-path are defined', async () => {
inputs.message = 'foobar' inputs.message = 'foobar'
inputs['message-path'] = path.resolve(__dirname, './message.txt') inputs['message-path'] = messagePath1Fixture
await expect(run()).resolves.not.toThrow() await expect(run()).resolves.not.toThrow()
expect(core.setFailed).toHaveBeenCalledWith('must specify only one, message or message-path') expect(core.setFailed).toHaveBeenCalledWith('must specify only one, message or message-path')

View file

@ -0,0 +1,7 @@
## [Preview link](https://antares-blog-staging-pr-${{ github.event.number }}.azurewebsites.net)
- Your changes have been deployed to the preview site. The preview site will update as you add more commits to this branch.
- The preview site shows any future-dated articles. Don't worry, if you are publishing a future-dated article, it will not show on the production site until the file's specified date.
- The preview link is shareable, but will be deleted when the pull request is merged or closed.
> *This is an automated message.*

View file

@ -5,7 +5,7 @@ inputs:
description: "The message to print." description: "The message to print."
required: false required: false
message-path: message-path:
description: "A path to a file to print as a message instead of a string." description: "A path or list of paths to a file to print as a message instead of a string."
required: false required: false
message-id: message-id:
description: "An optional id to use for this message." description: "An optional id to use for this message."

70
package-lock.json generated
View file

@ -9,8 +9,10 @@
"version": "2.4.0", "version": "2.4.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/artifact": "^1.1.1",
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
"@actions/github": "^5.1.1", "@actions/github": "^5.1.1",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.1.0" "@actions/http-client": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
@ -38,6 +40,28 @@
"node": "^14.15.0 || ^16.13.0 || ^18.0.0" "node": "^14.15.0 || ^16.13.0 || ^18.0.0"
} }
}, },
"node_modules/@actions/artifact": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-1.1.1.tgz",
"integrity": "sha512-Vv4y0EW0ptEkU+Pjs5RGS/0EryTvI6s79LjSV9Gg/h+O3H/ddpjhuX/Bi/HZE4pbNPyjGtQjbdFWphkZhmgabA==",
"dependencies": {
"@actions/core": "^1.9.1",
"@actions/http-client": "^2.0.1",
"tmp": "^0.2.1",
"tmp-promise": "^3.0.2"
}
},
"node_modules/@actions/artifact/node_modules/tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
"dependencies": {
"rimraf": "^3.0.0"
},
"engines": {
"node": ">=8.17.0"
}
},
"node_modules/@actions/core": { "node_modules/@actions/core": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
@ -58,6 +82,15 @@
"@octokit/plugin-rest-endpoint-methods": "^5.13.0" "@octokit/plugin-rest-endpoint-methods": "^5.13.0"
} }
}, },
"node_modules/@actions/glob": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.4.0.tgz",
"integrity": "sha512-+eKIGFhsFa4EBwaf/GMyzCdWrXWymGXfFmZU3FHQvYS8mPcHtTtZONbkcqqUMzw9mJ/pImEBFET1JNifhqGsAQ==",
"dependencies": {
"@actions/core": "^1.9.1",
"minimatch": "^3.0.4"
}
},
"node_modules/@actions/http-client": { "node_modules/@actions/http-client": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.0.tgz",
@ -1799,8 +1832,7 @@
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
"dev": true
}, },
"node_modules/base64-js": { "node_modules/base64-js": {
"version": "1.5.1", "version": "1.5.1",
@ -1879,7 +1911,6 @@
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -2405,8 +2436,7 @@
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
"dev": true
}, },
"node_modules/concordance": { "node_modules/concordance": {
"version": "5.0.4", "version": "5.0.4",
@ -3753,8 +3783,7 @@
"node_modules/fs.realpath": { "node_modules/fs.realpath": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
"dev": true
}, },
"node_modules/fsevents": { "node_modules/fsevents": {
"version": "2.3.2", "version": "2.3.2",
@ -3891,7 +3920,6 @@
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"dependencies": { "dependencies": {
"fs.realpath": "^1.0.0", "fs.realpath": "^1.0.0",
"inflight": "^1.0.4", "inflight": "^1.0.4",
@ -4427,7 +4455,6 @@
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"dependencies": { "dependencies": {
"once": "^1.3.0", "once": "^1.3.0",
"wrappy": "1" "wrappy": "1"
@ -4436,8 +4463,7 @@
"node_modules/inherits": { "node_modules/inherits": {
"version": "2.0.4", "version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"dev": true
}, },
"node_modules/ini": { "node_modules/ini": {
"version": "1.3.7", "version": "1.3.7",
@ -7483,7 +7509,6 @@
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
}, },
@ -8921,7 +8946,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true,
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
@ -9618,7 +9642,6 @@
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
"dev": true,
"dependencies": { "dependencies": {
"glob": "^7.1.3" "glob": "^7.1.3"
}, },
@ -10312,6 +10335,25 @@
"node": ">=0.6.0" "node": ">=0.6.0"
} }
}, },
"node_modules/tmp-promise": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
"integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
"dependencies": {
"tmp": "^0.2.0"
}
},
"node_modules/tmp-promise/node_modules/tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
"dependencies": {
"rimraf": "^3.0.0"
},
"engines": {
"node": ">=8.17.0"
}
},
"node_modules/to-readable-stream": { "node_modules/to-readable-stream": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz",

View file

@ -74,6 +74,23 @@
"@typescript-eslint/no-explicit-any": "off" "@typescript-eslint/no-explicit-any": "off"
} }
}, },
{
"files": [
"**/*.test.ts"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"extends": [
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "off"
}
},
{ {
"files": [ "files": [
"*.json" "*.json"
@ -103,8 +120,10 @@
"dist" "dist"
], ],
"dependencies": { "dependencies": {
"@actions/artifact": "^1.1.1",
"@actions/core": "^1.10.0", "@actions/core": "^1.10.0",
"@actions/github": "^5.1.1", "@actions/github": "^5.1.1",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.1.0" "@actions/http-client": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,10 +1,12 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import * as github from '@actions/github' import * as github from '@actions/github'
import fs from 'node:fs/promises' import { getMessageFromPaths } from './util'
interface Inputs { interface Inputs {
refreshMessagePosition: boolean
allowRepeats: boolean allowRepeats: boolean
attachPath?: string[]
commitSha: string
issue?: number
message?: string message?: string
messageId: string messageId: string
messagePath?: string messagePath?: string
@ -12,12 +14,11 @@ interface Inputs {
messageFailure?: string messageFailure?: string
messageCancelled?: string messageCancelled?: string
proxyUrl?: string proxyUrl?: string
pullRequestNumber?: number
refreshMessagePosition: boolean
repo: string
repoToken: string repoToken: string
status?: string status?: string
issue?: number
commitSha: string
pullRequestNumber?: number
repo: string
owner: string owner: string
updateOnly: boolean updateOnly: boolean
} }
@ -38,14 +39,14 @@ export async function getInputs(): Promise<Inputs> {
core.getInput('refresh-message-position', { required: false }) === 'true' core.getInput('refresh-message-position', { required: false }) === 'true'
const updateOnly = core.getInput('update-only', { required: false }) === 'true' const updateOnly = core.getInput('update-only', { required: false }) === 'true'
if (messageInput && messagePath) { if (messageInput && messagePath.length) {
throw new Error('must specify only one, message or message-path') throw new Error('must specify only one, message or message-path')
} }
let message let message
if (messagePath) { if (messagePath.length) {
message = await fs.readFile(messagePath, { encoding: 'utf8' }) message = await getMessageFromPaths(messagePath)
} else { } else {
message = messageInput message = messageInput
} }
@ -78,16 +79,16 @@ export async function getInputs(): Promise<Inputs> {
const { payload } = github.context const { payload } = github.context
return { return {
refreshMessagePosition,
allowRepeats, allowRepeats,
commitSha: github.context.sha,
issue: issue ? Number(issue) : payload.issue?.number,
message, message,
messageId: `<!-- ${messageId} -->`, messageId: `<!-- ${messageId} -->`,
proxyUrl, proxyUrl,
pullRequestNumber: payload.pull_request?.number,
refreshMessagePosition,
repoToken, repoToken,
status, status,
issue: issue ? Number(issue) : payload.issue?.number,
pullRequestNumber: payload.pull_request?.number,
commitSha: github.context.sha,
owner: repoOwner || payload.repo.owner, owner: repoOwner || payload.repo.owner,
repo: repoName || payload.repo.repo, repo: repoName || payload.repo.repo,
updateOnly: updateOnly, updateOnly: updateOnly,

48
src/util.ts Normal file
View file

@ -0,0 +1,48 @@
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 {
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) {
const fileStats = await fs.stat(searchResult)
if (!fileStats.isDirectory()) {
core.debug(`File: ${searchResult} was found using the provided searchPath`)
searchResults.push(searchResult)
} else {
core.debug(`Removing ${searchResult} from rawSearchResults because it is a directory`)
}
}
return searchResults
}

View file

@ -12,7 +12,7 @@
"removeComments": false, "removeComments": false,
"preserveConstEnums": true, "preserveConstEnums": true,
"resolveJsonModule": true, "resolveJsonModule": true,
"rootDir": "./src", "rootDir": "src",
"outDir": "./lib" "outDir": "./lib"
}, },
"exclude": ["node_modules", "**/*.test.ts"] "exclude": ["node_modules", "**/*.test.ts"]