GitHub is both a source of work and the place where Kiln delivers it: issues and comments start work items, Kiln opens pull requests on kiln/* branches, and a person's merge completes the work.
Set up
One click from the web app
An admin opens Integrations → GitHub and clicks Create GitHub App, optionally naming an organization. GitHub shows the app Kiln asks for (the permissions, events and webhook below); click Create. GitHub gives the app's private key and webhook secret to the Kiln server, and Kiln takes you to install the app on the repositories you pick. When you come back, GitHub is connected and Kiln uses the app from then on, without a restart.
This needs KILN_PUBLIC_URL (GitHub calls it) and KILN_SECRET_KEY (the key is stored encrypted with it). The key is kept apart from secrets: no agent can ask for it by name. POST /api/v1/connections/github/app-manifest returns the manifest and the URL to post it to; GET /api/v1/connections/github/app shows the app. Environment variables, below, take precedence.
By hand
- Create a GitHub App (Settings → Developer settings → GitHub Apps) with these repository permissions: Contents, Issues, Pull requests and Checks read and write, Metadata read.
- Set its webhook URL to
POST /webhooks/githubwith a secret, and subscribe to Issues, Issue comment, Pull request, Pull request review, Pull request review comment, Check suite, Check run, Status, Workflow run and Push. - Give Kiln the app's credentials and install the app on your organization:
| Variable | Notes |
|---|---|
GITHUB_APP_ID |
The app's ID. |
GITHUB_APP_PRIVATE_KEY |
The app's private key, as PEM (\n escapes are fine) or base64. |
GITHUB_APP_INSTALLATION_ID |
The installation on your organization. Kiln mints a short-lived installation token for each call. |
GITHUB_APP_SLUG |
Lets Kiln link to the install page and recognize its own <slug>[bot] events. |
GITHUB_WEBHOOK_SECRET |
The webhook secret. Without it (or a GitHub App created in Kiln), Kiln refuses GitHub webhooks. |
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET |
The app's OAuth credentials, for people to link their GitHub accounts. |
A plain GITHUB_TOKEN still works instead of an app. You can also connect GitHub from the API; see Connections.
- List the repositories in
factory.yamlunderrepositories. - Protect
main: require reviews and status checks, and do not let Kiln's identity bypass them.
Kiln verifies X-Hub-Signature-256 on every call and ignores repeated X-GitHub-Delivery IDs.
Connect more accounts and organizations with Add a GitHub account or organization in the same panel: each gets its own private app, and Kiln uses the app installed on each repository's owner (GET /api/v1/connections/github/apps lists them). An app created by mistake can be removed with the trash button next to it (DELETE /api/v1/connections/github/apps/{slug}): Kiln forgets its key and stops using it, and you delete the app itself on GitHub. A public app installed on several accounts works the same way. A sandbox never gets the app's own credentials: it clones and pushes with an installation token limited to that one repository (contents write, metadata read) that expires within the hour. Protect your default branch, because contents write can push to any branch that is not protected.
Studio pushes the same way. Each push asks for a fresh token for the App's one repository, and every push is in the audit log. An imported App pushes only its studio/<app id> branch. It pushes the default branch only in Cowboy mode, when a team owner or admin turned on default-branch pushes in the App's policy and no factory uses the repository. To let Studio create a repository for a template App on its first push, give the app Administration: read and write on the organization. Without it, template Apps aren't pushed.
GitHub Enterprise Server
Set GITHUB_URL to your server's web address, for example GITHUB_URL=https://github.acme.test. Kiln then uses that server for everything it does on GitHub: cloning and pushing kiln/* branches, pull requests, comments and checks, GitHub App installation tokens, the merge gate, creating and installing the app from the web app, GitHub login, and linking people's GitHub accounts. The API defaults to <GITHUB_URL>/api/v3; set GITHUB_API_URL only if yours lives elsewhere. Without GITHUB_URL, Kiln uses github.com.
Create the app (or token) on that server, not on github.com. With the egress proxy, add the server's host to KILN_EGRESS_ALLOW so sandboxes can clone and push.
Mention the factory
Mention @kiln-factory in a new issue, pull request, comment or review. Edits and mentions inside code blocks are ignored.
- With a
factory:<alias>label, the mention goes to that factory. - Without a label, Kiln looks for factories whose
repositoriesinclude the repo. With exactly one, it adds that factory's label and starts the work. With several, it comments asking you to add one of their labels and mention@kiln-factoryagain. With none, it comments that no factory works on the repo yet.
Kiln creates the factory:<alias> label on the factory's repositories whenever its definition is applied. Deleting the factory (DELETE /api/v1/factories/<id>, Admin role) removes the label again, cancels its open work and deletes its managed webhooks.
The default mentions template routes on both, and you can change the handle or label it filters on:
---
triggers:
- provider: github
event: issue_mentioned
filter: { mentioned: [kiln-factory], labels: ["factory:webapp"] }
- provider: github
event: issue_assigned
filter: { assignees: [kiln-factory], labels: ["factory:webapp"] }
---Starting work
Add an automation for the events you want:
---
triggers:
- provider: github
event: issue_labeled
filter:
repos: [acme/web]
labels: [kiln-ready]
---
Take the labeled issue through the factory.GitHub triggers cover issues (issue_created, issue_labeled, issue_assigned, issue_commented, issue_mentioned), pull requests (pull_request_opened, _ready, _reopened, _labeled, _assigned, _synchronized, _enqueued, _dequeued, _review_requested, _review_submitted, _commented, _mentioned, _merged, _closed), CI (check_suite_completed, check_suite_rerequested, check_run_rerequested, commit_status, workflow_run_completed) and push. The full list of events and filter keys is in Automation triggers.
- One delivery can produce several events. A comment with a mention is both
issue_commentedandissue_mentioned; an automation that listens to both still fires once. skip_botsdefaults toall: events from bots never start work. Useselfto skip only Kiln's own app, ornone. Admitting Kiln's own events can cause loops.- On check suite and workflow run events,
numberis the linked pull request.
What Kiln does on GitHub
- Branches. Each work item gets one branch,
kiln/<id>-<title-slug>. Kiln pushes it with the run's token, which can push onlykiln/*branches. - Spec pull request. When the work needs a spec, Kiln opens a draft pull request with the spec and the acceptance criteria as a checklist.
- Pull request title and body. The implement agent writes them: a conventional commit title and a Why / What / Verification description. Kiln adds the evidence (screenshots and videos) and links the work item, the source and the tracker issue below it. When the agent reports none, the title is the request's and the body is the request with its acceptance criteria.
- CI. The verify stage waits for check runs on the branch. Failures, cancellations and timeouts loop the work back to build.
- Preview card. With a preview provider, Kiln comments a card with the preview URL, test counts and one video link per acceptance criterion.
- Review findings. Findings that need a person's judgment are posted as a comment.
- Ready for review. When the build stage succeeds, Kiln opens the pull request, or takes the spec pull request out of draft.
- Attribution. When Kiln opens a pull request, it posts one comment, never twice: which factory opened it, for whom, from where, a link to the task, and that mentioning
@kiln-factoryon the pull request sends it follow-up work. - Hand-off. Kiln adds the label
factory:<alias>and posts "Ready to merge" with the pull request link where the work started, for example on the source issue.
After hand-off
- Merge. When a person merges the pull request, the
pull_requestwebhook completes the work item and closes its open gates. - Review comments. A submitted review that is not an approval sends the work item back to build, with the review text as findings.
- Comments. Comments on the source issue or the pull request decide an open spec or preview gate, answer an open question, steer a running agent, or are added to the work item's conversation. Map GitHub logins to people with the server's
identitiesoption (github:<login>). Replies decide a gate only when their author is one of its assignees; see Who may decide from a reply.
Config repos
A factory's definition can live in a GitHub repository. Merges to its branch apply the new definition when Kiln receives the push webhook, so install the app on the config repo too. See Definitions as code.
The kiln/factory-config check
On pull requests to a config repo, Kiln reads the head commit, validates it and dry-runs the apply: missing runners and routers, schema errors and alias names that do not resolve all fail the check. The summary counts what would be created, updated and deleted. When nothing in the definition changed, the check passes right away.
- The check is named
kiln/factory-config, orkiln/factory-config (<dir>)when the definition lives in a subdirectory. - Require it in branch protection to block broken definitions.
github.factoryConfigChecksinfactory.yamlchooses which pull requests get it:main(default) checks only pull requests to the production branch,allchecks every base branch.