Skip to content

Commit 04d9dee

Browse files
committed
Support for approve workflows
1 parent 9d6fd8f commit 04d9dee

File tree

9 files changed

+128
-8
lines changed

9 files changed

+128
-8
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"doctrine/doctrine-migrations-bundle": "^3.0",
1212
"doctrine/orm": "^2.7",
1313
"incenteev/composer-parameter-handler": "~2.0",
14-
"knplabs/github-api": "^2.16",
14+
"knplabs/github-api": "^3.3",
1515
"nyholm/psr7": "^1.3",
1616
"sensio/framework-extra-bundle": "^5.1",
1717
"symfony/console": "^5.1",

config/packages/github_api.yaml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ services:
1111
Github\HttpClient\Builder:
1212
arguments:
1313
- '@github.httplug_client'
14-
- '@Http\Message\RequestFactory'
15-
- '@Http\Message\StreamFactory'
14+
- '@Psr\Http\Message\RequestFactoryInterface'
15+
- '@Psr\Http\Message\StreamFactoryInterface'
1616

1717
github.httplug_client:
18-
class: Symfony\Component\HttpClient\HttplugClient
18+
class: Symfony\Component\HttpClient\Psr18Client
1919
arguments:
2020
- '@github.retryable_client'
2121
- '@Psr\Http\Message\ResponseFactoryInterface'
@@ -56,8 +56,6 @@ services:
5656

5757
Github\Api\Issue\Timeline:
5858
factory: ['@Github\Api\Issue', timeline]
59-
calls:
60-
- [configure]
6159

6260
Github\Api\PullRequest:
6361
factory: ['@Github\Client', api]
@@ -75,3 +73,8 @@ services:
7573
arguments: [search]
7674
calls:
7775
- ['setPerPage', [100]]
76+
77+
Github\Api\Repository\Actions\WorkflowRuns:
78+
factory: ['@Github\Api\Repo', workflowRuns]
79+
calls:
80+
- ['setPerPage', [100]]

config/services.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ services:
7575
resource: '../src/Subscriber/*'
7676
autoconfigure: false
7777

78-
7978
App\Api\Issue\IssueApi: '@App\Api\Issue\GithubIssueApi'
8079
App\Api\Label\LabelApi: '@App\Api\Label\GithubLabelApi'
8180
App\Api\Milestone\MilestoneApi: '@App\Api\Milestone\GithubMilestoneApi'
8281
App\Api\PullRequest\PullRequestApi: '@App\Api\PullRequest\GithubPullRequestApi'
8382
App\Api\Status\StatusApi: '@App\Api\Status\GitHubStatusApi'
83+
App\Api\Workflow\WorkflowApi: '@App\Api\Workflow\GitHubWorkflowApi'
8484

8585
App\Service\RepositoryProvider:
8686
arguments: [ '%repositories%' ]

config/services_test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ services:
88
App\Api\Milestone\MilestoneApi: '@App\Api\Milestone\StaticMilestoneApi'
99
App\Api\PullRequest\PullRequestApi: '@App\Api\PullRequest\NullPullRequestApi'
1010
App\Api\Status\StatusApi: '@App\Api\Status\NullStatusApi'
11+
App\Api\Workflow\WorkflowApi: '@App\Api\Workflow\NullWorkflowApi'
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
4+
namespace App\Api\Workflow;
5+
6+
7+
use App\Api\Label\LabelApi;
8+
use App\Model\Repository;
9+
use Github\Api\Repository\Actions\WorkflowRuns;
10+
use Psr\Log\LoggerInterface;
11+
12+
/**
13+
* @author Tobias Nyholm <[email protected]>
14+
*/
15+
class GithubWorkflowApi implements WorkflowApi
16+
{
17+
private WorkflowRuns $workflowApi;
18+
private LoggerInterface $logger;
19+
20+
public function __construct(WorkflowRuns $workflowApi, LoggerInterface $logger)
21+
{
22+
$this->workflowApi = $workflowApi;
23+
$this->logger = $logger;
24+
}
25+
26+
public function approveWorkflowsForPullRequest(Repository $repository, string $headRepository, string $headBranch): void
27+
{
28+
$result = $this->workflowApi->all($repository->getVendor(), $repository->getName(), [
29+
'branch' => $headBranch,
30+
'status' => 'action_required'
31+
]);
32+
33+
foreach ($result['workflow_runs'] as $run) {
34+
if ($headRepository === $run['head_repository']['full_name']) {
35+
$this->workflowApi->approve($repository->getVendor(), $repository->getName(), $run['id']);
36+
}
37+
}
38+
}
39+
}

src/Api/Workflow/NullWorkflowApi.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
4+
namespace App\Api\Workflow;
5+
6+
7+
use App\Model\Repository;
8+
9+
class NullWorkflowApi implements WorkflowApi
10+
{
11+
public function approveWorkflowsForPullRequest(Repository $repository, string $headRepository, string $headBranch): void
12+
{
13+
14+
}
15+
16+
}

src/Api/Workflow/WorkflowApi.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace App\Api\Workflow;
4+
5+
6+
use App\Model\Repository;
7+
8+
/**
9+
* @author Tobias Nyholm <[email protected]>
10+
*/
11+
interface WorkflowApi
12+
{
13+
/**
14+
* Find workflow runs related to the PR and approve them.
15+
*/
16+
public function approveWorkflowsForPullRequest(Repository $repository, string $headRepository, string $headBranch): void;
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace App\Subscriber;
4+
5+
use App\Api\Status\Status;
6+
use App\Api\Status\StatusApi;
7+
use App\Api\Workflow\WorkflowApi;
8+
use App\Event\GitHubEvent;
9+
use App\GitHubEvents;
10+
use App\Service\WipParser;
11+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12+
13+
/**
14+
* Make sure CI is running for all PRs.
15+
*
16+
* @author Wouter de Jong <[email protected]>
17+
*/
18+
class ApproveCiForNonContributors implements EventSubscriberInterface
19+
{
20+
private WorkflowApi $workflowApi;
21+
22+
public function onPullRequest(GitHubEvent $event)
23+
{
24+
$data = $event->getData();
25+
if (!in_array($data['action'], ['opened', 'reopened', 'synchronize'])) {
26+
return;
27+
}
28+
29+
$repository = $event->getRepository();
30+
$pullRequestNumber = $data['pull_request']['number'];
31+
$headRepository = $data['pull_request']['head']['repo']['full_name'];
32+
$headBranch = $data['pull_request']['head']['ref'];
33+
$this->workflowApi->approveWorkflowsForPullRequest($repository, $pullRequestNumber, $headRepository, $headBranch);
34+
35+
$event->setResponseData(['approved_run'=>true]);
36+
}
37+
38+
public static function getSubscribedEvents()
39+
{
40+
return [
41+
GitHubEvents::PULL_REQUEST => 'onPullRequest',
42+
];
43+
}
44+
}

tests/webhook_examples/pull_request.opened.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"repo": {
7171
"id": 21151556,
7272
"name": "symfony",
73-
"full_name": "carsonbot-playground/symfony",
73+
"full_name": "weaverryan/symfony",
7474
"owner": {
7575
"login": "weaverryan",
7676
"id": 121003,

0 commit comments

Comments
 (0)