Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .agents/skills/e2e-test/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,22 @@ Conventions that keep this clean and correct:
`test_context` forces the variant to be chosen before `tofu test` starts, which pushes a
test-matrix concern out of the hub and into whatever invokes it.

- **Never read a fixture from the environment.** If `test_context` can carry the value, it carries
it — a `TF_VAR_*` has to be wired in the harness repo too (an Actions variable, a workflow line, a
`setup-env.sh` line), and nothing checks that those still agree. That is exactly how the
`meshstack/noop` runner test broke silently when one of two wiring lines was removed. The harness
side of this rule, including where a new fixture value comes from, is the four-branch rule in
`meshstack-smoke-test`'s `AGENTS.md`.

### Provider authentication secrets

Provider authentication secrets should come via standard environment variables expected by these providers, not grab-bag fields in `test_context`.

Secrets are the one exception to the rule above: GitHub masks values only one by one, so a secret
cannot ride in the `test_context` grab-bag. It arrives as a scalar `TF_VAR_<variable>` and the module
declares a matching top-level `sensitive` variable (`nullable`, `default = null`, so foundation mode
can omit it).

---

## `e2e/main.tf` conventions
Expand Down Expand Up @@ -422,6 +434,7 @@ source setup-override-provider.sh
- [ ] `fixtures` is `optional()` with its inner shape fully required (no half-populated fixtures)
- [ ] Always-shared fields (`workspace`, `name_suffix`, `hub_git_ref`) are required, not `optional()`
- [ ] Cloud resource IDs sourced from `var.test_context.fixtures.*` (not flat `test_context` fields)
- [ ] No fixture read from the environment — only secrets arrive as `TF_VAR_*`
- [ ] Scalar secrets are top-level `nullable` vars with `default = null` (foundation mode omits them)
- [ ] Module sourced via relative path (not a GitHub URL), gated with `count = var.test_context.bbd_version_ref == null ? 1 : 0`
- [ ] `hub.git_ref = var.test_context.hub_git_ref` — no hardcoded `"main"`
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,10 @@ the diagram checklist.

Modules that can be smoke-tested against a live meshStack instance should include an `e2e/` directory alongside the module root.

An `e2e/` module takes every environment fact from `var.test_context` and **never from the
environment** — only secrets arrive as scalar `TF_VAR_*`. A `TF_VAR_` fixture has to be wired in the
harness repo as well, which is a second place for it to go missing.

See [.agents/skills/e2e-test/SKILL.md](.agents/skills/e2e-test/SKILL.md) (the `e2e-test` skill) for the full e2e testing conventions, including the `e2e/` structure, `test_context` wiring, `e2e/main.tf` and `*.tftest.hcl` conventions, the new-test checklist, and how to run and debug tests via the smoke-test runner.

---
Expand Down
4 changes: 2 additions & 2 deletions modules/meshstack/noop/e2e/runner/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module "backplane" {
source = "../../backplane"

meshstack_workspace_identifier = var.test_context.workspace
meshstack_endpoint = var.meshstack_endpoint
gcp_project_id = var.gcp_project_id
meshstack_endpoint = var.test_context.meshstack_endpoint
gcp_project_id = var.test_context.fixtures.gcp.project_id
gcp_region = var.gcp_region
gcp_resource_name_prefix = "noop-runner-${var.test_context.name_suffix}"
runner_display_name = "smoke-test-noop-runner-${var.test_context.name_suffix}"
Expand Down
2 changes: 1 addition & 1 deletion modules/meshstack/noop/e2e/runner/provider.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
provider "google" {
project = var.gcp_project_id
project = var.test_context.fixtures.gcp.project_id
region = var.gcp_region
}
20 changes: 10 additions & 10 deletions modules/meshstack/noop/e2e/runner/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ variable "test_context" {
workspace = string
project = string
name_suffix = string

# Base URL of the meshStack API, written into the runner config for API polling.
meshstack_endpoint = string

# Project the runner's Cloud Run service and Secret Manager secrets live in.
fixtures = object({
gcp = object({
project_id = string
})
})
})
nullable = false
}

variable "gcp_project_id" {
type = string
description = "GCP project ID for the runner Cloud Run service and Secret Manager secrets."
}

variable "gcp_region" {
type = string
default = "europe-west1"
description = "GCP region for the Cloud Run service and Secret Manager replicas."
}

variable "meshstack_endpoint" {
type = string
description = "Base URL of the meshStack API. Written into the runner config for API polling."
}
Loading