Merge pull request #168 from copenhagentruckwash/fix-auto-promotion-vulnerability-in-release-gate
Prevent auto-sync promotion when release gate `required_checks` is empty
This commit is contained in:
@@ -1064,6 +1064,7 @@ class release_manager
|
||||
private function releaseGateAutoSyncValidationSteps(array $gateInput, ?array $channel): array
|
||||
{
|
||||
$steps = [];
|
||||
$requiredChecks = is_array($gateInput['required_checks'] ?? null) ? $gateInput['required_checks'] : [];
|
||||
$context = [
|
||||
'channel_slug' => $gateInput['channel_slug'] ?? null,
|
||||
'app' => $gateInput['app'] ?? null,
|
||||
@@ -1071,6 +1072,7 @@ class release_manager
|
||||
'branch' => $gateInput['branch'] ?? null,
|
||||
'expected_commit' => $gateInput['expected_commit'] ?? null,
|
||||
'workflow_url' => $gateInput['workflow_url'] ?? null,
|
||||
'required_checks' => $requiredChecks,
|
||||
];
|
||||
|
||||
if ($channel === null) {
|
||||
@@ -1106,6 +1108,17 @@ class release_manager
|
||||
'context' => $context,
|
||||
];
|
||||
}
|
||||
if ($requiredChecks === []) {
|
||||
$steps[] = [
|
||||
'step_key' => 'auto_sync_required_checks',
|
||||
'label' => 'Automatic update required checks',
|
||||
'status' => 'failed',
|
||||
'message' => 'Automatic container updates require at least one release gate check.',
|
||||
'diagnostic' => 'required_checks was empty.',
|
||||
'solution_hint' => 'Include required_checks (for example static_artifact and/or api_gateway) in the release gate payload.',
|
||||
'context' => $context,
|
||||
];
|
||||
}
|
||||
|
||||
if ($steps === []) {
|
||||
$steps[] = [
|
||||
|
||||
@@ -96,6 +96,40 @@ it('normalizes app-specific release gate auto-sync metadata', function (): void
|
||||
expect($appMatches->invoke($manager, [], 'api'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('requires non-empty release gate checks before auto-sync can proceed', function (): void {
|
||||
$manager = new release_manager();
|
||||
$method = new ReflectionMethod(release_manager::class, 'releaseGateAutoSyncValidationSteps');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$failed = $method->invoke($manager, [
|
||||
'channel_slug' => 'stable',
|
||||
'app' => 'api',
|
||||
'repository' => 'copenhagentruckwash/api',
|
||||
'branch' => 'master',
|
||||
'expected_commit' => 'd52ceb85138740c45f20cda9b7ed9b7a21f0d4e8',
|
||||
'workflow_url' => 'https://github.com/copenhagentruckwash/api/actions/runs/123',
|
||||
'required_checks' => [],
|
||||
], ['slug' => 'stable']);
|
||||
expect($failed)->toContainEqual(expect()->toMatchArray([
|
||||
'step_key' => 'auto_sync_required_checks',
|
||||
'status' => 'failed',
|
||||
]));
|
||||
|
||||
$passed = $method->invoke($manager, [
|
||||
'channel_slug' => 'stable',
|
||||
'app' => 'api',
|
||||
'repository' => 'copenhagentruckwash/api',
|
||||
'branch' => 'master',
|
||||
'expected_commit' => 'd52ceb85138740c45f20cda9b7ed9b7a21f0d4e8',
|
||||
'workflow_url' => 'https://github.com/copenhagentruckwash/api/actions/runs/123',
|
||||
'required_checks' => ['api_gateway'],
|
||||
], ['slug' => 'stable']);
|
||||
expect($passed)->toContainEqual(expect()->toMatchArray([
|
||||
'step_key' => 'auto_sync_inputs',
|
||||
'status' => 'passed',
|
||||
]));
|
||||
});
|
||||
|
||||
it('normalizes GitHub repository identifiers for private repository access checks', function (): void {
|
||||
expect(release_manager::normalizeGithubRepositoryName('truckwash/backend-php'))->toBe('truckwash/backend-php');
|
||||
expect(release_manager::normalizeGithubRepositoryName('https://github.com/truckwash/front-end-vue.git'))->toBe('truckwash/front-end-vue');
|
||||
|
||||
Reference in New Issue
Block a user