GitHub App
GitHub App
Optional, but nicer: bot-posted comments and live PR/issue titles.
What it adds #
Everything in these docs works without the App. Installing the App upgrades four things:
- The bot posts all linked media automatically. The attachments comment is created and kept current on the server — no local
ghauth, no comments under contributors' own accounts. - File pages show titles for private repos. Public repos work out of the box; the App grants read access for private ones.
- Titles stay current. Webhooks pick up when a PR or issue is renamed, closed, or merged.
- Screenshots staged before the PR exists get promoted automatically. See Staging before a PR exists.
Install it #
Install from github.com/apps/uploads-sh and pick the repositories you attach files to (add more later in GitHub's settings). That's the whole setup — the next uploads attach against an installed repo posts as the bot:
>> uploading ./after.png
>> attachments comment updated (uploads-sh[bot])Staging before a PR exists #
No PR open yet? --branch stages screenshots against the branch instead (defaults to your current git branch). Staged files are hosted and public immediately — there's just no PR to comment on yet.
The moment a PR opens for that branch (or reopens, or gets new commits), the App promotes the staged files onto it and posts or updates the bot comment — no CLI involvement. Without the App, the next uploads attach against that PR promotes them, or run uploads attach --promote with no files (--no-promote skips it).
Promotion copies — it never deletes the staged original, so URLs you've already embedded keep working. Staged files stick around under the same rules as anything else in your workspace. The one caveat: a file staged more than 30 days before its PR opens won't auto-promote (it's still there, just not attached automatically).
Permissions & events #
The App asks for one permission: Issues and Pull requests, read & write — to read titles and state and post the one managed attachments comment. It never touches other comments, PR descriptions, or your code. If your org installed the App before a permission was added, GitHub holds the upgrade until an org admin approves it; the CLI prints the approval link and posts via gh in the meantime.
The App also needs webhook event subscriptions (Settings → your App → Permissions & events → Subscribe to events):
- Required —
issuesandpull_request. Without these the ping still shows green, but title updates and staged-file auto-promotion silently do nothing. - Recommended —
issue_comment. Enables self-healing comments; the App works fully without it.
uploads github doctor checks the subscriptions directly and reports anything missing:
Repo bindings #
Each repo maps to at most one workspace's managed comment. The binding is created implicitly the first time a workspace comments, attaches, or promotes against a repo; inspect or claim it explicitly with:
- Bindings can't be stolen. Claiming a bound repo just reports the current owner.
uploads github unlinkreleases your own binding; an operator can reassign stuck ones from the admin panel. - Other workspaces can't post to your repo. Their
comment/attachcalls get anot_authorizeddecline with noghfallback — nobody can deface or duplicate the bot comment on your repo. - First claims require push access. Before a workspace can bind an unclaimed repo, the server verifies live against GitHub that the calling token's linked GitHub account can push to it. Tokens with no linked GitHub identity can't make first claims (they still work on repos already bound to them), and repos bound before this check existed keep working.
Self-healing comments #
If the managed comment is deleted or edited out from under the bot, the App restores it automatically on the next comment activity in that PR or issue — same attachment list, no CLI call needed. This requires the issue_comment event (see Permissions & events). A briefly missing comment is expected and not a reason to repost one manually.
Without the App #
uploads attach posts the same managed comment through your local gh CLI, and file pages still resolve titles for public repos. Uninstalling just returns you to that behavior — hosted files and their URLs are unaffected either way.