You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: mandate bats tests for all new scripts in AGENTS.md and copilot-instructions.md
- Replaced the placeholder Testing section in AGENTS.md with full
bats suite documentation: test files table, what to test per script,
and the mock_curl.sh pattern with a code example
- Added step 7 (write tests) to the Adding a New Script checklist in
AGENTS.md; renumbered subsequent steps
- Updated CI/CD bullet to mention the bats test job
- Updated Maintenance Matrix 'Add a new script' row to include
tests/test_script_validation.bats
- Mirrored all changes in .github/copilot-instructions.md: expanded
Adding New Scripts checklist with mandatory test step, replaced
single-line Testing Approach with table + requirement prose
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+21-3Lines changed: 21 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -227,15 +227,33 @@ Uses API version `2026-03-10` and the new usage-metrics NDJSON endpoints (signed
227
227
3. Source `lib/github-common.sh` for validation and output helpers
228
228
4. Start with the standard boilerplate (see Script Anatomy above)
229
229
5. Create `action.yml` in the same directory — expose every env var as a named input (required inputs without defaults, optional inputs with sensible defaults); map CLI flags such as `--dry-run` and `--type` to boolean/string inputs and build an `ARGS` array in the `run:` step. Mirror the pattern of any existing `action.yml`.
230
-
6. Document in README.md following existing format:
230
+
6.**Add tests to `tests/test_script_validation.bats`** — mandatory. Add a labelled section with tests for every required env var missing (exit 1), unknown CLI args (exit 1), `--help` exits 0, and script-specific validation guards. See existing sections for the pattern.
231
+
7. Document in README.md following existing format:
231
232
- Use case description
232
233
- Required variables table
233
234
- Usage example with exports
234
235
- Output format (if applicable)
235
236
- Add a row to the Available Actions table in the "Using Scripts in GitHub Actions" section
236
237
237
238
### Testing Approach
238
-
-**Always test on a test organization first**
239
+
240
+
The project has a bats unit-test suite in `tests/`. Run the full suite with:
241
+
242
+
```bash
243
+
bats tests/
244
+
```
245
+
246
+
| File | What it covers |
247
+
|------|----------------|
248
+
|`tests/test_common.bats`|`lib/github-common.sh` pure-logic functions and API helpers |
|`tests/mock_curl.sh`| Universal curl mock used by both test files |
251
+
252
+
Every new script **must** include a test section in `tests/test_script_validation.bats` before it is merged. At minimum test: each required env var missing exits 1, unknown CLI args exit 1, and any enum or allowlist validation specific to the script.
253
+
254
+
Additional testing approaches:
255
+
-**Always test on a test organization first** before running against production
256
+
-**Dry-run flags** — several scripts support `--dry-run` to preview changes without applying them
| Add a new script |`action.yml` in the same directory; `README.md` (add use case, env var table, usage example, Available Actions table row) |
306
+
| Add a new script |`tests/test_script_validation.bats` (add a test section for the new script); `action.yml` in the same directory; `README.md` (add use case, env var table, usage example, Available Actions table row) |
289
307
| Add a new domain folder |`README.md` top-level structure description; `AGENTS.md` Repository Structure section |
290
308
|`.github/workflows/ci.yml` — shellcheck flags |`.githooks/pre-commit` shellcheck invocation (keep them in sync) |
|`tests/mock_curl.sh`| Universal drop-in curl mock (used by both test files); response data via env vars `MOCK_CURL_CODE`, `MOCK_CURL_BODY`, `MOCK_CURL_LINK`|
99
+
100
+
### What to test for every new script
101
+
102
+
1.**Missing required env vars** — one `@test` per required variable, in the order the script checks them. Each test asserts `status -eq 1`.
103
+
2.**Invalid CLI args** — unknown flag exits 1 with an "Unknown" message.
104
+
3.**`--help` flag** — exits 0 (for scripts that implement it).
105
+
4.**Recognised flags** — `--dry-run` and other known flags do not trigger the unknown-arg error (test by asserting output does *not* contain "Unknown").
Tests shadow real binaries by prepending a `MOCK_BIN` directory to `PATH`:
111
+
112
+
```bash
113
+
setup() {
114
+
MOCK_BIN="$(mktemp -d)"
115
+
# Fail gh auth so GITHUB_TOKEN is never auto-resolved from a session
116
+
printf'#!/bin/sh\nexit 1\n'>"$MOCK_BIN/gh"
117
+
chmod +x "$MOCK_BIN/gh"
118
+
}
119
+
120
+
teardown() { rm -rf "$MOCK_BIN"; }
121
+
122
+
@test "my-script: exits 1 when GITHUB_TOKEN is not set" {
123
+
run bash -c "export PATH='${MOCK_BIN}:${PATH}'; unset GITHUB_TOKEN; bash '${REPO_ROOT}/domain/my-script/my-script.sh'"
124
+
[ "$status"-eq 1 ]
125
+
}
126
+
```
127
+
128
+
Use `_mock_curl_200` (defined in `test_script_validation.bats`) when a test must reach code that runs after `validate_github_token`.
129
+
130
+
### Dry-run flags and other testing approaches
131
+
132
+
-**`--dry-run`** — several scripts support it to preview changes without applying them.
133
+
-**Test org first** — always run against a non-production GitHub org before production.
90
134
91
135
---
92
136
@@ -185,8 +229,9 @@ done
185
229
4.**Source the shared library** using `SCRIPT_DIR`
186
230
5.**Validate all inputs** before any API calls
187
231
6.**Create `action.yml`** in the same directory — expose every env var as an input (required inputs first, optional inputs with defaults); map CLI flags (`--dry-run`, `--type`, etc.) to boolean/string inputs and construct the `ARGS` array in the `run:` step. See existing `action.yml` files for the pattern.
188
-
7.**Add to README.md** — follow the existing format: use case, env var table, usage example, output format; add a row to the Available Actions table in the "Using Scripts in GitHub Actions" section
189
-
8. Place in the correct domain:
232
+
7.**Add tests to `tests/test_script_validation.bats`** — add a labelled section (`# ═══ github-<name> ═══`) with tests for: every required env var missing (exit 1), unknown CLI args (exit 1), `--help` exits 0, and any script-specific validation (enum guards, URL allowlists, positional args). See existing sections for the pattern.
233
+
8.**Add to README.md** — follow the existing format: use case, env var table, usage example, output format; add a row to the Available Actions table in the "Using Scripts in GitHub Actions" section
-**CI:** shellcheck runs on all `.sh` files on every PR (`.github/workflows/ci.yml`)
247
+
-**CI:** shellcheck runs on all `.sh` files on every PR (`.github/workflows/ci.yml`); bats unit tests run in a dedicated `test` job (`bats tests/`)
203
248
-**Releases:** automated by Release Please (`.github/workflows/release.yml`) — pushes to `main` trigger a release PR; merging it publishes the GitHub Release and tag
0 commit comments