# GitHub

> How midcode publishes to GitHub: which account pushes when your Mac has several, how to connect one, and where its token is kept.

- Page: https://midcode.app/docs/publish/github
- From the midcode docs. Every page as Markdown: https://midcode.app/llms.txt

You don't have to connect anything to publish to GitHub. [Publish](https://midcode.app/docs/publish/publish.md) is `git push`, and git uses whatever your Mac already has: an ssh key, a credential helper, the GitHub CLI.

What midcode adds for a repository on GitHub is the choice of account. Many people have more than one (their own, a client's), and git pushes as whichever one the Mac answers with, usually the wrong one for half the repositories. midcode asks GitHub which of your accounts can push to this repository and pushes as that one. Connecting an account in Settings gives it one more account to try, and lets it push over https on a Mac with no git credentials set up at all.

## Which account pushes

Before a push to a `github.com` remote, https or ssh, midcode does three things:

1. It gathers the accounts it can use: the one connected in midcode, then every account logged in to the GitHub CLI (`gh auth status`). The CLI's accounts count even if you never connected anything in midcode.
2. It asks GitHub about each one, in that order: can this account push to this repository?
3. It pushes as the first one that can. The Publish panel says who, after the commit and the branch: "as your-login".

The answer is remembered for that repository until you quit midcode.

If none of them can push, git goes on with the Mac's own setup, as if midcode had done nothing. If that fails too, midcode names the accounts it tried: "None of your GitHub accounts (studio, personal) can push to client/site. Log in with the account that has access (in Terminal: gh auth login; it adds the account, yours stays), then try again." Do that, then press "Push" in Publish.

## How the push is made

When midcode has found the account, the push is this:

```bash
git -c credential.helper= -c credential.https://github.com.helper= push
```

- The two `-c` settings turn your credential helpers off for this one command. Otherwise a helper would answer first, as another account. Your git config isn't changed.
- The account's token reaches git through `GIT_ASKPASS`: a small script of midcode's that answers git's question from an environment variable set for that command only. The token is never written into the remote's URL, into your git config or into the script.

### A remote over ssh

An ssh remote (`git@github.com:client/site.git`) pushes with your ssh key, and that key belongs to one account. If that push fails and midcode has an account that can push, it sends the same commits over https instead:

```bash
git push https://github.com/client/site.git HEAD:refs/heads/main
```

Then it records what a push to `origin` would have recorded (the remote branch, and the upstream if the branch had none), so `git status` agrees. Your remote's URL stays as it was.

## Connect an account

Open Settings with `⌘,`. Under "Connections" ("Optional. midcode works without them."), click "Connect" beside GitHub. There are three ways in.

### Sign in with GitHub

1. Click "Sign in with GitHub".
2. midcode shows a one-time code and opens GitHub's device page in your browser. Click the code to copy it.
3. Type the code on that page and approve.
4. midcode says "Connected to GitHub as your-login".

This is the GitHub CLI's own browser sign-in (`gh auth login --web`), which midcode runs for you, asking for the `repo` and `read:user` scopes. So it needs the GitHub CLI: without it, midcode says "Signing in with GitHub needs the GitHub CLI for now (brew install gh), or paste a token." It also means the account is signed in to the GitHub CLI on your Mac, not only in midcode.

### Use my GitHub CLI login

This button shows when the GitHub CLI is already logged in. midcode takes the token of the CLI's active account (`gh auth token`). The row then reads "via CLI" beside the account.

### Use a token instead

1. Click "Use a token instead".
2. Paste a fine-grained personal access token with "Contents: read and write" on the repositories you publish to. "Create one" opens GitHub's page for it.
3. Click "Connect".

Whichever way you choose, midcode checks the token with GitHub before it keeps it. A token that doesn't work gets "That token didn't work. Check it and its permissions."

"Disconnect" makes midcode forget the account. It doesn't revoke the token on GitHub and it doesn't log the GitHub CLI out.

## Where the token is kept

- It's encrypted with the macOS Keychain and stored in midcode's own data folder, not in your project. On a Mac that can't encrypt it, midcode refuses to store it.
- It lives in the app's main process. The window that draws the interface gets the account's name, login and picture, never the token.
- It goes to two places only: `api.github.com`, to check the account and ask about a repository, and the `git push` of your project's own GitHub remote. Never to midcode's servers or to any other host.

More in [Privacy and security](https://midcode.app/docs/reference/privacy.md).

## What midcode does with GitHub

It does three things:

- It reads who the account is.
- It asks whether the account can push to the repository you're publishing.
- It pushes the commits you made in Publish, and links to them with "View commit".

It never does these:

- Force-push, or rewrite history.
- Open, review or merge pull requests.
- Create repositories, or change a repository's settings.
- Read your issues, your organizations or your other repositories.

## Other git hosts

Publishing is plain git, so any remote your Mac can push to works: GitLab, Bitbucket, a server of your own. "View commit" also links to `gitlab.com` and `bitbucket.org`. Choosing the account is for repositories on `github.com`. A GitHub Enterprise host goes the plain git way.

## Troubleshooting

**"Repository not found", or a 403.** The account that pushed can't see the repository. In a terminal, run `gh auth login` with the account that has access (it's added beside the one you have), then press "Push" in Publish.

**The sign-in never finishes.** "Sign-in didn't finish. Try again, or paste a token." Use "Open the page again" if the browser tab was lost, or "Cancel" and paste a token.

**A push worked before and now fails.** A token can expire or be revoked. Disconnect and connect again. Meanwhile git falls back to the Mac's own credentials.

**The commit went out under the wrong name.** The account that pushes isn't the commit's author. The author is the name and email in your git config (`git config user.name`, `git config user.email`).
