{"id":19139733,"url":"https://github.com/trolit/patchron","last_synced_at":"2025-07-03T21:37:32.274Z","repository":{"id":52340634,"uuid":"449455487","full_name":"trolit/Patchron","owner":"trolit","description":"performs initial pull request code review 🕵️. Inteded to faster code reviews, not substitute human one","archived":false,"fork":false,"pushed_at":"2025-04-10T22:42:29.000Z","size":1677,"stargazers_count":5,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-06T23:15:22.477Z","etag":null,"topics":["automated-code-review","code-review","code-review-bot","github-bot","jest-tests","jsdocs","node-app","nodejs","pr-review","probot","probot-app","probot-apps","pull-request-review","review-bot"],"latest_commit_sha":null,"homepage":"https://github.com/trolit/patchron-test/pulls","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trolit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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,"zenodo":null}},"created_at":"2022-01-18T21:36:48.000Z","updated_at":"2023-11-16T21:00:59.000Z","dependencies_parsed_at":"2023-01-29T15:30:50.810Z","dependency_job_id":"ee8dc902-1491-4fa3-bfb1-0433322114bc","html_url":"https://github.com/trolit/Patchron","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trolit%2FPatchron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trolit%2FPatchron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trolit%2FPatchron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trolit%2FPatchron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trolit","download_url":"https://codeload.github.com/trolit/Patchron/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252782835,"owners_count":21803410,"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":["automated-code-review","code-review","code-review-bot","github-bot","jest-tests","jsdocs","node-app","nodejs","pr-review","probot","probot-app","probot-apps","pull-request-review","review-bot"],"created_at":"2024-11-09T07:14:52.723Z","updated_at":"2025-05-06T23:15:27.419Z","avatar_url":"https://github.com/trolit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"./.github/images/banner.png\" alt=\"banner image\"\u003e\n\n# 🐶 Patchron\n\n\u003cp\u003e\n\n\u003cimg src=\"https://img.shields.io/github/package-json/v/trolit/Patchron?color=ffa06b\" alt=\"version badge\"/\u003e\n\u003ca href=\"./.github/AVAILABLE_RULES.md\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/--%3E%20List%20of%20available%20rules%20%3C---65f9a0\" alt=\"badge with anchor to AVAILABLE_RULES.md\"/\u003e\n\u003c/a\u003e \u003ca href=\"./.github/DEV_OVERVIEW.md\" target=\"_blank\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/--%3E%20For%20Developer%20%3C---a175e8\" alt=\"badge with anchor to DEV_OVERVIEW.md \"/\u003e\n\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"justify\"\u003e\nGitHub bot 🤖 that performs initial pull request code review. It is intended to faster further code reviews, not substitute human ones 😎\n\u003c/p\u003e\n\n-   versioned rules\n-   built with [Probot](https://probot.github.io/docs/)\n-   easy to configure and [expand](./.github/DEV_OVERVIEW.md)\n-   includes tests (Jest) and type definitions (jsdoc)\n-   wrapped with [own context](./src/builders/PatchronContext.js) to improve logging and accessing Probot's context\n\nDisclaimer\n\n\u003e review is based upon patches (to not overload GitHub API) which contain limited number of information. Due to that, some comments might be unrelevant. Despite of that, it comes to clicking resolve button while at the same time reviewers don't have to focus on simple things.\n\n## 1. Setup\n\n\u003cdetails\u003e\n    \u003csummary\u003e\n        with Node.js\n    \u003c/summary\u003e\n\n1. Clone repository.\n2. Install dependencies.\n\n    ```sh\n    npm install\n    ```\n\n3. Run the bot.\n\n    ```sh\n    npm start\n    ```\n\n4. Follow further instructions from terminal to finish setup.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\n        with Docker\n    \u003c/summary\u003e\n\n1. Pull image from GHCR or build your own.\n\n    ```sh\n    docker pull ghcr.io/trolit/patchron:latest\n    ```\n\n    ```sh\n    docker build -t patchron .\n    ```\n\n2. Obtain `APP_ID` and `PRIVATE_KEY`.\n\n    Install app via marketplace https://github.com/apps/patchron and configure repository access. Afterwards visit app https://github.com/settings/installations, note down `APP_ID` and generate `PRIVATE_KEY`.\n\n3. Create running container from image (APP_ID and PRIVATE_KEY are mandatory)\n\n    ```sh\n    docker run -e APP_ID=\u003capp-id\u003e -e PRIVATE_KEY=\u003cpem-value\u003e patchron\n\n    more options:\n    -e SENDERS=\u003cusernames-separated-by-comma\u003e\n    -e MAX_COMMENTS_PER_REVIEW=\u003cnumber\u003e\n    ```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003e\n        with GitHub Actions\n    \u003c/summary\u003e\n\n### Use GitHub Token or PAT\n\nYou can use `GitHub token` that is generated automatically on event (comments will be associated with `github-actions` bot) or `personal access token` to associate review with e.g. your own bot account. In that case you only need to add following snippet to repository workflow and adjust it to your needs.\n\n```yml\nname: Perform first PR review (GITHUB TOKEN)\n\non:\n    pull_request:\n        types:\n            - opened\n\njobs:\n    reviewOpenedPull:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v3\n            with:\n                repository: 'trolit/Patchron'\n                ref: 'master'\n\n            - run: npm ci --only=production\n\n            - run: npm start\n            # options: https://github.com/trolit/Patchron#2-configuration\n            env:\n                GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # or secrets.PAT\n                # when 'github' is assigned, attempts to read variables directly from workflow\n                NODE_ENV: 'github'\n```\n\n### Use app installation token\n\n⚠️ Note: Snippet uses \u003ca href=\"https://github.com/navikt/github-app-token-generator\"\u003e@navikt/github-app-token-generator\u003c/a\u003e to generate app installation token. You can provide different solution (or your own). At this moment \u003ca href=\"https://github.com/probot/adapter-github-actions\"\u003eprobot/adapter-github-actions\u003c/a\u003e does not support to generate app installation token by app id and private key.\n\n1.  Install app via marketplace https://github.com/apps/patchron\n2.  Configure repository access (repository that you want to be reviewed should be accessible by app).\n3.  Generate `PRIVATE_KEY`\n4.  Add `APP_ID` and `PRIVATE_KEY` secrets to repository\n5.  Use following snippet to add workflow in your repository.\n\n    ```yml\n    name: Perform first PR review (APP INSTALLATION TOKEN)\n\n    on:\n        pull_request:\n            types:\n                - opened\n\n    jobs:\n        reviewOpenedPull:\n            runs-on: ubuntu-latest\n            steps:\n                - uses: navikt/github-app-token-generator@v1\n                id: get-token\n                with:\n                    private-key: ${{ secrets.PRIVATE_KEY }}\n                    app-id: ${{ secrets.APP_ID }}\n\n                - uses: actions/checkout@v3\n                with:\n                    repository: 'trolit/Patchron'\n                    ref: 'master'\n\n                - run: npm ci --only=production\n\n                - run: npm start\n                # options: https://github.com/trolit/Patchron#2-configuration\n                env:\n                    GITHUB_TOKEN: ${{ steps.get-token.outputs.token }}\n                    # when 'github' is assigned, attempts to read variables directly from workflow\n                    NODE_ENV: 'github'\n    ```\n\n\u003c/details\u003e\n\n\u003cbr/\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nRules configuration examples 🧩\n\u003c/summary\u003e\n\n-   [Default](./src/config/rules.json) (rules categorised by file extension)\n-   [Node (commonjs) + Vue in single repository](.github/examples/NodeVueSingleRepo.json) (rules split by relative path and file extension)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\nHow to arrange own rules 🤔\n\u003c/summary\u003e\n\nRules config file is expected to be expressed as `.json` with specific structure to unify app behaviour between all available ways of serving it. It should have `pull` array and `files` object. Pull rules are intended to verify pull request data (not changes in files) and that's why it has separated section. You can manage configuration in two ways:\n\n### via extension\n\n```json\n{\n    \"pull\": [],\n    \"files\": {\n        \"js\": [],\n        \"vue\": [],\n        \"cs\": []\n    }\n}\n```\n\nIt's used in repository as default configuration [here](./src/config/rules.json). When app fetches files from pull request event, it takes each filename and attempts to get related rules from `files` object by file extension. If e.g. bot receives `src/helpers/doSomething.js` it will attempt to get rules from `rules.files['js']`.\n\n### via relative paths\n\nThere might be a case where single repository is used to store more app parts (e.g. `client` and `server`) and you would like to separate `client` rules from `server` (because for example `server` is in `commonjs` type and `client` in `module`). To solve it, you can group rules by relative paths:\n\n```json\n{\n    \"pull\": [],\n    \"files\": [\n        \"server/*\": {\n            \"js\": [\n                { }\n            ]\n        },\n        \"client/*\": {\n            \"js\": [\n                { }\n            ],\n            \"vue\": [\n                { }\n            ]\n        }\n    ]\n}\n```\n\n⚠️ End relative paths with asterisks (e.g. `server/*`) if you want to match files that are stored under `server/` regardless of the nesting level.\n\n-   `server/*`\n\n    -   `server/doSomething.js` (matched)\n    -   `server/helpers/chart/saveLegendItems.js` (matched)\n\n-   `server`\n    -   `server/doSomething.js` (matched)\n    -   `server/helpers/chart/saveLegendItems.js` (not matched)\n\n\u003c/details\u003e\n\n## 2. Configuration\n\n| Property                                    | Type (default)              | Description                                                                                                                                                                                                                                             |\n| :------------------------------------------ | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `NODE_ENV`                                  | String (` `)                | specifies environment in which app is running. For GitHub actions use `github`, for testing purposes `test` and for self hosted app `production`. GitHub POST comments, summary, approve actions are limited to `github` and `production` environments. |\n| `RULES_CONFIGURATION_PATH`                  | String (`src/config/rules`) | Path to rules configuration file stored in project. Used when `RULES_CONFIGURATION_URL` is not provided.                                                                                                                                                |\n| `RULES_CONFIGURATION_URL`                   | String (` `)                | When provided, attempts to fetch rules configuration from given URL. URL should point to `.json` file ([example structure](./src/config/rules.json)).                                                                                                   |\n| `IS_GET_FILES_REQUEST_PAGINATED`            | boolean (`false`)           | Controls files fetching strategy. Unpaginated response includes a maximum of 3000 files which is sufficient in 99.9999999999% of cases.                                                                                                                 |\n| `DELAY_BETWEEN_COMMENT_REQUESTS_IN_SECONDS` | Number (`3`)                | After pull request review is done, delays time between each comment POST request to not overload GitHub API. Creating content too quickly may result in secondary rate limiting.                                                                        |\n| `IS_OWNER_ASSIGNING_ENABLED`                | boolean (`true`)            | When true, PR owner will be automatically assigned on issueing pull request.                                                                                                                                                                            |\n| `IS_REVIEW_SUMMARY_ENABLED`                 | boolean (`false`)           | When true, at the end of the PR review, app will post summary that contains various information e.g. total comments that were successfully posted.                                                                                                      |\n| `IS_STORING_LOGS_ENABLED`                   | boolean (`false`)           | When true, logs are also stored physically in `.logs` directory. Log files are named in following format: `YYYY-MM-DD`.                                                                                                                                 |\n| `MAX_COMMENTS_PER_REVIEW`                   | Number (`25`)               | Limits number of comments that can be posted in single review under single pull request.                                                                                                                                                                |\n| `SENDERS`                                   | String (` `)                | Allows to limit pull requests reviews to certain users. Pass string with usernames separated by comma e.g. `'test1, test2, test3'`                                                                                                                      |\n| `APPROVE_PULL_ON_EMPTY_REVIEW_COMMENTS`     | boolean (`true`)            | When true, approves pull request on empty review comments.                                                                                                                                                                                              |\n\n## 3. Useful links\n\n-   [Probot docs](https://probot.github.io/docs/)\n-   [Octokit Rest API](https://octokit.github.io/rest.js)\n-   [Deployments API example](https://developer.github.com/v3/repos/deployments/)\n-   [Pino (logger)](https://getpino.io/#/)\n-   [GitHub API - best practices](https://docs.github.com/en/rest/guides/best-practices-for-integrators)\n-   [GitHub API - rate limits](https://docs.github.com/en/developers/apps/building-github-apps/rate-limits-for-github-apps)\n-   [GitHub API - pulls](https://docs.github.com/en/rest/reference/pulls)\n-   [Default picture](https://pixabay.com/vectors/dog-pet-hound-black-eye-animal-151123/)\n\n## 4. Name origin\n\nName simply comes from merging two words: Patch and [Patron](\u003chttps://en.wikipedia.org/wiki/Patron_(dog)\u003e) 🐶\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrolit%2Fpatchron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrolit%2Fpatchron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrolit%2Fpatchron/lists"}