-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add GitHub action for cloning an openQA job mentioned in a PR descrip…
…tion This GitHub action allows to clone a job when creating a PR by mentioning it in the PR description via `@openqa: Clone https://…`. Related ticket: https://progress.opensuse.org/issues/130934
- Loading branch information
Showing
3 changed files
with
116 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
name: 'Clone job' | ||
description: 'Clone openQA job mentioned in PR description' | ||
|
||
runs: | ||
using: composite | ||
image: registry.opensuse.org/devel/openqa/containers/tumbleweed:client | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
repository: os-autoinst/scripts | ||
path: scripts | ||
- name: Clone and monitor job mentioned in PR description | ||
run: scripts/openqa-clone-and-monitor-job-from-pr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#!/usr/bin/env perl | ||
|
||
# Note that this script is intended for execution via the GitHub action defined in | ||
# actions/clone-job/action.yaml. | ||
|
||
package openqa_clone_and_monitor_job_from_pr; | ||
|
||
use Mojo::Base -strict, -signatures; | ||
use Mojo::JSON qw(decode_json); | ||
|
||
my $expected_url = $ENV{OPENQA_HOST} // 'https://openqa.opensuse.org'; | ||
my $group_id = $ENV{OPENQA_SCHEDULE_GROUP_ID} // 118; | ||
my $pr_body = $ENV{GH_PR_BODY} or die 'GH_PR_BODY must be set'; | ||
my $gh_repo = $ENV{GH_REPO} or die 'GH_REPO must be set'; | ||
my $gh_ref = $ENV{GH_REF} or die 'GH_REF must be set'; | ||
my $gh_srv = $ENV{GITHUB_SERVER_URL} or die 'GITHUB_SERVER_URL must be set'; | ||
my $api_key = $ENV{OPENQA_API_KEY} or die 'OPENQA_API_KEY must be set'; | ||
my $api_secret = $ENV{OPENQA_API_SECRET} or die 'OPENQA_API_SECRET must be set'; | ||
my $screts = "--apikey '$api_key' --apisecret '$api_secret'"; | ||
my $vars = "BUILD='$gh_repo.git#$gh_ref' _GROUP_ID='$group_id' CASEDIR='$gh_srv/$gh_repo.git#$gh_ref'"; | ||
|
||
sub _parse_urls ($text) { | ||
my @urls; | ||
while ($text =~ /(\@openqa:?\s+Clone\s+(https?:[^\s]+))/ig) { | ||
push @urls, $2 if index($2, $expected_url) == 0; | ||
} | ||
return \@urls if @urls; | ||
print 'No test cloned; the PR description does not contain '; # uncoverable statement | ||
print "a command like '\@openqa: Clone $expected_url/tests/<JOB_ID>'.\n"; # uncoverable statement | ||
exit 0; | ||
} | ||
|
||
sub _run_cmd ($name, $args, $capture_output = 0) { | ||
my $res = $capture_output ? `$name $args` : system "$name $args"; | ||
if ($? == -1) { die "failed to execute '$name $args': $!\n" } | ||
elsif ($? & 127) { die printf("'$name' received signal %d\n", $? & 127) } | ||
elsif ($? >> 8) { die printf("'$name' exited with %d\n", $? >> 8) } | ||
return $res; | ||
} | ||
|
||
sub _clone_job ($url) { | ||
my $args = "$screts --json-output --skip-chained-deps --within-instance '$url' $vars"; | ||
my $json = _run_cmd 'openqa-clone-job', $args, 1; | ||
return values %{decode_json($json)}; | ||
} | ||
|
||
sub run () { | ||
my $urls = _parse_urls($pr_body); | ||
my @job_ids = map { _clone_job $_ } @$urls; | ||
my @quoted_url_list = join(', ', map { "'$_'" } @$urls); | ||
my @job_url_list = map { "- $expected_url/tests/$_\n" } @job_ids; | ||
print "Cloned @quoted_url_list into:\n @job_url_list"; | ||
_run_cmd 'openqa-cli', "monitor --host '$expected_url' $screts @job_ids"; | ||
} | ||
|
||
$ENV{TEST_MODE} ? 1 : run; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env perl | ||
|
||
use Mojo::Base -strict, -signatures; | ||
|
||
use FindBin; | ||
use Test::More; | ||
use Test::Output qw(combined_like); | ||
use Test::MockModule; | ||
|
||
$ENV{TEST_MODE} = 1; | ||
$ENV{GH_REPO} = 'foo'; | ||
$ENV{GH_REF} = 'bar'; | ||
$ENV{OPENQA_HOST} = 'http://127.0.0.1:9526'; | ||
$ENV{OPENQA_API_KEY} = 'key'; | ||
$ENV{OPENQA_API_SECRET} = 'secret'; | ||
$ENV{GITHUB_SERVER_URL} = 'gh-srv-url'; | ||
$ENV{GH_PR_BODY} = 'Merge my changes | ||
@openqa: Clone http://127.0.0.1:9526/tests/4240 | ||
@openqa: Clone http://127.0.0.1:9526/tests/4239 | ||
footnote'; | ||
|
||
require "$FindBin::RealBin/../openqa-clone-and-monitor-job-from-pr"; | ||
|
||
my $mock = Test::MockModule->new('openqa_clone_and_monitor_job_from_pr', no_auto => 1); | ||
my @invoked_commands; | ||
my @clone_responses = (qq('{"4240" : 4246}'), qq('{"4239" : 4245}')); | ||
$mock->redefine(_run_cmd => sub ($name, $args, $capture_output = 0) { | ||
my $orig = $mock->original('_run_cmd'); | ||
my $resp = $name eq 'openqa-clone-job' ? shift @clone_responses : $args; | ||
push @invoked_commands, "$name $args"; | ||
$orig->('echo', $resp, $capture_output); | ||
}); | ||
|
||
combined_like { openqa_clone_and_monitor_job_from_pr::run() } | ||
qr(Cloned.*4240.*4239.*into:.*monitor --host http://127\.0\.0\.1:9526 --apikey key --apisecret secret 4246 4245)s, | ||
'monitor command invoked as expected'; | ||
|
||
my $expected_secrets = "--apikey 'key' --apisecret 'secret'"; | ||
my $expected_clone_options = "$expected_secrets --json-output --skip-chained-deps --within-instance"; | ||
my $expected_vars = "BUILD='foo.git#bar' _GROUP_ID='118' CASEDIR='gh-srv-url/foo.git#bar'"; | ||
my @expected_invocations; | ||
push @expected_invocations, "openqa-clone-job $expected_clone_options 'http://127.0.0.1:9526/tests/$_' $expected_vars" for 4240, 4239; | ||
push @expected_invocations, "openqa-cli monitor --host 'http://127.0.0.1:9526' $expected_secrets 4246 4245"; | ||
is_deeply \@invoked_commands, \@expected_invocations, 'expected commands invoked' or diag explain \@invoked_commands; | ||
|
||
done_testing; |