-
-
Notifications
You must be signed in to change notification settings - Fork 40
/
README.md
218 lines (160 loc) · 6.75 KB
/
README.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# Not only Composer tools to build a Monorepo
[![Downloads total](https://img.shields.io/packagist/dt/symplify/monorepo-builder.svg?style=flat-square)](https://packagist.org/packages/symplify/monorepo-builder/stats)
Do you maintain [a monorepo](https://tomasvotruba.com/blog/2019/10/28/all-you-always-wanted-to-know-about-monorepo-but-were-afraid-to-ask/) with more packages?
**This package has few useful tools, that will make that easier**.
## Install
```bash
composer require symplify/monorepo-builder --dev
```
## Usage
### 1. Are you New to Monorepo?
The best to lean-in fast is to read basic intro at blog post [All You Always Wanted to Know About Monorepo](https://www.tomasvotruba.com/blog/2019/10/28/all-you-always-wanted-to-know-about-monorepo-but-were-afraid-to-ask/#what-is-monorepo).
We also made a simple command to make that easy for you:
```bash
vendor/bin/monorepo-builder init
```
And the basic setup is done!
### 2. Merge local `composer.json` to the Root One
Merges configured sections to the root `composer.json`, so you can only edit `composer.json` of particular packages and let script to synchronize it.
Sections that are needed for monorepo to work will be merged:
- 'require'
- 'require-dev'
- 'autoload'
- 'autoload-dev'
- 'repositories'
- 'extra'
To merge run:
```bash
vendor/bin/monorepo-builder merge
```
<br>
Typical location for packages is `/packages`. But what if you have different naming or extra `/projects` directory?
```php
use Symplify\MonorepoBuilder\ComposerJsonManipulator\ValueObject\ComposerJsonSection;
use Symplify\MonorepoBuilder\Config\MBConfig;
use Symplify\MonorepoBuilder\ValueObject\Option;
return static function (MBConfig $mbConfig): void {
// where are the packages located?
$mbConfig->packageDirectories([
// default value
__DIR__ . '/packages',
// custom
__DIR__ . '/projects',
]);
// how to skip packages in loaded directories?
$mbConfig->packageDirectoriesExcludes([__DIR__ . '/packages/secret-package']);
// "merge" command related
// what extra parts to add after merge?
$mbConfig->dataToAppend([
ComposerJsonSection::AUTOLOAD_DEV => [
'psr-4' => [
'Symplify\Tests\\' => 'tests',
],
],
ComposerJsonSection::REQUIRE_DEV => [
'phpstan/phpstan' => '^0.12',
],
]);
$mbConfig->dataToRemove([
ComposerJsonSection::REQUIRE => [
// the line is removed by key, so version is irrelevant, thus *
'phpunit/phpunit' => '*',
],
ComposerJsonSection::REPOSITORIES => [
// this will remove all repositories
Option::REMOVE_COMPLETELY,
],
]);
};
```
### 3. Bump Package Inter-dependencies
Let's say you release `symplify/symplify` 4.0 and you need package to depend on version `^4.0` for each other:
```bash
vendor/bin/monorepo-builder bump-interdependency "^4.0"
```
### 4. Keep Synchronized Package Version
In synchronized monorepo, it's common to use same package version to prevent bugs and WTFs. So if one of your package uses `symfony/console` 3.4 and the other `symfony/console` 4.1, this will tell you:
```bash
vendor/bin/monorepo-builder validate
```
### 5. Keep Package Alias Up-To-Date
You can see this even if there is already version 3.0 out:
```json
{
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
}
}
```
**Not good.** Get rid of this manual work and add this command to your release workflow:
```bash
vendor/bin/monorepo-builder package-alias
```
This will add alias `3.1-dev` to `composer.json` in each package.
If you prefer [`3.1.x-dev`](https://getcomposer.org/doc/articles/aliases.md#branch-alias) over default `3.1-dev`, you can configure it:
```php
use Symplify\MonorepoBuilder\Config\MBConfig;
return static function (MBConfig $mbConfig): void {
// default: "<major>.<minor>-dev"
$mbConfig->packageAliasFormat('<major>.<minor>.x-dev');
};
```
### 6. Split Directories to Git Repositories
Thanks to GitHub Actions, this was never simpler to set up. Use [symplify/github-action-monorepo-split](https://github.com/symplify/github-action-monorepo-split).
How to configure it? See our local setup at [.github/workflows/split_monorepo.yaml](https://github.com/danharrin/monorepo-split-github-action/blob/main/.github/workflows/split.yaml)
### 7. Release Flow
When a new version of your package is released, you have to do many manual steps:
- bump mutual dependencies,
- tag this version,
- `git push` with tag,
- change `CHANGELOG.md` title *Unreleased* to `v<version> - Y-m-d` format
- bump alias and mutual dependencies to next version alias
But what if **you forget one or do it in wrong order**? Everything will crash!
The `release` command will make you safe:
```bash
vendor/bin/monorepo-builder release v7.0
```
And add the following release workers to your `monorepo-builder.php`:
```php
use Symplify\MonorepoBuilder\Config\MBConfig;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker;
use Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateReplaceReleaseWorker;
return static function (MBConfig $mbConfig): void {
// release workers - in order to execute
$mbConfig->workers([
UpdateReplaceReleaseWorker::class,
SetCurrentMutualDependenciesReleaseWorker::class,
AddTagToChangelogReleaseWorker::class,
TagVersionReleaseWorker::class,
PushTagReleaseWorker::class,
SetNextMutualDependenciesReleaseWorker::class,
UpdateBranchAliasReleaseWorker::class,
PushNextDevReleaseWorker::class,
]);
};
```
These `TagVersionReleaseWorker` and `PushTagReleaseWorker` are enabled by default.
If you want to disable these default workers, you can use the following code.
```php
return static function (MBConfig $mbConfig): void {
$mbConfig->disableDefaultWorkers();
};
```
You can also include your own workers. Just add services that implements `ReleaseWorkerInterface`.
Are you afraid to tag and push? Use `--dry-run` to see only descriptions:
```bash
vendor/bin/monorepo-builder release 7.0 --dry-run
```
Do you want to release next [patch version](https://semver.org/), e.g. current `v0.7.1` → next `v0.7.2`?
```bash
vendor/bin/monorepo-builder release patch
```
You can use `minor` and `major` too.