{"id":24167300,"url":"https://github.com/mattdowdell/pr-sizer","last_synced_at":"2026-02-07T12:02:23.336Z","repository":{"id":267949729,"uuid":"902832916","full_name":"mattdowdell/pr-sizer","owner":"mattdowdell","description":"Add size labels to pull requests","archived":false,"fork":false,"pushed_at":"2026-01-31T12:35:23.000Z","size":291,"stargazers_count":0,"open_issues_count":7,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-01T00:15:40.247Z","etag":null,"topics":["actions","code-review"],"latest_commit_sha":null,"homepage":"https://github.com/marketplace/actions/pr-sizer","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mattdowdell.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-12-13T11:08:04.000Z","updated_at":"2026-01-31T12:35:02.000Z","dependencies_parsed_at":"2025-01-05T11:28:41.337Z","dependency_job_id":"4a12e20d-c175-4e35-aa49-b74a7133ba08","html_url":"https://github.com/mattdowdell/pr-sizer","commit_stats":null,"previous_names":["mattdowdell/diff-size","mattdowdell/pr-size","mattdowdell/pr-sizer"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/mattdowdell/pr-sizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdowdell%2Fpr-sizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdowdell%2Fpr-sizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdowdell%2Fpr-sizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdowdell%2Fpr-sizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattdowdell","download_url":"https://codeload.github.com/mattdowdell/pr-sizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattdowdell%2Fpr-sizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29194007,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["actions","code-review"],"created_at":"2025-01-12T21:13:00.435Z","updated_at":"2026-02-07T12:02:23.331Z","avatar_url":"https://github.com/mattdowdell.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pr-sizer\n\nA GitHub Action for adding size labels to pull requests.\n\n\u003cimg src=\"https://raw.githubusercontent.com/mattdowdell/pr-sizer/main/assets/example.jpg\" width=\"750\" /\u003e\n\n## Description\n\nThere is a limit to how much code can be effectively reviewed in a single pull\nrequest. A [Smartbear study][1] found that reviewing more than 200-400 lines\nreduces the ability of reviewers to identify defects. Furthermore, smaller\nchanges are typically lower risk and require less effort to qualify. With that\nin mind, this action seeks to promote smaller pull requests by making it easier\nto identify excessively large changes.\n\nEach pull request is assigned a label that identifies its size. The thresholds\nfor the sizes and the names of the labels can be customised using the\n[action inputs](#inputs).\n\n| Category          | Lines changed | Label      |\n| ----------------- | ------------- | ---------- |\n| Extra Small       | 1-10          | `size/XS`  |\n| Small             | 11-100        | `size/S`   |\n| Medium            | 101-200       | `size/M`   |\n| Large             | 201-400       | `size/L`   |\n| Extra Large       | 401-800       | `size/XL`  |\n| Extra Extra Large | 801+          | `size/XXL` |\n\nThe calculation of the lines changed is determined by adding the number of lines\nadded and removed in each file. Whitespace only changes to lines, such as\nindentation modifications are excluded. Additionally, files that are marked as\ngenerated or vendored in `.gitattributes` are also excluded, allowing automated\nchanges to be filtered out. For example:\n\n```gitignore\nvendor/**    linguist-vendored\ngenerated/** linguist-generated\n```\n\nSee [Linguist's overrides][2] for further documentation.\n\n[1]: https://smartbear.com/learn/code-review/best-practices-for-peer-code-review\n[2]: https://github.com/github-linguist/linguist/blob/main/docs/overrides.md\n\n## Usage\n\n```yaml\nname: CI\non:\n  pull_request:\njobs:\n  size:\n    name: Size\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read # for checkout\n      pull-requests: write # for managing labels\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0 # for comparing changes to the target branch\n          persist-credentials: false\n\n      - uses: mattdowdell/pr-sizer@v0.5.1\n```\n\n## Inputs\n\n| Name                   | Type    | Default                        | Description                                                                  |\n| ---------------------- | ------- | ------------------------------ | ---------------------------------------------------------------------------- |\n| `xs-threshold`         | String  | `10`                           | The maximum number of lines changed for an extra small label to be assigned. |\n| `s-threshold`          | String  | `100`                          | The maximum number of lines changed for a small label to be assigned.        |\n| `m-threshold`          | String  | `200`                          | The maximum number of lines changed for a medium label to be assigned.       |\n| `l-threshold`          | String  | `400`                          | The maximum number of lines changed for a large label to be assigned.        |\n| `xl-threshold`         | String  | `800`                          | The maximum number of lines changed for an extra large label to be assigned. |\n| `xs-label`             | String  | `size/XS`                      | The name of the label for a very small number of lines changed.              |\n| `s-label`              | String  | `size/S`                       | The name of the label for a small number of lines changed.                   |\n| `m-label`              | String  | `size/M`                       | The name of the label for a medium number of lines changed.                  |\n| `l-label`              | String  | `size/L`                       | The name of the label for a large number of lines changed.                   |\n| `xl-label`             | String  | `size/XL`                      | The name of the label for a very large number of lines changed.              |\n| `xxl-label`            | String  | `size/XXL`                     | The name of the label for a very, very large number of lines changed.        |\n| `color`                | String  | ![](./assets/box.svg) `4f348b` | The colour to use when creating labels.                                      |\n| `github-token`         | String  | [github.token][3]              | The token to use for managing labels.                                        |\n| `ignore-deleted-files` | Boolean | `false`                        | Set to ignore deleted files when calculating the number of lines changed.    |\n| `ignore-deleted-lines` | Boolean | `false`                        | Set to ignore deleted lines when calculating the number of lines changed.    |\n| `ignore-whitespace`    | Boolean | `true`                         | Ignore all whitespace changes when calculating the number of lines changed.  |\n| `dry-run`              | Boolean | `false`                        | Skip creating labels and assigning a label to the PR.                        |\n\nLabels will be automatically created if they do not yet exist with using the\nconfigured name and colour, along with a hardcoded description. Once they have\nbeen created, the colour and description will not be modified so can be adjusted\nas needed.\n\n[3]: https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication\n\n## Outputs\n\n| Name       | Type   | Description                                             |\n| ---------- | ------ | ------------------------------------------------------- |\n| `label`    | String | The label assigned to the pull request.                 |\n| `size`     | String | The calculated size of the pull request's changes.      |\n| `includes` | String | The files included in the size calculation.             |\n| `excludes` | String | The files explictly excluded from the size calculation. |\n| `ignores`  | String | The files that were ignored from the size calculation.  |\n\n## Recipes\n\nLabelling pull requests with a size is a good start, but the real value comes\nfrom tracking the size of changes over time. The below recipes are aimed at\nachiving that using the [`gh`][4] CLI.\n\nThese example use the `gh api` subcommand instead of `gh pr list` to avoid\nmissing data due to the `--limit` option.\n\n[4]: https://cli.github.com/\n\n### List all sized PRs\n\nThe following lists all pull requests merged to the `main` branch with their\nrespective size labels.\n\n```sh\ngh api \\\n  /repos/mattdowdell/pr-sizer/pulls\\?state=closed \\\n  --paginate \\\n  --jq '.[]\n    | select((.merged_at != null) and (.base.ref == \"main\"))\n    | \"PR #\\(.number): Merged at: \\(.merged_at), \\(.labels[].name | select(. | startswith(\"size/\")))\"'\n```\n\nExample output:\n\n```text\nPR #27: Merged at: 2024-12-23T09:04:04Z, size/M\nPR #26: Merged at: 2024-12-21T11:34:34Z, size/XXL\nPR #23: Merged at: 2024-12-20T10:05:25Z, size/XL\nPR #21: Merged at: 2024-12-23T09:35:51Z, size/M\nPR #15: Merged at: 2024-12-19T12:19:42Z, size/S\n```\n\n### List sized PRs between 2 points\n\nIt can be useful to track the size of changes between 2 points in time, e.g. the\nchanges going into an upcoming release. The below lists the pull requests merged\nto the `main` branch between 2 dates with their respective size labels.\n\n```sh\ngh api \\\n  /repos/mattdowdell/pr-sizer/pulls\\?state=closed \\\n  --paginate \\\n  --jq '.[]\n    | select(\n      .merged_at \u003e \"2024-12-19T12:19:42Z\" and\n      .merged_at \u003c= \"2024-12-23T09:04:04Z\" and\n      .base.ref == \"main\"\n    )\n    | \"PR #\\(.number): Merged at: \\(.merged_at), \\(.labels[].name | select(. | startswith(\"size/\")))\"'\n```\n\nIf the pull requests between 2 commits or tags are preferred, each date can be\nidentified with the following and substituted in:\n\n```sh\ngit show --no-patch --date=format:'%Y-%m-%dT%H:%M:%S' --format=%cd \u003ccommit-or-tag\u003e\n```\n\nExample output:\n\n```text\nPR #27: Merged at: 2024-12-23T09:04:04Z, size/M\nPR #26: Merged at: 2024-12-21T11:34:34Z, size/XXL\nPR #23: Merged at: 2024-12-20T10:05:25Z, size/XL\n```\n\n### Count frequency of sizes over all PRs\n\nDrilling down into the sizes of individual pull requests can help understand why\nit was a particular size. However, it is also useful to track trends over time,\nsuch as how many pull requests of each size have been merged. The below counts\nthe number of pull requests merged to the `main` branch for each size.\n\n```sh\ngh api \\\n  /repos/mattdowdell/pr-sizer/pulls\\?state=closed \\\n  --paginate \\\n  --jq '[ .[] | select(.merged_at != null and .base.ref == \"main\") ]\n    | map({ size: .labels[].name | select(. | startswith(\"size/\")) })\n    | group_by(.size)\n    | .[]\n    | \"\\(length) x \\(.[0].size)\"'\n```\n\nExample output:\n\n```text\n2 x size/M\n1 x size/S\n1 x size/XL\n1 x size/XXL\n```\n\n### Count frequency of sizes between dates\n\nComparing of the size of changes across multiple releases can help identify\ntrends, including the number of changes in a release and the sizes of those\nchanges. The below counts the number of pull requests merged to the `main`\nbranch between 2 dates for each size.\n\n```sh\ngh api \\\n  /repos/mattdowdell/pr-sizer/pulls\\?state=closed \\\n  --paginate \\\n  --jq '[ .[] | select(\n      .merged_at \u003e \"2024-12-19T12:19:42Z\" and\n      .merged_at \u003c= \"2024-12-23T09:04:04Z\" and\n      .base.ref == \"main\"\n    ) ]\n    | map({ size: .labels[].name | select(. | startswith(\"size/\")) })\n    | group_by(.size)\n    | .[]\n    | \"\\(length) x \\(.[0].size)\"'\n```\n\nSee [above](#list-sized-prs-between-2-points) for how to convert commits and\ntags into dates.\n\nExample output:\n\n```text\n1 x size/M\n1 x size/XL\n1 x size/XXL\n```\n\n### List PRs with a specific size\n\nIt is not impossible for a change to be large out of necessity, even whilst\nstriving for smaller pull requests. The below will list all pull requests merged\nto the `main` branch with a `size/XXL` label.\n\n```sh\ngh api \\\n  /repos/mattdowdell/pr-sizer/pulls\\?state=closed \\\n  --jq '.[]\n    | select(.merged_at != null and .base.ref == \"main\" and .labels[].name == \"size/XXL\")\n    | \"PR #\\(.number)\"'\n```\n\nExample output:\n\n```text\nPR #26\n```\n\n## Troubleshooting\n\n### `git diff` failed\n\nIf `actions/checkout` was not configured with `fetch-depth: 0`, the following\nerror will be output. A branch other than `main` may be output depending on your\nrepository settings.\n\n```\nfatal: ambiguous argument 'origin/main': unknown revision or path not in the working tree.\n```\n\nTo correct this, set `fetch-depth: 0` for the `actions/checkout` action to fetch\nthe history for all branches as shown in [Usage](#usage). This means `git diff`\ncan compare the pull request's branch to its target branch and so calculate the\nsize of the change.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattdowdell%2Fpr-sizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattdowdell%2Fpr-sizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattdowdell%2Fpr-sizer/lists"}