.github/.github/workflows/ci-terraform.yaml
Adam Moussa 47185fa602
Some checks failed
ci / ci / ci (push) Has been cancelled
Release on reusable change / version (push) Has been cancelled
Release on reusable change / release (push) Has been cancelled
ci(terraform): fail mixed app and Terraform changes (#157)
* ci(terraform): fail mixed app and Terraform changes

* fix(ci): count deletions and honor the Terraform working directory

Deleted paths were excluded from the isolation diff, so a mixed change could pass. The checker now treats working-directory as the Terraform prefix.

* fix(ci): load the isolation checker from this workflow's commit

The second checkout used the caller's SHA and the caller's token, so a private clone of this repo could not resolve the script. The checker is now a composite action referenced with $/.
2026-10-02 00:54:43 +00:00

86 lines
2.9 KiB
YAML

name: CI — Terraform
# Reusable Terraform fmt/init/validate for HCP app repos. Init uses
# `-backend=false` so CI does not need remote state credentials. The caller
# owns the `ci-complete` aggregator.
#
# Caller example:
# jobs:
# terraform:
# uses: Sea-Haven-Industries/.github/.github/workflows/ci-terraform.yaml@<sha> # vX.Y.Z
# with:
# terraform-version: "1.16.0"
# app-paths: |
# src/
# package.json
# package-lock.json
#
# app-paths is optional. Empty skips isolation and leaves fmt/init/validate
# unchanged. A trailing slash is a directory prefix. Any other line is an
# exact file. pull_request classifies the merge-base of the base SHA to HEAD.
# merge_group classifies each first-parent commit against its parent, so a
# Terraform-only PR stacked with an app-only PR still passes. The classified
# diff includes deletions. Terraform paths are those under working-directory.
# The checker is a composite action in this repository. `$/` resolves that
# action at this workflow's commit, so callers do not clone this private
# repository with their GITHUB_TOKEN.
on:
workflow_call:
inputs:
terraform-version:
description: "Terraform version to install"
type: string
default: "1.16.0"
working-directory:
description: "Directory containing Terraform sources"
type: string
default: "terraform"
app-paths:
description: "Newline-separated deployable paths. A trailing slash is a prefix. Any other entry is an exact file. Empty skips isolation."
type: string
default: ""
permissions:
contents: read
jobs:
terraform:
name: terraform
runs-on: ubuntu-latest
timeout-minutes: 15
concurrency:
group: ci-terraform-${{ github.workflow }}-${{ github.ref }}-${{ inputs.working-directory }}
cancel-in-progress: true
defaults:
run:
working-directory: ${{ inputs.working-directory }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
- uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1
with:
terraform_version: ${{ inputs.terraform-version }}
terraform_wrapper: false
- name: Terraform fmt
run: terraform fmt -check -recursive
- name: Terraform init
run: terraform init -backend=false
- name: Terraform validate
run: terraform validate
- name: App and Terraform isolation
if: inputs.app-paths != ''
uses: $/.github/actions/app-terraform-isolation
with:
app-paths: ${{ inputs.app-paths }}
terraform-dir: ${{ inputs.working-directory }}
event-name: ${{ github.event_name }}
pr-base-sha: ${{ github.event.pull_request.base.sha }}
merge-group-base-sha: ${{ github.event.merge_group.base_sha }}