Skip to content

feat: Adding e2e hook tests#990

Open
pen-pal wants to merge 12 commits into
antonbabenko:masterfrom
pen-pal:feat/823-e2e-hook-tests
Open

feat: Adding e2e hook tests#990
pen-pal wants to merge 12 commits into
antonbabenko:masterfrom
pen-pal:feat/823-e2e-hook-tests

Conversation

@pen-pal

@pen-pal pen-pal commented May 28, 2026

Copy link
Copy Markdown
Contributor
  • This PR introduces breaking change.
  • This PR fixes a bug.
  • This PR adds new functionality.
  • This PR enhances existing functionality.

Description of your changes

Increment toward #823: a behavioral end-to-end test harness for the hooks. It runs each hook the way a user would - through pre-commit against fixture files — and compares the result against a committed "golden" output tree.

Addresses #823 (lays the foundation and seeds it with two hooks). It does not close the issue, since most hooks still need cases.

Harness - tests/e2e/run_e2e_tests.sh

  • Auto-discovers tests/e2e/cases/<hook_id>/<case_name>/. Adding a hook is just adding a dir — no runner changes.
  • Per case: builds a temp git repo from input/, renders the case's .pre-commit-config.yaml (__PCT_REPO__ → checkout root), runs the hook via
    pre-commit run --all-files.
  • A case passes when the exit code matches expected_returncode (default 0) and the working tree is byte-identical to expected/.
  • Optional requires file skips a case when a needed CLI tool is absent.

Seed cases

Hook Case Asserts
terraform_fmt reformats-misaligned-hcl misaligned HCL is reformatted; pre-commit exits 1 (hook modifies a tracked file)
terraform_wrapper_module_for_each generates-wrapper-for-root-module wrappers/{main,outputs,variables,versions}.tf + README.md generated for a

CI - .github/workflows/e2e-tests.yaml
Runs the suite on every PR inside the published multi-tool image (ghcr.io/antonbabenko/pre-commit-terraform:latest). The image supplies the tooling (terraform, hcledit, …); the hook and test code come from the checkout, so the image tag need not be in sync.

How can we test changes

Locally (needs pre-commit, git, and the hooks' tools — terraform, hcledit):

bash tests/e2e/run_e2e_tests.sh
# => 2 passed, 0 failed, 0 skipped

Inside the project image (matches CI):

docker build -t pct:e2e --build-arg INSTALL_ALL=true .
docker run --rm -v "$PWD:/lint" -w /lint --entrypoint bash pct:e2e \
  tests/e2e/run_e2e_tests.sh

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds end-to-end test infrastructure: a bash test runner, README, GitHub Actions workflow, and two Terraform-focused e2e cases with inputs, expected outputs, and requirements files.

Changes

End-to-End Test Infrastructure

Layer / File(s) Summary
E2E Test Framework Documentation
tests/e2e/README.md
Documents case layout, execution and validation rules, skip behavior for missing tools, local and Docker usage, and how to add cases.
Runner: init and setup
tests/e2e/run_e2e_tests.sh
Adds script setup, strict mode, path resolution, color helpers, and summary counters.
Runner: per-case execution
tests/e2e/run_e2e_tests.sh
Implements run_case: builds a temp git fixture from input/, runs pre-commit, validates exit code and output against expected artifacts, reports results, and cleans up.
Runner: discovery and orchestration
tests/e2e/run_e2e_tests.sh
Implements main: discovers case directories, runs them, prints the aggregate summary, and invokes the entrypoint.
CI Execution Workflow
.github/workflows/e2e-tests.yaml
Adds a GitHub Actions workflow for merge_group, pull_request, and push with branch exclusions, read-only permissions, concurrency cancellation, a pinned container image, and a 10-minute timeout.
terraform_fmt Test Case
tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/
Adds hook config, Terraform input and expected files, an expected return code of 1, and a requires file listing terraform.
terraform_wrapper_module_for_each Test Case
tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/
Adds hook config, Terraform input files, expected root outputs, generated wrapper files, and wrapper documentation.

Sequence Diagram(s)

sequenceDiagram
  participant Workflow
  participant RunScript as tests/e2e/run_e2e_tests.sh
  participant PreCommit as pre-commit
  participant Git as git diff

  Workflow->>RunScript: run tests in container
  RunScript->>PreCommit: pre-commit run --all-files
  PreCommit-->>RunScript: exit code and file changes
  RunScript->>Git: compare produced tree to expected/
  Git-->>RunScript: diff result
  RunScript-->>Workflow: PASS / FAIL summary
Loading

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: antonbabenko, MaxymVlasov, yermulnik

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding e2e hook tests.
Description check ✅ Passed The description is clearly related to the changeset and explains the new harness, seed cases, and CI workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/e2e-tests.yaml:
- Around line 31-33: The workflow uses env.IMAGE set to
ghcr.io/antonbabenko/pre-commit-terraform:latest which allows image drift;
change the IMAGE value to a digest-pinned reference
(ghcr.io/antonbabenko/pre-commit-terraform@sha256:<digest>) so the e2e runner
always pulls an immutable artifact, updating any references to IMAGE used in the
workflow (the env block and any docker pull/docker run invocations); obtain the
exact sha256 digest for the desired image tag via a docker registry query or
docker pull + docker inspect (or GHCR API) and replace :latest with
`@sha256`:<digest>.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f0b0b52-8698-431c-922f-5536c499b88a

📥 Commits

Reviewing files that changed from the base of the PR and between c838f02 and cdebf54.

📒 Files selected for processing (18)
  • .github/workflows/e2e-tests.yaml
  • tests/e2e/README.md
  • tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/.pre-commit-config.yaml
  • tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/expected/main.tf
  • tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/expected_returncode
  • tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/input/main.tf
  • tests/e2e/cases/terraform_fmt/reformats-misaligned-hcl/requires
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/.pre-commit-config.yaml
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/main.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/versions.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/wrappers/README.md
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/wrappers/main.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/wrappers/outputs.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/wrappers/variables.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/expected/wrappers/versions.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/input/main.tf
  • tests/e2e/cases/terraform_wrapper_module_for_each/generates-wrapper-for-root-module/input/versions.tf
  • tests/e2e/run_e2e_tests.sh

Comment thread .github/workflows/e2e-tests.yaml
@pen-pal pen-pal changed the title e2e hook tests feat: Adding e2e hook tests May 28, 2026

@yermulnik yermulnik left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution.
I'm out of context around tests and therefore I've added solely tech comments around Bash code.

Comment thread tests/e2e/run_e2e_tests.sh Outdated
Comment thread tests/e2e/run_e2e_tests.sh Outdated
Comment thread tests/e2e/run_e2e_tests.sh Outdated
Comment thread tests/e2e/run_e2e_tests.sh Outdated
Comment thread tests/e2e/run_e2e_tests.sh Outdated
Comment thread tests/e2e/run_e2e_tests.sh Outdated
pen-pal added a commit to pen-pal/pre-commit-terraform that referenced this pull request May 29, 2026
Per review on antonbabenko#990:
- replace the `RETURN` trap with explicit cleanup at the function's single
  exit (the `RETURN` trap is Bash-only and confused reviewers);
- read the expected return code with `$(< file)` instead of `$(cat file)`;
- quote the `true`/`false` flag values to avoid confusion with the builtins;
- use `&>` instead of `> ... 2>&1`;
- drop the redundant trailing slash on the copy destination;
- print the summary with `printf` instead of a loop.

No behavior change; the suite still passes natively and inside the image.

Signed-off-by: penpal <unameme@proton.me>
pen-pal added a commit to pen-pal/pre-commit-terraform that referenced this pull request May 29, 2026
Per review on antonbabenko#990, pin `ghcr.io/antonbabenko/pre-commit-terraform` by
`sha256` digest instead of the floating `:latest` tag, so the bundled
toolchain can't drift between runs. A Renovate annotation keeps the digest
updated.

Signed-off-by: penpal <unameme@proton.me>

@yermulnik yermulnik left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MaxymVlasov Shell code looks good to me, though I'm not really good with the rest of the tests logic — could you please have a look when you've got a moment? Thank you.

pen-pal added 8 commits May 30, 2026 10:55
Introduce `tests/e2e/run_e2e_tests.sh`, a behavioral test runner that
exercises each hook the way a user would -- through `pre-commit` against
fixture files -- and compares the result against a committed golden tree.

It auto-discovers `cases/<hook>/<case>/`, builds a temp git repo from
`input/`, renders the case's `.pre-commit-config.yaml` (`__PCT_REPO__` ->
checkout root), runs the hook via `pre-commit run --all-files`, then
asserts the exit code matches `expected_returncode` (default 0) and the
working tree is byte-identical to `expected/`. The tree compare uses
`git diff --no-index` so it works with the BusyBox `diff` shipped in the
project image. A `requires` file skips a case when a needed CLI tool is
absent.

Part of antonbabenko#823.

Signed-off-by: penpal <unameme@proton.me>
Add `generates-wrapper-for-root-module`: a root module (with no
`provider_meta`) is wrapped, and the generated
`wrappers/{main,outputs,variables,versions}.tf` plus `README.md` are
checked against the golden tree. Exits 0 (only new files are created).

Part of antonbabenko#823.

Signed-off-by: penpal <unameme@proton.me>
Add `reformats-misaligned-hcl`: misaligned HCL is rewritten to canonical
style. The hook modifies a tracked file, so `pre-commit` exits 1
(`expected_returncode=1`). The case requires `terraform`.

Part of antonbabenko#823.

Signed-off-by: penpal <unameme@proton.me>
Add `.github/workflows/e2e-tests.yaml`. Checkout runs on the host (the JS
action needs Node), then the suite runs inside the published multi-tool
image (`ghcr.io/antonbabenko/pre-commit-terraform:latest`), which supplies
terraform/hcledit/pre-commit while the hook and test code come from the
checkout -- so the image tag need not be in sync.

Part of antonbabenko#823.

Signed-off-by: penpal <unameme@proton.me>
Add `tests/e2e/README.md` describing the case layout, how to run the suite
natively and inside the project image, and how to add a new case.

Part of antonbabenko#823.

Signed-off-by: penpal <unameme@proton.me>
Per review on antonbabenko#990:
- replace the `RETURN` trap with explicit cleanup at the function's single
  exit (the `RETURN` trap is Bash-only and confused reviewers);
- read the expected return code with `$(< file)` instead of `$(cat file)`;
- quote the `true`/`false` flag values to avoid confusion with the builtins;
- use `&>` instead of `> ... 2>&1`;
- drop the redundant trailing slash on the copy destination;
- print the summary with `printf` instead of a loop.

No behavior change; the suite still passes natively and inside the image.

Signed-off-by: penpal <unameme@proton.me>
Per review on antonbabenko#990, pin `ghcr.io/antonbabenko/pre-commit-terraform` by
`sha256` digest instead of the floating `:latest` tag, so the bundled
toolchain can't drift between runs. A Renovate annotation keeps the digest
updated.

Signed-off-by: penpal <unameme@proton.me>
Signed-off-by: penpal <unameme@proton.me>
@pen-pal pen-pal force-pushed the feat/823-e2e-hook-tests branch from 235410e to a6052ac Compare May 30, 2026 05:10

@MaxymVlasov MaxymVlasov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for introducing this simple but powerful e2e test strategy!

I have a few requests for you before we proceed.

env:
# renovate: datasource=docker depName=ghcr.io/antonbabenko/pre-commit-terraform
# yamllint disable-line rule:line-length
IMAGE: ghcr.io/antonbabenko/pre-commit-terraform:latest@sha256:4ef4b8323b27fc263535ad88c9d2f20488fcb3b520258e5e7f0553ed5f6692b5

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we pin it to hash, then there's no sense to use the latest at all, which contradicts the main idea - test againt latest tool set & against the latest stable hook version.

In other words, we need 2 tests: against latest w/o pinning and against the latest available hook version, which can be bumped by renovate, but I'd like to have it as part of the release process.

Comment thread tests/e2e/README.md Outdated
Comment thread tests/e2e/README.md Outdated
Comment thread tests/e2e/README.md
Comment on lines +71 to +72
docker build -t pct:e2e --build-arg INSTALL_ALL=true .
docker run --rm -v "$PWD:/lint" -w /lint --entrypoint bash pct:e2e \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what's the reason to build a separate image?

Just use a exisitng one https://github.com/antonbabenko/pre-commit-terraform#1-install-dependencies

Comment thread tests/e2e/README.md Outdated
Comment thread tests/e2e/README.md

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a section about requesting the addition of e2e hooks to https://github.com/antonbabenko/pre-commit-terraform/blob/master/.github/CONTRIBUTING.md#add-new-hook

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has been open 30 days

with no activity. Remove stale label or comment or this PR will be closed in 10 days

@github-actions github-actions Bot added the stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 2, 2026
pen-pal and others added 4 commits July 2, 2026 09:34
Co-authored-by: Maksym Vlasov <MaxymVlasov@users.noreply.github.com>
Co-authored-by: Maksym Vlasov <MaxymVlasov@users.noreply.github.com>
Co-authored-by: Maksym Vlasov <MaxymVlasov@users.noreply.github.com>
@pen-pal

pen-pal commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

will apply the fixes based on comments

@github-actions github-actions Bot removed the stale Denotes an issue or PR has remained open with no activity and has become stale. label Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants