E2E tests run Neptune against MinIO (S3-compatible) using Docker Compose. They verify lock storage, workflow execution (plan/apply), and Terramate change detection without a real GitHub PR.
- Docker and Docker Compose – for MinIO
- Go – to build Neptune (see
go.mod) - Terraform (or OpenTofu) – for the test stacks
Neptune uses the Terramate Go SDK for change detection and run order; the Terramate CLI is not required for e2e or integration.
From the repository root:
make e2e # run all: Terramate, local (discovery), local (declared stacks)
make e2e.terramate # Terramate stacks only (./e2e/scripts/run-terramate.sh)
make e2e.localstacksfiles # stacks_management: local, stack.hcl discovery (./e2e/scripts/run-local-stacks-files.sh)
make e2e.localdeclaredstacks # stacks_management: local, root-level local_stacks config (./e2e/scripts/run-local-declared-stacks.sh)Or run the scripts directly:
./e2e/scripts/run-terramate.sh # Terramate
./e2e/scripts/run-local-stacks-files.sh # stacks_management: local (stack.hcl discovery)
./e2e/scripts/run-local-declared-stacks.sh # stacks_management: local (root-level local_stacks)The main script will:
- Build the
neptunebinary - Start MinIO with Docker Compose and create the
neptune-e2ebucket - Prepare an isolated git repo with a
mainbranch and apr-1branch that has changes instack-a(so Neptune’s Terramate SDK reports that stack as changed) - Run
neptune command planandneptune command applywithNEPTUNE_E2E=1 - Tear down MinIO
When NEPTUNE_E2E=1 is set:
- GitHub environment variables may be empty; defaults are used for repo and PR number so lock file metadata works.
- Neptune skips GitHub API calls (no requirement checks, no comment posting).
- A stub treats the current “PR” as open so locks are not removed as stale.
This allows e2e to run in CI and locally without a GitHub token or real pull request.
- stack-a, stack-b, stack-c – Terramate stacks with Terraform
null_resourceandlocal_file(no cloud providers). - .neptune.yaml – E2E config (Terramate) pointing at
s3://neptune-e2eand minimal plan/apply requirements. - .neptune.localstacksfiles.yaml – E2E config with
stacks_management: local(stack.hcl discovery) forscripts/run-local-stacks-files.sh. - .neptune.localdeclaredstacks.yaml – E2E config with
stacks_management: localand root-level local_stacks (source: config) forscripts/run-local-declared-stacks.sh. - docker-compose.yaml – MinIO plus an init container that creates the bucket.
- scripts/run-terramate.sh – Orchestrates MinIO, git fixture, and Neptune plan/apply (Terramate).
- scripts/run-local-stacks-files.sh – Same flow as run-terramate.sh but with
stacks_management: local(stack.hcl discovery). - scripts/run-local-declared-stacks.sh – Same flow as run-local-stacks-files.sh but uses root-level
local_stacks(source: config) for stack list and run order. - scripts/run-integration.sh – Orchestrates MinIO and Neptune plan/apply with real GitHub (used by the integration workflow).
The e2e workflow runs on pushes to main/release-* and on pull requests when relevant paths change (e2e/, internal/lock, cmd/, config, compose files). It sets up Terraform and runs ./e2e/scripts/run-terramate.sh.
Integration tests run Neptune (plan/apply) on a real pull request with a real GitHub connection: PR requirement checks and comment posting. Lock storage still uses MinIO in the same job (no real GCS/S3).
- When they run: The integration workflow runs only on pull requests when integration-relevant paths change (e2e/, internal/github/, internal/notifications/github/, cmd/, internal/config/, internal/lock/, internal/run/, internal/domain/, compose files, and the workflow file).
- What they do: Checkout (with full history so the base ref exists for Terramate), start MinIO and create the bucket, then run
./e2e/scripts/run-integration.sh. The script injects a trivial change ine2e/stack-a/main.tfande2e/stack-b/main.tfand commits it locally so Terramate always sees changed stacks (HEAD vsorigin/main), then runsneptune command planandneptune command applyfrom thee2e/directory withNEPTUNE_CONFIG_PATH=.neptune.yaml. GitHub env is set from the workflow so Neptune posts result comments on the PR. - Full plan/apply: Because the script commits a change under
e2e/, Terramate reports changed stacks and plan/apply run on them every time; PR comments show the full plan/apply format with stacks and command output.