Skip to content

Commit e945d0f

Browse files
committed
prepare release
0 parents  commit e945d0f

File tree

218 files changed

+8456
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

218 files changed

+8456
-0
lines changed

.gitattributes

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.gitattributes export-ignore
2+
.gitignore export-ignore
3+
phpunit.xml export-ignore
4+
*.md export-ignore
5+
tests export-ignore
6+
packages/composer-json-object/tests export-ignore
7+
packages/init/tests export-ignore
8+
packages/merge/tests export-ignore
9+
packages/release/tests export-ignore
10+
packages/split/tests export-ignore
11+
packages/testing/tests export-ignore

.github/FUNDING.yml

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# These are supported funding model platforms
2+
github: tomasvotruba
3+
custom: https://www.paypal.me/rectorphp

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor
2+
composer.lock

LICENSE

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
The MIT License
2+
---------------
3+
4+
Copyright (c) 2016 Tomas Votruba (http://tomasvotruba.com)
5+
6+
Permission is hereby granted, free of charge, to any person
7+
obtaining a copy of this software and associated documentation
8+
files (the "Software"), to deal in the Software without
9+
restriction, including without limitation the rights to use,
10+
copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the
12+
Software is furnished to do so, subject to the following
13+
conditions:
14+
15+
The above copyright notice and this permission notice shall be
16+
included in all copies or substantial portions of the Software.
17+
18+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25+
OTHER DEALINGS IN THE SOFTWARE.

README.md

+319
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
# Not only Composer tools to build a Monorepo
2+
3+
[![Downloads total](https://img.shields.io/packagist/dt/symplify/monorepo-builder.svg?style=flat-square)](https://packagist.org/packages/symplify/monorepo-builder/stats)
4+
5+
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?
6+
7+
**This package has few useful tools, that will make that easier**.
8+
9+
## Install
10+
11+
```bash
12+
composer require symplify/monorepo-builder --dev
13+
```
14+
15+
## Usage
16+
17+
### 0. Are you New to Monorepo?
18+
19+
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).
20+
We also made a simple command to make that easy for you:
21+
22+
```bash
23+
vendor/bin/monorepo-builder init
24+
```
25+
26+
And the basic setup is done!
27+
28+
### 1. Merge local `composer.json` to the Root One
29+
30+
Merges configured sections to the root `composer.json`, so you can only edit `composer.json` of particular packages and let script to synchronize it.
31+
32+
Sections that are needed for monorepo to work will be merged:
33+
34+
- 'require'
35+
- 'require-dev'
36+
- 'autoload'
37+
- 'autoload-dev'
38+
- 'repositories'
39+
- 'extra'
40+
41+
To merge run:
42+
43+
```bash
44+
vendor/bin/monorepo-builder merge
45+
```
46+
47+
<br>
48+
49+
Typical location for packages is `/packages`. But what if you have different naming or extra `/projects` directory?
50+
51+
```php
52+
declare(strict_types=1);
53+
54+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
55+
use Symplify\MonorepoBuilder\ValueObject\Option;
56+
57+
return static function (ContainerConfigurator $containerConfigurator): void {
58+
$parameters = $containerConfigurator->parameters();
59+
60+
// where are the packages located?
61+
$parameters->set(Option::PACKAGE_DIRECTORIES, [
62+
// default vaulue
63+
__DIR__ . '/packages',
64+
// custom
65+
__DIR__ . '/projects',
66+
]);
67+
68+
// how skip packages in loaded direectories?
69+
$parameters->set(Option::PACKAGE_DIRECTORIES_EXCLUDES, [__DIR__ . '/packages/secret-package']);
70+
71+
// "merge" command related
72+
73+
// what extra parts to add after merge?
74+
$parameters->set(Option::DATA_TO_APPEND, [
75+
'autoload-dev' => [
76+
'psr-4' => [
77+
'Symplify\Tests\\' => 'tests',
78+
],
79+
],
80+
'require-dev' => [
81+
'phpstan/phpstan' => '^0.12',
82+
],
83+
]);
84+
85+
$parameters->set(Option::DATA_TO_REMOVE, [
86+
'require' => [
87+
// the line is removed by key, so version is irrelevant, thus *
88+
'phpunit/phpunit' => '*',
89+
],
90+
]);
91+
};
92+
```
93+
94+
### 2. Bump Package Inter-dependencies
95+
96+
Let's say you release `symplify/symplify` 4.0 and you need package to depend on version `^4.0` for each other:
97+
98+
```bash
99+
vendor/bin/monorepo-builder bump-interdependency "^4.0"
100+
```
101+
102+
### 3. Keep Synchronized Package Version
103+
104+
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:
105+
106+
```bash
107+
vendor/bin/monorepo-builder validate
108+
```
109+
110+
### 4. Keep Package Alias Up-To-Date
111+
112+
You can see this even if there is already version 3.0 out:
113+
114+
```json
115+
{
116+
"extra": {
117+
"branch-alias": {
118+
"dev-master": "2.0-dev"
119+
}
120+
}
121+
}
122+
```
123+
124+
**Not good.** Get rid of this manual work and add this command to your release workflow:
125+
126+
```bash
127+
vendor/bin/monorepo-builder package-alias
128+
```
129+
130+
This will add alias `3.1-dev` to `composer.json` in each package.
131+
132+
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:
133+
134+
```php
135+
declare(strict_types=1);
136+
137+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
138+
use Symplify\MonorepoBuilder\ValueObject\Option;
139+
140+
return static function (ContainerConfigurator $containerConfigurator): void {
141+
$parameters = $containerConfigurator->parameters();
142+
// default: "<major>.<minor>-dev"
143+
$parameters->set(Option::PACKAGE_ALIAS_FORMAT, '<major>.<minor>.x-dev');
144+
};
145+
```
146+
147+
### 5. Split Directories to Git Repositories
148+
149+
Classic use case for monorepo is to synchronize last tag and the `master` branch to allow testing of `@dev` version.
150+
151+
```php
152+
declare(strict_types=1);
153+
154+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
155+
use Symplify\MonorepoBuilder\ValueObject\Option;
156+
157+
return static function (ContainerConfigurator $containerConfigurator): void {
158+
$parameters = $containerConfigurator->parameters();
159+
$parameters->set(Option::DIRECTORIES_TO_REPOSITORIES, [
160+
__DIR__ . '/packages/package-builder' => '[email protected]:symplify/package-builder.git',
161+
__DIR__ . '/packagages/monorepo-builder' => '[email protected]:symplify/monorepo-builder.git',
162+
__DIR__ . '/packagages/coding-standard' => '[email protected]:symplify/coding-standard.git',
163+
]);
164+
};
165+
```
166+
167+
Or even simpler:
168+
169+
```php
170+
declare(strict_types=1);
171+
172+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
173+
use Symplify\MonorepoBuilder\ValueObject\Option;
174+
175+
return static function (ContainerConfigurator $containerConfigurator): void {
176+
$parameters = $containerConfigurator->parameters();
177+
$parameters->set(Option::DIRECTORIES_TO_REPOSITORIES, [
178+
__DIR__ . '/packages/*' => '[email protected]:symplify/*.git',
179+
]);
180+
};
181+
```
182+
183+
Do you have non standard directory <=> repository name structure?
184+
185+
```bash
186+
/packages/MyFirstPackage => my-first-package.git
187+
```
188+
189+
Add `Option::DIRECTORIES_TO_REPOSITORIES_CONVERT_FORMAT`:
190+
191+
```php
192+
declare(strict_types=1);
193+
194+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
195+
use Symplify\MonorepoBuilder\Split\ValueObject\ConvertFormat;
196+
use Symplify\MonorepoBuilder\ValueObject\Option;
197+
198+
return static function (ContainerConfigurator $containerConfigurator): void {
199+
$parameters = $containerConfigurator->parameters();
200+
$parameters->set(Option::DIRECTORIES_TO_REPOSITORIES, [
201+
__DIR__ . '/packages/*' => '[email protected]:symplify/*.git',
202+
]);
203+
204+
$parameters->set(Option::DIRECTORIES_TO_REPOSITORIES_CONVERT_FORMAT, ConvertFormat::PASCAL_CASE_TO_KEBAB_CASE);
205+
};
206+
```
207+
208+
<br>
209+
210+
And run by:
211+
212+
```bash
213+
vendor/bin/monorepo-builder split
214+
```
215+
216+
To speed up the process about 50-60 %, all repositories are synchronized in parallel.
217+
218+
#### Testing split locally
219+
220+
If you want to test on local machine, you can set local targets by creating bare repositories:
221+
222+
```bash
223+
mkdir -p [target/path.git]
224+
cd [target/path.git]
225+
git init --bare
226+
# ^^^^^^ bare!!!
227+
```
228+
229+
Then you can set the target using `file://` prefix for absolute path:
230+
231+
```php
232+
declare(strict_types=1);
233+
234+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
235+
use Symplify\MonorepoBuilder\ValueObject\Option;
236+
237+
return static function (ContainerConfigurator $containerConfigurator): void {
238+
$parameters = $containerConfigurator->parameters();
239+
$parameters->set(Option::DIRECTORIES_TO_REPOSITORIES, [
240+
__DIR__ . '/packages/package-builder' => 'file:///home/developer/git/package-builder.git',
241+
__DIR__ . '/packagages/monorepo-builder' => 'file:///home/developer/git/monorepo-builder.git',
242+
]);
243+
};
244+
```
245+
246+
After that you can test the result:
247+
248+
```bash
249+
vendor/bin/monorepo-builder split
250+
cd /tmp
251+
git clone /home/developer/git/package-builder.git
252+
cd package-builder
253+
git log
254+
```
255+
256+
### 6. Release Flow
257+
258+
When a new version of your package is released, you have to do many manual steps:
259+
260+
- bump mutual dependencies,
261+
- tag this version,
262+
- `git push` with tag,
263+
- change `CHANGELOG.md` title *Unreleated* to `v<version> - Y-m-d` format
264+
- bump alias and mutual dependency to next version alias
265+
266+
But what if **you forget one or do it in wrong order**? Everything will crash!
267+
268+
The `release` command will make you safe:
269+
270+
```bash
271+
vendor/bin/monorepo-builder release v7.0
272+
```
273+
274+
Are you afraid to tag and push? Use `--dry-run` to see only descriptions:
275+
276+
```bash
277+
vendor/bin/monorepo-builder release v7.0 --dry-run
278+
```
279+
280+
Do you want ot release next [patch version](https://semver.org/), e.g. current `v0.7.1` → next `v0.7.2`?
281+
282+
```bash
283+
vendor/bin/monorepo-builder release patch
284+
```
285+
286+
You can use `minor` and `major` too.
287+
288+
### 7. Set Your Own Release Flow
289+
290+
There is set of few default release workers - classes that implement `Symplify\MonorepoBuilder\Release\Contract\ReleaseWorker\ReleaseWorkerInterface`.
291+
292+
You need to register them as services. Feel free to start with default ones:
293+
294+
```php
295+
declare(strict_types=1);
296+
297+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
298+
299+
return static function (ContainerConfigurator $containerConfigurator): void {
300+
$services = $containerConfigurator->services();
301+
302+
// release workers - in order to execute
303+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetCurrentMutualDependenciesReleaseWorker::class);
304+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\AddTagToChangelogReleaseWorker::class);
305+
306+
// you can extend with your own
307+
$services->set(App\SendPigeonToTwitterReleaseWorker::class);
308+
309+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\TagVersionReleaseWorker::class);
310+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushTagReleaseWorker::class);
311+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\SetNextMutualDependenciesReleaseWorker::class);
312+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\UpdateBranchAliasReleaseWorker::class);
313+
$services->set(Symplify\MonorepoBuilder\Release\ReleaseWorker\PushNextDevReleaseWorker::class);
314+
};
315+
```
316+
317+
## Contribute
318+
319+
The sources of this package are contained in the symplify monorepo. We welcome contributions for this package at [symplify/symplify](https://github.com/symplify/symplify).

0 commit comments

Comments
 (0)