{"id":24990832,"url":"https://github.com/belco90/octochangelog","last_synced_at":"2025-10-18T06:40:32.352Z","repository":{"id":37048173,"uuid":"245259736","full_name":"Belco90/octochangelog","owner":"Belco90","description":"Compare GitHub changelogs across multiple releases in a single view.","archived":false,"fork":false,"pushed_at":"2025-03-08T21:32:30.000Z","size":30366,"stargazers_count":59,"open_issues_count":48,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-09T09:29:58.796Z","etag":null,"topics":["chakra-ui","compare-changes","comparing-changelogs","comparing-releases","comparison","github","github-api","nextjs","releases","semantic-versioning","tool","typescript"],"latest_commit_sha":null,"homepage":"https://octochangelog.com","language":"TypeScript","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/Belco90.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":"2020-03-05T20:20:33.000Z","updated_at":"2025-03-05T02:07:21.000Z","dependencies_parsed_at":"2024-01-29T15:46:51.620Z","dependency_job_id":"52d41a15-5cbb-48b6-9c66-2f3badbc6d09","html_url":"https://github.com/Belco90/octochangelog","commit_stats":null,"previous_names":["octochangelog/octochangelog-webapp","octoclairvoyant/octoclairvoyant-webapp","belco90/octochangelog"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Belco90%2Foctochangelog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Belco90%2Foctochangelog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Belco90%2Foctochangelog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Belco90%2Foctochangelog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Belco90","download_url":"https://codeload.github.com/Belco90/octochangelog/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244066179,"owners_count":20392406,"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":["chakra-ui","compare-changes","comparing-changelogs","comparing-releases","comparison","github","github-api","nextjs","releases","semantic-versioning","tool","typescript"],"created_at":"2025-02-04T13:39:34.793Z","updated_at":"2025-10-18T06:40:32.332Z","avatar_url":"https://github.com/Belco90.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg\n    src=\"https://github.com/Belco90/octochangelog/blob/main/public/mascot-icon.png?raw=true\"\n    height=\"500\"\n    width=\"500\"\n    alt=\"Octochangelog mascot (a purple octopus-cat) reading a crystal ball\"\n  \u003e\n  \u003cp\u003e\n    \u003cspan role=\"img\" aria-label=\"Crystall ball\"\u003e🔮\u003c/span\u003e https://www.octochangelog.com/\n  \u003c/p\u003e\n  \u003cp\u003eCompare GitHub changelogs across multiple releases in a single view.\u003c/p\u003e\n\n\u003c/div\u003e\n\n\u003chr\u003e\n\n[![CI](https://github.com/Belco90/octochangelog/actions/workflows/ci.yml/badge.svg)](https://github.com/octochangelog/octochangelog-webapp/actions/workflows/ci.yml)\n[![Octochangelog Webapp Cypress tests](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/u8grd8\u0026style=flat\u0026logo=cypress)](https://dashboard.cypress.io/projects/u8grd8/runs)\n[![Netlify Status](https://api.netlify.com/api/v1/badges/4ef576fd-d384-4327-a1fc-54a73e71066f/deploy-status)](https://app.netlify.com/projects/octochangelog/deploys)\n\n## What is Octochangelog?\n\n\u003cimg src=\"https://github.com/Belco90/octochangelog/blob/main/public/browser-preview.png?raw=true\" alt=\"Octochangelog showing a comparison of releases for the eslint-plugin-testing-library repo\" \u003e\n\n[Octochangelog](https://www.octochangelog.com/) is a webapp that allows you to compare GitHub changelogs across multiple releases in a single view. You only have to pick a repo, and two versions to compare the changes between them.\n\n- Sifting through changelogs on GitHub taking too much time? Let Octochangelog put the list of changes in a single view!\n- Want to let your team review the changes in a dependency? Give them a link!\n- Octochangelog finds all breaking changes, and lists them at the top. You can’t miss those pesky gotcha’s now!\n- Want a list of major, minor and patch level changes? Octochangelog groups changes into categories for you!\n- Want to know which version introduced a certain change? Octochangelog labels each change with the version number.\n\n## Motivation\n\nIn January 2020 [GitHub announced a shortcut to compare across two releases](https://github.blog/changelog/2020-01-13-shortcut-to-compare-across-two-releases/).\nThis shortcut basically leaves you to [pick a release version to compare with from another release version working as base](https://help.github.com/en/github/administering-a-repository/comparing-releases).\nThen you'll see a diff of the code between those two versions.\nThis is a nice addition, so you can see at once all code changes between a range of versions.\nHowever, this is not what I expected at all or what I would find most useful when comparing releases.\n\nWhat did I expect then?\nI spend a lot of time comparing releases, either for upgrading dependencies at work or in my personal projects.\nOr even just to be up to date about some library updates.\nThis process is tedious, specially if there are a lot of releases between base and target versions as you need to paginate between multiple pages.\nI usually do this process over GitHub releases tab or going through the `CHANGELOG.md` if available.\nUsually I'm interested in looking for breaking changes more than any other kind of changes.\n**So why not compare changelogs through releases descriptions filtering, grouping and sorting what really matters?**\n\nThat's what Octochangelog does for you with their ability to gain information through extrasensory perception!\nIt retrieves all the releases description available from a repo, and leaves you to filter them by base and target versions.\nThen, it will **parse, normalize, group and sort** those changes for you.\n\n## How it works?\n\nOctochangelog needs to do some extra work for showing you the changelogs across multiple releases in a simple way.\n\n### Parsing\n\nThis is the most complex process of the app.\nEven if there is a big parsing step at first, after some other processes there are also some additional parsings too.\nThis is done with [unified js](https://unifiedjs.com/), an amazing content compiler to syntax tree.\nIt turns out that this powerful library is heavily used by `mdx-js`, `prettier` or `gatsby`!\nSo what's the process here?\nI receive Markdown from GitHub releases, and I want to output React elements, so the process is something like this:\n\n\u003e MD --\u003e MDAST --\u003e manipulation explained in steps below --\u003e HTML --\u003e React\n\nThe idea behind this is:\n\n1. Convert to MDAST (**M**ark**d**own **AST**) to manipulate the content.\n2. Look for interesting content: MD headings, so descriptions can be classified properly. This is when **normalizing** and **grouping** happens.\n3. When descriptions are grouped, convert them to HTML and apply some improvements (highlight GitHub references and code blocks).\n4. Finally, convert to React to avoid rendering the HTML through `dangerouslySetInnerHTML`.\n\n### Normalizing\n\nSemantic Versioning is nice.\nIt's easy to differentiate between changes level just looking at the number position at the version.\nThough now everyone refers to each change level in the same way.\nThe 3 changes levels in SemVer are:\n\n- Major \u003c--\u003e Breaking Changes\n- Minor \u003c--\u003e Features\n- Patch \u003c--\u003e Bug Fixes\n\nThis is one of the reasons Octochangelog will normalize the different levels of changes, so it makes sure all the changes under the same level can be grouped properly.\nObviously, it needs to normalize different cases, spacing or wording, as one repo could refer to patch level as \"bugfix\" and another one as \"BUG FIXES\".\n\n### Grouping\n\nAt the parsing step where the Markdown is converted into Markdown AST, it's best opportunity to group changes after being normalized.\nThis implies put all Breaking Changes together, Features together and so on.\nWhat if the group doesn't belong to SemVer though?\nWell, the app will do its best and keep every single category of changes received, and group them if several are found.\n\n### Sorting\n\nLast but not least: sort the groups by priority.\nAs mentioned in the intro, the group of changes we should worry about the most is **breaking changes**.\nFeatures and Bug Fixes will come next, but what about those groups out of SemVer?\nWell, they'll come after SemVer one without any specific order, except some low priority groups as \"Credits\", \"Thanks\" or \"Artifacts\".\nSo the final sorting will be:\n\n1. BREAKING CHANGES\n2. Features\n3. Bug fixes\n4. ...everything else\n5. Credits\n6. Thanks\n7. Artifacts\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelco90%2Foctochangelog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbelco90%2Foctochangelog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbelco90%2Foctochangelog/lists"}