Skip to content

Commit 3e141f9

Browse files
docs: update tooling for SDK 2.0.1 (#47)
1 parent 5de0164 commit 3e141f9

32 files changed

Lines changed: 194 additions & 202 deletions

.github/workflows/self-test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ jobs:
103103
- name: Test check_code.py — long lines pass with ruff.toml config
104104
run: python scripts/check_code.py tests/examples/long-lines-integration
105105

106+
- name: Test run_tests.py — SDK 2.0.1 unit fixtures
107+
run: python scripts/run_tests.py tests/examples/good-integration tests/examples/modular-integration tests/examples/long-lines-integration tests/sample-api
108+
106109
- name: Test check_code.py — ruff.toml applied from different working directory
107110
run: |
108111
cd /tmp

CONTRIBUTING.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,11 @@ Run these before submitting a PR:
3636
# Validate structure and config
3737
python scripts/validate_integration.py my-integration
3838

39-
# Run all code quality checks (syntax, imports, JSON, lint, format, security, deps)
39+
# Run all code quality checks (syntax, imports, JSON, lint, format, security, deps, config sync, fetch pattern)
4040
python scripts/check_code.py my-integration
41+
42+
# Run unit tests when the integration has test_*_unit.py files
43+
python scripts/run_tests.py my-integration
4144
```
4245

4346
### What Gets Checked
@@ -53,6 +56,8 @@ python scripts/check_code.py my-integration
5356
| Security | `bandit` | No hardcoded secrets, unsafe eval/exec |
5457
| Dependencies | `pip-audit` | No known CVEs in requirements.txt |
5558
| Config sync | `check_config_sync.py` | Config.json actions and input schemas match code |
59+
| Fetch pattern | `check_fetch_pattern.py` | SDK 2.x `context.fetch()` responses are accessed via `.data` |
60+
| Unit tests | `run_tests.py` | Runs `test_*_unit.py` files with each integration's own dependencies |
5661

5762
### Auto-Fixing Common Issues
5863

@@ -85,7 +90,7 @@ docs: update Netlify README with auth setup
8590

8691
## Pull Request Process
8792

88-
1. **Run validation locally**both `validate_integration.py` and `check_code.py`
93+
1. **Run validation locally**`validate_integration.py`, `check_code.py`, and `run_tests.py` when unit tests exist
8994
2. **Update the main README.md** — add your integration to the integrations table
9095
3. **Use a conventional commit PR title** — CI enforces this
9196
4. **One integration per PR** — keep PRs focused
@@ -95,7 +100,8 @@ docs: update Netlify README with auth setup
95100
Your PR will automatically run:
96101

97102
- **Structure Check** — validates folder structure and config.json
98-
- **Code Check** — syntax, imports, JSON, lint, format, security, dependency audit
103+
- **Code Check** — syntax, imports, JSON, lint, format, security, dependency audit, config sync, fetch pattern
104+
- **Tests** — runs `test_*_unit.py` files with pytest and coverage
99105
- **README Check** — verifies the main README.md was updated
100106
- **Version Check** — verifies config.json version was incremented, recommends bump level
101107
- **Conventional Commits** — validates PR title format

INTEGRATION_CHECKLIST.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ The structure check produces warnings (not errors) for these cases:
5656

5757
| Warning | Explanation |
5858
|---------|-------------|
59-
| `Integration.load()` not found | The check looks for the literal string `Integration.load()`. Using `Integration.load(config_path)` triggers this warning — that's expected for multi-file integrations. |
59+
| `Integration.load(...)` not found | The check looks for `Integration.load` in Python files. Use `Integration.load()` for vendored single-file integrations, or `Integration.load(config_path)` / `Integration.load(Path(__file__).with_name("config.json"))` when an explicit config path is needed. |
6060
| Missing `__init__.py` | Optional for modular integrations with an `actions/` subdirectory |
6161
| Missing top-level `display_name` | Recommended but not required |
6262
| Missing `display_name` on actions | Recommended but not required |
@@ -144,9 +144,9 @@ but only list_sites and create_site are implemented:
144144
| Missing icon | Add `icon.png` or `icon.svg` (512×512 pixels) |
145145
| Missing or incomplete README | Document all actions, auth setup, inputs/outputs |
146146
| Not updating main repo README | Add integration entry in alphabetical order |
147-
| Unpinned SDK version | Use `autohive-integrations-sdk~=2.0.0` (or `~=1.1.1` for 1.x) |
147+
| Unpinned SDK version | Use `autohive-integrations-sdk~=2.0.1` (or `~=1.1.1` for 1.x) |
148148
| Sync functions for action handlers | Must be `async def execute()` |
149149

150150
---
151151

152-
*Last updated: March 2026*
152+
*Last updated: July 2026*

LOCAL_DEVELOPMENT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ python scripts/validate_integration.py my-integration
2727
Run this **first** — it catches structural problems before you waste time on code quality checks. It validates:
2828

2929
- Folder name is lowercase
30-
- All required files exist (`config.json`, `__init__.py`, `requirements.txt`, `README.md`, `icon.png`/`icon.svg`)
30+
- All required files exist (`config.json`, `requirements.txt`, `README.md`, `icon.png`/`icon.svg`; `__init__.py` is required for single-file/package-style integrations and optional for modular integrations with `actions/`)
3131
- `config.json` has the required fields and valid schema
3232
- `__init__.py` is minimal (only import + `__all__`)
33-
- `requirements.txt` includes `autohive-integrations-sdk`
33+
- `requirements.txt` includes `autohive-integrations-sdk~=2.0.1` or later in the SDK 2.x line
3434
- `tests/` folder has `__init__.py`, `context.py` or `conftest.py`, and at least one `test_*.py`
3535
- Icon is exactly 512x512 pixels
3636
- OAuth scopes are actually used (heuristic)

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ flowchart TB
6262
end
6363
6464
subgraph external["External Repos"]
65-
EXT["uses: autohive-ai/autohive-integrations-tooling@1.0.0"]
65+
EXT["uses: autohive-ai/autohive-integrations-tooling@v2"]
6666
end
6767
6868
PR --> wf1
@@ -108,7 +108,7 @@ jobs:
108108
with:
109109
fetch-depth: 0
110110

111-
- uses: autohive-ai/autohive-integrations-tooling@1.0.0
111+
- uses: autohive-ai/autohive-integrations-tooling@v2
112112
with:
113113
base_ref: origin/${{ github.base_ref }}
114114
```
@@ -139,6 +139,7 @@ jobs:
139139
| `tests_output` | Full output of the test runner |
140140
| `readme_output` | Full output of the README check |
141141
| `version_output` | Full output of the version check |
142+
| `comment_path` | Path to the rendered Markdown PR comment body, useful for fork-safe comment posting from a separate workflow |
142143

143144
### PR Comment
144145

@@ -215,7 +216,7 @@ See `INTEGRATION_CHECKLIST.md` for full details.
215216
- `config.json` - Integration configuration
216217
- `{name}.py` - Main implementation
217218
- `__init__.py` - Package init (minimal, optional for modular integrations with `actions/`)
218-
- `requirements.txt` - Dependencies (must include `autohive-integrations-sdk`)
219+
- `requirements.txt` - Dependencies (must include `autohive-integrations-sdk~=2.0.1` or later in the SDK 2.x line)
219220
- `README.md` - Documentation
220221
- `icon.png` or `icon.svg` - Integration icon (512x512 pixels)
221222
- `tests/` - Test folder with `__init__.py`, `context.py` or `conftest.py`, and `test_*.py`

scripts/docs/check_code.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,8 @@ Called by the `validate-integration.yml` workflow (on pull requests):
354354

355355
```yaml
356356
- name: Code Check
357-
if: steps.changed.outputs.dirs != ''
358-
run: python scripts/check_code.py --base-ref origin/${{ github.base_ref }} ${{ steps.changed.outputs.dirs }}
357+
if: steps.detect.outputs.dirs != ''
358+
run: python scripts/check_code.py --base-ref origin/${{ github.base_ref }} ${{ steps.detect.outputs.dirs }}
359359
```
360360
361361
Also exercised by the `self-test.yml` workflow against test examples in `tests/examples/` as a regression guard.

scripts/docs/check_readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ Called by the `validate-integration.yml` workflow, **only during pull requests**
122122

123123
```yaml
124124
- name: README Check
125-
if: steps.changed.outputs.dirs != ''
126-
run: python scripts/check_readme.py "origin/${{ github.base_ref }}" ${{ steps.changed.outputs.dirs }}
125+
if: steps.detect.outputs.dirs != ''
126+
run: python scripts/check_readme.py "origin/${{ github.base_ref }}" ${{ steps.detect.outputs.dirs }}
127127
```
128128
129129
This check is skipped on direct pushes since there is no meaningful base ref to compare against for README changes.

scripts/docs/run_tests.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ flowchart TD
7979
Different integrations may pin different SDK versions. For example:
8080

8181
- `bitly/requirements.txt``autohive-integrations-sdk~=1.0.2`
82-
- `notion/requirements.txt``autohive-integrations-sdk~=2.0.0`
82+
- `notion/requirements.txt``autohive-integrations-sdk~=2.0.1`
8383

8484
The test runner handles this by installing dependencies and running pytest separately for each integration. The last `pip install` overwrites the previous SDK version, which is why pytest must run immediately after each install.
8585

scripts/docs/validate_integration.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Allowed patterns:
147147
| Check | Severity | Description |
148148
|-------|----------|-------------|
149149
| `autohive-integrations-sdk` present | Error | SDK dependency is mandatory |
150-
| Version pinned and not deprecated | Warning | Should pin SDK version (e.g., `~=2.0.0`); deprecated versions warn |
150+
| Version pinned and not deprecated | Warning | Should pin SDK version (e.g., `~=2.0.1`); deprecated versions warn |
151151

152152
### 6. Tests Folder (`_check_tests_folder`)
153153

@@ -166,7 +166,7 @@ Inspects all `.py` files in the integration directory (not just the entry point)
166166
|-------|----------|-------------|
167167
| `Integration` imported | Warning | Should import from SDK |
168168
| `ActionHandler` imported | Warning | Should import from SDK |
169-
| `Integration.load()` called | Warning | Standard loading pattern |
169+
| `Integration.load(...)` called | Warning | Standard loading pattern, with or without an explicit config path |
170170

171171
> **Note:** Action decorator matching (config ↔ code) is handled by `check_config_sync.py`, which uses AST parsing for more accurate bidirectional validation.
172172
@@ -254,8 +254,8 @@ Called by the `validate-integration.yml` workflow (on pull requests) as the **St
254254

255255
```yaml
256256
- name: Structure Check
257-
if: steps.changed.outputs.dirs != ''
258-
run: python scripts/validate_integration.py ${{ steps.changed.outputs.dirs }}
257+
if: steps.detect.outputs.dirs != ''
258+
run: python scripts/validate_integration.py ${{ steps.detect.outputs.dirs }}
259259
```
260260
261261
The script is also exercised by the `self-test.yml` workflow, which runs it against the test examples in `tests/examples/` as a regression guard whenever `scripts/` or `tests/` change.

scripts/validate_integration.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def _check_init_py(self):
309309
# Integrations pinning older versions will receive a deprecation warning.
310310
_MIN_SDK_VERSIONS = {
311311
1: (1, 1, 1), # 1.x line: minimum 1.1.1
312-
2: (2, 0, 0), # 2.x line: minimum 2.0.0
312+
2: (2, 0, 1), # 2.x line: minimum 2.0.1
313313
}
314314

315315
def _check_requirements_txt(self):
@@ -330,7 +330,7 @@ def _check_requirements_txt(self):
330330
if not match:
331331
self.add_warning(
332332
"requirements.txt should pin SDK version "
333-
"(e.g., autohive-integrations-sdk~=2.0.0)"
333+
"(e.g., autohive-integrations-sdk~=2.0.1)"
334334
)
335335
return
336336

@@ -404,9 +404,9 @@ def _check_main_python_file(self):
404404
if item not in all_content:
405405
self.add_warning(f"Integration may be missing import: {item} ({source})")
406406

407-
# Check for Integration.load() across all Python files
408-
if 'Integration.load()' not in all_content:
409-
self.add_warning("Integration should use 'Integration.load()' to load the integration")
407+
# Check for Integration.load(...) across all Python files.
408+
if 'Integration.load' not in all_content:
409+
self.add_warning("Integration should use 'Integration.load(...)' to load the integration")
410410

411411
def _check_unused_scopes(self):
412412
"""Check for potentially unused scopes."""

0 commit comments

Comments
 (0)