Skip to content

Commit 24ade3d

Browse files
docs: require env example updates in integration skills (#44)
* docs: require env example updates in integration test skill * docs: reinforce env example requirement across skills
1 parent 47f149a commit 24ade3d

4 files changed

Lines changed: 39 additions & 10 deletions

File tree

skills/building-integration/SKILL.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,16 +141,22 @@ pytest <name>/ -v
141141

142142
Only runs tests in `test_*_unit.py` files (configured in `pyproject.toml`).
143143

144-
### Step 5 — Auto-fix lint and formatting issues
144+
### Step 5 — Verify `.env.example` for integration-test env vars
145145

146-
If steps 2–4 report ruff errors, auto-fix with:
146+
If the integration has `test_*_integration.py` files, check whether they reference environment variables via `env_credentials(...)`, `os.environ.get(...)`, `os.getenv(...)`, `os.environ[...]`, or equivalent helpers. Every referenced variable must appear as a blank template entry in the repository root `.env.example`.
147+
148+
This is a manual review/build requirement: `.env` stays local and uncommitted, but `.env.example` is the committed contract that tells humans, reviewers, and automation what to provide.
149+
150+
### Step 6 — Auto-fix lint and formatting issues
151+
152+
If steps 2–5 report ruff errors, auto-fix with:
147153

148154
```bash
149155
ruff check --fix --config ../autohive-integrations-tooling/ruff.toml <name>
150156
ruff format --config ../autohive-integrations-tooling/ruff.toml <name>
151157
```
152158

153-
Then re-run steps 2–4 to confirm.
159+
Then re-run steps 2–5 to confirm.
154160

155161
## Ruff Configuration
156162

@@ -169,8 +175,9 @@ Key settings:
169175
2. Validate structure → `python ../autohive-integrations-tooling/scripts/validate_integration.py <name>`
170176
3. Check code → `python ../autohive-integrations-tooling/scripts/check_code.py <name>`
171177
4. Run tests → `pytest <name>/ -v`
172-
5. Fix issues → `ruff check --fix ...` / `ruff format ...`
173-
6. Re-run until all pass
178+
5. Verify integration-test env vars are listed in root `.env.example` (if applicable)
179+
6. Fix issues → `ruff check --fix ...` / `ruff format ...`
180+
7. Re-run until all pass
174181

175182
## Interpreting Output
176183

@@ -194,3 +201,4 @@ Key settings:
194201
| Config-code sync | Ensure actions in `config.json` match handlers in source code |
195202
| Missing test files | Create `tests/test_<name>_unit.py` (see `writing-unit-tests` skill) |
196203
| Import errors | Check `requirements.txt` has all dependencies; check `__init__.py` exports |
204+
| Integration tests use env vars but `.env.example` missing entries | Add blank entries for every referenced env var to root `.env.example` |

skills/migrating-private-integration/SKILL.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ The private repo accumulates files that don't belong in the public repo. Drop th
121121
| `__pycache__/`, `.pytest_cache/`, `.ruff_cache/` | Build artefacts. |
122122
| Internal-only documentation (`INTERNAL.md`, `RUNBOOK.md` referencing internal infra) | Keep in private repo or rewrite without internal references. |
123123
| `.env*` files | Should not exist anywhere; if they do, abort Step 1. |
124+
| Migrated integration tests reference env vars but root `.env.example` was not updated | Add blank entries for every referenced env var in the public repo's root `.env.example`. |
124125

125126
## Step 3 — Copy and adapt files
126127

@@ -152,6 +153,7 @@ cp ../integrations/<name>/tests/test_*.py ../autohive-integrations/<name>/t
152153
- `## Usage Examples` (1–3 realistic JSON examples)
153154
- `## Testing`
154155
- Strip any internal references (Slack channels, Notion links, employee names) from the README before copying.
156+
- **Root `.env.example`** → if migrated tests read environment variables, add every required and optional test variable to the public repo's root `.env.example` in the same PR. Include variables read through `env_credentials(...)`, `os.environ.get(...)`, `os.getenv(...)`, `os.environ[...]`, or equivalent helpers. Do **not** copy private `.env*` files; only add blank template entries such as `MYINTEGRATION_ACCESS_TOKEN=` and `MYINTEGRATION_TEST_ITEM_ID=`.
155157

156158
### Update the repo-level READMEs
157159

@@ -173,6 +175,7 @@ Required outcome:
173175
- `validate_integration.py``0` exit code (warnings about deprecated SDK pin are OK for a pure migration).
174176
- `check_code.py``✅ CODE CHECK PASSED`.
175177
- `pytest` → no failures (placeholder tests are fine; new tests are out of scope for a migration).
178+
- If migrated tests reference env vars, root `.env.example` includes all of them as blank template entries.
176179

177180
If anything fails, fix with:
178181

skills/upgrading-sdk-v2/SKILL.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,8 @@ async def real_fetch(url, *, method="GET", json=None, headers=None, **kwargs):
210210
)
211211
```
212212

213+
If the integration tests read credentials or test resource IDs from environment variables, also verify the repository root `.env.example` lists every variable used by those tests. Add missing entries in the same PR. This applies to variables read through `env_credentials(...)`, `os.environ.get(...)`, `os.getenv(...)`, `os.environ[...]`, or equivalent helpers. The local `.env` file remains uncommitted; `.env.example` is the committed setup contract for humans and tooling.
214+
213215
### Step 7 — Local validation (required before pushing)
214216

215217
Run the **same checks CI runs** locally. Skipping this step will result in CI failures. The tooling repo must be cloned alongside the integrations repo (see [CONTRIBUTING.md](CONTRIBUTING.md) for setup).
@@ -263,6 +265,7 @@ Before considering an integration upgraded, verify:
263265
- [ ] Unit test error assertions use `result.type == ResultType.ACTION_ERROR` and `result.result.message`
264266
- [ ] `pytest.raises(ValidationError)` replaced with `result.type == ResultType.VALIDATION_ERROR`
265267
- [ ] Integration test `real_fetch` returns `FetchResponse(...)` (if applicable)
268+
- [ ] Integration test env vars are documented in root `.env.example` (if integration tests read env vars)
266269
- [ ] `FetchResponse` and `ResultType` are imported where needed
267270
- [ ] All unit tests pass
268271
- [ ] `ruff check` and `ruff format --config ../autohive-integrations-tooling/ruff.toml` pass
@@ -299,3 +302,5 @@ Before considering an integration upgraded, verify:
299302
The 2.0.0 upgrade is the right time to catch this because you're already touching the auth path to convert error returns to `ActionError`.
300303

301304
10. **PyPI package name collision**: If your integration folder name matches a PyPI package the source imports (e.g. an integration in `supadata/` that does `from supadata import Supadata`), an empty `<integration>/__init__.py` will shadow the real PyPI package and every test fails with `ImportError`. Drop `<integration>/__init__.py` — the validator's "missing __init__.py" warning is correct to ignore in this case, and the Lambda runtime is unaffected (the entry point is the action source file, not the package). See the `writing-unit-tests` skill for the matching test-side guidance.
305+
306+
11. **Missing `.env.example` entries after touching integration tests**: SDK upgrades often touch `live_context` and credential handling. If the integration test file references `FOO_ACCESS_TOKEN`, `FOO_TEST_ID`, or similar, root `.env.example` must contain `FOO_ACCESS_TOKEN=`, `FOO_TEST_ID=`, etc. Do not rely on future contributors or automation to grep test code for setup requirements.

skills/writing-integration-tests/SKILL.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: writing-integration-tests
3-
description: "Writes pytest end-to-end integration tests for an Autohive integration that call real APIs using the live_context fixture pattern. Use when asked to write integration tests, add e2e tests, create live API tests, or test an integration against a real service. Covers file structure, live_context fixture variants, environment variable handling, destructive markers, and test organization."
3+
description: "Writes pytest end-to-end integration tests for an Autohive integration that call real APIs using the live_context fixture pattern. Use when asked to write integration tests, add e2e tests, create live API tests, or test an integration against a real service. Covers file structure, live_context fixture variants, required root .env.example updates, environment variable handling, destructive markers, and test organization."
44
---
55

66
# Writing Integration Tests for an Integration
@@ -125,9 +125,18 @@ class TestGetItem:
125125
...
126126
```
127127

128-
### .env.example Documentation
128+
### .env.example Documentation (required)
129129

130-
Document all required and optional environment variables in the integration's `.env.example`:
130+
If an integration test reads any environment variable, you **must** add that variable to the repository root `.env.example` in the same PR. This is not optional documentation — it is part of the integration-test deliverable.
131+
132+
Why this matters:
133+
- Humans can set up local integration tests without digging through test code for variable names.
134+
- Automated and AI tooling can discover which credentials, test IDs, and optional knobs it needs to ask for.
135+
- Reviewers have one canonical place to verify the local test contract.
136+
137+
Add every variable used by `env_credentials(...)`, `os.environ.get(...)`, `os.getenv(...)`, `os.environ[...]`, or equivalent helpers. Include both required credentials and optional test resource IDs. Keep real secrets only in local `.env`; never commit `.env`.
138+
139+
Use a clearly labeled block in root `.env.example`:
131140

132141
```bash
133142
# -- MyIntegration --
@@ -136,6 +145,8 @@ MYINTEGRATION_TEST_ITEM_ID=
136145
MYINTEGRATION_TEST_PROJECT_ID=
137146
```
138147

148+
Before finishing, cross-check the integration test file against `.env.example`: every env var referenced in tests must appear in `.env.example`, even if the test skips when it is missing.
149+
139150
## The live_context Fixture
140151

141152
The `live_context` fixture provides a `MagicMock` of the SDK's `ExecutionContext` but replaces the `fetch` method with a real async HTTP client using `aiohttp`. This lets the integration code run unchanged while making real network calls.
@@ -455,7 +466,7 @@ Write actions (create/update/delete) need at least:
455466
1. **Read the integration source** — understand each action and its auth mechanism
456467
2. **Check `config.json`** — determine auth type (none / API key / platform OAuth)
457468
3. **Choose the right `live_context` variant** — see the three variants above
458-
4. **Document env vars** in `.env.example`
469+
4. **Document env vars in root `.env.example` (required)** — add every env var referenced by the integration test file in the same PR
459470
5. **Write read-only tests first** — these are safe to run repeatedly
460471
6. **Add destructive tests** with `@pytest.mark.destructive` for write actions
461472
7. **Run read-only tests**:
@@ -483,7 +494,9 @@ Write actions (create/update/delete) need at least:
483494

484495
5. **Destructive test cleanup**: Always clean up created data at the end of lifecycle tests. Use `os.getpid()` in created object names to avoid collisions when running tests in parallel.
485496

486-
6. **OAuth token expiry**: Platform OAuth tokens expire. Document the refresh process in the integration's README or `.env.example`.
497+
6. **Missing `.env.example` entries**: If you add `env_credentials("FOO")`, `os.environ.get("FOO")`, or similar test env-var usage, add `FOO=` to root `.env.example` before you commit. Do not make reviewers or future contributors grep test files to discover setup requirements.
498+
499+
7. **OAuth token expiry**: Platform OAuth tokens expire. Document the refresh process in the integration's README or root `.env.example`.
487500

488501
## Reference Implementations
489502

0 commit comments

Comments
 (0)