Get the repository's GitHub attach and its preview
GET/api/repos/{owner}/{repo}/github-attach
getGithubAttach
The attach in flight, else the most recent one, with its plan: every ref with how its local and GitHub tips compare (`class`) and what the attach does with it (`outcome`, and `preserved_as` where the local tip is kept under `neosource-preserved/`), every ref a confirmed attach would **publish** to GitHub, the open pull requests whose refs move, blockers (each with a `fix` code) and warnings. While the run is still `planning` the lists are empty and `upstream_shape` is `null`. `plan_hash` and `authority_epoch` are what `POST …/github-attach/confirm` must echo (`authority_epoch: null` when the repository has no relationship yet). Requires repository **admin**; `404` when the repository was never attached.
Requires authentication using a bearer token or a session cookie — see tokens and scopes.
curl
curl -X GET 'https://neosource.dev/api/repos/OWNER/REPO/github-attach' \
-H 'Authorization: Bearer $NEOSOURCE_TOKEN'fetch
fetch("https://neosource.dev/api/repos/OWNER/REPO/github-attach", {
method: "GET",
headers: {
Authorization: "Bearer $NEOSOURCE_TOKEN",
},
});Path parameters
ownerrequiredRepository owner or organization slug.
reporequiredRepository name.
Responses
200The attach and its preview
application/json
Standard errors
Bodies documented once for the whole API — see standard errors.
- 400Bad Request — one of: invalid_input
- 401Authentication required
- 403Forbidden — one of: forbidden
- 404Not Found — one of: not_found
- 423Locked — one of: busy
- 429Rate limited — retry after the `Retry-After` header
- 500Internal server error
- 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
- 504Gateway timeout — the request exceeded the server's handling budget
Schemas
Referenced above. Listed here rather than expanded inline, so the same definition is not repeated at every level.
AttachPrChange
What an attach does to an open pull request's refs.
"head_follows""head_preserved""base_moves"
GithubSyncBlocker
Everything that stops GitHub sync, enabling or ongoing: closed and typed, so the GitHub panel can name a fix for each. Each variant mirrors an existing core outcome rather than restating it: the binding ones are [`GithubAppBindingHealth`] values, `RulesetAudit` / `ProtectionEventsNotSubscribed` / `AdministrationReadMissing` are [`RulesetAuditOutcome`] refusals, `WritesRefused` is [`GithubWriteHealth::refuses_managed_writes`], the LFS ones are [`LfsVerificationResult`] verdicts. An empty or unrelated upstream is not a blocker (D11), nor is a tombstone (D7). Serialized internally tagged by `kind`, which is also [`Self::kind`].
The GitHub-sync offering is not enabled for this repository.
kindrequired"feature_not_offered"
No App installation is bound to the repository.
kindrequired"no_app_binding"
[`GithubAppBindingHealth::Unverified`], or `RulesetUnverified` with no refusing audit outcome recorded (awaiting a (re-)audit).
kindrequired"binding_unverified"
[`GithubAppBindingHealth::Error`]: the binding probe failed.
kindrequired"binding_error"
[`GithubAppBindingHealth::Revoked`].
kindrequired"binding_revoked"
[`GithubAppBindingHealth::InsufficientScope`].
kindrequired"binding_insufficient_scope"
The ruleset audit refused the binding for `outcome` ([`RulesetAuditOutcome::remedy`] is the fix). A struct variant because an internally tagged enum cannot carry a bare string newtype.
kindrequired"ruleset_audit"outcomerequired
[`RulesetAuditOutcome::ProtectionEventsNotSubscribed`], with the webhook events the installation has not accepted (from the audit's detail; display only).
kindrequired"protection_events_not_subscribed"missing_eventsrequired- items
[`RulesetAuditOutcome::ClassicProtectionUnreadable`] on an installation without `administration: read`.
kindrequired"administration_read_missing"
The write health refuses managed writes on its own ([`GithubWriteHealth::refuses_managed_writes`]).
healthrequiredkindrequired"writes_refused"
[`LfsVerificationResult::PointersDetected`] over the post-attach ref set, published refs included.
kindrequired"lfs_pointers_detected"
[`LfsVerificationResult::Unverified`], or no verification at all.
kindrequired"lfs_unverified"
The GitHub repository is archived.
kindrequired"github_archived"
GitHub advertises `refname` inside the preserved namespace.
kindrequired"github_advertises_preserved_prefix"refnamerequired
This repository already holds `refname` inside the preserved namespace.
kindrequired"local_ref_under_preserved_prefix"refnamerequired
No preserved name within [`MAX_REFNAME_BYTES`] can be formed for `refname`.
kindrequired"preserved_name_too_long"refnamerequired
A GitHub ref intent is not terminal (an `ambiguous` one included).
kindrequired"unsettled_ref_intent"
Another attach run for this repository is not settled.
kindrequired"unsettled_attach"
GithubSyncFix
The stable code the GitHub panel renders as the remedy for a [`GithubSyncBlocker`]. Closed, so the SPA's copy table is exhaustive; one code may answer several blockers ([`GithubSyncBlocker::fix`] is the map).
"contact_operator""install_github_app""wait_for_binding_audit""recheck_github_app""reinstall_github_app""grant_github_app_permissions""fix_github_rulesets""accept_github_app_events""resume_sync""check_write_health""remove_lfs_pointers""recheck_lfs""unarchive_github_repository""remove_preserved_refs_on_github""rename_local_ref""resolve_ref_intent""settle_attach"
AttachPublishKind
What a publish sends to GitHub: a branch or a tag, read off the refname.
"branch""tag"
AttachRefClass
How one ref's local and GitHub tips compare — the left column of D4.
"equal""local_behind""local_ahead""diverged""only_github""only_neosource"
AttachRefOutcome
What the attach does with one ref — the middle column of D4.
"keep""fast_forward""create""preserve_and_reset""preserve""drop""publish"