diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 30c82fbef0..120c9704ce 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -863,17 +863,6 @@ return [ 'array' => true, 'filters' => [], ], - [ - '$id' => ID::custom('providerCommitSkipPatterns'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 128, - 'signed' => true, - 'required' => false, - 'default' => [], - 'array' => true, - 'filters' => [], - ], ], 'indexes' => [ [ @@ -1375,17 +1364,6 @@ return [ 'array' => true, 'filters' => [], ], - [ - '$id' => ID::custom('providerCommitSkipPatterns'), - 'type' => Database::VAR_STRING, - 'format' => '', - 'size' => 128, - 'signed' => true, - 'required' => false, - 'default' => [], - 'array' => true, - 'filters' => [], - ], ], 'indexes' => [ [ diff --git a/src/Appwrite/Vcs/Validator/CommitSkipPatterns.php b/src/Appwrite/Vcs/Validator/CommitSkipPatterns.php deleted file mode 100644 index 9dbe45ba83..0000000000 --- a/src/Appwrite/Vcs/Validator/CommitSkipPatterns.php +++ /dev/null @@ -1,85 +0,0 @@ -patterns as $pattern) { - if (!is_string($pattern)) { - continue; - } - - $pattern = trim($pattern); - if ($pattern === '') { - continue; - } - - // Split on whitespace; each token is regex-quoted. Tokens are rejoined - // with \s+ (required space) so that "skipappwrite" does NOT match the - // pattern "skip appwrite". The only exception: when the preceding token - // ends with ":" (git trailer style), \s* is used so that - // "skip-checks:true" still matches the pattern "skip-checks: true". - $tokens = preg_split('/\s+/', $pattern); - $regexParts = []; - $count = count($tokens); - for ($i = 0; $i < $count; $i++) { - $regexParts[] = preg_quote($tokens[$i], '~'); - if ($i < $count - 1) { - $regexParts[] = str_ends_with($tokens[$i], ':') ? '\s*' : '\s+'; - } - } - $regexBody = implode('', $regexParts); - - // (?assertTrue($validator->isValid('fix: update readme')); - $this->assertTrue($validator->isValid('[skip deploy] docs only')); - $this->assertTrue($validator->isValid('')); - } - - // ------------------------------------------------------------------------- - // Single pattern — directive match - // ------------------------------------------------------------------------- - - public function testSinglePatternMatchSkips(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $this->assertFalse($validator->isValid('[skip deploy] docs only')); - $this->assertFalse($validator->isValid('chore: update deps [skip deploy]')); - $this->assertFalse($validator->isValid('prefix [skip deploy] suffix')); - } - - public function testSinglePatternNoMatchProceeds(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $this->assertTrue($validator->isValid('fix: real bug fix')); - $this->assertTrue($validator->isValid('feat: add new feature')); - $this->assertTrue($validator->isValid('skip deploy without brackets')); - $this->assertTrue($validator->isValid('prefix[skip deploy]suffix')); - } - - // ------------------------------------------------------------------------- - // Case insensitivity - // ------------------------------------------------------------------------- - - public function testCaseInsensitiveMatch(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $this->assertFalse($validator->isValid('[SKIP DEPLOY] uppercase')); - $this->assertFalse($validator->isValid('[Skip Deploy] mixed case')); - $this->assertFalse($validator->isValid('[skip DEPLOY] partial upper')); - } - - public function testPatternItselfCaseInsensitive(): void - { - $validator = new CommitSkipPatterns(['[SKIP DEPLOY]']); - $this->assertFalse($validator->isValid('[skip deploy] lowercase message')); - $this->assertFalse($validator->isValid('[Skip Deploy] mixed message')); - } - - // ------------------------------------------------------------------------- - // Array of patterns — any match skips (OR semantics) - // ------------------------------------------------------------------------- - - public function testMultiplePatternsFirstMatches(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]', '[skip ci]', '[no deploy]']); - $this->assertFalse($validator->isValid('[skip deploy] docs only')); - } - - public function testMultiplePatternsSecondMatches(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]', '[skip ci]', '[no deploy]']); - $this->assertFalse($validator->isValid('chore: update readme [skip ci]')); - } - - public function testMultiplePatternsThirdMatches(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]', '[skip ci]', '[no deploy]']); - $this->assertFalse($validator->isValid('[no deploy] just docs')); - } - - public function testMultiplePatternsNoneMatchProceeds(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]', '[skip ci]', '[no deploy]']); - $this->assertTrue($validator->isValid('feat: completely new feature')); - $this->assertTrue($validator->isValid('fix: important bug fix')); - } - - // ------------------------------------------------------------------------- - // Common real-world skip conventions - // ------------------------------------------------------------------------- - - public function testCommonSkipCiPattern(): void - { - $validator = new CommitSkipPatterns(['[skip ci]']); - $this->assertFalse($validator->isValid('[skip ci] update changelog')); - $this->assertFalse($validator->isValid('[SKIP CI]')); - $this->assertTrue($validator->isValid('feat: something real')); - } - - public function testNoDeployPattern(): void - { - $validator = new CommitSkipPatterns(['[no deploy]']); - $this->assertFalse($validator->isValid('[no deploy] tweak docs')); - $this->assertTrue($validator->isValid('deploy this please')); - } - - // ------------------------------------------------------------------------- - // Edge cases - // ------------------------------------------------------------------------- - - public function testEmptyCommitMessageNeverSkipsWithPatterns(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $this->assertTrue($validator->isValid('')); - } - - public function testBlankPatternsInArrayAreIgnored(): void - { - $validator = new CommitSkipPatterns(['', ' ', '[skip deploy]']); - $this->assertTrue($validator->isValid('normal commit message')); - $this->assertFalse($validator->isValid('[skip deploy] docs')); - } - - public function testPatternMustBeStandaloneDirective(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $this->assertTrue($validator->isValid('skippy the kangaroo')); - $this->assertTrue($validator->isValid('prefix[skip deploy]suffix')); - } - - public function testMultilineCommitMessage(): void - { - $validator = new CommitSkipPatterns(['[skip deploy]']); - $msg = "feat: add new stuff\n\nMore detail here.\n\n[skip deploy]"; - $this->assertFalse($validator->isValid($msg)); - } - - public function testWhitespaceInsideDirectiveIsNormalized(): void - { - $validator = new CommitSkipPatterns([' [skip deploy] ']); - $this->assertFalse($validator->isValid('[skip deploy] docs only')); - $this->assertFalse($validator->isValid('[SKIP DEPLOY] docs only')); - } - - public function testTrailerDirectiveCanSkip(): void - { - $validator = new CommitSkipPatterns(['skip-checks: true']); - $msg = "feat: add new stuff\n\nMore detail here.\n\nskip-checks:true"; - $this->assertFalse($validator->isValid($msg)); - } - - // ------------------------------------------------------------------------- - // Plain-word patterns: "skip appwrite" and "appwrite skip" - // ------------------------------------------------------------------------- - - public function testSkipAppwritePatternSkips(): void - { - $validator = new CommitSkipPatterns(['skip appwrite']); - $this->assertFalse($validator->isValid('docs: update readme skip appwrite')); - $this->assertFalse($validator->isValid('skip appwrite')); - } - - public function testSkipAppwritePatternCaseInsensitive(): void - { - $validator = new CommitSkipPatterns(['skip appwrite']); - $this->assertFalse($validator->isValid('SKIP APPWRITE')); - $this->assertFalse($validator->isValid('Skip Appwrite')); - $this->assertFalse($validator->isValid('SKIP appwrite')); - } - - public function testSkipAppwritePatternNoMatchProceeds(): void - { - $validator = new CommitSkipPatterns(['skip appwrite']); - $this->assertTrue($validator->isValid('feat: real feature')); - $this->assertTrue($validator->isValid('skipappwrite')); // no space — not standalone - $this->assertTrue($validator->isValid('appwrite is great')); - } - - public function testAppwriteSkipPatternSkips(): void - { - $validator = new CommitSkipPatterns(['appwrite skip']); - $this->assertFalse($validator->isValid('appwrite skip ci')); - $this->assertFalse($validator->isValid('docs appwrite skip')); - $this->assertFalse($validator->isValid('appwrite skip')); - } - - public function testAppwriteSkipPatternCaseInsensitive(): void - { - $validator = new CommitSkipPatterns(['appwrite skip']); - $this->assertFalse($validator->isValid('APPWRITE SKIP')); - $this->assertFalse($validator->isValid('Appwrite Skip')); - $this->assertFalse($validator->isValid('appwrite SKIP')); - } - - public function testAppwriteSkipPatternNoMatchProceeds(): void - { - $validator = new CommitSkipPatterns(['appwrite skip']); - $this->assertTrue($validator->isValid('feat: deploy appwrite changes')); - $this->assertTrue($validator->isValid('appwriteskip')); // no space — not standalone - $this->assertTrue($validator->isValid('skip the appwrite stuff')); - } - - public function testBothAppwritePatternsInArray(): void - { - $validator = new CommitSkipPatterns(['skip appwrite', 'appwrite skip']); - $this->assertFalse($validator->isValid('skip appwrite')); - $this->assertFalse($validator->isValid('appwrite skip')); - $this->assertFalse($validator->isValid('SKIP APPWRITE')); - $this->assertFalse($validator->isValid('APPWRITE SKIP')); - $this->assertTrue($validator->isValid('feat: deploy appwrite changes')); - } -}