{"id":19029687,"url":"https://github.com/guardian/prout","last_synced_at":"2025-04-04T17:05:55.409Z","repository":{"id":20377681,"uuid":"23653216","full_name":"guardian/prout","owner":"guardian","description":"Looks after your pull requests, tells you when they're live","archived":false,"fork":false,"pushed_at":"2025-03-04T10:56:08.000Z","size":6062,"stargazers_count":147,"open_issues_count":14,"forks_count":15,"subscribers_count":52,"default_branch":"main","last_synced_at":"2025-03-28T11:16:52.524Z","etag":null,"topics":["continuous-deployment","monitoring","production","pull-requests"],"latest_commit_sha":null,"homepage":"https://www.theguardian.com/info/developer-blog/2015/feb/03/prout-is-your-pull-request-out","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/guardian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-09-04T07:41:19.000Z","updated_at":"2025-03-04T10:55:56.000Z","dependencies_parsed_at":"2023-02-18T05:31:26.450Z","dependency_job_id":"34f8ac93-41de-48ce-a872-7c503b8dd9ed","html_url":"https://github.com/guardian/prout","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guardian%2Fprout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guardian%2Fprout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guardian%2Fprout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guardian%2Fprout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guardian","download_url":"https://codeload.github.com/guardian/prout/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247217175,"owners_count":20903008,"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":["continuous-deployment","monitoring","production","pull-requests"],"created_at":"2024-11-08T21:14:55.561Z","updated_at":"2025-04-04T17:05:55.390Z","avatar_url":"https://github.com/guardian.png","language":"Scala","readme":"# Prout\n\n_\"Has your pull request been deployed yet?\"_ - [Guardian blogpost](http://www.theguardian.com/info/developer-blog/2015/feb/03/prout-is-your-pull-request-out)\n\nTells you when your pull-requests are live. Tells you when they're not, and should be.\n\n![prout overduethenseen](https://cloud.githubusercontent.com/assets/52038/5635027/4bff5d08-95dd-11e4-817f-2a77284bb776.png)\n\nProut comes from the tenet that:\n\n    Developers are responsible for checking their changes on Production\n\nThis becomes more important, and _easier_ once you move to a Continuous Deployment\nrelease process. Important, because now a developer can break the site simply by\nhitting 'Merge' on a pull request - but also easier because with such a small delay\n(say, [less than 10 minutes](https://github.com/guardian/membership-frontend/pull/14#issuecomment-68436665)) between merging the work and having it ready to view in a\nProduction setting, the developer is in a much better place to review their work;\nit's still fresh in their mind.\n\nWhile everyone on your team may agree with this philosophy, that 10 minute lag\nbetween merge and deploy can be enough time for a developer like me to get distracted\n(\"Look, shiny thing!\" or, more realistically, \"What's the next bit of work?\") and\nforget about promptly reviewing their changes on Production.\n\nProut simply notifies developers in their pull request that the code has been _seen_\nin Production (a slightly stronger statement than simply saying it's been deployed).\n\n\n# Configuration\n\nFollow the 4-step program:\n\n1. [Give prout-bot write-access](#give-prout-bot-write-access) to your repo (so it can set labels on your pull request)\n2. [Add one or more `.prout.json` config files to your project](#add-config-file)\n3. [Add callbacks to prout](#add-callbacks) - ie a GitHub webhook and ideally also a post-deploy hook\n4. [Expose the commit id](#expose-the-commit-id) of your build on your deployed site\n\n## Give [prout-bot](https://github.com/prout-bot) write-access\n\n![Giving prout write-access by going to Settings -\u003e Collaborators and team -\u003e Add teams and typing in 'prout'](./artwork/prout-team-write.gif)\n\nAdmin access to the repository is required to give prout-bot write-access. Please contact your team's Engineering Manager for this.\n\n## Add config file\n\nAdd a `.prout.json` file to any folder you want monitored in your repo:\n\n```\n{\n  \"checkpoints\": {\n    \"DEV\": { \"url\": \"http://dev.mysite.com/\", \"overdue\": \"10M\" },\n    \"PROD\": { \"url\": \"http://mysite.com/\", \"overdue\": \"1H\" }\n  }\n}\n```\n\nWhen a pull-request changes a file anywhere under that folder, Prout will scan the\ncheckpoints defined in your config file, and update the pull-request with labels\nand a comment as appropriate. The url you specify in the checkpoint will be fetched,\nand the contents of the response will be read- so long as you embed the commit id\nthat response, Prout will be able to work out whether or not the PR has been deployed.\n\n## Add callbacks\n\nAdd Prout-hitting callbacks to GitHub and (optionally) post-deploy hooks to your deployment systems\nso that Prout can immediately check your site.\n\n### GitHub\n\nAdd a [GitHub webhook](https://developer.github.com/webhooks/creating/#setting-up-a-webhook)\nwith these settings:\n\n* Payload URL : `https://prout-bot.herokuapp.com/api/hooks/github`\n* Content type : `application/json`\n\nThe hook should be set to activate on `Pull Request` events.\n\n![Adding a GitHub web hook by navigating to Settings -\u003e Webhooks -\u003e Add webhook](./artwork/prout-web-hook.gif)\n\nNote that this can be done _once_ at the [Organization Webhook](https://docs.github.com/en/rest/orgs/webhooks) level, which removes the need for doing it on each individual repo. Prout will check that any repository has a `.prout.json` config file present before attempting to take any action on it.\n### Post-deploy hooks\n\nWhatever deployment tool you use (RiffRaff, Heroku, etc) just set it to hit Prout\nas a post-deploy hook (for your repo on _github.com/[owner]/[repo]_):\n\n```\nhttps://prout-bot.herokuapp.com/api/update/[owner]/[repo]\n```\n\nHitting that url (`GET` or `POST`) will always prompt Prout to\nscan the repository for outstanding pull-requests.\n\n## Expose the commit id\n\nYou must embed the commit id in your site - we do this on\n[membership.theguardian.com](https://membership.theguardian.com/)\nfor instance.\n\nProut [searches the response body and headers](app/lib/CheckpointSnapshot.scala#L45-L58) for any 40-character string of hexadecimal digits surrounded by word breaks, so adding the commit id almost anywhere should work. \n\nI use the [`sbt-buildinfo`](https://github.com/sbt/sbt-buildinfo) plugin to store the Git commit id in my stored artifact, and then expose\nthat value on the production site. The ugly-looking SBT config is:\n\n```\nbuildInfoKeys := Seq[BuildInfoKey](\n      name,\n        \"gitCommitId\" -\u003e (Option(System.getenv(\"GITHUB_SHA\")) getOrElse (try {\n        \"git rev-parse HEAD\".!!.trim\n      } catch {\n          case e: Exception =\u003e \"unknown\"\n      }))\n    )\n```\n\n## Slack\n\nUsers [can configure a Slack hook](https://github.com/guardian/prout/pull/11) for Prout\nby creating a new Slack 'Incoming Webhook':\n\nhttps://your-domain.slack.com/services/new/incoming-webhook\n\n...this will get you a 'Webhook URL', which looks something like this:\n\nhttps://hooks.slack.com/services/T05FTQF9H/B012N1Y2Y/p9VyRC1ZlTqNGuu\n\n...stick that url into a GitHub webhook for your repo as the 'Payload URL':\n\nhttps://github.com/my-org/my-repo/settings/hooks/new\n\n...and then (optionally) **disable** the hook in GitHub! You don't actually want to send _GitHub_\nevents to the hook - this is just a place to store the private url where Prout can find it.\n**Note that Prout needs repo-admin access in order to read the hook data!**\n\n# Status\n\nProut has a status page per repository available at\nhttps://prout-bot.herokuapp.com/view/{organisation}/{repository}. This lists useful information\nlike if it was able to find `.prout.json`, which commit it thinks is currently deployed in\nproduction, etc.\n\nProut also logs lots of useful information which is available in the heroku backend.\n\n\n# Run your own instance of Prout\n\n[![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/guardian/prout)\n\n...you want to run your own instance of Prout - the instance at https://prout-bot.herokuapp.com/\nis really only for the Guardian.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguardian%2Fprout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguardian%2Fprout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguardian%2Fprout/lists"}