Skip to content

← All use cases

A password-gated static documentation build that an entire module drives

A gated documentation site, and a variable no tooling knew about

What makes it hard

Every scenario in the module failed on staging, with a message the step itself had written:

text
Error: this docs build is password-gated and DOCS_GATE_PASSWORD is not set — export it

The failure screenshot showed the gate: "This documentation is private. Enter the password to continue."

The variable was read directly by a project step. It was absent from .env.example, which the repository states is the contract for what an operator must supply. It was absent from the env: blocks of both CI workflows. And sdods doctor passed clean.

That last one is the finding. Doctor's variables check resolves every ${VAR} reference declared under envs/<env>.yaml vars: against the .env files and the shell. A variable that only a step reads is not in that set, so doctor reported a fully configured workspace for an environment where a whole module could not run. An operator who followed the setup instructions exactly ended up red.

It is a small bug with a general shape: configuration that bypasses the configuration system is invisible to the tools that check configuration.

How to cover it

The fix is one line of YAML and it generalises.

Declare the variable in the environment file, so it enters the set doctor knows about:

yaml
vars:
  docsGatePassword: ${DOCS_GATE_PASSWORD}

Then read it in the step through the template renderer rather than from process.env. Every {string} argument and every doc string is rendered, and variables resolve in order: values captured with I save the response JSON path ... as ..., then the current dataset row, then vars: from the environment file. ${VAR} references are resolved earlier, by configuration. Secrets stay references; they are never literals in a feature file or a YAML.

Now sdods doctor -p <slug> reports it missing instead of passing, and the same variable name goes into the workflow env: blocks as a repository secret.

The second half is a testing question rather than a configuration one. There was no scenario proving the gate works. A gate that nothing asserts is a gate nobody knows is closed. Two scenarios, and the more valuable one needs no secret at all:

  • the gate refuses without a password — runnable by anyone, on any machine, with nothing configured
  • the gate opens with the right password — the one that needs the secret, and the one that should skip cleanly when it is absent rather than failing the module
This is the general rule worth taking away: any value a test needs should be declared where sdods doctor can see it. If a step reaches around the environment file for something, the first symptom will be a green doctor over a red module, and that combination costs more to diagnose than either failure alone.

Scenario sketch

gherkin
@ui @sanity
Scenario: The documentation gate refuses an empty password
  Given I navigate to the "docs" page
  Then I should see the text "This documentation is private"
  And the "Unlock" button should be visible

@ui @smoke
Scenario: The documentation gate opens for the deploy password
  Given I navigate to the "docs" page
  When I fill the "Password" field with "{{docsGatePassword}}"
  And I click the "Unlock" button
  Then I should not see the text "This documentation is private"
  And the element with test id "docs-sidebar" should be visible
bash
sdods doctor -p <slug> --json

Once the variable is declared under vars:, that command is the thing that tells a new operator what to export — which is what .env.example was trying to be, and what doctor can actually enforce.

Other use cases