Skip to content

Commit

Permalink
Add option for automerge (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
eiriksm committed Jun 21, 2022
1 parent 6b3f1f0 commit 265b550
Show file tree
Hide file tree
Showing 30 changed files with 1,128 additions and 10 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"violinist-dev/process-factory": "^1.0",
"symfony/process": "^3",
"violinist-dev/composer-changelog-fetcher": "^1.0",
"violinist-dev/violinist-config": "^1.2",
"violinist-dev/violinist-config": "^1.3",
"violinist-dev/commit-message-creator": "^1.2",
"violinist-dev/allow-list-handler": "^1.0"
},
Expand Down
24 changes: 19 additions & 5 deletions src/CosyComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1084,12 +1084,13 @@ protected function handleUpdateAll($initial_composer_lock_data, $composer_lock_a
$this->log($pullRequest['html_url'], Message::PR_URL, [
'package' => 'all',
]);
$this->handleAutomerge($config, $pullRequest, $security_update);
}
} catch (ValidationFailedException $e) {
// @todo: Do some better checking. Could be several things, this.
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named);
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
} catch (\Gitlab\Exception\RuntimeException $e) {
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named);
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
} catch (\Throwable $e) {
$this->log('Caught exception while running update all: ' . $e->getMessage());
}
Expand Down Expand Up @@ -1483,6 +1484,7 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
$this->log($pullRequest['html_url'], Message::PR_URL, [
'package' => $package_name,
]);
$this->handleAutomerge($config, $pullRequest, $security_update);
}
$total_prs++;
} catch (CanNotUpdateException $e) {
Expand All @@ -1509,9 +1511,9 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
]);
} catch (ValidationFailedException $e) {
// @todo: Do some better checking. Could be several things, this.
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named);
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
} catch (\Gitlab\Exception\RuntimeException $e) {
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named);
$this->handlePossibleUpdatePrScenario($e, $branch_name, $pr_params, $prs_named, $config, $security_update);
} catch (ComposerUpdateProcessFailedException $e) {
$this->log('Caught an exception: ' . $e->getMessage(), 'error');
$this->log($e->getErrorOutput(), Message::COMMAND, [
Expand Down Expand Up @@ -1545,12 +1547,24 @@ protected function handleIndividualUpdates($data, $lockdata, $cdata, $one_pr_per
}
}

protected function handlePossibleUpdatePrScenario(\Exception $e, $branch_name, $pr_params, $prs_named)
protected function handlePossibleUpdatePrScenario(\Exception $e, $branch_name, $pr_params, $prs_named, Config $config, $security_update = false)
{
$this->log('Had a problem with creating the pull request: ' . $e->getMessage(), 'error');
if ($this->shouldUpdatePr($branch_name, $pr_params, $prs_named)) {
$this->log('Will try to update the PR based on settings.');
$this->getPrClient()->updatePullRequest($this->slug, $prs_named[$branch_name]['number'], $pr_params);
$this->handleAutoMerge($config, $prs_named[$branch_name], $security_update);
}
}

protected function handleAutoMerge(Config $config, $pullRequest, $security_update = false)
{
if ($config->shouldAutoMerge($security_update)) {
$this->log('Config indicated automerge should be enabled, Trying to enable automerge');
$result = $this->getPrClient()->enableAutomerge($pullRequest, $this->slug);
if (!$result) {
$this->log('Enabling automerge failed.');
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/ProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

interface ProviderInterface
{
public function enableAutomerge(array $pr_data, Slug $slug) : bool;

public function authenticate($user, $token);

public function authenticatePrivate($user, $token);
Expand Down
6 changes: 6 additions & 0 deletions src/Providers/Bitbucket.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,10 @@ public function updatePullRequest(Slug $slug, $id, $params)
$user_repo = $slug->getUserRepo();
return $this->client->repositories()->users($user_name)->pullRequests($user_repo)->update($id, $params);
}

public function enableAutomerge(array $pr_data, Slug $slug) : bool
{
// @todo: Not implemented yet.
return false;
}
}
22 changes: 22 additions & 0 deletions src/Providers/Github.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,28 @@ public function __construct(Client $client)
$this->client = $client;
}

public function enableAutomerge(array $pr_data, Slug $slug) : bool
{
if (!isset($pr_data["node_id"])) {
return false;
}
$data = $this->client->graphql()->execute('mutation MyMutation ($input: EnablePullRequestAutoMergeInput!) {
enablePullRequestAutoMerge(input: $input) {
pullRequest {
id
}
}
}', [
'input' => [
'pullRequestId' => $pr_data['node_id']
]
]);
if (!empty($data["errors"])) {
return false;
}
return true;
}

public function authenticate($user, $token)
{
$this->client->authenticate($user, null, Client::AUTH_HTTP_TOKEN);
Expand Down
27 changes: 27 additions & 0 deletions src/Providers/Gitlab.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,31 @@ public static function getProjectId($url)
$url = parse_url($url);
return ltrim($url['path'], '/');
}

public function enableAutomerge(array $pr_data, Slug $slug) : bool
{
if (empty($pr_data['number']) && !empty($pr_data["iid"])) {
$pr_data['number'] = $pr_data["iid"];
}
$data = [
'merge_when_pipeline_succeeds' => true,
];
$project_id = self::getProjectId($slug->getUrl());
$retries = 0;
while (true) {
try {
$result = $this->client->mergeRequests()->merge($project_id, $pr_data["number"], $data);
if (!empty($result["merge_when_pipeline_succeeds"])) {
return true;
}
} catch (\Throwable $e) {
}
$retries++;
if ($retries > 10) {
return false;
}
usleep($retries * 100);
}
return true;
}
}
10 changes: 10 additions & 0 deletions test/fixtures/composer.automerge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"require": {
"psr/log": "^1.1.3"
},
"extra": {
"violinist": {
"automerge": 1
}
}
}
69 changes: 69 additions & 0 deletions test/fixtures/composer.automerge.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "592003a0c759ae236e67d71f487a0c05",
"packages": [
{
"name": "psr/log",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.3"
},
"time": "2020-03-23T09:12:05+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
69 changes: 69 additions & 0 deletions test/fixtures/composer.automerge.lock.updated
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "592003a0c759ae236e67d71f487a0c05",
"packages": [
{
"name": "psr/log",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
},
"time": "2021-05-03T11:20:27+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}
11 changes: 11 additions & 0 deletions test/fixtures/composer.automerge_sec_no_update.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"require": {
"psr/log": "^1.1.3"
},
"extra": {
"violinist": {
"automerge": 0,
"automerge_security": 1
}
}
}
69 changes: 69 additions & 0 deletions test/fixtures/composer.automerge_sec_no_update.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "592003a0c759ae236e67d71f487a0c05",
"packages": [
{
"name": "psr/log",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.3"
},
"time": "2020-03-23T09:12:05+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.3.0"
}

0 comments on commit 265b550

Please sign in to comment.