Skip to content

Commit

Permalink
Support push events in configure_repositories step
Browse files Browse the repository at this point in the history
Co-authored-by: Dany Marcoux <dmarcoux@suse.com>
  • Loading branch information
eduardoj and Dany Marcoux committed Sep 23, 2021
1 parent 67da790 commit 2ba89db
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 9 deletions.
17 changes: 15 additions & 2 deletions src/api/app/models/workflow/step/configure_repositories.rb
Expand Up @@ -8,8 +8,11 @@ class Workflow::Step::ConfigureRepositories < Workflow::Step
def call(_options = {})
return unless valid?

target_project = Project.get_by_name(target_project_name)
Pundit.authorize(@token.user, target_project, :update?)

step_instructions[:repositories].each do |repository_instructions|
repository = Repository.includes(:architectures).find_or_create_by(name: repository_instructions[:name], project: Project.get_by_name(target_project_name))
repository = Repository.includes(:architectures).find_or_create_by(name: repository_instructions[:name], project: target_project)

target_repository = Repository.find_by_project_and_name(repository_instructions[:target_project], repository_instructions[:target_repository])
repository.path_elements.find_or_create_by(link: target_repository)
Expand All @@ -26,8 +29,18 @@ def project_name
step_instructions[:project]
end

# This method needs to be public because it is used in the Workflow model.
def target_project_name
"home:#{@token.user.login}:#{project_name}:PR-#{scm_webhook.payload[:pr_number]}"
if scm_webhook.pull_request_event?
case scm_webhook.payload[:scm]
when 'github'
"#{project_name}:#{scm_webhook.payload[:target_repository_full_name]}:PR-#{scm_webhook.payload[:pr_number]}".tr('/', '-')
when 'gitlab'
"#{project_name}:#{scm_webhook.payload[:path_with_namespace]}:PR-#{scm_webhook.payload[:pr_number]}".tr('/', '-')
end
elsif scm_webhook.push_event?
project_name
end
end

private
Expand Down
119 changes: 112 additions & 7 deletions src/api/spec/models/workflow/step/configure_repositories_spec.rb
@@ -1,15 +1,16 @@
require 'rails_helper'

RSpec.describe Workflow::Step::ConfigureRepositories do
let(:user) { create(:confirmed_user, :with_home, login: 'Iggy') }
let(:token) { create(:workflow_token, user: user) }

describe '#call' do
let!(:user) { create(:confirmed_user, :with_home, login: 'Iggy') }
let(:token) { create(:workflow_token, user: user) }
let(:project) { create(:project, name: 'openSUSE:Factory', maintainer: user) }
let(:project) { create(:project, name: 'openSUSE:Factory') }
let!(:repository) { create(:repository, project: project, name: 'snapshot', architectures: ['i586', 'aarch64']) }
let(:target_project_name) do
'home:Iggy:OBS:Server:Unstable:PR-1'
'OBS:Server:Unstable:openSUSE-repo123:PR-1'
end
let(:target_project) { create(:project, name: target_project_name) }
let(:target_project) { create(:project, name: target_project_name, maintainer: user) }
let(:step_instructions) do
{
project: 'OBS:Server:Unstable',
Expand All @@ -33,7 +34,8 @@
event: 'pull_request',
action: 'opened',
pr_number: 1,
source_repository_full_name: 'reponame',
source_repository_full_name: 'openSUSE/repo123',
target_repository_full_name: 'openSUSE/repo123',
commit_sha: '123'
})
end
Expand All @@ -47,6 +49,29 @@
token: token)
end

context 'when the token user does not have enough permissions' do
let(:another_user) { create(:confirmed_user, :with_home, login: 'Pop') }
let(:token) { create(:workflow_token, user: another_user) }
let(:scm_webhook) do
ScmWebhook.new(payload: {
scm: 'github',
event: 'pull_request',
action: 'opened',
pr_number: 1,
target_repository_full_name: 'openSUSE/repo123',
commit_sha: '123'
})
end

before do
target_project
project
login(another_user)
end

it { expect { subject.call }.to raise_error(Pundit::NotAuthorizedError) }
end

context 'when the target branch project is present' do
before do
target_project
Expand Down Expand Up @@ -276,7 +301,87 @@
end

it 'raises an error due to an inexistent target project' do
expect { subject.call }.to raise_error(Project::Errors::UnknownObjectError, 'Project not found: home:Iggy:OBS:Server:Unstable:PR-1')
expect { subject.call }.to raise_error(Project::Errors::UnknownObjectError, "Project not found: #{target_project_name}")
end
end
end

describe '#target_project_name' do
let(:step_instructions) do
{
project: 'OBS:Server:Unstable',
repositories:
[
{
name: 'openSUSE_Tumbleweed',
target_project: 'openSUSE:Factory',
target_repository: 'snapshot',
architectures: [
'x86_64',
'ppc'
]
}
]
}
end
let(:scm_webhook) { ScmWebhook.new(payload: payload) }

subject do
described_class.new(step_instructions: step_instructions,
scm_webhook: scm_webhook,
token: token).target_project_name
end

context 'for an unsupported event' do
let(:payload) do
{
scm: 'github',
event: 'unsupported'
}
end

it { is_expected.to be_nil }
end

context 'for a pull request webhook event' do
context 'from GitHub' do
let(:payload) do
{
scm: 'github',
event: 'pull_request',
pr_number: 1,
target_repository_full_name: 'openSUSE/repo123'
}
end

it { is_expected.to eq('OBS:Server:Unstable:openSUSE-repo123:PR-1') }
end

context 'from GitLab' do
let(:payload) do
{
scm: 'gitlab',
event: 'Merge Request Hook',
pr_number: 1,
path_with_namespace: 'openSUSE/repo123'
}
end

it { is_expected.to eq('OBS:Server:Unstable:openSUSE-repo123:PR-1') }
end
end

context 'for a push webhook event' do
context 'from GitHub' do
let(:payload) { { scm: 'github', event: 'push' } }

it { is_expected.to eq('OBS:Server:Unstable') }
end

context 'from GitLab' do
let(:payload) { { scm: 'gitlab', event: 'Push Hook' } }

it { is_expected.to eq('OBS:Server:Unstable') }
end
end
end
Expand Down

0 comments on commit 2ba89db

Please sign in to comment.