feat: change tf test and validation to use paths-filter (#483)

## Description

<!-- Briefly describe what this PR does and why -->

## Type of Change

- [ ] New module
- [ ] New template
- [ ] Bug fix
- [ ] Feature/enhancement
- [ ] Documentation
- [ ] Other

## Module Information

<!-- Delete this section if not applicable -->

**Path:** `registry/[namespace]/modules/[module-name]`  
**New version:** `v1.0.0`  
**Breaking change:** [ ] Yes [ ] No

## Template Information

<!-- Delete this section if not applicable -->

**Path:** `registry/[namespace]/templates/[template-name]`

## Testing & Validation

- [ ] Tests pass (`bun test`)
- [ ] Code formatted (`bun fmt`)
- [ ] Changes tested locally

## Related Issues

<!-- Link related issues or write "None" if not applicable -->
This commit is contained in:
DevCats 2025-10-16 14:21:03 -05:00 committed by GitHub
parent 90873e8009
commit ff09c415e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 149 additions and 18 deletions

View File

@ -27,6 +27,8 @@ jobs:
- 'tsconfig.json' - 'tsconfig.json'
- '.github/workflows/ci.yaml' - '.github/workflows/ci.yaml'
- 'scripts/ts_test_auto.sh' - 'scripts/ts_test_auto.sh'
- 'scripts/terraform_test_all.sh'
- 'scripts/terraform_validate.sh'
modules: modules:
- 'registry/**/modules/**' - 'registry/**/modules/**'
all: all:
@ -49,10 +51,18 @@ jobs:
ALL_CHANGED_FILES: ${{ steps.filter.outputs.all_files }} ALL_CHANGED_FILES: ${{ steps.filter.outputs.all_files }}
SHARED_CHANGED: ${{ steps.filter.outputs.shared }} SHARED_CHANGED: ${{ steps.filter.outputs.shared }}
MODULE_CHANGED_FILES: ${{ steps.filter.outputs.modules_files }} MODULE_CHANGED_FILES: ${{ steps.filter.outputs.modules_files }}
run: ./scripts/ts_test_auto.sh run: bun tstest
- name: Run Terraform tests - name: Run Terraform tests
run: ./scripts/terraform_test_all.sh env:
ALL_CHANGED_FILES: ${{ steps.filter.outputs.all_files }}
SHARED_CHANGED: ${{ steps.filter.outputs.shared }}
MODULE_CHANGED_FILES: ${{ steps.filter.outputs.modules_files }}
run: bun tftest
- name: Run Terraform Validate - name: Run Terraform Validate
env:
ALL_CHANGED_FILES: ${{ steps.filter.outputs.all_files }}
SHARED_CHANGED: ${{ steps.filter.outputs.shared }}
MODULE_CHANGED_FILES: ${{ steps.filter.outputs.modules_files }}
run: bun terraform-validate run: bun terraform-validate
validate-style: validate-style:
name: Check for typos and unformatted code name: Check for typos and unformatted code

View File

@ -4,7 +4,8 @@
"fmt": "bun x prettier --write . && terraform fmt -recursive -diff", "fmt": "bun x prettier --write . && terraform fmt -recursive -diff",
"fmt:ci": "bun x prettier --check . && terraform fmt -check -recursive -diff", "fmt:ci": "bun x prettier --check . && terraform fmt -check -recursive -diff",
"terraform-validate": "./scripts/terraform_validate.sh", "terraform-validate": "./scripts/terraform_validate.sh",
"test": "./scripts/terraform_test_all.sh", "tftest": "./scripts/terraform_test_all.sh",
"tstest": "./scripts/ts_test_auto.sh",
"update-version": "./update-version.sh" "update-version": "./update-version.sh"
}, },
"devDependencies": { "devDependencies": {

View File

@ -1,7 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
# Find all directories that contain any .tftest.hcl files and run terraform test in each # Auto-detect which Terraform tests to run based on changed files from paths-filter
# Uses paths-filter outputs from GitHub Actions:
# ALL_CHANGED_FILES - all files changed in the PR (for logging)
# SHARED_CHANGED - boolean indicating if shared infrastructure changed
# MODULE_CHANGED_FILES - only files in registry/**/modules/** (for processing)
# Runs all tests if shared infrastructure changes, or skips if no changes detected
#
# This script only runs tests for changed modules. Documentation and template changes are ignored.
run_dir() { run_dir() {
local dir="$1" local dir="$1"
@ -9,13 +16,72 @@ run_dir() {
(cd "$dir" && terraform init -upgrade -input=false -no-color > /dev/null && terraform test -no-color -verbose) (cd "$dir" && terraform init -upgrade -input=false -no-color > /dev/null && terraform test -no-color -verbose)
} }
mapfile -t test_dirs < <(find . -type f -name "*.tftest.hcl" -print0 | xargs -0 -I{} dirname {} | sort -u) echo "==> Detecting changed files..."
if [[ ${#test_dirs[@]} -eq 0 ]]; then if [[ -n "${ALL_CHANGED_FILES:-}" ]]; then
echo "No .tftest.hcl tests found." echo "Changed files in PR:"
echo "$ALL_CHANGED_FILES" | tr ' ' '\n' | sed 's/^/ - /'
echo ""
fi
if [[ "${SHARED_CHANGED:-false}" == "true" ]]; then
echo "==> Shared infrastructure changed"
echo "==> Running all tests for safety"
mapfile -t test_dirs < <(find . -type f -name "*.tftest.hcl" -print0 | xargs -0 -I{} dirname {} | sort -u)
elif [[ -z "${MODULE_CHANGED_FILES:-}" ]]; then
echo "✓ No module files changed, skipping tests"
exit 0
else
CHANGED_FILES=$(echo "$MODULE_CHANGED_FILES" | tr ' ' '\n')
MODULE_DIRS=()
while IFS= read -r file; do
if [[ "$file" =~ \.(md|png|jpg|jpeg|svg)$ ]]; then
continue
fi
if [[ "$file" =~ ^registry/([^/]+)/modules/([^/]+)/ ]]; then
namespace="${BASH_REMATCH[1]}"
module="${BASH_REMATCH[2]}"
module_dir="registry/${namespace}/modules/${module}"
if [[ -d "$module_dir" ]] && [[ ! " ${MODULE_DIRS[*]} " =~ " ${module_dir} " ]]; then
MODULE_DIRS+=("$module_dir")
fi
fi
done <<< "$CHANGED_FILES"
if [[ ${#MODULE_DIRS[@]} -eq 0 ]]; then
echo "✓ No Terraform tests to run"
echo " (documentation, templates, namespace files, or modules without changes)"
exit 0 exit 0
fi fi
echo "==> Finding .tftest.hcl files in ${#MODULE_DIRS[@]} changed module(s):"
for dir in "${MODULE_DIRS[@]}"; do
echo " - $dir"
done
echo ""
test_dirs=()
for module_dir in "${MODULE_DIRS[@]}"; do
while IFS= read -r test_file; do
test_dir=$(dirname "$test_file")
if [[ ! " ${test_dirs[*]} " =~ " ${test_dir} " ]]; then
test_dirs+=("$test_dir")
fi
done < <(find "$module_dir" -type f -name "*.tftest.hcl")
done
fi
if [[ ${#test_dirs[@]} -eq 0 ]]; then
echo "✓ No .tftest.hcl tests found in changed modules"
exit 0
fi
echo "==> Running terraform test in ${#test_dirs[@]} directory(ies)"
echo ""
status=0 status=0
for d in "${test_dirs[@]}"; do for d in "${test_dirs[@]}"; do
if ! run_dir "$d"; then if ! run_dir "$d"; then

View File

@ -2,36 +2,90 @@
set -euo pipefail set -euo pipefail
# Auto-detect which Terraform modules to validate based on changed files from paths-filter
# Uses paths-filter outputs from GitHub Actions:
# ALL_CHANGED_FILES - all files changed in the PR (for logging)
# SHARED_CHANGED - boolean indicating if shared infrastructure changed
# MODULE_CHANGED_FILES - only files in registry/**/modules/** (for processing)
# Validates all modules if shared infrastructure changes, or skips if no changes detected
#
# This script only validates changed modules. Documentation and template changes are ignored.
validate_terraform_directory() { validate_terraform_directory() {
local dir="$1" local dir="$1"
echo "Running \`terraform validate\` in $dir" echo "Running \`terraform validate\` in $dir"
pushd "$dir" pushd "$dir" > /dev/null
terraform init -upgrade terraform init -upgrade
terraform validate terraform validate
popd popd > /dev/null
} }
main() { main() {
# Get the directory of the script echo "==> Detecting changed files..."
if [[ -n "${ALL_CHANGED_FILES:-}" ]]; then
echo "Changed files in PR:"
echo "$ALL_CHANGED_FILES" | tr ' ' '\n' | sed 's/^/ - /'
echo ""
fi
local script_dir=$(dirname "$(readlink -f "$0")") local script_dir=$(dirname "$(readlink -f "$0")")
local registry_dir=$(readlink -f "$script_dir/../registry")
# Code assumes that registry directory will always be in same position if [[ "${SHARED_CHANGED:-false}" == "true" ]]; then
# relative to the main script directory echo "==> Shared infrastructure changed"
local registry_dir="$script_dir/../registry" echo "==> Validating all modules for safety"
local subdirs=$(find "$registry_dir" -mindepth 3 -maxdepth 3 -path "*/modules/*" -type d | sort)
elif [[ -z "${MODULE_CHANGED_FILES:-}" ]]; then
echo "✓ No module files changed, skipping validation"
exit 0
else
CHANGED_FILES=$(echo "$MODULE_CHANGED_FILES" | tr ' ' '\n')
# Get all module subdirectories in the registry directory. Code assumes that MODULE_DIRS=()
# Terraform module directories won't begin to appear until three levels deep into while IFS= read -r file; do
# the registry (e.g., registry/coder/modules/coder-login, which will then if [[ "$file" =~ \.(md|png|jpg|jpeg|svg)$ ]]; then
# have a main.tf file inside it) continue
local subdirs=$(find "$registry_dir" -mindepth 3 -path "*/modules/*" -type d | sort) fi
if [[ "$file" =~ ^registry/([^/]+)/modules/([^/]+)/ ]]; then
namespace="${BASH_REMATCH[1]}"
module="${BASH_REMATCH[2]}"
module_dir="registry/${namespace}/modules/${module}"
if [[ -d "$module_dir" ]] && [[ ! " ${MODULE_DIRS[*]} " =~ " ${module_dir} " ]]; then
MODULE_DIRS+=("$module_dir")
fi
fi
done <<< "$CHANGED_FILES"
if [[ ${#MODULE_DIRS[@]} -eq 0 ]]; then
echo "✓ No modules to validate"
echo " (documentation, templates, namespace files, or modules without changes)"
exit 0
fi
echo "==> Validating ${#MODULE_DIRS[@]} changed module(s):"
for dir in "${MODULE_DIRS[@]}"; do
echo " - $dir"
done
echo ""
local subdirs="${MODULE_DIRS[*]}"
fi
status=0
for dir in $subdirs; do for dir in $subdirs; do
# Skip over any directories that obviously don't have the necessary # Skip over any directories that obviously don't have the necessary
# files # files
if test -f "$dir/main.tf"; then if test -f "$dir/main.tf"; then
validate_terraform_directory "$dir" if ! validate_terraform_directory "$dir"; then
status=1
fi
fi fi
done done
exit $status
} }
main main