Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/VCS/Adapter/Git/Bitbucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,26 @@ private function normalizeRepository(array $repository): array
return $repository;
}

public function createRepository(string $owner, string $repositoryName, bool $private): array
/**
* Bitbucket alone groups repositories under a project, so the argument
* stays optional and off the shared three-argument contract.
*
* @return array<mixed> Details of new repository
*/
public function createRepository(string $owner, string $repositoryName, bool $private, string $project = ''): array
Comment thread
Meldiron marked this conversation as resolved.
Comment thread
greptile-apps[bot] marked this conversation as resolved.
{
$url = "/repositories/{$owner}/{$repositoryName}";

$response = $this->call(self::METHOD_POST, $url, ['Authorization' => $this->authorizationHeader()], [
$payload = [
'scm' => 'git',
'name' => $repositoryName,
'is_private' => $private,
]);
];

if ($project !== '') {
$payload['project'] = ['key' => $project];
}

$response = $this->call(self::METHOD_POST, $url, ['Authorization' => $this->authorizationHeader()], $payload);

$responseHeaders = $response['headers'] ?? [];
$statusCode = $responseHeaders['status-code'] ?? 0;
Expand Down
54 changes: 50 additions & 4 deletions tests/VCS/Adapter/BitbucketTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Utopia\Cache\Cache;
use Utopia\System\System;
use Utopia\Tests\Base;
use Exception;
use Utopia\VCS\Adapter\Git\Bitbucket;

class BitbucketTest extends Base
Expand Down Expand Up @@ -45,6 +46,10 @@ class BitbucketTest extends Base
// Bitbucket Cloud can't reach a local test catcher
protected static bool $supportsWebhookDelivery = false;

// Projects are Bitbucket's alone, so they are reached off the adapter
// itself rather than through the shared contract
private Bitbucket $bitbucket;
Comment on lines +49 to +51

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets try to make Appwrite PR. Curious what this casting will look like there, for bitbuket specific behaviour

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worried this will be trouble, but not sure. Maybe PHP has some magic to make it nice


protected function signWebhookPayload(string $payload, string $secret): string
{
return 'sha256=' . hash_hmac('sha256', $payload, $secret);
Expand Down Expand Up @@ -75,6 +80,7 @@ protected function setupAdapter(): void
}

$this->vcsAdapter = $adapter;
$this->bitbucket = $adapter;
}

/**
Expand Down Expand Up @@ -171,10 +177,50 @@ private function eventActor(): array
];
}

/**
* Bitbucket only names the author in a raw "Name <email>" string; a commit
* linked to an account is named by the account instead.
*/
public function testCreateRepositoryProject(): void
{
// Naming no project files the repository under the workspace default,
// which is also the only place an existing key can be read from
$withoutProject = 'test-create-repository-no-project-' . \uniqid();
$repository = $this->bitbucket->createRepository(static::$owner, $withoutProject, false);

try {
$this->assertSame($withoutProject, $repository['name']);
$this->assertArrayHasKey('project', $repository);
$this->assertIsArray($repository['project']);
$this->assertArrayHasKey('key', $repository['project']);
$this->assertIsString($repository['project']['key']);
$projectKey = $repository['project']['key'];
} finally {
$this->discardRepositories($withoutProject);
}

$inProject = 'test-create-repository-project-' . \uniqid();
$repository = $this->bitbucket->createRepository(static::$owner, $inProject, false, $projectKey);

try {
$this->assertSame($inProject, $repository['name']);
$this->assertArrayHasKey('project', $repository);
$this->assertIsArray($repository['project']);
$this->assertArrayHasKey('key', $repository['project']);
$this->assertSame($projectKey, $repository['project']['key']);
} finally {
$this->discardRepositories($inProject);
}
}

public function testCreateRepositoryInAnUnknownProjectFails(): void
Comment thread
Meldiron marked this conversation as resolved.
{
$this->expectException(Exception::class);

$this->bitbucket->createRepository(
static::$owner,
'test-create-repository-unknown-project-' . \uniqid(),
false,
'NOSUCHPROJECTKEY'
);
}

public function testGetEventPushWithLinkedAuthor(): void
{
$payload = json_decode($this->pushPayload(static::$defaultBranch), true);
Expand Down
Loading