From 3d4c27080c2364ae61ab3489425615ea4d2a2980 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Thu, 6 Nov 2025 16:51:46 -0700 Subject: [PATCH 1/9] chore: update underlying dependencies --- aqua.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aqua.yaml b/aqua.yaml index 7637986..01a9de8 100644 --- a/aqua.yaml +++ b/aqua.yaml @@ -1,11 +1,11 @@ --- registries: - type: standard - ref: v4.78.0 # renovate: depName=aquaproj/aqua-registry + ref: v4.433.0 # renovate: depName=aquaproj/aqua-registry packages: - - name: go-task/task@v3.31.0 - - name: TomWright/dasel@v2.4.1 - - name: stedolan/jq@jq-1.7.1 + - name: go-task/task@v3.45.4 + - name: TomWright/dasel@v2.8.1 + - name: stedolan/jq@jq-1.8.1 tags: [cursor] - - name: cli/cli@v2.74.2 + - name: cli/cli@v2.83.0 tags: [gh] From 1a506d4bcca3cc2901da1e8fd851ed36e04e199e Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Thu, 6 Nov 2025 16:52:18 -0700 Subject: [PATCH 2/9] feat: rename the folder, terraform -> tf --- Taskfile.yaml | 5 ++--- lib/{terraform => tf}/Taskfile.yml | 0 2 files changed, 2 insertions(+), 3 deletions(-) rename lib/{terraform => tf}/Taskfile.yml (100%) diff --git a/Taskfile.yaml b/Taskfile.yaml index b9aad4a..895a492 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,9 +8,8 @@ includes: mixins: lib/mixins os: lib/os-modules snaplet: lib/snaplet - terraform: - taskfile: lib/terraform - aliases: [tf] + tf: + taskfile: lib/tf toolbox: lib/toolbox tasks: {} diff --git a/lib/terraform/Taskfile.yml b/lib/tf/Taskfile.yml similarity index 100% rename from lib/terraform/Taskfile.yml rename to lib/tf/Taskfile.yml From b971ea55fe7876497b32f902377650e93dfd3968 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Thu, 6 Nov 2025 17:07:44 -0700 Subject: [PATCH 3/9] feat: allow users to use opentofu or terraform --- lib/tf/Taskfile.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/tf/Taskfile.yml b/lib/tf/Taskfile.yml index 3f59b00..115986b 100644 --- a/lib/tf/Taskfile.yml +++ b/lib/tf/Taskfile.yml @@ -24,6 +24,8 @@ tasks: sh: echo "{{.BACKEND_CONFIG_PATH}}/{{.ENV}}.backend.tf" TFVARS_FILE: sh: echo "{{.TFVARS_PATH}}/{{.ENV}}.tfvars" + TF_CMD: + sh: '[ "${USE_TERRAFORM}" = "true" ] && echo "terraform" || echo "tofu"' init: desc: Initialize Terraform working directory with a backend configuration file. @@ -39,7 +41,7 @@ tasks: - sh: test -f {{.BACKEND_CONFIG_FILE}} msg: "Backend configuration file does not exist: {{.BACKEND_CONFIG_FILE}}" cmds: - - terraform init -backend-config {{.BACKEND_CONFIG_FILE}} {{.TF_ARGS}} + - "{{.TF_CMD}} init -backend-config {{.BACKEND_CONFIG_FILE}} {{.TF_ARGS}}" plan: desc: Generate a Terraform execution plan Terraform loading variable values from the given file. @@ -56,7 +58,7 @@ tasks: - sh: test -f {{.TFVARS_FILE}} msg: "Variables file does not exist: {{.TFVARS_FILE}}" cmds: - - terraform plan -var-file {{.TFVARS_FILE}} {{.TF_ARGS}} + - "{{.TF_CMD}} plan -var-file {{.TFVARS_FILE}} {{.TF_ARGS}}" apply: desc: Create or update infrastructure according to Terraform configuration files in the current directory. @@ -73,7 +75,7 @@ tasks: - sh: test -f {{.TFVARS_FILE}} msg: "Variables file does not exist: {{.TFVARS_FILE}}" cmds: - - terraform apply -var-file {{.TFVARS_FILE}} {{.TF_ARGS}} + - "{{.TF_CMD}} apply -var-file {{.TFVARS_FILE}} {{.TF_ARGS}}" refresh: desc: Refresh the Terraform state to match the real-world infrastructure (safer via apply -refresh-only). @@ -90,4 +92,4 @@ tasks: - sh: test -f {{.TFVARS_FILE}} msg: "Variables file does not exist: {{.TFVARS_FILE}}" cmds: - - terraform apply -refresh-only -var-file {{.TFVARS_FILE}} {{.TF_ARGS}} + - "{{.TF_CMD}} apply -refresh-only -var-file {{.TFVARS_FILE}} {{.TF_ARGS}}" From ed45202e0fdd73b7327697365a97dc9c0a73dbd7 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Thu, 6 Nov 2025 17:39:12 -0700 Subject: [PATCH 4/9] fix: remove cursor after we removed the directory --- Taskfile.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 895a492..4c600c7 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -4,7 +4,6 @@ includes: aqua: lib/aqua aws: lib/aws components: lib/components - cursor: lib/cursor mixins: lib/mixins os: lib/os-modules snaplet: lib/snaplet From 4009938eb128e458eb64f10fbaf5267b673641c4 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Thu, 6 Nov 2025 17:58:33 -0700 Subject: [PATCH 5/9] fix: trim down tf plan tests --- .github/workflows/test.yaml | 42 ++++++++++++ tests/README.md | 127 ++++++++++++++++++++++++++++++++++++ tests/terraform_plan.bats | 60 +++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 .github/workflows/test.yaml create mode 100644 tests/README.md create mode 100755 tests/terraform_plan.bats diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..1247331 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,42 @@ +name: Test + +on: + pull_request: {} + push: + branches: + - main + +permissions: + actions: read + checks: write + contents: read + pull-requests: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Check out Git repository + uses: actions/checkout@v4 + + - name: Install BATS + run: | + sudo apt-get update + sudo apt-get install -y bats + + - name: Install Task + uses: arduino/setup-task@v2 + with: + version: 3.x + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Run BATS tests + run: bats tests/ + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: tests/ + retention-days: 30 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..b5586ab --- /dev/null +++ b/tests/README.md @@ -0,0 +1,127 @@ +# Taskit Test Suite + +## Purpose + +This directory contains the BATS (Bash Automated Testing System) test suite for Taskit. Tests validate Task command functionality using dry-run mode, ensuring reliability without requiring actual tool installations. + +## Prerequisites + +Install BATS: + +```bash +# macOS +brew install bats-core + +# Debian/Ubuntu +apt-get install bats + +# Manual installation +git clone https://github.com/bats-core/bats-core.git +cd bats-core +./install.sh /usr/local +``` + +## Running Tests + +### Local Development + +```bash +# Run all tests +bats tests/ + +# Run specific test file +bats tests/terraform_plan.bats + +# Run tests by tag +bats --filter-tags basic tests/ +bats --filter-tags precondition tests/ +``` + +### Continuous Integration + +Tests run automatically on: + +- **Pull Requests**: All PRs trigger the test suite +- **Main Branch**: Tests run on every push to main + +The GitHub Actions workflow (`.github/workflows/test.yaml`) handles: + +1. BATS and Task installation +2. Test execution across the `tests/` directory +3. Result artifacts upload (30-day retention) + +View results in the GitHub Actions tab or PR checks section. + +## Writing Tests + +Tests leverage Task's dry-run mode (`task -v -n`) to verify command construction without execution: + +```bash +@test "terraform:plan validates environment argument" { + # Arrange: Create test fixture + touch "tfvars/test-env.tfvars" + + # Act: Execute task in dry-run mode + run task -v -n terraform:plan -- test-env + + # Assert: Verify output + [ "$status" -eq 0 ] + [[ "$output" =~ "expected text" ]] +} +``` + +### Test Structure + +- `setup()`: Pre-test fixture creation and environment setup +- `@test "description"`: Individual test case +- `teardown()`: Post-test cleanup + +### Test Tags + +Use tags for selective test execution: + +- `terraform`: Terraform-related functionality +- `plan`: Plan command behavior +- `basic`: Core functionality +- `args`: Argument handling +- `precondition`: Validation logic +- `config`: Configuration management +- `error`: Error handling + +## Best Practices + +1. **Dry-run Testing**: Use `task -v -n` to test without requiring actual tool installations +2. **Debug Output**: Include `echo "Output: $output" >&3` for troubleshooting failed tests +3. **Fixture Management**: Create temporary files in `setup()`, clean up in `teardown()` +4. **Assertions**: Use `[ ]` for exit codes, `[[ =~ ]]` for pattern matching + +## Troubleshooting + +**Tests fail in CI but pass locally:** + +- Ensure proper cleanup in `teardown()` +- Verify tests don't depend on local environment state +- Confirm all required files are committed + +**Workflow doesn't run:** + +- Verify `.github/workflows/test.yaml` exists +- Check GitHub Actions are enabled for the repository +- Review branch protection rules + +## Workflow Permissions + +The CI workflow uses minimal permissions: + +- `actions: read` - Access workflow logs +- `checks: write` - Report check results +- `contents: read` - Read repository +- `pull-requests: read` - Access PR information + +No secrets or credentials required for test execution. + +## Resources + +- [BATS Documentation](https://bats-core.readthedocs.io/en/stable/) +- [Writing BATS Tests](https://bats-core.readthedocs.io/en/stable/writing-tests.html) +- [Task Documentation](https://taskfile.dev/) diff --git a/tests/terraform_plan.bats b/tests/terraform_plan.bats new file mode 100755 index 0000000..176ed3b --- /dev/null +++ b/tests/terraform_plan.bats @@ -0,0 +1,60 @@ +#!/usr/bin/env bats +# Test suite for terraform:plan task command + +setup() { + cd "$(dirname "$BATS_TEST_FILENAME")/.." + export TEST_WORKSPACE="test-env" + mkdir -p tfvars backend-configurations + touch "tfvars/${TEST_WORKSPACE}.tfvars" + touch "backend-configurations/${TEST_WORKSPACE}.backend.tf" +} + +teardown() { + rm -rf tfvars backend-configurations +} + +# bats test_tags=terraform,plan,basic +@test "terraform:plan generates correct command with workspace" { + run task -v -n tf:plan -- "$TEST_WORKSPACE" + + echo "Output: $output" >&3 + + [ "$status" -eq 0 ] + [[ "$output" =~ terraform.*workspace.*select.*-or-create.*${TEST_WORKSPACE} ]] + [[ "$output" =~ terraform.*plan.*-var-file.*tfvars/${TEST_WORKSPACE}.tfvars ]] +} + +# bats test_tags=terraform,plan,args +@test "terraform:plan passes additional arguments to terraform" { + run task -v -n tf:plan -- "$TEST_WORKSPACE" -out=tfplan.out -lock=false + + echo "Output: $output" >&3 + + [ "$status" -eq 0 ] + [[ "$output" =~ -out=tfplan.out ]] + [[ "$output" =~ -lock=false ]] + [[ "$output" =~ -var-file.*tfvars/${TEST_WORKSPACE}.tfvars ]] +} + +# bats test_tags=terraform,plan,precondition +@test "terraform:plan fails when tfvars file does not exist" { + rm -f "tfvars/${TEST_WORKSPACE}.tfvars" + + run task -v -n tf:plan -- "$TEST_WORKSPACE" + + echo "Output: $output" >&3 + + [ "$status" -ne 0 ] + [[ "$output" =~ "Variables file does not exist" ]] +} + +# bats test_tags=terraform,plan,config +@test "terraform:plan uses terraform when USE_TERRAFORM=true" { + run env USE_TERRAFORM=true task -v -n tf:plan -- "$TEST_WORKSPACE" + + echo "Output: $output" >&3 + + [ "$status" -eq 0 ] + [[ "$output" =~ \[tf:plan\]\ terraform\ workspace\ select ]] + [[ "$output" =~ \[tf:plan\]\ terraform\ plan ]] +} From 1b7628c4427d2113cee1fcf83c43c48a11f06be7 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Fri, 7 Nov 2025 12:07:08 -0700 Subject: [PATCH 6/9] fix: update tests/README.md to use aqua --- .github/workflows/test.yaml | 12 +--- aqua.yaml | 2 + tests/README.md | 111 ++++++------------------------------ 3 files changed, 23 insertions(+), 102 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1247331..69ce032 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,16 +19,10 @@ jobs: - name: Check out Git repository uses: actions/checkout@v4 - - name: Install BATS - run: | - sudo apt-get update - sudo apt-get install -y bats - - - name: Install Task - uses: arduino/setup-task@v2 + - name: Install tools via aqua + uses: aquaproj/aqua-installer@v3.0.1 with: - version: 3.x - repo-token: ${{ secrets.GITHUB_TOKEN }} + aqua_version: v2.55.0 - name: Run BATS tests run: bats tests/ diff --git a/aqua.yaml b/aqua.yaml index 01a9de8..2f16f3d 100644 --- a/aqua.yaml +++ b/aqua.yaml @@ -9,3 +9,5 @@ packages: tags: [cursor] - name: cli/cli@v2.83.0 tags: [gh] + - name: bats-core/bats-core@v1.13.0 + tags: [cicd] diff --git a/tests/README.md b/tests/README.md index b5586ab..fd0d16e 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,124 +1,49 @@ # Taskit Test Suite -## Purpose +BATS test suite for Taskit. Tests validate Task commands using dry-run mode (`task -n`). -This directory contains the BATS (Bash Automated Testing System) test suite for Taskit. Tests validate Task command functionality using dry-run mode, ensuring reliability without requiring actual tool installations. - -## Prerequisites - -Install BATS: +## Setup ```bash -# macOS -brew install bats-core - -# Debian/Ubuntu -apt-get install bats - -# Manual installation -git clone https://github.com/bats-core/bats-core.git -cd bats-core -./install.sh /usr/local +aqua install # Installs BATS and Task ``` ## Running Tests -### Local Development - ```bash -# Run all tests -bats tests/ - -# Run specific test file -bats tests/terraform_plan.bats - -# Run tests by tag -bats --filter-tags basic tests/ -bats --filter-tags precondition tests/ +bats tests/ # Run all +bats tests/terraform_plan.bats # Run specific file +bats --filter-tags precondition tests/ # Run by tag ``` -### Continuous Integration - -Tests run automatically on: - -- **Pull Requests**: All PRs trigger the test suite -- **Main Branch**: Tests run on every push to main - -The GitHub Actions workflow (`.github/workflows/test.yaml`) handles: - -1. BATS and Task installation -2. Test execution across the `tests/` directory -3. Result artifacts upload (30-day retention) - -View results in the GitHub Actions tab or PR checks section. +CI runs automatically on PRs and main branch pushes via `.github/workflows/test.yaml`. ## Writing Tests -Tests leverage Task's dry-run mode (`task -v -n`) to verify command construction without execution: +Tests use Task's dry-run mode to verify command construction: ```bash @test "terraform:plan validates environment argument" { - # Arrange: Create test fixture - touch "tfvars/test-env.tfvars" - - # Act: Execute task in dry-run mode + touch "tfvars/test-env.tfvars" # Setup fixture run task -v -n terraform:plan -- test-env - - # Assert: Verify output [ "$status" -eq 0 ] - [[ "$output" =~ "expected text" ]] + [[ "$output" =~ "tofu plan -var-file ./tfvars/test-env.tfvars" ]] } ``` -### Test Structure - -- `setup()`: Pre-test fixture creation and environment setup -- `@test "description"`: Individual test case -- `teardown()`: Post-test cleanup - -### Test Tags +Key helpers: `setup()`, `teardown()`, `run`, `$status`, `$output` -Use tags for selective test execution: +## Quick Reference -- `terraform`: Terraform-related functionality -- `plan`: Plan command behavior -- `basic`: Core functionality -- `args`: Argument handling -- `precondition`: Validation logic -- `config`: Configuration management -- `error`: Error handling - -## Best Practices - -1. **Dry-run Testing**: Use `task -v -n` to test without requiring actual tool installations -2. **Debug Output**: Include `echo "Output: $output" >&3` for troubleshooting failed tests -3. **Fixture Management**: Create temporary files in `setup()`, clean up in `teardown()` -4. **Assertions**: Use `[ ]` for exit codes, `[[ =~ ]]` for pattern matching +**Debug failed tests:** `echo "Output: $output" >&3` +**Test pattern:** `task -v -n -- ` +**Assertions:** `[ ]` for exit codes, `[[ =~ ]]` for regex matching +**Tags:** terraform, plan, basic, args, precondition, config, error +**Fixtures:** Create in `setup()`, clean in `teardown()` ## Troubleshooting -**Tests fail in CI but pass locally:** - -- Ensure proper cleanup in `teardown()` -- Verify tests don't depend on local environment state -- Confirm all required files are committed - -**Workflow doesn't run:** - -- Verify `.github/workflows/test.yaml` exists -- Check GitHub Actions are enabled for the repository -- Review branch protection rules - -## Workflow Permissions - -The CI workflow uses minimal permissions: - -- `actions: read` - Access workflow logs -- `checks: write` - Report check results -- `contents: read` - Read repository -- `pull-requests: read` - Access PR information - -No secrets or credentials required for test execution. +**CI/local mismatch:** Check `teardown()` cleanup and committed test fixtures. ## Resources From a1895e4c325b6927988274bcf8a94f3f642468f5 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Fri, 7 Nov 2025 12:13:53 -0700 Subject: [PATCH 7/9] fix: update versions and practice good hygene --- .github/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 69ce032..3f95453 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -20,9 +20,9 @@ jobs: uses: actions/checkout@v4 - name: Install tools via aqua - uses: aquaproj/aqua-installer@v3.0.1 + uses: aquaproj/aqua-installer@11dd79b4e498d471a9385aa9fb7f62bb5f52a73c # v4.0.4 with: - aqua_version: v2.55.0 + aqua_version: v2.55.1 - name: Run BATS tests run: bats tests/ From dd47e876ac71be2c18ec2679b3b3d797d531c8e9 Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Fri, 7 Nov 2025 12:17:11 -0700 Subject: [PATCH 8/9] fix: remove uploading results --- .github/workflows/test.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3f95453..d49c87d 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,11 +26,3 @@ jobs: - name: Run BATS tests run: bats tests/ - - - name: Upload test results - if: always() - uses: actions/upload-artifact@v4 - with: - name: test-results - path: tests/ - retention-days: 30 From 98996bc03c6706f27fc3f9273aca680ab9f2d71c Mon Sep 17 00:00:00 2001 From: Weston Platter Date: Fri, 7 Nov 2025 12:26:23 -0700 Subject: [PATCH 9/9] fix: commit pin more GHAs --- .github/workflows/lint.yaml | 5 +++-- .github/workflows/release-please.yaml | 2 +- .github/workflows/test.yaml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 092d215..5ace1ee 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -13,6 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - name: Trunk Check - uses: trunk-io/trunk-action@v1 + uses: trunk-io/trunk-action@4d5ecc89b2691705fd08c747c78652d2fc806a94 # v1.1.19 diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index 13798ec..665a04a 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -13,6 +13,6 @@ jobs: release-please: runs-on: ubuntu-latest steps: - - uses: googleapis/release-please-action@7987652d64b4581673a76e33ad5e98e3dd56832f #v4.1.3 + - uses: googleapis/release-please-action@16a9c90856f42705d54a6fda1823352bdc62cf38 # v4.4.0 with: release-type: terraform-module diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d49c87d..b9d48f3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out Git repository - uses: actions/checkout@v4 + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 - name: Install tools via aqua uses: aquaproj/aqua-installer@11dd79b4e498d471a9385aa9fb7f62bb5f52a73c # v4.0.4