Pre-Commit workflow (terraform-aws-modules/terraform-aws-notify-slack)
The Pre-Commit workflow from terraform-aws-modules/terraform-aws-notify-slack, explained and optimized by Latchkey.
CI health: C - fair
Point runs-on at Latchkey and get run de-duplication, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.
What it does
This is the Pre-Commit workflow from the terraform-aws-modules/terraform-aws-notify-slack repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.
Below, Latchkey shows a faster, safer version produced by its optimization engine.
The workflow
name: Pre-Commit
on:
pull_request:
branches:
- main
- master
env:
TERRAFORM_DOCS_VERSION: v0.20.0
TFLINT_VERSION: v0.59.1
jobs:
collectInputs:
name: Collect workflow inputs
runs-on: ubuntu-latest
outputs:
directories: ${{ steps.dirs.outputs.directories }}
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Get root directories
id: dirs
uses: clowdhaus/terraform-composite-actions/directories@v1.14.0
preCommitMinVersions:
name: Min TF pre-commit
needs: collectInputs
runs-on: ubuntu-latest
strategy:
matrix:
directory: ${{ fromJson(needs.collectInputs.outputs.directories) }}
steps:
- name: Install rmz
uses: jaxxstorm/action-install-gh-release@v2.1.0
with:
repo: SUPERCILEX/fuc
asset-name: x86_64-unknown-linux-gnu-rmz
rename-to: rmz
chmod: 0755
extension-matching: disable
# https://github.com/orgs/community/discussions/25678#discussioncomment-5242449
- name: Delete unnecessary files
run: |
formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); }
BEFORE=$(getAvailableSpace)
ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz
rmz -f /opt/hostedtoolcache/CodeQL &
rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk &
rmz -f /opt/hostedtoolcache/PyPy &
rmz -f /opt/hostedtoolcache/Ruby &
rmz -f /opt/hostedtoolcache/go &
wait
AFTER=$(getAvailableSpace)
SAVED=$((AFTER-BEFORE))
echo "=> Saved $(formatByteCount $SAVED)"
- name: Checkout
uses: actions/checkout@v5
- name: Terraform min/max versions
id: minMax
uses: clowdhaus/terraform-min-max@v2.1.0
with:
directory: ${{ matrix.directory }}
- name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }}
# Run only validate pre-commit check on min version supported
if: ${{ matrix.directory != '.' }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.minVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*'
- name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }}
# Run only validate pre-commit check on min version supported
if: ${{ matrix.directory == '.' }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.minVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)'
preCommitMaxVersion:
name: Max TF pre-commit
runs-on: ubuntu-latest
needs: collectInputs
steps:
- name: Install rmz
uses: jaxxstorm/action-install-gh-release@v2.1.0
with:
repo: SUPERCILEX/fuc
asset-name: x86_64-unknown-linux-gnu-rmz
rename-to: rmz
chmod: 0755
extension-matching: disable
# https://github.com/orgs/community/discussions/25678#discussioncomment-5242449
- name: Delete unnecessary files
run: |
formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); }
getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); }
BEFORE=$(getAvailableSpace)
ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz
rmz -f /opt/hostedtoolcache/CodeQL &
rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk &
rmz -f /opt/hostedtoolcache/PyPy &
rmz -f /opt/hostedtoolcache/Ruby &
rmz -f /opt/hostedtoolcache/go &
sudo rmz -f /usr/local/lib/android &
if [[ ${{ github.repository }} == terraform-aws-modules/terraform-aws-security-group ]]; then
sudo rmz -f /usr/share/dotnet &
sudo rmz -f /usr/local/.ghcup &
sudo apt-get -qq remove -y 'azure-.*'
sudo apt-get -qq remove -y 'cpp-.*'
sudo apt-get -qq remove -y 'dotnet-runtime-.*'
sudo apt-get -qq remove -y 'google-.*'
sudo apt-get -qq remove -y 'libclang-.*'
sudo apt-get -qq remove -y 'libllvm.*'
sudo apt-get -qq remove -y 'llvm-.*'
sudo apt-get -qq remove -y 'mysql-.*'
sudo apt-get -qq remove -y 'postgresql-.*'
sudo apt-get -qq remove -y 'php.*'
sudo apt-get -qq remove -y 'temurin-.*'
sudo apt-get -qq remove -y kubectl firefox mono-devel
sudo apt-get -qq autoremove -y
sudo apt-get -qq clean
fi
wait
AFTER=$(getAvailableSpace)
SAVED=$((AFTER-BEFORE))
echo "=> Saved $(formatByteCount $SAVED)"
- name: Checkout
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{github.event.pull_request.head.repo.full_name}}
- name: Terraform min/max versions
id: minMax
uses: clowdhaus/terraform-min-max@v2.1.0
- name: Hide template dir
# Special to this repo, we don't want to check this dir
if: ${{ github.repository == 'terraform-aws-modules/terraform-aws-security-group' }}
run: rm -rf modules/_templates
- name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }}
uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0
with:
terraform-version: ${{ steps.minMax.outputs.maxVersion }}
tflint-version: ${{ env.TFLINT_VERSION }}
terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }}
install-hcledit: true
The same workflow, on Latchkey
Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.
name: Pre-Commit on: pull_request: branches: - main - master env: TERRAFORM_DOCS_VERSION: v0.20.0 TFLINT_VERSION: v0.59.1 concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: collectInputs: timeout-minutes: 30 name: Collect workflow inputs runs-on: latchkey-small outputs: directories: ${{ steps.dirs.outputs.directories }} steps: - name: Checkout uses: actions/checkout@v5 - name: Get root directories id: dirs uses: clowdhaus/terraform-composite-actions/directories@v1.14.0 preCommitMinVersions: timeout-minutes: 30 name: Min TF pre-commit needs: collectInputs runs-on: latchkey-small strategy: matrix: directory: ${{ fromJson(needs.collectInputs.outputs.directories) }} steps: - name: Install rmz uses: jaxxstorm/action-install-gh-release@v2.1.0 with: repo: SUPERCILEX/fuc asset-name: x86_64-unknown-linux-gnu-rmz rename-to: rmz chmod: 0755 extension-matching: disable # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 - name: Delete unnecessary files run: | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } BEFORE=$(getAvailableSpace) ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz rmz -f /opt/hostedtoolcache/CodeQL & rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & rmz -f /opt/hostedtoolcache/PyPy & rmz -f /opt/hostedtoolcache/Ruby & rmz -f /opt/hostedtoolcache/go & wait AFTER=$(getAvailableSpace) SAVED=$((AFTER-BEFORE)) echo "=> Saved $(formatByteCount $SAVED)" - name: Checkout uses: actions/checkout@v5 - name: Terraform min/max versions id: minMax uses: clowdhaus/terraform-min-max@v2.1.0 with: directory: ${{ matrix.directory }} - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} # Run only validate pre-commit check on min version supported if: ${{ matrix.directory != '.' }} uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 with: terraform-version: ${{ steps.minMax.outputs.minVersion }} tflint-version: ${{ env.TFLINT_VERSION }} args: 'terraform_validate --color=always --show-diff-on-failure --files ${{ matrix.directory }}/*' - name: Pre-commit Terraform ${{ steps.minMax.outputs.minVersion }} # Run only validate pre-commit check on min version supported if: ${{ matrix.directory == '.' }} uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 with: terraform-version: ${{ steps.minMax.outputs.minVersion }} tflint-version: ${{ env.TFLINT_VERSION }} args: 'terraform_validate --color=always --show-diff-on-failure --files $(ls *.tf)' preCommitMaxVersion: timeout-minutes: 30 name: Max TF pre-commit runs-on: latchkey-small needs: collectInputs steps: - name: Install rmz uses: jaxxstorm/action-install-gh-release@v2.1.0 with: repo: SUPERCILEX/fuc asset-name: x86_64-unknown-linux-gnu-rmz rename-to: rmz chmod: 0755 extension-matching: disable # https://github.com/orgs/community/discussions/25678#discussioncomment-5242449 - name: Delete unnecessary files run: | formatByteCount() { echo $(numfmt --to=iec-i --suffix=B --padding=7 $1'000'); } getAvailableSpace() { echo $(df -a $1 | awk 'NR > 1 {avail+=$4} END {print avail}'); } BEFORE=$(getAvailableSpace) ln -s /opt/hostedtoolcache/SUPERCILEX/x86_64-unknown-linux-gnu-rmz/latest/linux-x64/rmz /usr/local/bin/rmz rmz -f /opt/hostedtoolcache/CodeQL & rmz -f /opt/hostedtoolcache/Java_Temurin-Hotspot_jdk & rmz -f /opt/hostedtoolcache/PyPy & rmz -f /opt/hostedtoolcache/Ruby & rmz -f /opt/hostedtoolcache/go & sudo rmz -f /usr/local/lib/android & if [[ ${{ github.repository }} == terraform-aws-modules/terraform-aws-security-group ]]; then sudo rmz -f /usr/share/dotnet & sudo rmz -f /usr/local/.ghcup & sudo apt-get -qq remove -y 'azure-.*' sudo apt-get -qq remove -y 'cpp-.*' sudo apt-get -qq remove -y 'dotnet-runtime-.*' sudo apt-get -qq remove -y 'google-.*' sudo apt-get -qq remove -y 'libclang-.*' sudo apt-get -qq remove -y 'libllvm.*' sudo apt-get -qq remove -y 'llvm-.*' sudo apt-get -qq remove -y 'mysql-.*' sudo apt-get -qq remove -y 'postgresql-.*' sudo apt-get -qq remove -y 'php.*' sudo apt-get -qq remove -y 'temurin-.*' sudo apt-get -qq remove -y kubectl firefox mono-devel sudo apt-get -qq autoremove -y sudo apt-get -qq clean fi wait AFTER=$(getAvailableSpace) SAVED=$((AFTER-BEFORE)) echo "=> Saved $(formatByteCount $SAVED)" - name: Checkout uses: actions/checkout@v5 with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{github.event.pull_request.head.repo.full_name}} - name: Terraform min/max versions id: minMax uses: clowdhaus/terraform-min-max@v2.1.0 - name: Hide template dir # Special to this repo, we don't want to check this dir if: ${{ github.repository == 'terraform-aws-modules/terraform-aws-security-group' }} run: rm -rf modules/_templates - name: Pre-commit Terraform ${{ steps.minMax.outputs.maxVersion }} uses: clowdhaus/terraform-composite-actions/pre-commit@v1.14.0 with: terraform-version: ${{ steps.minMax.outputs.maxVersion }} tflint-version: ${{ env.TFLINT_VERSION }} terraform-docs-version: ${{ env.TERRAFORM_DOCS_VERSION }} install-hcledit: true
What changed
- Run on Latchkey managed runners with one line (
runs-on), which apply the fixes below automatically and self-heal transient failures. This example useslatchkey-small; pick the runner size that fits the job. - Cancel superseded runs when a branch or PR gets a newer push.
- Add a job timeout so a hung step cannot burn hours of runner time.
3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.
What Latchkey heals here
This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:
- Dependency installs
This workflow runs 3 jobs per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.