Skip to main content

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.

#StageCLIWhat happens
1Createsynapse plugin createInteractive scaffolding of a new plugin directory.
2Developsynapse plugin run, synapse plugin testLocal execution and iterative testing.
3Configuresynapse plugin update-configAuto-discover actions and sync config.yaml.
4Validatesynapse plugin publish --dry-run, --debugPreview without uploading; debug bypasses backend validation.
5Publishsynapse plugin publishUploads ZIP to the Synapse Backend (runtime registry).
6Archivesynapse 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.
7Distributesynapse 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.yaml and synapse plugin package -m plugin.yaml resolve plugin versions from GitHub Releases — not from local checkouts.
  • Recovery and re-deploy without local sources. Anyone with repo access 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

BackendGitHub Archive
RoleRuntime registry for Synapse AgentsVersioned source archive
Consumed byAgents at execution timepublish -m, package -m, humans browsing source
When writtenEvery formal synapse plugin publishSame call, post-publish step (when GitHub configured)
Failure impactBlocks publish (must succeed)Logged warning only — Backend publish still succeeds

Failure of one does not block the other.

Prerequisites

Before setting up GitHub archiving:

  • Complete Authentication (synapse login)
  • Prepare a GitHub Personal Access Token with repo scope
  • Know your GitHub organization name (default: synapse-plugins)

Overview

At a Glance

FeatureCommand / ConfigDescription
Setupsynapse plugin github-setupConfigure GitHub token and organization
Removesynapse plugin github-clearRemove GitHub configuration
Auto-archivesynapse plugin publishAutomatically archives on formal publish
Batch publishsynapse plugin publish -m plugin.yamlFetch from GitHub and publish to Backend
Env varsSYNAPSE_GITHUB_TOKEN, SYNAPSE_GITHUB_ORGOverride config file settings

How It Works

GitHub archiving is opt-in and non-blocking:

  • Opt-in: Only activates when GitHub config is present (github-setup completed)
  • Non-blocking: If GitHub archiving fails, the Backend publish still succeeds — you get a warning, not an error
  • Debug skip: synapse plugin publish --debug skips GitHub archiving entirely for fast iteration

Setup

Configure GitHub Integration

Run the interactive setup:

synapse plugin github-setup

You will be prompted for:

  1. GitHub personal access token — Needs repo scope for creating repositories and releases
  2. 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:

VariableDescription
SYNAPSE_GITHUB_TOKENGitHub personal access token
SYNAPSE_GITHUB_ORGGitHub 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 .synapseignore rules
  • 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

VariantBranchExample
None (default)mainmain
ligvariant/ligvariant/lig
kevariant/kevariant/ke

Tag Rules

VariantTag FormatExample
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

ProblemCauseSolution
"GitHub not configured"No token/org savedRun synapse plugin github-setup
"Invalid GitHub token"Token expired or wrong scopeGenerate a new PAT with repo scope
404 on org accessToken lacks org permissionAuthorize the token for the organization in GitHub Settings
"No files to archive"All files excluded by .synapseignoreCheck .synapseignore rules
Remote mismatch warningLocal git remote differs from archive targetVerify the correct org in github-setup
GitHub archive failedNetwork issue or API rate limitBackend publish still succeeded; retry later
Batch publish partial failureMixed auth/network errorsCheck the summary output for per-plugin status