|
| 1 | +--- |
| 2 | +name: migrating-private-integration |
| 3 | +description: "Migrates an Autohive integration from the private `Autohive-AI/integrations` repo to the public `Autohive-AI/autohive-integrations` repo. Use when asked to migrate, move, open-source, or publish an integration. Covers a mandatory security/safety/secrets review, structural cleanup, the three coordinated PRs (public add, private remove, SDK skill update if needed), and the obligatory ask in the AH engineering Slack channel for a second opinion before merging." |
| 4 | +--- |
| 5 | + |
| 6 | +# Migrating a Private Integration to the Public Repo |
| 7 | + |
| 8 | +This skill describes the process for moving an integration from the **private** [`Autohive-AI/integrations`](https://github.com/Autohive-AI/integrations) repo to the **public** [`Autohive-AI/autohive-integrations`](https://github.com/Autohive-AI/autohive-integrations) repo. |
| 9 | + |
| 10 | +> **🚨 Stop and read this first.** Once code is published to a public repo, deleting it does not "unpublish" it — git history, forks, and search-engine caches are forever. **Never** migrate without completing the security/safety/secrets review in Step 1, and **always** ask a second engineer in the AH Slack channel before merging the PRs. |
| 11 | +
|
| 12 | +## When to use this skill |
| 13 | + |
| 14 | +Trigger phrases: |
| 15 | + |
| 16 | +- "migrate the X integration to public" |
| 17 | +- "move X to the public repo" |
| 18 | +- "open-source X" |
| 19 | +- "publish X to autohive-integrations" |
| 20 | + |
| 21 | +## When NOT to use this skill |
| 22 | + |
| 23 | +- The integration is being **created from scratch** — it should go straight to the public repo if it's safe; use [building-integration](../building-integration/SKILL.md) and the [starter template](https://github.com/autohive-ai/integrations-sdk/tree/master/samples/template) instead. |
| 24 | +- The integration is being **removed** from the private repo without going public — that's a normal `chore: remove X` PR, not a migration. |
| 25 | +- The integration touches **internal Autohive infrastructure** (`agno-agent`, `file_echo`, `python-executor`, `testserver`, anything that wraps Dash/internal APIs) — these stay private. If unsure, ask in Slack before doing anything. |
| 26 | + |
| 27 | +## Prerequisites |
| 28 | + |
| 29 | +Before starting, the following repos must exist as siblings: |
| 30 | + |
| 31 | +``` |
| 32 | +parent-dir/ |
| 33 | +├── integrations/ ← private (source) |
| 34 | +├── autohive-integrations/ ← public (destination) |
| 35 | +├── autohive-integrations-tooling/ ← validation scripts |
| 36 | +└── integrations-sdk/ ← skill + docs |
| 37 | +``` |
| 38 | + |
| 39 | +Check: |
| 40 | + |
| 41 | +```bash |
| 42 | +ls ../integrations/<name> # the integration to migrate |
| 43 | +ls ../autohive-integrations # the public repo |
| 44 | +ls ../autohive-integrations-tooling/scripts/validate_integration.py |
| 45 | +``` |
| 46 | + |
| 47 | +Activate the public repo's venv (or create one — see [building-integration](../building-integration/SKILL.md) for setup): |
| 48 | + |
| 49 | +```bash |
| 50 | +cd ../autohive-integrations |
| 51 | +source .venv/bin/activate |
| 52 | +``` |
| 53 | + |
| 54 | +## Step 1 — Security / safety / secrets review (MANDATORY) |
| 55 | + |
| 56 | +This is the gate. If anything below is found and cannot be cleanly removed, **abort the migration** and discuss in Slack. |
| 57 | + |
| 58 | +### 1a. Static secret scan |
| 59 | + |
| 60 | +```bash |
| 61 | +# Hardcoded secrets, tokens, API keys, credentials |
| 62 | +grep -rni -E "secret|password|api[_-]?key|token|credential|client[_-]?id|client[_-]?secret|bearer|private[_-]?key" \ |
| 63 | + ../integrations/<name>/ \ |
| 64 | + --include='*.py' --include='*.json' --include='*.txt' --include='*.md' --include='*.yml' --include='*.yaml' \ |
| 65 | + | grep -v __pycache__ |
| 66 | +``` |
| 67 | + |
| 68 | +Expect **zero** real values. Documentation strings like `YOUR_API_KEY`, schema field names like `api_key`, and runtime extraction like `context.auth["credentials"]["access_token"]` are fine. Hardcoded JWT-shaped strings, base64 blobs, or anything that looks like a real key are **not**. |
| 69 | + |
| 70 | +### 1b. Internal hostnames, employee names, customer references |
| 71 | + |
| 72 | +```bash |
| 73 | +grep -rni -E "@autohive\.|autohive\.io|autohive-internal|dash\.|qa\.|staging\.|kai|alex|lohit|joel" \ |
| 74 | + ../integrations/<name>/ \ |
| 75 | + --include='*.py' --include='*.json' --include='*.txt' --include='*.md' \ |
| 76 | + | grep -v __pycache__ |
| 77 | +``` |
| 78 | + |
| 79 | +Investigate every match. Real customer URLs, employee emails, or internal hostnames must be removed or replaced with generic examples (`example.com`, `me@example.com`). |
| 80 | + |
| 81 | +### 1c. Trade secrets / proprietary business logic |
| 82 | + |
| 83 | +Read the source file end-to-end and ask: |
| 84 | + |
| 85 | +- Does it contain Autohive's *secret sauce* — e.g., proprietary scoring, internal pricing models, internal API contracts not visible to customers? |
| 86 | +- Does it duplicate or reveal internal Autohive platform internals (Dash internals, customer routing logic, billing logic)? |
| 87 | +- Is the integration logic itself a competitive moat we don't want to give away? |
| 88 | + |
| 89 | +If yes to any of these, **abort and discuss**. A "wrapper around a public third-party API" is almost never a trade secret. Anything that talks to internal Autohive systems probably is. |
| 90 | + |
| 91 | +### 1d. .env / credential files |
| 92 | + |
| 93 | +```bash |
| 94 | +find ../integrations/<name> -name '.env*' -o -name '*credentials*' -o -name '*secrets*' -o -name 'service-account*.json' |
| 95 | +``` |
| 96 | + |
| 97 | +These should not exist in the source tree. If they do, abort and clean up before re-attempting. |
| 98 | + |
| 99 | +### 1e. Run the GitHub secret scanner on the diff |
| 100 | + |
| 101 | +Use the `mcp__github__run_secret_scanning` tool (or equivalent CLI) on every text file you intend to publish. Don't skip — this catches things grep won't. |
| 102 | + |
| 103 | +### 1f. Icon and binary assets |
| 104 | + |
| 105 | +- Confirm the icon is a clean PNG (no embedded EXIF/metadata leaking employee names). |
| 106 | +- `file <name>/icon.png` — should report standard PNG with no comments. |
| 107 | + |
| 108 | +### 1g. Document the review in the PR body |
| 109 | + |
| 110 | +Use a table like the one in the Gmail migration PR (`Autohive-AI/autohive-integrations#322`). The reviewer should be able to see at a glance what was checked. |
| 111 | + |
| 112 | +## Step 2 — Identify and drop legacy artifacts |
| 113 | + |
| 114 | +The private repo accumulates files that don't belong in the public repo. Drop these before copying: |
| 115 | + |
| 116 | +| File / pattern | Why drop it | |
| 117 | +|---|---| |
| 118 | +| `integration.py` (vendored old SDK) | Public repo uses `autohive-integrations-sdk` from PyPI. | |
| 119 | +| `test_<name>_integration.py` (manual harness with `argparse --token`) | Replace with the public pytest pattern. | |
| 120 | +| `dependencies/` directory | Build artefact — should never be in source. | |
| 121 | +| `__pycache__/`, `.pytest_cache/`, `.ruff_cache/` | Build artefacts. | |
| 122 | +| Internal-only documentation (`INTERNAL.md`, `RUNBOOK.md` referencing internal infra) | Keep in private repo or rewrite without internal references. | |
| 123 | +| `.env*` files | Should not exist anywhere; if they do, abort Step 1. | |
| 124 | + |
| 125 | +## Step 3 — Copy and adapt files |
| 126 | + |
| 127 | +The public repo follows the standard SDK structure. Copy this minimal set: |
| 128 | + |
| 129 | +```bash |
| 130 | +mkdir -p ../autohive-integrations/<name>/tests |
| 131 | +cp ../integrations/<name>/config.json ../autohive-integrations/<name>/ |
| 132 | +cp ../integrations/<name>/<name>.py ../autohive-integrations/<name>/ |
| 133 | +cp ../integrations/<name>/icon.png ../autohive-integrations/<name>/ |
| 134 | +cp ../integrations/<name>/requirements.txt ../autohive-integrations/<name>/ |
| 135 | +touch ../autohive-integrations/<name>/__init__.py |
| 136 | +touch ../autohive-integrations/<name>/tests/__init__.py |
| 137 | +# Tests — copy if they're real pytest tests; otherwise create the placeholder structure |
| 138 | +cp ../integrations/<name>/tests/context.py ../autohive-integrations/<name>/tests/ 2>/dev/null |
| 139 | +cp ../integrations/<name>/tests/test_*.py ../autohive-integrations/<name>/tests/ 2>/dev/null |
| 140 | +``` |
| 141 | + |
| 142 | +### Adaptations to make |
| 143 | + |
| 144 | +- **`__init__.py`** → empty file (matches public repo convention). |
| 145 | +- **`requirements.txt`** → keep the SDK version pin from the source as-is (the migration is a *move*, not an *upgrade*; bumping the SDK is a separate PR using the [upgrading-sdk-v2](../upgrading-sdk-v2/SKILL.md) skill). |
| 146 | +- **`README.md`** → **rewrite** in the public repo style. Model it on a recent public README such as [`google-calendar/README.md`](https://github.com/Autohive-AI/autohive-integrations/blob/master/google-calendar/README.md). Sections: |
| 147 | + - `# <Name> Integration for Autohive` |
| 148 | + - `## Description` (what it does, key features) |
| 149 | + - `## Setup & Authentication` (auth type, scopes, fields) |
| 150 | + - `## Actions` (table or per-action breakdown) |
| 151 | + - `## Requirements` (from `requirements.txt`) |
| 152 | + - `## Usage Examples` (1–3 realistic JSON examples) |
| 153 | + - `## Testing` |
| 154 | +- Strip any internal references (Slack channels, Notion links, employee names) from the README before copying. |
| 155 | + |
| 156 | +### Update the repo-level READMEs |
| 157 | + |
| 158 | +- **Public repo `README.md`** — add a new section for the integration, alphabetically near related ones. |
| 159 | +- **Private repo `README.md`** — remove the integration's section and add it to a "Migrated to the Public Repo" list at the bottom so contributors know where the new home is. |
| 160 | + |
| 161 | +## Step 4 — Local validation |
| 162 | + |
| 163 | +From the public repo root, with the venv activated: |
| 164 | + |
| 165 | +```bash |
| 166 | +python ../autohive-integrations-tooling/scripts/validate_integration.py <name> |
| 167 | +python ../autohive-integrations-tooling/scripts/check_code.py <name> |
| 168 | +pytest <name>/ -v |
| 169 | +``` |
| 170 | + |
| 171 | +Required outcome: |
| 172 | + |
| 173 | +- `validate_integration.py` → `0` exit code (warnings about deprecated SDK pin are OK for a pure migration). |
| 174 | +- `check_code.py` → `✅ CODE CHECK PASSED`. |
| 175 | +- `pytest` → no failures (placeholder tests are fine; new tests are out of scope for a migration). |
| 176 | + |
| 177 | +If anything fails, fix with: |
| 178 | + |
| 179 | +```bash |
| 180 | +ruff check --fix --config ../autohive-integrations-tooling/ruff.toml <name> |
| 181 | +ruff format --config ../autohive-integrations-tooling/ruff.toml <name> |
| 182 | +``` |
| 183 | + |
| 184 | +See the [building-integration](../building-integration/SKILL.md) skill for the full validation playbook. |
| 185 | + |
| 186 | +## Step 5 — Coordinate three PRs |
| 187 | + |
| 188 | +Open one GitHub issue and one branch per repo. Cross-reference the PRs in each PR body so reviewers can see the complete picture. |
| 189 | + |
| 190 | +```diagram |
| 191 | +╭───────────────────────╮ ╭─────────────────────────╮ |
| 192 | +│ private: integrations │ │ public: autohive- │ |
| 193 | +│ chore/N/remove-<name> │ ──▶ │ integrations │ |
| 194 | +│ • delete <name>/ │ │ feat/N/migrate-<name>- │ |
| 195 | +│ • update README │ │ from-private │ |
| 196 | +╰───────────────────────╯ │ • add <name>/ │ |
| 197 | + │ • update README │ |
| 198 | + ╰─────────────────────────╯ |
| 199 | + ╭─────────────────────────╮ |
| 200 | + │ integrations-sdk │ |
| 201 | + │ (only if process changed│ |
| 202 | + │ → update this skill) │ |
| 203 | + ╰─────────────────────────╯ |
| 204 | +``` |
| 205 | + |
| 206 | +### PR titles (Conventional Commits) |
| 207 | + |
| 208 | +- Public repo: `feat(<name>): migrate <Name> integration from private repo` |
| 209 | +- Private repo: `chore(<name>): remove integration after migration to public repo` |
| 210 | +- SDK repo (if updating this skill): `docs(skills): refine migrating-private-integration skill` |
| 211 | + |
| 212 | +### Branch names |
| 213 | + |
| 214 | +- Public: `feat/<issue>/migrate-<name>-from-private` |
| 215 | +- Private: `chore/<issue>/remove-<name>-migrated-to-public` |
| 216 | +- SDK: `docs/<issue>/migrating-skill-update` |
| 217 | + |
| 218 | +### What each PR body must contain |
| 219 | + |
| 220 | +- A copy of the security/safety/secrets review table from Step 1. |
| 221 | +- Links to the companion PRs in the other repos. |
| 222 | +- The exact local validation output (validate + check_code). |
| 223 | +- `Closes #<issue>` for the matching issue in that repo. |
| 224 | + |
| 225 | +### Merge order |
| 226 | + |
| 227 | +1. **Public PR first.** Publishing has to succeed before the private code is removed. |
| 228 | +2. **Private PR second.** Once merged, the private location is gone and the README points to the new home. |
| 229 | +3. **SDK PR last** (if any). Skill updates are independent and should land after the migration so they reflect what actually happened. |
| 230 | + |
| 231 | +## Step 6 — Ask in the AH engineering Slack channel |
| 232 | + |
| 233 | +> **You are required to do this. Do not skip.** |
| 234 | +
|
| 235 | +Before merging the public PR, post in the AH engineering Slack channel (`#engineering`, `#integrations`, or whichever the team uses for this kind of review): |
| 236 | + |
| 237 | +> 👋 Migrating `<name>` from the private `integrations` repo to the public `autohive-integrations` repo. PR: <link>. Security/safety/secrets review is in the PR body. Could someone take a second look before I merge — particularly anything I might have missed under "internal references" or "trade secrets"? Thanks! |
| 238 | +
|
| 239 | +Wait for at least one explicit thumbs-up from another engineer before clicking merge. The review in the PR is mandatory but a second pair of eyes is what catches the things you missed because you wrote the PR. |
| 240 | + |
| 241 | +If the response surfaces a concern, **fix it before merging**, even if it means closing the PR and starting over. |
| 242 | + |
| 243 | +## Step 7 — Post-merge cleanup |
| 244 | + |
| 245 | +After all PRs merge: |
| 246 | + |
| 247 | +- Verify the integration appears in the public repo's `README.md`. |
| 248 | +- Verify the private repo no longer lists it (and the "Migrated" section does). |
| 249 | +- If any other repos (`autohive-blog`, `autohive-docs`, the platform repo) reference the old private path, open follow-up issues to update them. |
| 250 | +- Close the GitHub issues if `Closes #N` didn't auto-close them. |
| 251 | + |
| 252 | +## Common Failures and Fixes |
| 253 | + |
| 254 | +| Failure | Fix | |
| 255 | +|---|---| |
| 256 | +| Secret scan finds a `# nosec` test token like `"your_access_token_here"` | Fine — these are placeholders, no action needed. | |
| 257 | +| `validate_integration.py` warns about deprecated SDK | Acceptable for an as-is migration. Open a follow-up issue to upgrade with [upgrading-sdk-v2](../upgrading-sdk-v2/SKILL.md). | |
| 258 | +| `check_code.py` reports config-code sync warnings | These are warnings (⚠️), not failures (❌). Fine to leave for a migration; the integration was already running in production with these. | |
| 259 | +| Icon `file` reports embedded EXIF | Strip with `convert icon.png -strip icon.png` (ImageMagick) and re-commit. | |
| 260 | +| README mentions internal Slack channel / employee | Rewrite the section before copying. | |
| 261 | +| You discover a trade secret mid-migration | Stop. Close the public PR. Discuss in Slack. | |
| 262 | + |
| 263 | +## Reference Migration |
| 264 | + |
| 265 | +The Gmail migration is a complete worked example of this skill in action: |
| 266 | + |
| 267 | +- Public PR: [Autohive-AI/autohive-integrations#323](https://github.com/Autohive-AI/autohive-integrations/pull/323) |
| 268 | +- Private PR: [Autohive-AI/integrations#154](https://github.com/Autohive-AI/integrations/pull/154) |
| 269 | +- SDK PR (this skill): [Autohive-AI/integrations-sdk#43](https://github.com/Autohive-AI/integrations-sdk/pull/43) |
0 commit comments