Skip to content

Importing from GitHub

There are two ways to get an existing repository into neosource, and a separate opt-in for keeping its issues in sync afterwards.

Start at /new.

The simplest path, and it is not GitHub-specific: paste any public HTTPS Git URL and neosource clones it.

POST /api/imports/url

No OAuth, no token, no account linkage. The URL is validated when the import is queued — it must be HTTPS, must not carry embedded credentials, and must resolve to a publicly routable host.

Use this for public repositories, or for sources other than GitHub.

Link your GitHub identity and import by owner/name instead of a URL. This is what you need for private repositories, and it avoids the rate limits that apply to anonymous clones.

GET /api/github/repos # list repositories you can import
POST /api/github/imports # start an import

The import runs with your stored GitHub OAuth token. Because it is addressed by owner/name rather than a free-form URL, there is no user-supplied URL in the clone path at all.

The web UI wraps this at /onboarding/github.

GET /api/repos/{owner}/{repo}/import-status

Importing brings the code. Issues, comments and labels are a separate opt-in, available only for repositories that came in through the authenticated GitHub import — a repository imported from a plain URL has no GitHub identity to sync against.

POST /api/repos/{owner}/{repo}/github-sync # enable
GET /api/repos/{owner}/{repo}/github-sync # status

or in the UI at /<owner>/<repo>/settings/github-sync.

Two modes:

Mode Behaviour
Synced Field-split. GitHub owns issue title, body, open/closed state, comments and labels. neosource owns the planning overlay on top — lane, priority, cycle, assignees.
Mirror (read-only) A read-only mirror of the GitHub metadata, with no overlay editing.

The split in Synced mode is the point: GitHub stays the system of record for the conversation, while the planning layer that GitHub does not have lives in neosource and does not fight it.

Enabling sync requires:

  • repo admin on the neosource repository,
  • a linked GitHub identity with a stored access token — that account becomes the importer whose token the backfill and subsequent polls run on,
  • a repository that was imported from GitHub, and
  • a repository with no natively-created issues or pull requests yet.

That last one is a hard constraint, not a soft preference. Enabling sync reserves the issue-numbering band, and existing content cannot be renumbered afterwards — so sync can only be turned on for a freshly imported repository. Decide before you start filing issues.

If a sync exhausts its failure budget it enters an error state. Calling the enable endpoint again re-arms it: the state returns to backfilling and the backfill resumes from where its cursors left off, rather than starting over.

Your workflows will not run. neosource reads .neosource/workflows/, and .github/workflows/ is ignored entirely — with no warning. An imported repository with a full set of GitHub Actions workflows simply has no CI until you move and adapt the files.

Start with Coming from GitHub Actions, which covers what carries over unchanged and what has to be rewritten. The main rewrite is that jobs declare tools with packages: rather than choosing a container image — see the job environment.