{"id":23435547,"url":"https://github.com/customcommander/lerna-workflow-example","last_synced_at":"2025-04-13T03:41:59.242Z","repository":{"id":73818561,"uuid":"259303371","full_name":"customcommander/lerna-workflow-example","owner":"customcommander","description":"Example on how to use Lerna to manage the development life cycle of an application","archived":false,"fork":false,"pushed_at":"2020-05-03T08:12:14.000Z","size":16,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T20:51:29.266Z","etag":null,"topics":["example-project","javascript","lerna","monorepo"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc-by-4.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/customcommander.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":"2020-04-27T12:09:06.000Z","updated_at":"2024-03-18T17:22:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"abcbcf0d-9197-4e0f-a5c0-499a60be4e68","html_url":"https://github.com/customcommander/lerna-workflow-example","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/customcommander%2Flerna-workflow-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Flerna-workflow-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Flerna-workflow-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/customcommander%2Flerna-workflow-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/customcommander","download_url":"https://codeload.github.com/customcommander/lerna-workflow-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248660974,"owners_count":21141380,"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":["example-project","javascript","lerna","monorepo"],"created_at":"2024-12-23T12:51:51.131Z","updated_at":"2025-04-13T03:41:59.236Z","avatar_url":"https://github.com/customcommander.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lerna Workflow Example\n\n## Summary\n\nIn this article we explore how we can use **Lerna 3.20.2** to manage an application. We use Lerna to break down the codebase into small packages and to help us go through the different stages of the development cycle.\n\n⚠️While this article can be used as a starting point for designing alternative worklows, it is important to note that the workflow described here is **incompatible with the \"Conventional Commits\" specification**. See the following resources:\n\n- https://stackoverflow.com/q/61144530/1244884\n- https://github.com/lerna/lerna/issues/2536\n- https://github.com/customcommander/lerna-prerelease-conventional-commits\n\n---\n\n_What follows is based on observations and is completely reproducible. The repository in the case study is available as a Docker container and all steps are fully automated. (See Appendix.)_\n\n---\n\n## Case Study: Managing a website\n\nThe website development cycle is powered by a Lerna-managed monorepo. The codebase is split into several sub packages of which the website is one of them and depends on the other packages:\n\n* lib_a\n* lib_b\n* lib_c\n* website (depends on the three packages above)\n\n```\ndev\n|-- packages\n|   |-- lib_a             1.0.0-alpha.0\n|   |-- lib_b             1.0.0-alpha.0\n|   |-- lib_c             1.0.0-alpha.0\n|   |-- website           1.0.0-alpha.0\n|       |-- lib_a         1.0.0-alpha.0\n|       |-- lib_b         1.0.0-alpha.0\n|       |-- lib_c         1.0.0-alpha.0\n|-- package.json\n|-- lerna.json\n```\n\n### Workflow Summary\n\nThe `website` package is our main releasable artifact and will be released every two weeks as minor updates (e.g. 1.0.0, 1.1.0, 1.2.0, etc.). Patch releases (e.g. 1.0.1, 1.0.2, etc.) can happen to fix production issues.\n\nMajor releases (e.g. 2.0.0, 3.0.0, etc.) **shall not** happen. In this case study the website is similar to an ever-green browser; it gets updated unconditionally. Therefore using major updates as a way to protect users from breaking changes makes no sense in this context.\n\n### Workflow Details\n\nNew features and bug fixes go through three stages. Each stage has it own branch and versioning scheme:\n\n|             | Alpha                | Beta                | Production   |\n|:------------|:---------------------|:--------------------|:-------------|\n| **Branch**  | integration          | release/*           | master       |\n| **Version** | *e.g.* 1.0.0-alpha.0 | *e.g.* 1.0.0-beta.0 | *e.g.* 1.0.0 |\n\n#### Alpha Stage\n\nAt the start of a new development cycle, all packages are minor bumped.\n\n|         | lib_a         | lib_b         | lib_c         | website       |\n|:--------|:--------------|:--------------|:--------------|:--------------|\n| Cycle 1 | 1.0.0-alpha.0 | 1.0.0-alpha.0 | 1.0.0-alpha.0 | 1.0.0-alpha.0 |\n| Cycle 2 | 1.1.0-alpha.0 | 1.1.0-alpha.0 | 1.1.0-alpha.0 | 1.1.0-alpha.0 |\n| Cycle 3 | 1.2.0-alpha.0 | 1.2.0-alpha.0 | 1.2.0-alpha.0 | 1.2.0-alpha.0 |\n| ...     | ...           | ...           | ...           | ...           |\n\nDevelopers implement new features and bug fixes in the **integration** branch. The CI/CD pipeline publishes packages on a per commit basis.\n\nExample: at the end of the Alpha stage of Cycle 1:\n\n|       | # commits | version       |\n|:------|:----------|:--------------|\n| lib_a | 3         | 1.0.0-alpha.3 |\n| lib_b | 1         | 1.0.0-alpha.1 |\n| lib_c | 0         | 1.0.0-alpha.0 |\n\n\nThe public-facing website *never* consumes alpha packages!\n\n#### Beta Stage\n\nAfter two weeks of development it is time to release to our beta testers at http://beta.example.com.\n\nDevelopers cut a new release branch from the **integration** branch and name the release branch after the current minor version e.g. **release/v1.0.0**, **release/v1.1.0**, etc.\n\nThe CI/CD pipeline is configured to promote all alpha packages to beta packages:\n\n|         | Alpha         | Beta         |\n|:--------|:--------------|:-------------|\n| lib_a   | 1.0.0-alpha.3 | 1.0.0-beta.0 |\n| lib_b   | 1.0.0-alpha.1 | 1.0.0-beta.0 |\n| lib_c   | 1.0.0-alpha.0 | 1.0.0-beta.0 |\n\n#### Production Stage\n\nAfter two weeks of beta testing and with no major issues reported, it is time to promote our beta packages to production:\n\n|         | Beta         | Production |\n|:--------|:-------------|:-----------|\n| lib_a   | 1.0.0-beta.0 | 1.0.0      |\n| lib_b   | 1.0.0-beta.0 | 1.0.0      |\n| lib_c   | 1.0.0-beta.0 | 1.0.0      |\n\n\n### Workflow Example\n\n_Note: the following Lerna commands would typically run on your CI/CD pipeline._\n\n| Event                                                      | Branch         | Lerna Command                                                 | lib_a         | lib_b         | lib_c         | website        |\n|:-----------------------------------------------------------|:---------------|:--------------------------------------------------------------|:--------------|:--------------|:--------------|:---------------|\n| Start of 1\u003csup\u003est\u003c/sup\u003e cycle \u003csup\u003e1\u003c/sup\u003e                 | integration    | lerna publish --yes prerelease                                | 1.0.0-alpha.1 | 1.0.0-alpha.1 | 1.0.0-alpha.1 | 1.0.0-alpha.1  |\n| Made changes to `lib_a` \u003csup\u003e2\u003c/sup\u003e                       | integration    | lerna publish --yes prerelease                                | 1.0.0-alpha.2 | 1.0.0-alpha.1 | 1.0.0-alpha.1 | 1.0.0-alpha.2  |\n| First beta release \u003csup\u003e3\u003c/sup\u003e                            | release/v1.0.0 | lerna publish --yes --force-publish=* --preid=beta prerelease | 1.0.0-beta.0  | 1.0.0-beta.0  | 1.0.0-beta.0  | 1.0.0-beta.0   |\n| First production release \u003csup\u003e4\u003c/sup\u003e                      | master         | lerna publish --yes --force-publish=* minor                   | 1.0.0         | 1.0.0         | 1.0.0         | 1.0.0          |\n| Start of 2\u003csup\u003end\u003c/sup\u003e (and any other) cycle \u003csup\u003e5\u003c/sup\u003e | integration    | lerna publish --yes --force-publish=* --preid=alpha preminor  | 1.1.0-alpha.0 | 1.1.0-alpha.0 | 1.1.0-alpha.0 | 1.1.0-alpha.0  |\n| Made changes to `lib_a` and `lib_b` \u003csup\u003e6\u003c/sup\u003e           | integration    | lerna publish --yes prerelease                                | 1.1.0-alpha.1 | 1.1.0-alpha.1 | 1.1.0-alpha.0 | 1.1.0-alpha.1  |\n| Applied hot fix on 1.0.0 release \u003csup\u003e7\u003c/sup\u003e              | release/v1.0.0 | lerna publish --yes --force-publish=* --preid=beta prepatch   | 1.0.1-beta.0  | 1.0.1-beta.0  | 1.0.1-beta.0  | 1.0.1-beta.0   |\n| Released hot fix \u003csup\u003e8\u003c/sup\u003e                              | master         | lerna publish --yes --force-publish=* patch                   | 1.0.1         | 1.0.1         | 1.0.1         | 1.0.1          |\n| Second beta release                                        | release/v1.1.0 | lerna publish --yes --force-publish=* --preid=beta prerelease | 1.1.0-beta.0  | 1.1.0-beta.0  | 1.1.0-beta.0  | 1.1.0-beta.0   |\n| Second production release                                  | master         | lerna publish --yes --force-publish=* minor                   | 1.1.0         | 1.1.0         | 1.1.0         | 1.1.0          |\n| Applied hot fix on 1.1.0 release                           | release/v1.1.0 | lerna publish --yes --force-publish=* --preid=beta prepatch   | 1.1.1-beta.0  | 1.1.1-beta.0  | 1.1.1-beta.0  | 1.1.1-beta.0   |\n| Released hot fix                                           | master         | lerna publish --yes --force-publish=* patch                   | 1.1.1         | 1.1.1         | 1.1.1         | 1.1.1          |\n\nNotes:\n\n1.  Initial publication of all packages. (Start of 1\u003csup\u003est\u003c/sup\u003e cycle only.)\n2.  Publish changes during current development cycle. `website` has been updated because `lib_a` is one of its dependencies.\n3.  The `release/v1.0.0` branch has been cut from the `integration` branch.\n4.  The `release/v1.0.0` branch has been merged into the `master` branch.\n5.  When starting a new development cycle (after the first), we do a minor bump on all packages.\n6.  Publish changes during current development cycle.\n7.  The hot fix was made on the `integration` branch and cherry-picked onto the `release/v1.0.0` branch (e.g. `git cherry-pick integration --strategy-option=theirs`)\n8.  The `release/v1.0.0` branch has been merged into the `master` branch (e.g. `git merge release/v1.0.0 --strategy-option=theirs --no-edit`)\n\n### Appendix: How To Reproduce\n\nFirst build the Docker container:\n\n```\ncd /path/to/lerna-workflow-example\ndocker build . -t customcommander/lerna-workflow-example\n```\n\nYou can run all steps mentioned in this article with:\n\n```\ncd /path/to/lerna-workflow-example\n./run.sh\n```\n\nTo simply access the repository and experiment by yourself:\n\n```\ndocker run -it --rm customcommander/lerna-workflow-example\n```\n\n_Since everything runs inside the Docker container, you can experiment at will. To start afresh, just spin another instance of the container._\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Flerna-workflow-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcustomcommander%2Flerna-workflow-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcustomcommander%2Flerna-workflow-example/lists"}