{"id":20333127,"url":"https://github.com/jaebradley/github-languages-watcher","last_synced_at":"2026-05-18T03:32:13.303Z","repository":{"id":47270634,"uuid":"129423215","full_name":"jaebradley/github-languages-watcher","owner":"jaebradley","description":"A naive Travis job that automatically opens PRs based on changes to GitHub's language file","archived":false,"fork":false,"pushed_at":"2022-06-22T08:07:09.000Z","size":325,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-14T15:50:50.235Z","etag":null,"topics":["github","github-language","github-languages"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaebradley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-13T15:47:38.000Z","updated_at":"2018-04-15T15:00:17.000Z","dependencies_parsed_at":"2022-09-16T09:22:11.491Z","dependency_job_id":null,"html_url":"https://github.com/jaebradley/github-languages-watcher","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaebradley%2Fgithub-languages-watcher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaebradley%2Fgithub-languages-watcher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaebradley%2Fgithub-languages-watcher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaebradley%2Fgithub-languages-watcher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaebradley","download_url":"https://codeload.github.com/jaebradley/github-languages-watcher/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241852146,"owners_count":20030966,"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":["github","github-language","github-languages"],"created_at":"2024-11-14T20:29:26.844Z","updated_at":"2026-05-18T03:32:08.264Z","avatar_url":"https://github.com/jaebradley.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GitHub Languages Watcher\n\nA naive Travis CI job that looks for updates to [the `languages.yml` file](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) in [the `github/linguist` repository](https://github.com/github/linguist).\n\n## Why?\n\nI built [a NodeJS client for GitHub languages](https://github.com/jaebradley/github-languages-client) (mostly because I'm a huge nerd but also because there's not really a good way to get this information). \u003csup\u003e[1](#good-way-footnote)\u003c/sup\u003e\n\nWhat are these languages used for?\n\nYou can use them for GitHub's [`Advanced Search`](https://github.com/search/advanced), for example (and [the associated `search` API](https://developer.github.com/v3/search/#parameters-2)).\n\nHowever, the client uses [an underlying `JSON` file](https://github.com/jaebradley/github-languages-client/blob/master/src/languages.json) to power it's API (it's essentially a thin wrapper around a `JSON` blob).\n\nSo when languages get added to the `linguist/languages.yml` file, the client's underlying `JSON` file needs to get updated as well.\n\n## Can I Do This Manually?\n\nIt's definitely possible to manually\n\n1. Fetch the contents of the `languages.yml` file\n2. Convert to the `JSON` schema the client expects\n3. Write `JSON` to `languages.json` file\n4. Create a PR if `languages.json` has changed\n5. Merge PR, cut a new release of the client, and publish new version to `npm`\n\nBut it's also a pain to remember to do all of these things, especially at least once a day, which is my target cadence (it'd be kind've not great if GitHub added a language to their canonical list of languages, and the client wasn't up-to-date for a week).\n\n## So How Can I Automate This?\n\nSo the client actually uses a tool called [`semantic-release`](https://github.com/semantic-release/semantic-release) to do all the, well, release automation. So when a PR gets merged (given the correct commit message format) a new GitHub release and `npm` release will be cut as part of the `master` Travis CI job.\n\nSo I don't need to worry about step 5 (phew!)...but I still need to come up with a plan for steps 1 through 4.\n\n## Implementation\n\nI thought about using Heroku to run this job - and I could definitely see myself moving to Heroku in the future, but I tried implementing the job automation in Travis ([Travis has cron jobs!](https://docs.travis-ci.com/user/cron-jobs/)).\n\nIn this cron job, I do a\n\n1. `git clone` the client repository\n    1. Set the author information\n1. Create a new branch\n1. Fetch the contents of `languages.yml`\n1. Write `JSON` to `languages.json` file\n1. `git diff` the file\n1. If it's changed...\n    1. I `git add` and `git commit` the change with the appropriate `semantic-release` commit message syntax\n    1. I then create a PR using [the `octonode`](https://github.com/pksunkara/octonode) library\n1. If it hasn't changed...do nothing!\n\n## Tradeoffs\n\n* The main [`script`](https://github.com/jaebradley/github-languages-watcher/blob/master/src/script.js) feels kind've gross to me - it just seems a little hacky (I guess I'm just not used to executing `git` commands programmatically).\n* The entire implementation is dumb as 💩\n  * It doesn't take into account existing PRs which might have identical file changes - this might lead to PR pollution\n    * The reason I made this decision is that I don't expect `languages.yml` to change *that* often\n    * Also, I keep a pretty close eye on GitHub notifications - I'd hope that if I'm running a daily (at its most frequent) job, I'd be able to merge the automatically generated PR pretty quickly.\n\n## Footnotes\n\n\u003cul\u003e\n  \u003cli\u003e\n    \u003ca name=\"good-way-footnote\"\u003e\u003csup\u003e1\u003c/sup\u003eThis would be a really not great time to learn that there is an API endpoint that delivers this information...\u003c/a\u003e\n  \u003c/li\u003e\n\u003c/ul\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaebradley%2Fgithub-languages-watcher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaebradley%2Fgithub-languages-watcher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaebradley%2Fgithub-languages-watcher/lists"}