Skip to content

test: exercise every documented task example#399

Merged
josegonzalez merged 10 commits into
mainfrom
388-exercise-every-documented-task-example-offline-validation-integration
Jul 18, 2026
Merged

test: exercise every documented task example#399
josegonzalez merged 10 commits into
mainfrom
388-exercise-every-documented-task-example-offline-validation-integration

Conversation

@josegonzalez

Copy link
Copy Markdown
Member

Nothing tested the documented task examples, so a snippet that would fail docket validate could ship straight into the generated task reference, which is how #323 slipped in. TestAllTaskExamplesValidate now decodes every registered task's examples the way the loader does, applies the field defaults, and runs the optional input validation offline as part of make test, covering any future task automatically. It flagged three tasks whose examples could not validate: the per-app snippets for the global-only letsencrypt-email property on dokku_haproxy_property and dokku_traefik_property, and the global snippet for the per-app-only rev-env-var on dokku_git_property, all corrected to the scope the property actually supports.

TestIntegrationTaskExamples then applies every example against a live Dokku under make test-integration, so the snippets are provably runnable and not merely valid. It provisions the app each example references, deploys the ones that need a running app, creates backing services, and provisions real material where a documented value is a placeholder that cannot apply verbatim, with the per-task prerequisites and opt-outs kept in one small policy so a new task is exercised by default and only genuinely special ones need an entry. The dokku_git_from_archive example pointed at a placeholder URL that could never apply, so it now references a real archive and runs as written.

The dokku_letsencrypt example applies against a real pebble ACME server in a dedicated CI job that reuses the dokku-letsencrypt harness, and the scheduler-k3s examples apply against a live cluster in the existing k3s job, so both classes of heavy-infra example are exercised in their own jobs while the default integration run applies everything else.

Closes #388.

Adds `TestAllTaskExamplesValidate`, which decodes every registered task's documented examples the way the loader does, applies the field defaults, and runs the optional input validation, so an example that would fail `docket validate` can no longer ship into the generated task reference. It runs as part of `make test` and covers any future task automatically. Correcting the examples it flagged fixes the per-app snippets for the global-only `letsencrypt-email` property on `dokku_haproxy_property` and `dokku_traefik_property` and the global snippet for the per-app-only `rev-env-var` on `dokku_git_property`, and replaces the unreachable placeholder archive URLs on `dokku_git_from_archive` with real ones so the example is runnable.
Adds `TestIntegrationTaskExamples`, a registry-driven driver that wraps each task's documented examples as a recipe, loads them through the real loader, and runs Plan then apply against a live Dokku, so every snippet in the task reference is provably runnable and not merely offline-valid. It provisions the app each example references, deploys the ones that need a running app, creates backing services, and provisions real material for the two tasks whose documented value is a placeholder that cannot apply verbatim. A small `exampleIntegrationPolicy` carries the per-task prerequisites and opt-outs, and the `dokku_letsencrypt` example is gated behind `DOKKU_TEST_LETSENCRYPT` so it applies against a pebble ACME server, so a new task is exercised by default and only genuinely special ones need an entry.
Adds a CI job that stands up a pebble ACME server by reusing the dokku-letsencrypt harness and runs the `dokku_letsencrypt` example under `DOKKU_TEST_LETSENCRYPT`, and extends the scheduler-k3s job to apply the scheduler-k3s examples against a live cluster, so both classes of heavy-infra example run in their own jobs while the default integration run applies everything else.
The `dokku_git_from_image` example referenced `dokku/node-js-app:latest`, which does not exist, and its second example pinned a build directory that the real image does not have; both now deploy `dokku/smoke-test-app:dockerfile`. The `dokku_git_sync` example synced `main`, but the repository's branch is `master`, so the build could never resolve the ref. These are the sources the apply-every-example integration driver deploys, so they must exist.
Teaches the example driver the setup a first CI run showed several examples need before they apply: enabling HTTP auth and adding the app's domains for the `http_auth` family, creating the named storage entry the `storage_mount` examples attach, writing a real maintenance-page tarball where the example only names a path, and redeploying `git_from_archive` from a fresh app so its second, same-content deploy is not rejected as unchanged. It also opts out `ps_scale`, `scheduler_k3s_autoscaling_auth`, and `service_backup`, whose examples need infra the environment does not provide, leaving them to the offline guard.
The letsencrypt job's `docker compose up` validated every service in the dokku-letsencrypt compose file, including the compose-mode dokku service whose bind mount is empty when `LETEST_HOST_DIR` is unset, so the stack failed to start before Pebble came up.
The apply-every-example driver shares a dokku instance with the per-task integration suite, and its extra deploys destabilized the existing deploy tests when both landed on the same shard. Running `TestIntegrationTaskExamples` in a dedicated, separately sharded job and skipping it in the per-task shards keeps each suite's load independent.
`git_from_image` and `git_from_archive` deploy the heavily reused example app late in a run and failed only in the isolated job, where every deploy example lands together; the same examples pass in the four-way per-task sharding. Matching that four-way split thins the per-shard deploy load, and the apply failure now reports the captured command output so any remaining deploy error is legible instead of an empty string.
The network_property global example sets `attach-post-create` to a network globally, and with no global-clear example that setting persisted for the rest of the run, so every later app build failed attaching to a network the environment no longer had. The example driver now creates that network before the examples and, on cleanup, clears the global property and removes the network, which is what left git_from_image, git_from_archive, and git_sync deploys failing depending on run order.
A property task's "Setting a global X" example has no global-clear counterpart, so the setting persisted for the rest of the run and broke later deploys - a leftover global network attachment or registry server made every subsequent app build fail against a resource the environment did not have. The driver now clears any global property an example sets once that example finishes, which generalizes the earlier network-specific workaround to every property family and removes the ordering sensitivity that surfaced different deploy failures per run.
@josegonzalez
josegonzalez merged commit 5eece6b into main Jul 18, 2026
19 checks passed
@josegonzalez
josegonzalez deleted the 388-exercise-every-documented-task-example-offline-validation-integration branch July 18, 2026 12:26
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.

test: exercise every documented task example (offline validation + integration)

1 participant