Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 25 additions & 0 deletions .github/actions/github-actions.check-jsonschema/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ inputs:
target_dir:
required: false
description: "(Optional) The directory to validate. Defaults to `.github/workflows` for `schema_type: workflows` and to `.github/actions` for `schema_type: actions`."
annotations_enabled:
required: false
default: "true"
description: "(Optional) Whether to annotate the failing files in the pull request when the validation fails, by re-running `check-jsonschema` with `--output-format json`. Schema validation reports no line numbers, so the annotation points at the file and names the failing JSON path. Defaults to `true`."

outputs:
skipped:
Expand Down Expand Up @@ -94,6 +98,27 @@ runs:
readarray -t files <<< "$FILES"
check-jsonschema --builtin-schema "$SCHEMA" "${files[@]}"

# GitHub only renders annotations from `::error` lines, so the errors are re-read as JSON. The file names are
# the ones passed in, which are repository-relative already.
- name: Annotate Findings
id: validate-annotate
if: always() && inputs.annotations_enabled == 'true' && steps.validate.outcome == 'failure'
shell: bash
env:
SCHEMA_TYPE: ${{ inputs.schema_type }}
SCHEMA: ${{ steps.target.outputs.schema }}
FILES: ${{ steps.target.outputs.files }}
run: |
# A workflow command takes one line, so newlines and the property separators are percent-encoded the way
# the runner decodes them.
readarray -t files <<< "$FILES"
check-jsonschema --builtin-schema "$SCHEMA" --output-format json "${files[@]}" 2>/dev/null | jq -r --arg type "$SCHEMA_TYPE" '
def esc: gsub("%"; "%25") | gsub("\r"; "%0D") | gsub("\n"; "%0A");
def prop: esc | gsub(":"; "%3A") | gsub(","; "%2C");
(.errors // [])[]
| "::error file=\(.filename),title=\("check-jsonschema · " + $type | prop)::\(.path + ": " + .message | esc)"
' || true

- name: Add Failure Details to Job Summary
id: validate-summary
if: always() && steps.validate.outcome == 'failure'
Expand Down
22 changes: 22 additions & 0 deletions .github/actions/terraform.docs/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ inputs:
args:
required: false
description: "(Optional) Additional arguments to pass to `terraform-docs` (e.g. `--sort-by required`)."
annotations_enabled:
required: false
default: "true"
description: "(Optional) Whether to annotate the out-of-date documentation file in the pull request when the check fails. Only applies with `check: true`. Defaults to `true`."

outputs:
skipped:
Expand Down Expand Up @@ -136,6 +140,24 @@ runs:

terraform-docs "${args[@]}" .

# `terraform-docs` names the stale file (`Error: <path> is out of date`), relative to the module it ran in.
- name: Annotate Findings
id: docs-annotate
if: always() && inputs.annotations_enabled == 'true' && inputs.check == 'true' && steps.docs.outcome == 'failure'
shell: bash
env:
TARGET_DIR: ${{ steps.target.outputs.target_dir }}
LOG_FILE: ${{ steps.docs.outputs.log_file }}
run: |
prefix=""
if [ "$TARGET_DIR" != "." ]; then
prefix="$TARGET_DIR/"
fi

sed -n 's/^Error: \(.*\) is out of date$/\1/p' "$LOG_FILE" | while IFS= read -r file; do
echo "::error file=$prefix$file,title=terraform-docs · Out of date::Regenerate this file with \`terraform-docs\`."
done

- name: Add Failure Details to Job Summary
id: docs-summary
if: always() && steps.docs.outcome == 'failure'
Expand Down
27 changes: 27 additions & 0 deletions .github/actions/terraform.fmt/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ inputs:
required: false
default: "true"
description: "(Optional) Whether to also check subdirectories. Defaults to `true`."
annotations_enabled:
required: false
default: "true"
description: "(Optional) Whether to annotate the unformatted lines in the pull request when `terraform fmt` fails, from the hunks of the diff it printed. Defaults to `true`."

outputs:
skipped:
Expand Down Expand Up @@ -66,6 +70,29 @@ runs:

terraform -chdir="$TARGET_DIR" fmt "${args[@]}"

# The diff already names each file (`+++ new/<file>`) and the first line of every hunk (`@@ -a,b +c,d @@`), so
# the annotations are read from the captured output. Paths are relative to `target_dir`.
- name: Annotate Findings
id: fmt-annotate
if: always() && inputs.annotations_enabled == 'true' && steps.fmt.outcome == 'failure'
shell: bash
env:
TARGET_DIR: ${{ steps.target.outputs.target_dir }}
LOG_FILE: ${{ steps.fmt.outputs.log_file }}
run: |
prefix=""
if [ "$TARGET_DIR" != "." ]; then
prefix="$TARGET_DIR/"
fi

awk -v prefix="$prefix" '
/^\+\+\+ new\// { file = substr($0, 9); next }
/^@@ / && file != "" {
line = $3; sub(/^\+/, "", line); sub(/,.*/, "", line)
printf "::error file=%s%s,line=%s,title=terraform fmt · Not formatted::Run `terraform fmt` to format this file.\n", prefix, file, line
}
' "$LOG_FILE"

- name: Add Failure Details to Job Summary
id: fmt-summary
if: always() && steps.fmt.outcome == 'failure'
Expand Down
Loading