Skip to content

GitHub Sync

Back up your project, track history, and collaborate via pull requests by connecting Doable to a GitHub repository.

Why connect GitHub

Every Doable project already has a local Git history (Versioning), but GitHub sync gives you:

  • Off-site backup: your code lives on GitHub even if you delete the project in Doable.
  • Full commit history: browse diffs, tag releases, and roll back from GitHub's UI.
  • Team collaboration: teammates can open PRs, leave inline reviews, and merge changes outside Doable.
  • CI/CD triggers: connect GitHub Actions, Vercel, Netlify, or any other pipeline to the repo.

You connect GitHub once at the account level; the same token is then available to all your projects.

  1. Open Settings → GitHub (top-right avatar → Settings).
  2. Click Connect GitHub.
  3. You are redirected to GitHub. Review the requested scopes (Doable asks for repo and read:user), then click Authorize.
  4. GitHub redirects you back to Doable. Your GitHub username appears next to a green indicator.

Your token is encrypted with the instance's ENCRYPTION_KEY and stored in the database. No one, including platform admins, can read the raw token.

Note

Doable requests repo scope (full access to public and private repos) so it can create repositories and push commits on your behalf. If you only want Doable to push to public repos, you can use a fine-grained personal access token instead; paste it in the Token field of the GitHub connect dialog.

Manage multiple GitHub accounts

Doable stores one GitHub token per user at a time. To switch accounts:

  1. Open Settings → GitHub.
  2. Click Disconnect. This removes the stored token. Any projects still linked to repos keep their github_repo_url but will need a reconnect before the next push.
  3. Click Connect GitHub and complete OAuth with the new account.

Existing project-repo links are preserved in the database; only the auth token is removed.

Sync a project

First push: creating the repo

Open the editor for your project and click the GitHub button in the toolbar (shows a gray dot when disconnected).

Fill in the dialog:

Field Notes
Repository name Auto-filled from your project name. You can change it.
Owner Your GitHub username or an org you have write access to.
Private On by default. Uncheck for a public repo.
Create new Creates the repo on GitHub automatically if checked. Uncheck to connect to an existing repo by the same name.

Click Connect. Doable:

  1. Creates the repo on GitHub (if "Create new" is checked).
  2. Pushes all project files as the initial commit on main.
  3. Stores the repo URL and marks the project as synced (green dot in toolbar).

Tip

Doable pushes over HTTPS using your stored OAuth token, with no SSH key setup required. For tighter access control (e.g. scoping push access to one repo only), create a GitHub fine-grained personal access token with Contents: Read and write on that repo and paste it into the Token field of the connect dialog.

Subsequent pushes

Click GitHub → Push in the toolbar (or from Project → GitHub). Enter a commit message and click Push. Doable commits the current project state and pushes to origin/main.

Pulling remote changes

If collaborators have pushed commits directly to GitHub, click GitHub → Pull. Doable fetches and merges the remote changes into the local project.

Conflict resolution

If a pull detects diverged history, Doable returns a 409 Conflict and prompts you to choose a resolution strategy:

Strategy Effect
Keep mine (ours) Discards remote changes; your local state wins.
Use theirs Discards local changes; GitHub's state wins.

To abandon the merge entirely, click Abort merge. No files are changed.

For complex conflicts, resolve them in a local clone, push from there, then pull in Doable.

What's pushed

Doable pushes all project files: HTML, CSS, JS, images, config files, and anything else in the project directory.

What is never pushed:

  • Environment variables set in Project → Settings → Environments: these stay server-side only.
  • Secrets injected by the AI at runtime.
  • Internal Doable metadata (.doable/ internals).

Troubleshooting

OAuth callback error (github_oauth_failed) The token exchange failed. Try reconnecting. If it persists, check that your browser isn't blocking the redirect from api.doable.me.

github_invalid_state The OAuth state parameter was lost (usually a browser extension or session issue). Try in a private/incognito window.

"No repo permission" on org repos GitHub organizations require you to grant the Doable OAuth app access in your org's Settings → Third-party Access. An org owner must approve the app, or you must use a personal access token with the required repo scope.

Token revoked / tokenExpired: true If you revoked the token from GitHub's side (GitHub → Settings → Applications → Authorized OAuth Apps → Revoke), Doable detects the expired state on the next status check. Open Settings → GitHub and reconnect.

Push rejected, "Conflict detected" The remote has commits your local project doesn't. Pull first, resolve any conflicts, then push.