Skip to content

Commit b7377df

Browse files
wip monorepo packagae
1 parent 68a5965 commit b7377df

31 files changed

+3483
-1405
lines changed

packages/monorepo/README.md

Lines changed: 459 additions & 0 deletions
Large diffs are not rendered by default.

packages/monorepo/composer.json

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "moox/monorepo",
3-
"description": "The Moox Monorepo containing Laravel and Filament packages (FOSS).",
3+
"description": "Clean, fast, and simple monorepo management for Laravel packages (v2.0)",
44
"type": "library",
55
"license": "MIT",
66
"authors": [
@@ -10,19 +10,25 @@
1010
}
1111
],
1212
"require": {
13-
"php": "^8.3",
14-
"ext-intl": "*",
15-
"composer-runtime-api": "^2.1",
16-
"symplify/monorepo-builder": "^11.0",
17-
"laravel/socialite": "^5.21",
18-
"moox/core": "self.version"
13+
"php": "^8.2",
14+
"laravel/framework": "^11.0|^12.0",
15+
"guzzlehttp/guzzle": "^7.0",
16+
"symfony/process": "^6.0|^7.0"
1917
},
2018
"require-dev": {
21-
"moox/devlink": "*"
19+
"pestphp/pest": "^2.0",
20+
"pestphp/pest-plugin-laravel": "^2.0",
21+
"mockery/mockery": "^1.6",
22+
"orchestra/testbench": "^9.0"
2223
},
2324
"autoload": {
2425
"psr-4": {
25-
"Moox\\Monorepo\\": "src"
26+
"Moox\\Monorepo\\": "src/"
27+
}
28+
},
29+
"autoload-dev": {
30+
"psr-4": {
31+
"Moox\\Monorepo\\Tests\\": "tests/"
2632
}
2733
},
2834
"extra": {
@@ -34,6 +40,11 @@
3440
"moox-stability": "stable"
3541
},
3642
"config": {
37-
"sort-packages": true
38-
}
43+
"sort-packages": true,
44+
"allow-plugins": {
45+
"pestphp/pest-plugin": true
46+
}
47+
},
48+
"minimum-stability": "dev",
49+
"prefer-stable": true
3950
}
Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,79 @@
11
<?php
22

33
return [
4-
'packages_path' => env('MOOX_PACKAGES_PATH', 'packages'),
5-
'branch' => env('MOOX_RELEASE_BRANCH', 'main'),
6-
'public_repo' => env('MOOX_PUBLIC_REPO', 'moox'),
7-
'private_repo' => env('MOOX_PRIVATE_REPO', 'pro'),
8-
'github_org' => env('MOOX_GITHUB_ORG', 'mooxphp'),
9-
];
4+
/*
5+
|--------------------------------------------------------------------------
6+
| GitHub Configuration
7+
|--------------------------------------------------------------------------
8+
*/
9+
'github' => [
10+
'organization' => env('MONOREPO_GITHUB_ORG', 'mooxphp'),
11+
'public_repo' => env('MONOREPO_PUBLIC_REPO', 'moox'),
12+
'private_repo' => env('MONOREPO_PRIVATE_REPO', 'pro'),
13+
'default_branch' => env('MONOREPO_DEFAULT_BRANCH', 'main'),
14+
'api_version' => '2022-11-28',
15+
],
16+
17+
/*
18+
|--------------------------------------------------------------------------
19+
| Package Configuration
20+
|--------------------------------------------------------------------------
21+
*/
22+
'packages' => [
23+
'public_path' => env('MONOREPO_PUBLIC_PACKAGES_PATH', 'packages'),
24+
'private_path' => env('MONOREPO_PRIVATE_PACKAGES_PATH', null), // null means no private packages
25+
'devlog_path' => env('MONOREPO_DEVLOG_PATH', 'packages/monorepo/DEVLOG.md'),
26+
'stability_mapping' => [
27+
'init' => 'Initial release',
28+
'dev' => 'Compatibility release',
29+
'stable' => 'Compatibility release',
30+
],
31+
// Automatically detect devlink paths if available
32+
'use_devlink_paths' => env('MONOREPO_USE_DEVLINK_PATHS', true),
33+
],
34+
35+
/*
36+
|--------------------------------------------------------------------------
37+
| Release Configuration
38+
|--------------------------------------------------------------------------
39+
*/
40+
'release' => [
41+
'auto_generate_notes' => env('MONOREPO_AUTO_GENERATE_NOTES', false),
42+
'workflow_file' => env('MONOREPO_WORKFLOW_FILE', 'split.yml'),
43+
'max_payload_size' => env('MONOREPO_MAX_PAYLOAD_SIZE', 50000),
44+
'batch_size' => env('MONOREPO_BATCH_SIZE', 10),
45+
],
46+
47+
/*
48+
|--------------------------------------------------------------------------
49+
| Repository Creation Configuration
50+
|--------------------------------------------------------------------------
51+
*/
52+
'repository' => [
53+
'default_license' => env('MONOREPO_DEFAULT_LICENSE', null),
54+
'auto_init' => env('MONOREPO_REPO_AUTO_INIT', false), // Keep empty for workflow
55+
'gitignore_template' => env('MONOREPO_REPO_GITIGNORE', null), // Let workflow handle
56+
'has_issues' => env('MONOREPO_REPO_HAS_ISSUES', true),
57+
'has_projects' => env('MONOREPO_REPO_HAS_PROJECTS', false),
58+
'has_wiki' => env('MONOREPO_REPO_HAS_WIKI', false),
59+
'has_discussions' => env('MONOREPO_REPO_HAS_DISCUSSIONS', false),
60+
'allow_forking' => env('MONOREPO_REPO_ALLOW_FORKING', true),
61+
'web_commit_signoff_required' => env('MONOREPO_REPO_WEB_COMMIT_SIGNOFF', false),
62+
'allow_squash_merge' => env('MONOREPO_REPO_ALLOW_SQUASH', true),
63+
'allow_merge_commit' => env('MONOREPO_REPO_ALLOW_MERGE', false),
64+
'allow_rebase_merge' => env('MONOREPO_REPO_ALLOW_REBASE', false),
65+
'allow_auto_merge' => env('MONOREPO_REPO_ALLOW_AUTO_MERGE', false),
66+
'delete_branch_on_merge' => env('MONOREPO_REPO_DELETE_BRANCH_ON_MERGE', true),
67+
],
68+
69+
/*
70+
|--------------------------------------------------------------------------
71+
| Cache Configuration
72+
|--------------------------------------------------------------------------
73+
*/
74+
'cache' => [
75+
'enabled' => env('MONOREPO_CACHE_ENABLED', true),
76+
'ttl' => env('MONOREPO_CACHE_TTL', 300), // 5 minutes
77+
'prefix' => 'monorepo_v2',
78+
],
79+
];
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
3+
namespace Moox\Monorepo\Actions;
4+
5+
use Illuminate\Support\Collection;
6+
use Moox\Monorepo\Contracts\GitHubClientInterface;
7+
use Moox\Monorepo\Contracts\VersionManagerInterface;
8+
use Moox\Monorepo\DataTransferObjects\ReleaseInfo;
9+
use Moox\Monorepo\DataTransferObjects\PackageChange;
10+
11+
class CreateReleaseAction
12+
{
13+
public function __construct(
14+
private GitHubClientInterface $githubClient,
15+
private VersionManagerInterface $versionManager
16+
) {}
17+
18+
/**
19+
* Create a release for a repository
20+
*/
21+
public function createRelease(ReleaseInfo $releaseInfo): bool
22+
{
23+
$result = $this->githubClient->createRelease(
24+
$releaseInfo->organization,
25+
$releaseInfo->repository,
26+
$releaseInfo->version,
27+
$releaseInfo->body,
28+
$releaseInfo->isPrerelease
29+
);
30+
31+
return $result !== null;
32+
}
33+
34+
/**
35+
* Prepare packages for workflow dispatch
36+
*/
37+
public function preparePackagesForWorkflow(Collection $packageChanges): array
38+
{
39+
$maxSize = config('monorepo.release.max_payload_size', 50000);
40+
41+
// Convert package changes to workflow format
42+
$packages = $packageChanges->mapWithKeys(function (PackageChange $change) {
43+
return [
44+
$change->packageName => [
45+
'release-message' => [$change->getSanitizedReleaseMessage()],
46+
'change-type' => $change->changeType,
47+
'moox-stability' => $change->metadata['moox_stability'] ?? 'dev',
48+
]
49+
];
50+
})->toArray();
51+
52+
$json = json_encode($packages, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
53+
54+
// If payload is too large, truncate messages
55+
if (strlen($json) > $maxSize) {
56+
$packages = $this->truncatePackagesPayload($packages, $maxSize);
57+
$json = json_encode($packages, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
58+
}
59+
60+
return $packages;
61+
}
62+
63+
/**
64+
* Trigger workflow for packages
65+
*/
66+
public function triggerWorkflow(
67+
string $organization,
68+
string $repository,
69+
string $version,
70+
array $packages,
71+
?string $userToken = null
72+
): bool {
73+
$inputs = [
74+
'version' => $version,
75+
'packages' => json_encode($packages, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
76+
];
77+
78+
if ($userToken) {
79+
$inputs['user_token'] = $userToken;
80+
}
81+
82+
return $this->githubClient->triggerWorkflow(
83+
$organization,
84+
$repository,
85+
config('monorepo.release.workflow_file', 'split.yml'),
86+
$inputs
87+
);
88+
}
89+
90+
/**
91+
* Create releases for multiple repositories
92+
*/
93+
public function createMultipleReleases(Collection $releaseInfos): Collection
94+
{
95+
return $releaseInfos->map(function (ReleaseInfo $releaseInfo) {
96+
$success = $this->createRelease($releaseInfo);
97+
98+
return $releaseInfo->withMetadata([
99+
'created' => $success,
100+
'created_at' => now()->toISOString(),
101+
]);
102+
});
103+
}
104+
105+
/**
106+
* Process a complete release with packages
107+
*/
108+
public function processCompleteRelease(
109+
ReleaseInfo $releaseInfo,
110+
Collection $packageChanges,
111+
?string $userToken = null
112+
): array {
113+
// Create the release
114+
$releaseCreated = $this->createRelease($releaseInfo);
115+
116+
if (!$releaseCreated) {
117+
return [
118+
'success' => false,
119+
'error' => 'Failed to create release',
120+
'release' => $releaseInfo->toArray(),
121+
];
122+
}
123+
124+
// Prepare and trigger workflow
125+
$packages = $this->preparePackagesForWorkflow($packageChanges);
126+
$workflowTriggered = $this->triggerWorkflow(
127+
$releaseInfo->organization,
128+
$releaseInfo->repository,
129+
$releaseInfo->version,
130+
$packages,
131+
$userToken
132+
);
133+
134+
return [
135+
'success' => true,
136+
'release' => $releaseInfo->toArray(),
137+
'workflow_triggered' => $workflowTriggered,
138+
'packages_count' => $packageChanges->count(),
139+
'packages' => $packages,
140+
];
141+
}
142+
143+
/**
144+
* Truncate packages payload to fit size limits
145+
*/
146+
private function truncatePackagesPayload(array $packages, int $maxSize): array
147+
{
148+
$truncated = [];
149+
150+
foreach ($packages as $name => $data) {
151+
$truncated[$name] = [
152+
'release-message' => ['Release update'],
153+
'change-type' => $data['change-type'] ?? 'compatibility',
154+
'moox-stability' => $data['moox-stability'] ?? 'dev',
155+
];
156+
}
157+
158+
return $truncated;
159+
}
160+
}

0 commit comments

Comments
 (0)