{"id":28125138,"url":"https://github.com/xing/canarist","last_synced_at":"2025-05-14T09:20:36.613Z","repository":{"id":37031058,"uuid":"170095060","full_name":"xing/canarist","owner":"xing","description":null,"archived":false,"fork":false,"pushed_at":"2025-01-23T18:25:20.000Z","size":971,"stargazers_count":7,"open_issues_count":18,"forks_count":1,"subscribers_count":17,"default_branch":"master","last_synced_at":"2025-01-23T19:27:38.002Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/xing.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-11T08:39:56.000Z","updated_at":"2022-12-14T22:57:33.000Z","dependencies_parsed_at":"2023-11-26T19:42:21.260Z","dependency_job_id":null,"html_url":"https://github.com/xing/canarist","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xing%2Fcanarist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xing%2Fcanarist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xing%2Fcanarist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xing%2Fcanarist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xing","download_url":"https://codeload.github.com/xing/canarist/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254110399,"owners_count":22016393,"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":[],"created_at":"2025-05-14T09:20:20.848Z","updated_at":"2025-05-14T09:20:36.602Z","avatar_url":"https://github.com/xing.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# canarist\n\n**TLDR**: _A bit like `npm link`, but for workspaces / monorepos :rocket:_\n\n## Introduction\n\ncanarist is a tool that allows you to combine multiple yarn workspace monorepos into one single temporary workspace and execute commands inside each of them.\n\nThis is useful if, for example, you have a tool or library that is being developed inside a monorepo and you want to test out new changes to your library in downstream projects by executing their test suites.\n\nAt XING we have this automated within our CI, so that PRs to central repositories will be tested against a few downstream projects.\n\n_If you want to read more into how and why this tool works, check out the [overview](./docs/overview.md) (which I had prepared for a small presentation in our company)._\n\n## System requirements\n\nThis tool is built with modern Node.js and needs at least Node.js 10.13 or higher.\n\nSince this is a tool for managing yarn workspaces, it is required to have `yarn` and `git` installed locally.\n\n## Quick start\n\nYou can use canarist as a CLI tool: Install it globally or use npx to run it as a one-off command:\n\n```shell\nnpx canarist -r . -r git@github.com:some/other.git\n```\n\nThis command will create a temporary folder and clone the repository from your current working directory (`.`) and the `some/other` repository from GitHub into a temporary folder and execute `yarn test` in both repositories.\n\n## Configuration and projects\n\ncanarist is fully configurable through `cosmiconfig` and even allows to specify multiple different combinations of repositories (called \"projects\") which can be run from the CLI.\n\nYou can configure canarist through one of the following places:\n\n- a `\"canarist\"` key in the package.json\n- a `.canaristrc{.json,.yml,.js}` file\n- a `canarist.config.js` file\n\n**Example single-mode configuration in package.json**\n\n```json\n{\n  \"canarist\": {\n    \"repositories\": [\n      {\n        \"url\": \".\",\n        \"directory\": \"local-repo\",\n        \"commands\": [\"\"]\n      },\n      {\n        \"url\": \"git@github.com:some/other.git\",\n        \"commands\": [\"yarn build\"]\n      },\n      {\n        \"url\": \"git@github.com:my/other.git\",\n        \"directory\": \"my-other\",\n        \"branch\": \"next\"\n      }\n    ],\n    \"rootManifest\": {\n      \"resolutions\": {\n        \"typescript\": \"3.2.4\"\n      }\n    },\n    \"targetDirectory\": \"~/work/canarist-target\",\n    \"yarnArguments\": \"--production\"\n  }\n}\n```\n\nThe above configuration can be executed by typing:\n\n```shell\nnpx canarist\n```\n\ninto the terminal and will do the following:\n\n- clone the local repository (`.`) into `~/work/canarist-target/local-repo`\n- clone the remote repository (`git@github.com:some/other.git`) into `~/work/canarist-target/other`\n- clone the remote repository (`git@github.com:my/other.git`) into `~/work/canarist-target/my-other`\n- create a `package.json` in `~/work/canarist-target/` which combines all workspaces from the other repositories\n- execute `yarn --production` in `~/work/canarist-target/`\n- execute `yarn build` in `~/work/canarist-target/other`\n- execute `yarn test` in `~/work/canarist-target/my-other`\n\n_Note:_ This configuration will link all packages from all three configured repositories together.\n\nIn case you want to test multiple different combinations, you can make use of projects (see below):\n\n**Example project-mode configuration in package.json**\n\n```json\n{\n  \"canarist\": {\n    \"projects\": [\n      {\n        \"name\": \"canarist\",\n        \"repositories\": [\n          {\n            \"url\": \"git@github.com:xing/canarist.git\"\n          },\n          {\n            \"url\": \"git@github.com:my/canarist.git\",\n            \"directory\": \"my-canarist\",\n            \"branch\": \"next\",\n            \"commands\": [\"yarn build\", \"yarn test\"]\n          }\n        ],\n        \"rootManifest\": {\n          \"resolutions\": {\n            \"jest\": \"^24.0.0\"\n          }\n        }\n      },\n      {\n        \"name\": \"other\",\n        \"repositories\": [\n          {\n            \"url\": \"git@github.com:some/other.git\",\n            \"branch\": \"next\"\n          },\n          {\n            \"url\": \"git@github.com:my/other.git\",\n            \"directory\": \"my-other\"\n          }\n        ],\n        \"yarnArguments\": \"--ignore-scripts\"\n      }\n    ]\n  }\n}\n```\n\nThe above configuration specifies two projects, which can each be run by typing:\n\n```shell\nnpx canarist -p canarist\n```\n\nor\n\n```shell\nnpx canarist -p other\n```\n\ninto the terminal.\n\n_Note:_ This configuration allows to link `canarist` with `my/canarist` and `some/other` with `my/other`, this is useful when you want to test changes in several different repositories without linking all of them together at once.\n\n**CLI output:**\n\n```\n$ canarist --help\nUsage: canarist options [\u003ctarget\u003e]\n\nOptions:\n    --repository, -r\n        The URL (or local file path) to a repository to clone.\n        This option accepts sub-arguments (see examples):\n            --branch, -b\n                The branch that should be checked out (default: master).\n            --command, -c\n                The command to execute in this repository (default: \"yarn test\").\n            --directory, -d\n                This option allows to change the directory name in case of conflicts.\n    --root-manifest, -m\n        A valid JSON string that should be merged into the generated root manifest.\n    --yarn-arguments, -y\n        Additional arguments that should be passed to the \"yarn install\" command.\n    --project, -p\n        The name of a project to execute in a multi-project configuration.\n\nExamples:\n    $ canarist -r git@github.com:xing/canarist.git -r git@github.com:some/other.git\n        Clones xing/canarist and some/other into a temporary directory\n        and executes \"yarn test\" in both repositories.\n\n    $ canarist -r [git@github.com:xing/canarist.git -b next -c] -r git@github.com:some/other.git\n        Clones the \"next\" branch of xing/canarist and the master branch of some/other\n        and executes no command in xing/canarist and \"yarn test\" in some/other.\n\n    $ canarist -r [git@github.com:xing/canarist.git -d canarist] -r [git@github.com:my/canarist.git -d my-canarist]\n        Clones xing/canarist into canarist and my/canarist into my-canarist inside a temporary directory.\n\n    $ canarist -r ~/work/canarist -r ~/work/other -m '{\"resolutions\":{\"typescript\":\"3.2.4\"},\"devDependencies\":{\"jest\":\"23.0.0}}'\n        Clones the master branches of both local repositories into a temporary directory\n        and additionally installs yarn resolutions and a missing dev dependency.\n\n    $ canarist -r ~/work/canarist -r ~/work/other -r ~/work/other2 -r ~/work/other3\n        Clones the master branches of all four local repositories into a temporary directory\n        and executes \"yarn test\" for each of them.\n\n    $ canarist -r ~/work/canarist -r ~/work/other --y \"--production=true\"\n        Clones the master branches of both repositories and installs production dependencies only\n\n    $ canarist -p my-project\n        Looks up the project configuration with the name \"my-project\" in the cosmiconfig\n        of the current repository and clones and executes the repositories and commands therein.\n        Read more: https://github.com/xing/canarist/blob/master/README.md\n```\n\n## TODOs\n\n- [ ] allow to unpin dependencies which would otherwise be installed multiple times (for example: packages of both repositories have \"webpack\" as a dependency, one has it pinned to \"4.40.0\" and the other has a semver range \"^4.30.0\". If webpack@latest is at 4.40.0 we have no issues, but if webpack has a new release, say 4.41.0, we now have two versions installed).\n- [ ] allow to configure which dotfiles should be copied / merged into the root (currently only \".npmrc\" will be merged)\n- [ ] implement a `--no-install` or `--no-commands` flag, as a simple way to \"link\" two repositories and debug inside them?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxing%2Fcanarist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxing%2Fcanarist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxing%2Fcanarist/lists"}