# Pushing

> The push sheet, pushing as yourself or as the bot, confirmation, retries and the history.

Choose **Changes**, then **Review and push**, to open the push sheet.

![The push sheet: new issues with their bodies and labels, how many people will be notified, Push as You or Tack's bot, and Push 10 changes.](https://tack.social/_astro/push-light.QcVjUCaM_2S3Ej.webp)

## Reviewing

The sheet groups the changes by repository, then by kind: new issues, pull requests, discussions, sub-issues, blocked-by, labels, assignees, milestones, closing and reopening, and comments.

- **Previews** show exactly what will be written: each issue’s title, body, labels, assignees and milestone; each comment; a pull request’s branch and files. Markdown is shown as it’ll read on GitHub.
- **Notifications**: each repository says roughly how many people its changes will notify (“Notifies \~40 people”). New issues, pull requests, discussions, comments and closing or reopening notify the repository’s watchers; labels, milestones and links are quiet. People being assigned hear about it too.
- **Switches** leave a change, or a whole group, out of your push. It’s your choice alone, for this push: nobody else’s push changes. Leaving out a new issue also leaves out the changes about it. Changes to repositories without the [GitHub App](https://tack.social/self-hosting/github-app.md) start left out, since they’d be refused; tick them back in once it’s installed.
- **Corrections**: a new issue’s title and description can be reworded in place, and its labels, milestone and assignees changed with the same pickers as Make issues. Words that came from a sticky are written back to the sticky, so the board and the issue agree. Issues with no description read as one compact line.
- **Where it came from**: new issues made from stickies or sections end with a short line linking back to the board, naming the section and who wrote the sticky (“From _EmDash planning_ › Plugin API, an idea by @priya”), since GitHub shows whoever pushed as the author. It’s on by default, with a switch in the sheet, remembered for each board, and the previews show it.
- Each change says what happens on the board afterwards, such as “On the board, its sticky turns into the new card”.

## Pushing as yourself or the bot

**Push as** has two choices, remembered in your browser:

- **You**: GitHub shows the issues, comments and pull requests as yours, “via Tack”. Written with your own GitHub sign-in.
- **Tack’s bot**: “Written by the app, not by you”. Written with the app’s installation.

Either way, Tack checks that **you** can write to every repository first, and the app must be installed there.

Choose **Push N changes** (`⌘` `Enter`).

### When a push can’t start

| The sheet says                                  | Because                                                                                | What to do                                                     |
| ----------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Sign in to push                                 | Pushing writes as a person, so Tack needs to know who you are                          | **Sign in with GitHub**                                        |
| You can stage but not push here                 | GitHub says you can’t write to the repository                                          | Someone with write access can push, or leave those changes out |
| Install the app on these repos                  | The [GitHub App](https://tack.social/self-hosting/github-app.md) isn’t installed there | **Install the app**, or leave them out                         |
| A change needs an issue that isn’t in this push | A change refers to a new issue you left out; the sheet names both                      | **Include it**                                                 |
| Couldn’t start the push                         | Another push is still going, or the changes changed meanwhile                          | Try again: nothing is ever sent twice                          |

## Progress and confirmation

Tack writes one change at a time, a second apart, in dependency order (new issues before the changes about them), though the sheet lists them in the order you reviewed them. A longer push says roughly how long it has left (“About 40 s left”). You can close the sheet: the push carries on, and the changes panel follows along. Everyone on the board sees it.

Each change goes **Waiting its turn** → **Sending…** → **Sent, waiting for GitHub to confirm** → **On GitHub**, linking to what it wrote. When they’re all done: “All N changes are on GitHub”.

**Confirming** is what makes a push trustworthy. Changes a card can show (new issues and pull requests, labels, assignees, state) count as done only when the card shows them, from GitHub’s webhook. If that hasn’t happened within two minutes, Tack fetches the item to check, and if it still doesn’t show the change, it fails: “GitHub accepted this, but owner/repo#12 didn’t show it within 2 minutes.” That usually means webhooks aren’t arriving: see [Troubleshooting](https://tack.social/help/troubleshooting.md).

Changes no card shows (milestones, sub-issues, blocked-by, comments, discussions) are done when GitHub accepts them.

When it’s done, the board catches up by itself: stickies turn into their issues’ cards in place, a parent issue’s card lands above its section connected to its sub-issues, and a decision shows its pull request. Cards are wider than stickies, so as a push starts, rows of stickies about to become cards spread out just enough for each card to fit, and sections grow to keep them: a pushed brainstorm doesn’t turn into a pile of overlapping cards.

## Failures and retries

- **Rate limits, timeouts and GitHub outages** are waited out and retried, in order, for up to eight attempts. A rate limit that won’t lift within 70 minutes fails instead.

- **Refusals** (no permission, an item that’s gone) fail that change, and changes that needed it fail too. The reason is in plain words, with what to do (“Tack’s GitHub App doesn’t have permission to assign people in acme/app. An owner of the repository may need to accept the app’s new permissions”); **Details** shows what GitHub said itself.

- A failed change stays in the changes panel. **Retry** pushes it again (as you or as the bot, whichever it was pushed as before), or unstage it to let it go.

- **Sub-issues and blocked-by** have refusals of their own, each with a way out instead of a Retry that can’t work:

  - “#5 already has a parent issue (#4), and an issue can only have one.” **Move it here** takes it off #4 and pushes it again; **Leave it out** unstages it. There’s no Retry: it would be refused again.
  - An issue can’t be its own sub-issue, or block itself: **Leave it out**.
  - A link that would make a loop (“#8 is already under #5…”), a parent with as many sub-issues as GitHub allows, sub-issues nested deeper than it allows, or issues it won’t link across repositories: the reason says what to change on GitHub. **Retry** once you have, or **Leave it out**.

- **Retry all** in the push sheet only retries what could work as it is.

A sub-issue being moved says so wherever it shows: “Move #5 from #4 to “Resizing”” in the changes panel, push sheet and history, “Moves to “Resizing” from #4” on its card’s mark. Moving one that’s already under the new parent does nothing more.

Tack never writes anything twice. A change being pushed or already done is never pushed again, and a retried create first looks for what an unanswered earlier attempt made.

## Push history

**History**, in the changes panel or the push sheet, is the board’s audit log of pushes (not to be confused with the [board’s history](https://tack.social/boards/history.md), in the top bar): every push, who pushed it and as whom (“as Tack’s bot”), when, and each change with its status, linking to what it wrote on GitHub. Anyone who can open the board can read it. The board keeps its last 200 pushes.
