{"id":42194623,"url":"https://github.com/scientific-python/changelist","last_synced_at":"2026-01-27T00:01:55.341Z","repository":{"id":177855463,"uuid":"661012109","full_name":"scientific-python/changelist","owner":"scientific-python","description":"Prepare an automatic changelog from GitHub pull requests ","archived":false,"fork":false,"pushed_at":"2025-12-05T16:30:02.000Z","size":131,"stargazers_count":9,"open_issues_count":17,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-05T00:42:03.872Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","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/scientific-python.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-01T14:08:25.000Z","updated_at":"2025-12-05T16:30:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"f9abb83f-5729-4754-808e-de404ed575fa","html_url":"https://github.com/scientific-python/changelist","commit_stats":{"total_commits":74,"total_committers":6,"mean_commits":"12.333333333333334","dds":0.472972972972973,"last_synced_commit":"386d5b0851e5f5b5078dc2ec1ea42b8aa9b01a3a"},"previous_names":["scientific-python/changelist"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/scientific-python/changelist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Fchangelist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Fchangelist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Fchangelist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Fchangelist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scientific-python","download_url":"https://codeload.github.com/scientific-python/changelist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scientific-python%2Fchangelist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28792638,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:49:50.245Z","status":"ssl_error","status_checked_at":"2026-01-26T21:48:29.455Z","response_time":59,"last_error":"SSL_read: 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":[],"created_at":"2026-01-27T00:01:54.508Z","updated_at":"2026-01-27T00:01:55.330Z","avatar_url":"https://github.com/scientific-python.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# changelist\n\nA tool that automates release note generation.\n\nFor example, see\nhttps://github.com/scientific-python/changelist/blob/main/CHANGELOG.md.\n\n**Features**\n\n- Compile a list of pull requests, code authors, and reviewers between\n  two given git commits.\n- Categorize pull requests into sections based on GitHub labels.\n- Override pull request titles with more descriptive summaries.\n- Document unrelated changes in a pull requests in separate summaries.\n\n_This project is currently in its alpha stage and might be incomplete or change a lot!_\n\n## Installation\n\n```sh\npip install changelist\n```\n\n## Usage\n\nThe script requires a [GitHub personal access\ntoken](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).\nThe token does not need any permissions, since it is used only to\nincrease query limits.\n\n```sh\nexport GH_TOKEN='...'\nchangelist scientific-python/changelist v0.2.0 main\n```\n\nThis will list all pull requests, authors and reviewers that touched commits\nbetween `v0.2.0` and `main` (excluding `v0.2.0`).\nPull requests are sorted into sections according to the configuration in\n`tool.changelist.label_section_map`.\n\n## Writing pull request summaries\n\nBy default, changelist will fall back to the title of a pull request and its\nGitHub labels to sort it into the appropriate section. However, if you want\nlonger summaries of your changes you can add a code block with the following\nform anywhere in the description of the pull request:\n\n    ```release-note\n    An ideally expressive description of the change that is included as\n    a single bullet point. Newlines are removed.\n    ```\n\nSometimes pull requests introduce multiple changes that should be listed in different\nsections. For that reason, a summary block like above can be used more than\nonce. Additionally, you can add independent labels to each summary by adding a\n`{label=\"...\"}` anywhere in the summary. These labels are sorted the same way\nas regular pull request labels are. E.g. the two summaries below will go into\nseparate sections:\n\n    ```release-note {label=\"Bug fix\"}\n    Make `is_odd()` work for negative numbers.\n    ```\n\n    ```release-note\n    Deprecate `ìs_odd`; use `not (x % 2)` instead! {label=\"API, Highlight\"}\n    ```\n\n## Configuration\n\nchangelist can be configured from two sources, in order of precedence:\n\n- A local TOML file specified with the `--config` option\n- A remote `pyproject.toml` at `stop_rev`\n\nIf a configuration option is not specified in either file above, changelist\nfalls back to the following configuration:\n\n\u003c!--- Changes to the following block are overridden by a pre-commit hook! ---\u003e\n\u003c!--- begin default_config.toml ---\u003e\n\n````toml\n# Default changelist configuration as supported in pyproject.toml\n[tool.changelist]\n\n# A template string that is included as the title of the generated notes.\n# \"{repo_name}\" and \"{version}\", if given, are replaced by the respective\n# values given in the command line.\ntitle_template = \"{repo_name} {version}\"\n\n# A template string that is included as introductory text after the title.\n# \"{repo_name}\" and \"{version}\", if given, are replaced by the respective\n# values given in the command line.\nintro_template = \"\"\"\nWe're happy to announce the release of {repo_name} {version}!\n\"\"\"\n\n# A template string that is included at the end of the generated notes.\n# \"{repo_name}\" and \"{version}\", if given, are replaced by the respective\n# values given in the command line.\noutro_template = \"\"\"\n_These lists are automatically generated, and may not be complete or may contain\nduplicates._\n\"\"\"\n\n# Usernames that are excluded from the contributor list. This may also ignore\n# pull request of these users (see field `ignore_prs_by_username`).\nignored_user_logins = [\n    \"web-flow\",\n]\n\n# Ignore pull requests authored by these users.\n# If `{include = \"ignored_user_logins\"}` is included in this list (the default),\n# usernames from the field `ignored_user_logins` are also included.\nignore_prs_by_username = [\n    {include = \"ignored_user_logins\"},\n]\n\n# If this regex matches a pull requests description, the captured content\n# is included instead of the pull request title. E.g. the\n# default regex below is matched by\n#\n# ```release-note\n# An ideally expressive description of the change that is included as\n# a single bullet point. Newlines are removed.\n# ```\n#\n# If you modify this regex, make sure to match the content with a capture\n# group named \"summary\". The regex is allowed to match more than once in which\n# case a single pull request may result in multiple items (see\n# `pr_summary_label_regex` for why that might be useful).\npr_summary_regex = \"^```release-note\\\\s*(?P\u003csummary\u003e[\\\\s\\\\S]*?\\\\w[\\\\s\\\\S]*?)\\\\s*^```\"\n\n# Sometimes pull requests introduce changes that should be listed in different\n# sections. For that reason, `pr_summary_regex` can match more than once and\n# this regex, `pr_summary_label_regex`, can be used to add independent labels\n# to each summary. These labels are sorted with the `label_section_map` the\n# same way as regular pull request labels are. E.g. the example below will both\n# match and go into separate sections:\n#\n# ```release-note {label=\"Bug fix\"}\n# Make `is_odd()` work for negative numbers.\n# ```\n#\n# ```release-note\n# Deprecate `ìs_odd`; use `not (x % 2)` instead! {label=\"API, Highlight\"}\n# ```\n#\n# If you modify this regex, make sure to match the content with a capture\n# group named \"label\".\npr_summary_label_regex = \"\"\"{[^}]*?label=[\\\\\"](?P\u003clabel\u003e[^\\\\\"]+)[^}]*?}\"\"\"\n\n# If any of a pull request's labels matches one of the regexes on the left side\n# its summary will appear in the appropriate section with the title given on\n# the right side. If a pull request doesn't match one of these categories it is\n# sorted into a section titled \"Other\". Pull request can appear in multiple\n# sections as long as their labels match.\n[tool.changelist.label_section_map]\n\".*Highlight.*\" = \"Highlights\"\n\".*New feature.*\" = \"New Features\"\n\".*API.*\" = \"API Changes\"\n\".*Enhancement.*\" = \"Enhancements\"\n\".*Performance.*\" = \"Performance\"\n\".*Bug fix.*\" = \"Bug Fixes\"\n\".*Documentation.*\" = \"Documentation\"\n\".*Infrastructure.*\" = \"Infrastructure\"\n\".*Maintenance.*\" = \"Maintenance\"\n````\n\n\u003c!--- end default_config.toml ---\u003e\n\n## Set up your repository\n\nTo categorize merged PRs in the changelist with the default configuration, each\nPR must have a label that matches one of the regexes on the left side of the\n`label_section_map` table, e.g. `type: Highlights`.\n\n### Label checking\n\nYou may want to ensure that each PR has an associated `type: ` label,\nwe recommend adding an action that fails CI if the label is missing.\n\nTo do so, place the following in `.github/workflows/label-check.yaml`:\n\n\u003c!--- Changes to the following block are overridden by a pre-commit hook! ---\u003e\n\u003c!--- begin label-check.yaml ---\u003e\n\n```yaml\nname: Labels\n\non:\n  pull_request:\n    types:\n      - opened\n      - reopened\n      - labeled\n      - unlabeled\n      - synchronize\n\nenv:\n  LABELS: ${{ join( github.event.pull_request.labels.*.name, ' ' ) }}\n\njobs:\n  check-type-label:\n    name: ensure type label\n    runs-on: ubuntu-latest\n    steps:\n      - if: \"contains( env.LABELS, 'type: ' ) == false\"\n        run: exit 1\n```\n\n\u003c!--- end label-check.yaml ---\u003e\n\n### Milestones\n\nOften, it is helpful to have milestones that reflect the actual PRs\nmerged. We therefore recommend adding an action that attached the\nnext open milestone to any merged PR.\n\nTo do so, place the following in `.github/workflows/milestone-merged-prs.yaml`:\n\n\u003c!--- Changes to the following block are overridden by a pre-commit hook! ---\u003e\n\u003c!--- begin milestone-merged-prs.yaml ---\u003e\n\n```yaml\nname: Milestone\n\non:\n  pull_request_target:\n    types:\n      - closed\n    branches:\n      - \"main\"\n\njobs:\n  milestone_pr:\n    name: attach to PR\n    runs-on: ubuntu-latest\n    steps:\n      - uses: scientific-python/attach-next-milestone-action@c9cfab10ad0c67fed91b01103db26b7f16634639\n        with:\n          token: ${{ secrets.MILESTONE_LABELER_TOKEN }}\n          force: true\n```\n\n\u003c!--- end milestone-merged-prs.yaml ---\u003e\n\nSee https://github.com/scientific-python/attach-next-milestone-action for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientific-python%2Fchangelist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscientific-python%2Fchangelist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscientific-python%2Fchangelist/lists"}