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

docs: plan-file download and tflint workflow examples #363

Merged
merged 97 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
587ae04
expand command input description
rdhar Dec 4, 2024
b0653ac
enforce command input for initial steps
rdhar Dec 4, 2024
e9cad00
as above
rdhar Dec 4, 2024
4f6afbf
limit tests
rdhar Dec 4, 2024
232400d
use placeholder hostname for gh cli
rdhar Dec 4, 2024
f114ccf
inputs.command description wording
rdhar Dec 4, 2024
a6c9ffe
test init only
rdhar Dec 4, 2024
7cd0738
empty command input
rdhar Dec 4, 2024
bfe64da
comment format and validate inputs as well
rdhar Dec 4, 2024
ec36bac
fallback for empty command input
rdhar Dec 4, 2024
2569865
add fallback for tf.console.txt
rdhar Dec 4, 2024
56fd23d
change fallback to touch empty file instead of passing default true v…
rdhar Dec 4, 2024
388dab4
revert fallback value and default values in place of selective comman…
rdhar Dec 4, 2024
b16d888
comment out command input altogether just to see what happens
rdhar Dec 4, 2024
dfff6a3
show plan-file artifact
rdhar Dec 4, 2024
24696aa
show "tfplan"
rdhar Dec 4, 2024
521f322
require tf init before tf show
rdhar Dec 4, 2024
daf9a8d
change dir
rdhar Dec 4, 2024
d631d0b
test without init, just to see what the error looks like
rdhar Dec 4, 2024
7e86333
comment in tf init again
rdhar Dec 4, 2024
7160e8c
grep planfile
rdhar Dec 4, 2024
6c7ef56
decrypt
rdhar Dec 4, 2024
6175d64
plan-encrypt
rdhar Dec 4, 2024
6c90325
check the basics
rdhar Dec 4, 2024
79b1f35
retry
rdhar Dec 4, 2024
d99c55b
change directory
rdhar Dec 4, 2024
f00e591
retry
rdhar Dec 4, 2024
f62e38a
decrypt
rdhar Dec 4, 2024
d7707b5
init plan-encrypt
rdhar Dec 4, 2024
19aecdd
show tfplan
rdhar Dec 4, 2024
35e12dd
output
rdhar Dec 4, 2024
517b7ad
comment out command input for kicks and giggles
rdhar Dec 4, 2024
d86c3d6
revert include command input init
rdhar Dec 4, 2024
93f6108
docs improve wording command input
rdhar Dec 5, 2024
5ac1f45
check apply job output
rdhar Dec 5, 2024
a31135b
check negative case
rdhar Dec 5, 2024
fac3e6b
echo diff_exists status
rdhar Dec 5, 2024
b6eeb96
retry
rdhar Dec 5, 2024
52fde72
output diff_exists value from step
rdhar Dec 5, 2024
fa81c36
test negative case
rdhar Dec 5, 2024
afc3f79
revert post-test
rdhar Dec 5, 2024
9410031
doc pr_push_stages example workflow for condition job stages
rdhar Dec 5, 2024
8ac3826
line breaks
rdhar Dec 5, 2024
283da61
line breaks
rdhar Dec 5, 2024
e11d82a
br
rdhar Dec 5, 2024
47dbcfa
br
rdhar Dec 5, 2024
196a35a
br
rdhar Dec 5, 2024
2309209
br
rdhar Dec 5, 2024
083d812
br clean
rdhar Dec 5, 2024
05fee56
bold
rdhar Dec 5, 2024
95a1010
plan file naming
rdhar Dec 5, 2024
3f5a36d
being tflint workflow example
rdhar Dec 5, 2024
d9d232d
draft pr_push_lint workflow
rdhar Dec 5, 2024
6b71787
code
rdhar Dec 5, 2024
ef9a7cc
dogfood pr_push_lint workflow
rdhar Dec 5, 2024
01dd838
test with tofu
rdhar Dec 5, 2024
bb97b9c
use terraform for simplicity
rdhar Dec 5, 2024
3d4d6c4
debug
rdhar Dec 5, 2024
4cfae0a
debug static string
rdhar Dec 5, 2024
73d83e2
more debug
rdhar Dec 5, 2024
3a8290b
test tflint stderr output
rdhar Dec 5, 2024
fc29989
now with tflint stdout
rdhar Dec 5, 2024
4177243
raw tflint error
rdhar Dec 5, 2024
a2fd5df
remove dquotes
rdhar Dec 5, 2024
91ef435
remove ticks
rdhar Dec 5, 2024
e0da273
re-introduce dquotes
rdhar Dec 5, 2024
71e8bc3
introduce heredoc
rdhar Dec 5, 2024
f1145ff
variable tflint output
rdhar Dec 5, 2024
8242e21
er
rdhar Dec 5, 2024
50117de
one backtick
rdhar Dec 5, 2024
8303c43
second backtick
rdhar Dec 5, 2024
09132b7
erm
rdhar Dec 5, 2024
1e4ce82
just tflint output by itself
rdhar Dec 5, 2024
d6cabc0
sub backtick for squote
rdhar Dec 5, 2024
d16aad4
sub backtick for dquote
rdhar Dec 5, 2024
c34ff71
heredoc
rdhar Dec 5, 2024
03dc50b
retry
rdhar Dec 5, 2024
2a47d48
re
rdhar Dec 5, 2024
c4728e0
um
rdhar Dec 5, 2024
58dca1e
re
rdhar Dec 5, 2024
29d84c3
backticks syntax highlighting
rdhar Dec 5, 2024
6562f4b
sheesh
rdhar Dec 5, 2024
356f7f7
what
rdhar Dec 5, 2024
2c513d6
er
rdhar Dec 5, 2024
f9af0b0
concise
rdhar Dec 5, 2024
939dc30
dquotes
rdhar Dec 5, 2024
869ffe0
remove braces
rdhar Dec 5, 2024
88fb64e
squotes
rdhar Dec 5, 2024
8b2c878
surround in parentheses
rdhar Dec 5, 2024
4346d46
dquotes
rdhar Dec 5, 2024
52e4a4e
separate
rdhar Dec 5, 2024
2c96d7a
compact
rdhar Dec 5, 2024
41574f4
dquotes instead of squotes
rdhar Dec 5, 2024
2426142
stderr or stdout
rdhar Dec 5, 2024
0caac8b
ready pr_push_lint
rdhar Dec 5, 2024
177b945
revert tf_tests
rdhar Dec 5, 2024
471c12b
ready merge
rdhar Dec 5, 2024
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
83 changes: 83 additions & 0 deletions .github/examples/pr_push_lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
name: Trigger on pull_request (plan) and push (apply) events with fmt/validate checks and TFLint.

on:
pull_request:
push:
branches: [main]

jobs:
tf:
runs-on: ubuntu-latest

permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add comment and label.

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup TF
uses: hashicorp/setup-terraform@v3

- name: Init TF
id: tf
if: ${{ github.event_name == 'pull_request' }}
uses: devsectop/tf-via-pr@v12
with:
command: init
arg-lock: false
working-directory: path/to/directory
format: true
validate: true

- name: Setup TFLint
if: ${{ github.event_name == 'pull_request' }}
uses: terraform-linters/setup-tflint@v4
with:
tflint_wrapper: true

- name: Run TFLint
id: tflint
if: ${{ github.event_name == 'pull_request' }}
working-directory: path/to/directory
run: |
tflint --init
tflint --format compact
continue-on-error: true

- name: Comment if TFLint errors
if: ${{ github.event_name == 'pull_request' && steps.tflint.outputs.exitcode != 0 }}
env:
GH_TOKEN: ${{ github.token }}
run: |
# Compose TFLint output.
tflint='${{ steps.tflint.outputs.stderr || steps.tflint.outputs.stdout }}'
tflint="<details><summary>TFLint error.</summary>
\`\`\`hcl
$(echo "$tflint" | sed 's/`/\\`/g')
\`\`\`
</details>"
# Get body of PR comment from tf step output.
comment=$(gh api /repos/{owner}/{repo}/issues/comments/${{ steps.tf.outputs.comment-id }} --method GET --jq '.body')
# Replace placeholder with TFLint output.
comment="${comment//<!-- placeholder-2 -->/$tflint}"
# Update PR comment combined with TFLint output.
gh api /repos/{owner}/{repo}/issues/comments/${{ steps.tf.outputs.comment-id }} --method PATCH --field body="$comment"
# Exit workflow due to TFLint error.
exit 1
- name: Provision TF
uses: devsectop/tf-via-pr@v12
with:
command: ${{ github.event_name == 'push' && 'apply' || 'plan' }}
arg-lock: ${{ github.event_name == 'push' }}
working-directory: path/to/directory
97 changes: 97 additions & 0 deletions .github/examples/pr_push_stages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
name: Trigger on pull_request (plan) and push (apply) events with conditional job stages based on plan file.

on:
pull_request:
push:
branches: [main]

permissions:
actions: read # Required to identify workflow run.
checks: write # Required to add status summary.
contents: read # Required to checkout repository.
pull-requests: write # Required to add comment and label.

jobs:
plan:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup TF
uses: hashicorp/setup-terraform@v3

- name: Plan TF
uses: devsectop/tf-via-pr@v12
with:
command: plan
working-directory: path/to/directory
plan-encrypt: ${{ secrets.PASSPHRASE }}

pre_apply:
if: github.event_name == 'push'
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup TF
uses: hashicorp/setup-terraform@v3

- name: Init TF
id: tf
uses: devsectop/tf-via-pr@v12
with:
command: init
working-directory: path/to/directory
comment-pr: none

- name: Check for diff
id: check
env:
GH_TOKEN: ${{ github.token }}
path: path/to/directory
plan: ${{ steps.tf.outputs.identifier }}
pass: ${{ secrets.PASSPHRASE }} # For use with "plan-encrypt".
run: |
echo "Download plan file artifact."
artifact_id=$(gh api /repos/{owner}/{repo}/actions/artifacts --method GET --field "name=$plan" --jq '.artifacts[0].id')
gh api /repos/{owner}/{repo}/actions/artifacts/${artifact_id}/zip --method GET > "$plan.zip"
unzip "$plan.zip" -d "$path"
cd "$path"
echo "Optionally decrypt plan file."
temp=$(mktemp)
printf "%s" "$pass" > "$temp"
openssl enc -aes-256-ctr -pbkdf2 -salt -in "tfplan" -out "tfplan.decrypted" -pass file:"$temp" -d
mv "tfplan.decrypted" "tfplan"
echo "Check if plan file has diff."
diff_exists=$(tofu show "tfplan" | grep -q "^Plan:" && echo "true" || echo "false")
echo "diff_exists=$diff_exists" >> $GITHUB_OUTPUT
outputs:
diff_exists: ${{ steps.check.outputs.diff_exists }}

apply:
needs: pre_apply
if: ${{ needs.pre_apply.outputs.diff_exists == 'true' }}
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup TF
uses: hashicorp/setup-terraform@v3

- name: Apply TF
uses: devsectop/tf-via-pr@v12
with:
command: apply
working-directory: path/to/directory
plan-encrypt: ${{ secrets.PASSPHRASE }}
6 changes: 2 additions & 4 deletions .github/examples/schedule_refresh.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Trigger on schedule (cron) event with fmt/validate checks to open an issue on configuration drift.
name: Trigger on schedule (cron) event with -refresh-only to open an issue on configuration drift.

on:
schedule:
Expand All @@ -23,7 +23,7 @@ jobs:
- name: Setup TF
uses: hashicorp/setup-terraform@v3

- name: Provision TF
- name: Plan TF
id: provision
uses: devsectop/tf-via-pr@v12
with:
Expand All @@ -32,8 +32,6 @@ jobs:
arg-refresh-only: true
working-directory: path/to/directory
plan-encrypt: ${{ secrets.PASSPHRASE }}
format: true
validate: true

- name: Open issue on drift
if: steps.provision.outputs.exitcode != 0
Expand Down
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,38 @@ The following workflows showcase common use cases, while a comprehensive list of
<table>
<tr>
<td>
<a href="/.github/examples/pr_push_auth.yaml">Run on</a> <code>pull_request</code> (plan) and <code>push</code> (apply) events with Terraform, AWS <strong>authentication</strong> and <strong>caching</strong>.
</br>
<a href="/.github/examples/pr_push_auth.yaml"><strong>Run on</strong></a> <code>pull_request</code> (plan) and <code>push</code> (apply) events with Terraform, AWS <strong>authentication</strong> and <strong>caching</strong>.
</br></br>
</td>
<td>
<a href="/.github/examples/pr_merge_matrix.yaml">Run on</a> <code>pull_request</code> (plan) and <code>merge_group</code> (apply) events with OpenTofu in <strong>matrix</strong> strategy.
</br>
<a href="/.github/examples/pr_merge_matrix.yaml"><strong>Run on</strong></a> <code>pull_request</code> (plan) and <code>merge_group</code> (apply) events with OpenTofu in <strong>matrix</strong> strategy.
</br></br>
</td>
</tr>
<tr>
<td>
<a href="/.github/examples/pr_self_hosted.yaml">Run on</a> <code>pull_request</code> (plan or apply) event with Terraform and OpenTofu on <strong>self-hosted</strong> runner.
</br>
<a href="/.github/examples/pr_push_stages.yaml"><strong>Run on</strong></a> <code>pull_request</code> (plan) and <code>push</code> (apply) events with <strong>conditional job stages</strong> based on plan file.
</br></br>
</td>
<td>
<a href="/.github/examples/schedule_refresh.yaml">Run on</a> <code>schedule</code> (cron) event with fmt/validate checks to open an issue on <strong>configuration drift</strong>.
</br>
<a href="/.github/examples/schedule_refresh.yaml"><strong>Run on</strong></a> <code>schedule</code> (cron) event with <code>-refresh-only</code> to open an issue on <strong>configuration drift</strong>.
</br></br>
</td>
</tr>
<tr>
<td>
</br>
<a href="/.github/examples/pr_push_lint.yaml"><strong>Run on</strong></a> <code>pull_request</code> (plan) and <code>push</code> (apply) events with <strong>fmt/validate checks</strong> and TFLint.
</br></br>
</td>
<td>
</br>
<a href="/.github/examples/pr_self_hosted.yaml"><strong>Run on</strong></a> <code>pull_request</code> (plan or apply) event with Terraform and OpenTofu on <strong>self-hosted</strong> runner.
</br></br>
</td>
</tr>
</table>
Expand Down Expand Up @@ -127,7 +147,7 @@ For each workflow run, a matrix-friendly job summary with logs is added as a fal

| Type | Name | Description |
| -------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| CLI | `command` | Command to run between: `plan`, `apply` or leave empty for `init` with checks.</br>Example: `plan` |
| CLI | `command` | Command to run between: `plan` or `apply`. Optionally `init` for checks and outputs only.</br>Example: `plan` |
| CLI | `working-directory` | Specify the working directory of TF code, alias of `arg-chdir`.</br>Example: `path/to/directory` |
| CLI | `tool` | Provisioning tool to use between: `terraform` or `tofu`.</br>Default: `terraform` |
| Check | `format` | Check format of TF code.</br>Default: `false` |
Expand Down
39 changes: 20 additions & 19 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ runs:
# Get PR number using different query methods for push, merge_group, and pull_request events.
if [[ "$GITHUB_EVENT_NAME" == "push" ]]; then
# List PRs associated with the commit, then get the PR number from the head ref or the latest PR.
associated_prs=$(gh api /repos/${GITHUB_REPOSITORY}/commits/${GITHUB_SHA}/pulls --header "$GH_API" --method GET --field per_page=100)
associated_prs=$(gh api /repos/{owner}/{repo}/commits/${GITHUB_SHA}/pulls --header "$GH_API" --method GET --field per_page=100)
pr_number=$(echo "$associated_prs" | jq --raw-output '(.[] | select(.head.ref == env.GITHUB_REF_NAME) | .number) // .[0].number // 0')
elif [[ "$GITHUB_EVENT_NAME" == "merge_group" ]]; then
# Get the PR number by parsing the ref name.
Expand All @@ -94,7 +94,7 @@ runs:
echo "name=${{ inputs.tool }}-${pr_number}-${identifier}.tfplan" >> "$GITHUB_OUTPUT"
# List jobs from the current workflow run.
workflow_run=$(gh api /repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}/jobs --header "$GH_API" --method GET --field per_page=100)
workflow_run=$(gh api /repos/{owner}/{repo}/actions/runs/${GITHUB_RUN_ID}/attempts/${GITHUB_RUN_ATTEMPT}/jobs --header "$GH_API" --method GET --field per_page=100)
# Get the current job ID from the workflow run using different query methods for matrix and regular jobs.
if [[ "$GH_MATRIX" == "null" ]]; then
Expand Down Expand Up @@ -122,7 +122,8 @@ runs:
echo "${{ inputs.tool }} fmt${{ steps.arg.outputs.arg-chdir }}${args}" | sed 's/ -/\n -/g' > tf.command.txt
${{ inputs.tool }}${{ steps.arg.outputs.arg-chdir }} fmt${args} 2> >(tee tf.console.txt) > >(tee tf.console.txt)
- id: initialize
- if: ${{ contains(fromJSON('["plan", "apply", "init"]'), inputs.command) }}
id: initialize
shell: bash
run: |
# TF initialize.
Expand All @@ -131,7 +132,7 @@ runs:
echo "${{ inputs.tool }} init${{ steps.arg.outputs.arg-chdir }}${args}" | sed 's/ -/\n -/g' > tf.command.txt
${{ inputs.tool }}${{ steps.arg.outputs.arg-chdir }} init${args} 2> >(tee tf.console.txt) > >(tee tf.console.txt)
- if: ${{ inputs.arg-workspace != '' }}
- if: ${{ inputs.arg-workspace != '' && contains(fromJSON('["plan", "apply", "init"]'), inputs.command) }}
id: workspace
shell: bash
run: |
Expand All @@ -141,7 +142,7 @@ runs:
echo "${{ inputs.tool }} workspace select${{ steps.arg.outputs.arg-chdir }}${args}" | sed 's/ -/\n -/g' > tf.command.txt
${{ inputs.tool }}${{ steps.arg.outputs.arg-chdir }} workspace select${args} 2> >(tee tf.console.txt) > >(tee tf.console.txt)
- if: ${{ inputs.validate == 'true' }}
- if: ${{ inputs.validate == 'true' && contains(fromJSON('["plan", "apply", "init"]'), inputs.command) }}
id: validate
shell: bash
run: |
Expand All @@ -151,15 +152,15 @@ runs:
echo "${{ inputs.tool }} validate${{ steps.arg.outputs.arg-chdir }}${args}" | sed 's/ -/\n -/g' > tf.command.txt
${{ inputs.tool }}${{ steps.arg.outputs.arg-chdir }} validate${args} 2> >(tee tf.console.txt) > >(tee tf.console.txt)
- if: ${{ inputs.label-pr == 'true' && steps.identifier.outputs.pr != 0 }}
- if: ${{ inputs.label-pr == 'true' && steps.identifier.outputs.pr != 0 && contains(fromJSON('["plan", "apply"]'), inputs.command) }}
continue-on-error: true
shell: bash
run: |
# Label PR.
# If the label does not exist, create it before adding it to the PR in the format 'tf:${{ inputs.command }}'.
gh api /repos/${GITHUB_REPOSITORY}/labels/tf:${{ inputs.command }} --header "$GH_API" --method GET || \
gh api /repos/${GITHUB_REPOSITORY}/labels --header "$GH_API" --method POST --field "name=tf:${{ inputs.command }}" --field "description=Pull requests that ${{ inputs.command }} TF code." --field "color=5C4EE5"
gh api /repos/${GITHUB_REPOSITORY}/issues/${{ steps.identifier.outputs.pr }}/labels --header "$GH_API" --method POST --field "labels[]=tf:${{ inputs.command }}"
gh api /repos/{owner}/{repo}/labels/tf:${{ inputs.command }} --header "$GH_API" --method GET || \
gh api /repos/{owner}/{repo}/labels --header "$GH_API" --method POST --field "name=tf:${{ inputs.command }}" --field "description=Pull requests that ${{ inputs.command }} TF code." --field "color=5C4EE5"
gh api /repos/{owner}/{repo}/issues/${{ steps.identifier.outputs.pr }}/labels --header "$GH_API" --method POST --field "labels[]=tf:${{ inputs.command }}"
- if: ${{ inputs.command == 'plan' }}
id: plan
Expand All @@ -177,8 +178,8 @@ runs:
run: |
# Download plan file.
# Get the artifact ID of the latest matching plan files for download.
artifact_id=$(gh api /repos/${GITHUB_REPOSITORY}/actions/artifacts --header "$GH_API" --method GET --field "name=${{ steps.identifier.outputs.name }}" --jq '.artifacts[0].id')
gh api /repos/${GITHUB_REPOSITORY}/actions/artifacts/${artifact_id}/zip --header "$GH_API" --method GET > "${{ steps.identifier.outputs.name }}.zip"
artifact_id=$(gh api /repos/{owner}/{repo}/actions/artifacts --header "$GH_API" --method GET --field "name=${{ steps.identifier.outputs.name }}" --jq '.artifacts[0].id')
gh api /repos/{owner}/{repo}/actions/artifacts/${artifact_id}/zip --header "$GH_API" --method GET > "${{ steps.identifier.outputs.name }}.zip"
# Unzip the plan file to the working directory, then clean up the zip file.
unzip "${{ steps.identifier.outputs.name }}.zip" -d "${{ inputs.arg-chdir || inputs.working-directory }}"
Expand Down Expand Up @@ -261,7 +262,7 @@ runs:
${{ inputs.tool }}${{ steps.arg.outputs.arg-chdir }} apply${args} 2> >(tee tf.console.txt) > >(tee tf.console.txt)
- id: post
if: ${{ !cancelled() && steps.identifier.outcome == 'success' }}
if: ${{ !cancelled() && steps.identifier.outcome == 'success' && contains(fromJSON('["plan", "apply", "init"]'), inputs.command) }}
shell: bash
run: |
# Post output.
Expand Down Expand Up @@ -301,7 +302,7 @@ runs:
if [[ "${{ steps.format.outcome }}" == "failure" ]]; then syntax="diff"; fi
# Add summary to the job status.
check_run=$(gh api /repos/${GITHUB_REPOSITORY}/check-runs/${{ steps.identifier.outputs.job }} --header "$GH_API" --method PATCH --field "output[title]=${summary}" --field "output[summary]=${summary}")
check_run=$(gh api /repos/{owner}/{repo}/check-runs/${{ steps.identifier.outputs.job }} --header "$GH_API" --method PATCH --field "output[title]=${summary}" --field "output[summary]=${summary}")
# From check_run, echo html_url.
check_url=$(echo "$check_run" | jq --raw-output '.html_url')
Expand Down Expand Up @@ -364,23 +365,23 @@ runs:
# Post PR comment per ${{ inputs.comment-pr }} and if the PR number is not 0.
if [[ "${{ inputs.comment-pr }}" != "none" && "${{ steps.identifier.outputs.pr }}" != "0" ]]; then
# Check if the PR contains a bot comment with the same identifier.
list_comments=$(gh api /repos/${GITHUB_REPOSITORY}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method GET --field per_page=100)
list_comments=$(gh api /repos/{owner}/{repo}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method GET --field per_page=100)
bot_comment=$(echo "$list_comments" | jq --raw-output --arg identifier "${{ steps.identifier.outputs.name }}" '.[] | select(.user.type == "Bot") | select(.body | contains($identifier)) | .id' | tail -n 1)
if [[ -n "$bot_comment" ]]; then
if [[ "${{ inputs.comment-pr }}" == "recreate" ]]; then
# Delete previous comment before posting a new one.
gh api /repos/${GITHUB_REPOSITORY}/issues/comments/${bot_comment} --header "$GH_API" --method DELETE
pr_comment=$(gh api /repos/${GITHUB_REPOSITORY}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method POST --field "body=${body}")
gh api /repos/{owner}/{repo}/issues/comments/${bot_comment} --header "$GH_API" --method DELETE
pr_comment=$(gh api /repos/{owner}/{repo}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method POST --field "body=${body}")
echo "comment_id=$(echo "$pr_comment" | jq --raw-output '.id')" >> "$GITHUB_OUTPUT"
elif [[ "${{ inputs.comment-pr }}" == "update" ]]; then
# Update existing comment.
pr_comment=$(gh api /repos/${GITHUB_REPOSITORY}/issues/comments/${bot_comment} --header "$GH_API" --method PATCH --field "body=${body}")
pr_comment=$(gh api /repos/{owner}/{repo}/issues/comments/${bot_comment} --header "$GH_API" --method PATCH --field "body=${body}")
echo "comment_id=$(echo "$pr_comment" | jq --raw-output '.id')" >> "$GITHUB_OUTPUT"
fi
else
# Post new comment.
pr_comment=$(gh api /repos/${GITHUB_REPOSITORY}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method POST --field "body=${body}")
pr_comment=$(gh api /repos/{owner}/{repo}/issues/${{ steps.identifier.outputs.pr }}/comments --header "$GH_API" --method POST --field "body=${body}")
echo "comment_id=$(echo "$pr_comment" | jq --raw-output '.id')" >> "$GITHUB_OUTPUT"
fi
fi
Expand Down Expand Up @@ -430,7 +431,7 @@ inputs:
# Action parameters.
command:
default: ""
description: "Command to run between: `plan`, `apply` or leave empty for `init` with checks (e.g., `plan`)."
description: "Command to run between: `plan` or `apply`. Optionally `init` for checks and outputs only (e.g., `plan`)."
required: false
comment-pr:
default: "update"
Expand Down
Loading