Skip to Content

GitHub

Tares connects to GitHub in one of two ways. You pick a credential, and Tares decides how events arrive.

GitHub App (recommended)Personal token
How events arriveas they happen, by webhookpolled, every 2 minutes by default
What arrivespull requests, pushes, reviews, review comments, comments, issues, releases, CI runscommits, and pull requests opened, merged or closed
Which repositoriesevery repository the App is installed on, in one sourceone source per repository you add
Agents act asthe App (your-app[bot])the token’s user
Check runs from agentsyesno

With the GitHub App

On Tares Cloud

In your workspace settings, choose Connect GitHub, pick the organization and the repositories, and confirm on GitHub. Your workspace gets a github source carrying every event of those repositories. To add another organization, choose Connect another account. Disconnect removes the credential from your workspace and uninstalls the App on GitHub.

Self-hosted

  1. Open Settings > GitHub and choose Create GitHub App.
  2. Enter the GitHub organization to create it in (leave it empty for your own account). Under Address and App name, check that the address is how GitHub reaches this Tares.
  3. Choose Continue on GitHub. GitHub shows the App with its permissions and events filled in. Confirm it.
  4. Back in Tares, choose Install on GitHub, pick the repositories, and install.

Tares stores the App (its id, private key and webhook secret) as a credential and creates a github source for its webhook. Nothing is pasted by hand.

GitHub must be able to reach your Tares for webhooks to arrive. A local tares up is not reachable from the internet, so run a tunnel and use its address as the public URL, for example:

cloudflared tunnel --url http://localhost:8787 TARES_PUBLIC_URL=https://<your-tunnel>.trycloudflare.com tares up

The App can still be created without one; deliveries start once Tares is reachable.

Already have an App? Add it under Settings > GitHub through the API with its app id, private key, webhook secret and installation ids (POST /api/integrations/github with kind: app), then point the App’s webhook at the github source’s ingest URL.

The App asks for these permissions, which you can narrow on GitHub’s page:

permissionaccesswhy
Metadatareadrequired by GitHub
Contentsread and writeagents read code and write files on a branch
Pull requestsread and writeagents open pull requests and review them
Issuesread and writeagents comment
Checksread and writeagents post their verdict as a check run
ActionsreadCI run events
Commit statusesreadcommit status events

and these events: pull request, pull request review, pull request review comment, push, issues, issue comment, release, workflow run.

Every delivery is checked against the App’s webhook secret before anything is stored. An unsigned or wrongly signed request gets a 401 and is counted on the credential’s row in Settings > GitHub. A delivery GitHub sends twice is stored once. An installation that was not started from this Tares (someone installing a public App on their own account) is not added.

With a personal token

  1. Create a fine-grained token on GitHub with the repositories you want and these permissions: Metadata read, Contents read, Pull requests read. Add Contents and Pull requests write only if agents should change repositories with it. A classic token needs the repo scope for private repositories.
  2. Open Settings > GitHub, choose Add a personal token, and paste it.
  3. Add a source per repository: Sources > Add source > GitHub, pick the credential and the repository, and save.

Each source polls its repository’s commits and its pull requests. The first poll imports recent commits and no old pull requests. A pull request reopened between two polls is not reported. If the token cannot read pull requests, commits still arrive and the daemon log says why once.

- name: checkout-api connector: github poll: 2m config: repo: acme/checkout-api credential: github labels: - { name: repo, field: repo, primary: true }

Or POST /api/sources with the same object.

fieldtypedescription
repo*stringowner/name, e.g. acme/checkout-api
credentialstringa GitHub credential from Settings > GitHub, resolved at every poll
tokenstringa token for this source only (secret); prefer a credential
branchstringbranch to follow (default: the repository’s default branch)
limitnumbercommits fetched per poll (default 20)
filesbooladd each new commit’s changed files (capped) to its payload (default true)
prsboolalso report pull requests opened, merged or closed (default true)
api_urlstringGitHub API base for GitHub Enterprise (default https://api.github.com)

Events and labels

Both ways produce the same events, so a trigger keeps working when you switch from a token to the App.

event_typearrives withkey
pull_requestboth (a token: opened, merged, closed)owner/repo#number
commitpersonal tokenowner/repo
pushAppowner/repo
pull_request_review, pull_request_review_commentAppowner/repo#number
issues, issue_commentAppowner/repo#number
releaseAppowner/repo
workflow_runAppowner/repo

Every GitHub event carries these labels when they apply: repo, action (opened, synchronize, merged, closed, reopened, ready_for_review, submitted, created, published, completed, pushed), number, author, branch, base, state, draft, sha, url, title, conclusion (CI runs), release_tag, workflow, commits (pushes) and on_default_branch (pushes). A closed pull request that merged reads merged.

Example: every merged pull request in two repositories. A trigger on the github source with these filters, one firing per pull request:

- name: pr-merged sources: [github] filters: - { field: event_type, op: eq, value: pull_request } - { field: action, op: eq, value: merged } - { field: repo, op: in, value: [acme/checkout-api, acme/payments] } condition: { aggregate: count, predicate: "> 0", window: 5m } cooldown: 5m

In the console’s trigger editor, a filter on event_type or action over a GitHub source offers these values to pick from.

Agents on GitHub

In a Tares agent’s settings, the GitHub section picks a credential and what the agent may do: read repositories, or read and write (branches, files, pull requests, comments, reviews). Reads and writes go through GitHub’s MCP server, authenticated with that credential, so with the App every write shows as the App. Tares sets the server up the first time; there is nothing to register.

With the App, the agent can also post its verdict on a pull request as a check run: a pass, fail or neutral result in the pull request’s checks, with notes on the lines it is about. Ask for it in the agent’s instructions, for example “post your verdict as a check run on the pull request’s head commit”. Every GitHub call shows in the run’s record, and a check run appears in the run’s results.

Prefer pull requests over writing to the default branch: ask the agent to open a pull request with its change, so a person reviews it.

Troubleshooting

  • No deliveries from the App. Check that Tares is reachable at the address the App uses (a local Tares needs a tunnel) and that the App is installed on the repository. GitHub’s App settings list recent deliveries under Advanced, with their responses.
  • Deliveries refused (401). The webhook secret on GitHub does not match the credential’s. A recreated App gets a new one; reconnect it from Settings > GitHub.
  • A 403 from GitHub. The App or token lacks a permission; the error names the call. On the App, accept new permissions on GitHub after changing them.
  • Pull requests do not arrive on a token source. The token lacks Pull requests read.
Last updated on