Fold two overlapping local skills (scripts-shell, shell-scripts-module) into this one, keeping only what it did not already cover. - Add references/environment-model.md: the three-layer .env selector model, why set -a dot-sourcing beats export $(grep|xargs), tracked samples, the no-re-sourcing rule for module readers, and the deployment boundary (repo-presence is not git-tracked is not deployed). - Extend references/taskfile.md with the one-env-driven-task rule (no :default pairs) and composing commands through the task surface. - Add the lifecycle-hook module type to references/module-patterns.md. - Keep this skill's _moduleExampleV1_ naming as canonical; the retired skills' HL_V1_ and double-underscore dialects were not carried over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
113 lines
3.5 KiB
Markdown
113 lines
3.5 KiB
Markdown
# Taskfile Integration
|
|
|
|
Exposing module commands through the `task` runner.
|
|
|
|
Add a module `Taskfile.yml` only when its commands should be discoverable through `task`. A
|
|
module that is only consumed by other modules does not need one.
|
|
|
|
---
|
|
|
|
## 1. Module `Taskfile.yml`
|
|
|
|
```yaml
|
|
# https://taskfile.dev
|
|
|
|
version: "3"
|
|
|
|
tasks:
|
|
initialize-one:
|
|
cmds:
|
|
- |
|
|
./.scripts/module-example-v1/api/initialize-one.sh {{.CLI_ARGS}}
|
|
silent: true
|
|
```
|
|
|
|
Rules:
|
|
|
|
1. Task names mirror the public `api/` command names, unless an alias is deliberate. A task
|
|
named differently from the script it runs makes `task --list` output impossible to map back
|
|
to files.
|
|
2. Forward `{{.CLI_ARGS}}` whenever the command accepts flags.
|
|
3. `silent: true` suppresses task's own command echo, so only the script's logger output
|
|
appears.
|
|
4. Invoke the `api/` wrapper — never a `lib/` file directly.
|
|
5. The path is repository-root-relative, matching how the scripts source their dependencies.
|
|
|
|
Arguments pass through after `--`:
|
|
|
|
```bash
|
|
task module-example-v1:initialize-one -- --name demo --dry-run
|
|
```
|
|
|
|
Without the `--`, task treats the flags as its own and the script never sees them.
|
|
|
|
### One env-driven task, not a `:default` pair
|
|
|
|
Where the repository uses the layered environment model
|
|
(`references/environment-model.md`), the env layers already supply every value a task needs.
|
|
A module therefore needs **one** task, not a `<task>` + `<task>:default` pair that hardcodes
|
|
what the environment already provides:
|
|
|
|
```yaml
|
|
tasks:
|
|
initialize-one:
|
|
desc: Initialize using the .env layers (override with --flag=…)
|
|
cmds:
|
|
- ./.scripts/module-example-v1/api/initialize-one.sh {{.CLI_ARGS}}
|
|
silent: true
|
|
```
|
|
|
|
A `:default` wrapper duplicates configuration in a second place, and the two drift.
|
|
Environment-specific behaviour belongs in `.env-<env>`; one-off overrides belong in flags
|
|
after `--`.
|
|
|
|
### Composing commands
|
|
|
|
When an operator-facing command already exists, prefer calling it through `task` rather than
|
|
re-implementing or sourcing its internals, and pass parameters explicitly:
|
|
|
|
```bash
|
|
task keycloak:realm-registration-enable-one -- --realm-id="${KEYCLOAK_ROOT_REALM_ID}"
|
|
```
|
|
|
|
Composing at the task surface keeps the public contract the only contract. Reaching into
|
|
another module's `lib/` couples you to its internals and bypasses its reader and validator.
|
|
|
|
Do not add a second entrypoint for an operation that already has one unless it carries clear
|
|
operator value — duplicate entrypoints drift apart and it stops being obvious which is
|
|
authoritative.
|
|
|
|
---
|
|
|
|
## 2. Root `Taskfile.yml` include
|
|
|
|
```yaml
|
|
includes:
|
|
module-example-v1: ./.scripts/module-example-v1/Taskfile.yml
|
|
```
|
|
|
|
Rules:
|
|
|
|
1. Add a root include only for a module intended as a **stable public task namespace**. The
|
|
include name becomes a permanent user-facing prefix; renaming it later breaks every
|
|
documented command and every CI invocation.
|
|
2. Choose a short, clear namespace. Existing examples include `ca`, `kube`, `npmrc`,
|
|
`repos-local`, and `repos-local-nodejs`.
|
|
3. Do not add includes for experimental or in-progress modules — run them through their `api/`
|
|
path until the interface settles.
|
|
|
|
---
|
|
|
|
## 3. Verifying
|
|
|
|
```bash
|
|
# Every included namespace and task, with descriptions
|
|
task --list-all
|
|
|
|
# Confirm a specific task resolves and forwards arguments
|
|
task <module-alias>:<task-name> -- --dry-run
|
|
```
|
|
|
|
`task --list` shows only tasks carrying a `desc:`; `task --list-all` shows everything. A task
|
|
missing from `--list-all` means the root include is absent or its path is wrong.
|