Github Action for PR comment with command output on exit status
Here’s a Github Action that runs a given bash command, captures the stdout and strderr output, and posts a comment with the output back to the PR if the command has a non-zero exit status.
This is useful for running check commands such as linters against a PR, and making a PR comment with the linter output if there are linting errors.
name: Command & Comment
description: Run a bash command and comment failure output back to PR
inputs:
identifier:
description: Single word identifier for the check command
required: true
bash_command:
description: Bash command to run and comment from
required: true
runs:
using: "composite"
steps:
- uses: ./.github/actions/job_url
id: job_url
with:
step_name: ${{inputs.identifier}}
- id: check_command
name: ${{inputs.identifier}}
shell: bash
run: |
set +e
echo "COMMAND_OUT<<EOF" | tee "$GITHUB_OUTPUT"
${{inputs.bash_command}} 2>&1 | sed 's/$/\\n/g' | tr -d '\n' | tee -a "$GITHUB_OUTPUT" ; COMMAND_STATUS=$?
( echo ; echo "EOF" ) | tee -a "$GITHUB_OUTPUT"
exit $COMMAND_STATUS
- name: Remove previous command comments
uses: ./.github/actions/remove_comments
if: always()
with:
identifier: ${{inputs.identifier}}
- name: PR comment command failure
uses: actions/github-script@v7
if: always() && steps.check_command.outcome == 'failure'
with:
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '[${{inputs.identifier}}](${{steps.job_url.outputs.job_url}})\n\n```\n${{steps.check_command.outputs.COMMAND_OUT}}```'
})
Note that this uses separate actions to get the job URL and to remove previous PR comments.
The bash step to run the given command and capture the output and exit status looks like this:
set +e
echo "COMMAND_OUT<<EOF" | tee "$GITHUB_OUTPUT"
${{inputs.bash_command}} 2>&1 | sed 's/$/\\n/g' | tr -d '\n' | tee -a "$GITHUB_OUTPUT" ; COMMAND_STATUS=$?
( echo ; echo "EOF" ) | tee -a "$GITHUB_OUTPUT"
That is subsequently picked up in a Github Script step that posts a PR comment with the job URL and the failed command output in a Markdown block:
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '[${{inputs.identifier}}](${{steps.job_url.outputs.job_url}})\n\n```\n${{steps.check_command.outputs.COMMAND_OUT}}```'
})
You can use this command-and-comment action like this:
# ...
jobs:
isort:
name: isort
description: Run isort check and post output on failure
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/command_comment
id: isort
with:
identifier: isort
bash_command: isort . --check