{"id":18952407,"url":"https://github.com/tailscale/tobereviewedbot","last_synced_at":"2025-04-15T18:17:29.836Z","repository":{"id":41992401,"uuid":"458054734","full_name":"tailscale/ToBeReviewedBot","owner":"tailscale","description":"GitHub App to watch for PRs merged without a reviewer approving.","archived":false,"fork":false,"pushed_at":"2024-01-04T01:43:10.000Z","size":101,"stargazers_count":123,"open_issues_count":5,"forks_count":7,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-04-15T18:17:21.914Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tailscale.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2022-02-11T05:15:08.000Z","updated_at":"2025-03-28T16:36:40.000Z","dependencies_parsed_at":"2024-01-04T02:40:12.850Z","dependency_job_id":"3cbf706f-42f0-4ca9-8a3d-b4ce59b6cc22","html_url":"https://github.com/tailscale/ToBeReviewedBot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tailscale%2FToBeReviewedBot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tailscale%2FToBeReviewedBot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tailscale%2FToBeReviewedBot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tailscale%2FToBeReviewedBot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tailscale","download_url":"https://codeload.github.com/tailscale/ToBeReviewedBot/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249126000,"owners_count":21216705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T13:33:14.690Z","updated_at":"2025-04-15T18:17:29.817Z","avatar_url":"https://github.com/tailscale.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## ToBeReviewed Bot\n\nThe automation in this repository supports a To-Be-Reviewed Pull Request workflow:\n+ Allows a repository to enable branch protection and require pull\n  requests, but have flexibility in submission of pull requests in\n  case of urgent need by not mandating an approver before submission.\n+ If a PR is submitted without an Approver, the bot will notice\n  within a few minutes and file a GitHub issue requiring followup.\n+ The bot notes cases where intent is clear and does not intervene. Merging\n  someone else's PR constitutes Approval. A comment containing \"LGTM\"\n  constitutes Approval.\n+ The issues requiring followup carry a distinctive title allowing for\n  easy generation of the full population during a Compliance-related\n  periodic audit, and to demonstrate that all such issues did get\n  a followup review within a reasonable amount of time.\n\n\n### Configuration variables\nThe bot expects to run continuously on a production system, and\nsupports the following environment variables:\n- `TBRBOT_ORG`: The GitHub organization to use, like \"tailscale\".\n- `TBRBOT_BUGREPO`: The name of the repository to file followup issues in, like \"private\".\n- `TBRBOT_APPNAME`: The name of the GitHub app account, like \"tbr-bot\", to use as the\n  author in issues filed.\n- `TBRBOT_REPOS`: A comma-separated list of GitHub repositories to check for\n  to-be-reviewed PRs, like \"opensource,private\".\n- `TBRBOT_APP_ID`: The GitHub App ID, found in https://github.com/organizations/*ORGNAME*/settings/apps/*APPNAME*\n- `TBRBOT_APP_INSTALL`: The GitHub App Install ID for this installation, found in\n  https://github.com/organizations/*ORGNAME*/settings/installations\n\nAdditionally, the bot supports the following environment variables which should ideally\nbe handled by secrets management infrastructure in cloud providers:\n- `TBRBOT_APP_PRIVATE_KEY`: a PEM encoded private key, which can be generated in\n  https://github.com/organizations/*ORGNAME*/settings/apps/*APPNAME*\n\n\n### Reducing latency using GitHub webhooks\nNormally the bot wakes up every hour to check for recently submitted PRs needing\nfollowup. Its reaction to a submitted PR can be hastened by setting up a \n[GitHub webhook](https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks)\nfor \"Pull requests\" events (which send on a merged PR).\n\nGitHub should be configured to deliver webhook events to `https://Public-DNS-name/webhook`\n\nThe bot expects to find the shared secret for validating webhook payloads in a `WEBHOOK_SECRET`\nenvironment variable. The shared secret is configured in the webhook in\nhttps://github.com/organizations/*ORGNAME*/settings/hooks/*WEBHOOK_ID*?tab=settings\n\n\n### Monitoring\nWhen used as part of the controls for Compliance requirements, it is important to \nto monitor whether the bot is working. Finding out on the eve of an audit that the\nbot has been offline for an extended period would be ruinous.\n\nIn addition to `/webhook` the bot also exports metrics:\n- `https://Tailscale-MagicDNS-name/debug/vars` in JSON format\n- `https://Tailscale-MagicDNS-name/debug/varz` in Prometheus metric format\n\nThe `/debug` endpoints can only be reached from a local [Tailscale](https://tailscale.com)\ntailnet. It is reasonable to allow public Internet access to https://Public-DNS-name/\nfor GitHub to be able to deliver webhooks, TBR-bot will restrict the other endpoints to\nonly be accessible via a private tailnet connection.\n\nA metric of interest for monitoring is `tbrbot_repos_checked`, which counts the number of times\nthe bot has checked a repository for submitted PRs. This is expected to increment at least once\nper hour. An alert when `tbrbot_repos_checked` goes N hours with no change is a reasonable way\nto monitor TBR-bot's operation. An example alerting rule for Grafana in a panel for the\n`tbrbot_repos_checked` metric is: `WHEN diff_abs() OF query (A, 12h, now) IS BELOW 1`\n\n\n### Hosting\nThe included Dockerfile and example fly.toml are suitable to run the tbr-bot\n[hosted on fly.io](https://fly.io/).\n\nWe recommend forking this repository and making local modifications to the supplied fly.toml\nto set it to the name of your instance and update the environment variables to correspond\nto the GitHub repositories you want it to watch.\n\nThe bot needs a small amount of persistent storage for its Tailscale state, plus the various\nconfiguration and secrets described above.\n```\n$ flyctl volumes create tbrbot_data --region sjc --size 1\n$ flyctl scale count 1\n$ flyctl secrets set TS_AUTHKEY=... TBRBOT_APP_ID=... TBRBOT_APP_INSTALL=...\n$ flyctl secrets set TBRBOT_WEBHOOK_SECRET=...\n$ flyctl secrets set TBRBOT_APP_PRIVATE_KEY=- \u003c pem\n$ flyctl ips allocate-v6\n$ flyctl ips allocate-v4\n```\n\nWe recommend using a [one-time authkey with Tags set](https://tailscale.com/blog/acl-tags-ga/) to\nauthorize the bot to join the tailnet. Once the bot has run once and written its state\nto persistent storage, the `TS_AUTHKEY` secret should be removed.\n\n### Contributing\n\nPRs welcome! But please [file bugs](https://github.com/tailscale/ToBeReviewedBot/issues).\nCommit messages should [reference bugs](https://docs.github.com/en/github/writing-on-github/autolinked-references-and-urls).\n\nWe require [Developer Certificate of Origin](https://en.wikipedia.org/wiki/Developer_Certificate_of_Origin)\n`Signed-off-by` lines in commits.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftailscale%2Ftobereviewedbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftailscale%2Ftobereviewedbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftailscale%2Ftobereviewedbot/lists"}