GitHub Archiving Guide
When you publish a plugin with synapse plugin publish, the SDK can automatically archive the plugin source code to GitHub — creating a repository, pushing the code, tagging the version, and creating a GitHub Release with the ZIP asset.
Plugin Lifecycle Context
The synapse plugin CLI walks a plugin from scaffolding through distribution. Archiving is the lifecycle stage that gives every release a versioned, immutable source-of-truth on GitHub — distinct from publishing to the runtime Backend.
| # | Stage | CLI | What happens |
|---|---|---|---|
| 1 | Create | synapse plugin create | Interactive scaffolding of a new plugin directory. |
| 2 | Develop | synapse plugin run, synapse plugin test | Local execution and iterative testing. |
| 3 | Configure | synapse plugin update-config | Auto-discover actions and sync config.yaml. |
| 4 | Validate | synapse plugin publish --dry-run, --debug | Preview without uploading; debug bypasses backend validation. |
| 5 | Publish | synapse plugin publish | Uploads ZIP to the Synapse Backend (runtime registry). |
| 6 | Archive | synapse plugin publish (post-publish step) | When GitHub config is present, mirrors source to a GitHub repo, tags it, and creates a Release. Opt-in, non-blocking. |
| 7 | Distribute | synapse plugin publish -m plugin.yaml, synapse plugin package -m plugin.yaml [--offline] | Manifest-driven batch deploy / packaging from GitHub-archived releases. |
Why Archive?
GitHub archiving is its own lifecycle stage — not just a side-effect of publish — because it provides:
- Immutable source-of-truth per release. The same ZIP uploaded to the Backend is attached as a GitHub Release asset.
- Variant-branch isolation. Customer- or deployment-specific variants live on
variant/{name}branches with{version}+{variant}tags, isolated from the main release line. - Resolution basis for manifest-driven deploys.
synapse plugin publish -m plugin.yamlandsynapse plugin package -m plugin.yamlresolve plugin versions from GitHub Releases — not from local checkouts. - Recovery and re-deploy without local sources. Anyone with
repoaccess can re-publish a known release without holding the original working tree. - Audit trail. A timestamped, tagged record of exactly what source was published when.
Backend vs GitHub
| Backend | GitHub Archive | |
|---|---|---|
| Role | Runtime registry for Synapse Agents | Versioned source archive |
| Consumed by | Agents at execution time | publish -m, package -m, humans browsing source |
| When written | Every formal synapse plugin publish | Same call, post-publish step (when GitHub configured) |
| Failure impact | Blocks publish (must succeed) | Logged warning only — Backend publish still succeeds |
Failure of one does not block the other.
Before setting up GitHub archiving:
- Complete Authentication (
synapse login) - Prepare a GitHub Personal Access Token with
reposcope - Know your GitHub organization name (default:
synapse-plugins)
Overview
At a Glance
| Feature | Command / Config | Description |
|---|---|---|
| Setup | synapse plugin github-setup | Configure GitHub token and organization |
| Remove | synapse plugin github-clear | Remove GitHub configuration |
| Auto-archive | synapse plugin publish | Automatically archives on formal publish |
| Batch publish | synapse plugin publish -m plugin.yaml | Fetch from GitHub and publish to Backend |
| Env vars | SYNAPSE_GITHUB_TOKEN, SYNAPSE_GITHUB_ORG | Override config file settings |
How It Works
GitHub archiving is opt-in and non-blocking:
- Opt-in: Only activates when GitHub config is present (
github-setupcompleted) - Non-blocking: If GitHub archiving fails, the Backend publish still succeeds — you get a warning, not an error
- Debug skip:
synapse plugin publish --debugskips GitHub archiving entirely for fast iteration
Setup
Configure GitHub Integration
Run the interactive setup:
synapse plugin github-setup
You will be prompted for:
- GitHub personal access token — Needs
reposcope for creating repositories and releases - GitHub organization — Where plugin repos will be created (default:
synapse-plugins)
The command validates your token by calling the GitHub API before saving.
You can also provide values directly:
synapse plugin github-setup --token ghp_xxxxxxxxxxxx --org my-org
Configuration is saved to ~/.synapse/config.json under the github key.
Environment Variables
Environment variables take priority over the config file:
| Variable | Description |
|---|---|
SYNAPSE_GITHUB_TOKEN | GitHub personal access token |
SYNAPSE_GITHUB_ORG | GitHub organization name |
# Set via environment (useful for CI/CD)
export SYNAPSE_GITHUB_TOKEN=ghp_xxxxxxxxxxxx
export SYNAPSE_GITHUB_ORG=my-org
Good to know: If both environment variables are set, the config file is not read at all. If only one is set, the other falls back to the config file.
Remove Configuration
# Interactive confirmation
synapse plugin github-clear
# Skip confirmation
synapse plugin github-clear -y
Auto-Archiving Workflow
When you run synapse plugin publish (without --debug), the SDK executes these steps after a successful Backend upload:
What Gets Archived
- All plugin source files, filtered by
.synapseignorerules - Files larger than 100MB are automatically skipped
- The same ZIP uploaded to Backend is attached as a GitHub Release asset
Output Example
A successful publish with GitHub archiving shows:
Using config: config.yaml
Plugin: my-plugin v1.2.0 (neural_net)
Archive: 15 files, 45.2 KB
✓ Published to Backend (release_id: 42)
╭─ GitHub ──────────────────────────────────────╮
│ GitHub archived! │
│ │
│ Repo: https://github.com/my-org/my-plugin │
│ Tag: 1.2.0 │
│ Release: https://github.com/my-org/my-plugin/ │
│ releases/tag/1.2.0 │
╰────────────────────────────────────────────────╯
If GitHub archiving fails, you see a warning instead:
Warning: GitHub archiving failed: <error details>
The plugin was published to Backend successfully.
GitHub sync can be retried later.
Variant Branch Strategy
Plugins can have variants — customized builds for specific customers or deployments. Each variant uses its own branch and tag scheme.
Branch Rules
| Variant | Branch | Example |
|---|---|---|
| None (default) | main | main |
lig | variant/lig | variant/lig |
ke | variant/ke | variant/ke |
Tag Rules
| Variant | Tag Format | Example |
|---|---|---|
| None | {version} | 1.2.0 |
lig | {version}+{variant} | 1.2.0+lig |
ke | {version}+{variant} | 1.2.0+ke |
The + follows SemVer build metadata convention.
Repository Structure
A plugin with multiple variants creates this structure on GitHub:
github.com/{org}/{plugin-code}/
├── main branch
│ └── tags: 1.0.0, 1.1.0, 1.2.0
├── variant/lig branch
│ └── tags: 1.0.0+lig, 1.1.0+lig
└── variant/ke branch
└── tags: 1.0.0+ke
Set the variant in your plugin's config.yaml:
code: my-plugin
version: "1.2.0"
variant: lig # Optional — omit for default variant
Manifest-Based Batch Publish
For deploying multiple plugins at once, use a plugin manifest (plugin.yaml).
Writing plugin.yaml
plugins:
yolo_test:
version: ">=2.0.0"
sam2-smart-tool:
version: ">=1.0.0"
Each entry specifies a plugin code and a PEP 440 version specifier. The SDK resolves the best matching version from GitHub releases.
Short form (latest version):
plugins:
yolo_test:
sam2-smart-tool:
Batch Publish
# Resolve from GitHub → download → publish to Backend
synapse plugin publish -m plugin.yaml
# Debug mode (skip backend validation)
synapse plugin publish -m plugin.yaml --debug
Transitive Dependency Resolution
If a plugin declares dependencies in its config.yaml, those dependencies are automatically resolved and included:
plugin.yaml: [sam2-smart-tool] (1 declared)
↓ resolve + download
sam2-smart-tool
→ dependencies: { segment-anything-2: ">=2.0.0" }
↓ auto-added
segment-anything-2 (2 total processed)
The SDK uses BFS (breadth-first search) with cycle detection to handle transitive dependencies.
Batch Packaging
You can also package plugins for offline deployment:
# Standard packaging (code only)
synapse plugin package -m plugin.yaml
# Offline packaging (code + Python wheels)
synapse plugin package -m plugin.yaml --offline
Safety Features
Remote Mismatch Warning
Before archiving, the SDK checks if the plugin directory has a local .git/config with a remote origin URL. If that URL points to a different {org}/{repo} than the archive target, a warning is displayed:
Warning: local git remote (personal-org/my-plugin) does not match
archive target (datamaker-kr/my-plugin)
This prevents accidentally creating duplicate repos across organizations.
Pre-flight Organization Check
For manifest-based batch operations (publish -m, package -m), the SDK validates GitHub token permissions before processing any plugins:
- Calls
GET /orgs/{org}to verify token access - Fails early if the token lacks organization access
- Prevents partial failures in batch operations
Fatal Error Early Termination
During batch publish/package, if a fatal error occurs (HTTP 401 Unauthorized or 403 Forbidden), the SDK stops immediately instead of continuing with remaining plugins — since all subsequent operations would fail with the same authentication error.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| "GitHub not configured" | No token/org saved | Run synapse plugin github-setup |
| "Invalid GitHub token" | Token expired or wrong scope | Generate a new PAT with repo scope |
| 404 on org access | Token lacks org permission | Authorize the token for the organization in GitHub Settings |
| "No files to archive" | All files excluded by .synapseignore | Check .synapseignore rules |
| Remote mismatch warning | Local git remote differs from archive target | Verify the correct org in github-setup |
| GitHub archive failed | Network issue or API rate limit | Backend publish still succeeded; retry later |
| Batch publish partial failure | Mixed auth/network errors | Check the summary output for per-plugin status |
Related
- CLI Usage Guide — Full CLI command reference
- Plugin Development — Publishing workflow overview
- Semantic Versioning — Version format reference
- PEP 440 — Version specifier syntax for manifest files