Commit f8e7ad51 authored by Mark Lapierre's avatar Mark Lapierre

Merge branch 'acunskis-qa-octokit' into 'master'

E2E: Replace github_api gem with octokit

See merge request gitlab-org/gitlab!66066
parents 7c55cc72 96b5bc73
......@@ -22,7 +22,7 @@ gem 'rotp', '~> 3.1.0'
gem 'timecop', '~> 0.9.1'
gem 'parallel', '~> 1.19'
gem 'rspec-parameterized', '~> 0.4.2'
gem 'github_api', '~> 0.18.2'
gem "octokit", "~> 4.21"
gem "webdrivers", "~> 4.6"
gem 'chemlab', '~> 0.7'
......
......@@ -56,31 +56,36 @@ GEM
adamantium (~> 0.2.0)
equalizer (~> 0.0.9)
concurrent-ruby (1.1.9)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.3)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
equalizer (0.0.11)
faker (1.9.3)
i18n (>= 0.7)
faraday (0.17.3)
faraday (1.5.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0.1)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.1)
faraday-patron (~> 1.0)
multipart-post (>= 1.2, < 3)
github_api (0.18.2)
addressable (~> 2.4)
descendants_tracker (~> 0.0.4)
faraday (~> 0.8)
hashie (~> 3.5, >= 3.5.2)
oauth2 (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
gitlab-qa (4.0.0)
hashie (3.6.0)
http-accept (1.7.0)
http-cookie (1.0.3)
domain_name (~> 0.5)
i18n (1.8.10)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
jwt (2.2.2)
knapsack (1.17.1)
rake
launchy (2.4.3)
......@@ -96,19 +101,14 @@ GEM
mini_mime (1.0.2)
mini_portile2 (2.5.0)
minitest (5.14.4)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
netrc (0.11.0)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
racc (~> 1.4)
oauth2 (1.4.4)
faraday (>= 0.8, < 2.0)
jwt (>= 1.0, < 3.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
octokit (4.21.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
oj (3.11.5)
parallel (1.19.2)
parallel_tests (2.29.0)
......@@ -166,7 +166,11 @@ GEM
rspec-core (>= 2, < 4, != 2.12.0)
ruby-debug-ide (0.7.2)
rake (>= 0.8.1)
ruby2_keywords (0.0.4)
rubyzip (2.3.2)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
selenium-webdriver (4.0.0.beta4)
childprocess (>= 0.5, < 5.0)
rexml (~> 3.2)
......@@ -212,10 +216,10 @@ DEPENDENCIES
chemlab (~> 0.7)
chemlab-library-www-gitlab-com (~> 0.1)
faker (~> 1.6, >= 1.6.6)
github_api (~> 0.18.2)
gitlab-qa
knapsack (~> 1.17)
nokogiri (~> 1.11.1)
octokit (~> 4.21)
parallel (~> 1.19)
parallel_tests (~> 2.29)
pry-byebug (~> 3.5.1)
......
......@@ -48,7 +48,7 @@ module QA
end
def mirror_direction=(value)
raise ArgumentError, "Mirror direction must be 'Push' or 'Pull'" unless %w(Push Pull).include? value
raise ArgumentError, "Mirror direction must be 'Push' or 'Pull'" unless %w[Push Pull].include?(value)
select_element(:mirror_direction, value)
......@@ -59,7 +59,9 @@ module QA
end
def authentication_method=(value)
raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'" unless %w(Password None SSH\ public\ key).include? value
unless %w[Password None SSH\ public\ key].include?(value)
raise ArgumentError, "Authentication method must be 'SSH public key', 'Password', or 'None'"
end
select_element(:authentication_method, value)
end
......@@ -129,4 +131,7 @@ module QA
end
end
QA::Page::Project::Settings::MirroringRepositories.prepend_mod_with('Page::Project::Settings::MirroringRepositories', namespace: QA)
QA::Page::Project::Settings::MirroringRepositories.prepend_mod_with( # rubocop:disable Cop/InjectEnterpriseEditionModule
'Page::Project::Settings::MirroringRepositories',
namespace: QA
)
# frozen_string_literal: true
require 'github_api'
require 'octokit'
module QA
module Resource
class ProjectImportedFromGithub < Resource::Project
attribute :github_repo_id do
github_repository_path.split('/').yield_self do |path|
github_client.repos.get(user: path[0], repo: path[1]).id
end
github_client.repository(github_repository_path).id
end
def fabricate!
......@@ -42,6 +40,10 @@ module QA
'/import/github'
end
def api_trigger_mirror_pull_path
"#{api_get_path}/mirror/pull"
end
def api_post_body
{
repo_id: github_repo_id,
......@@ -56,13 +58,24 @@ module QA
api_resource
end
def trigger_project_mirror
Runtime::Logger.info "Triggering pull mirror request"
Support::Retrier.retry_until(max_attempts: 6, sleep_interval: 10) do
response = post(request_url(api_trigger_mirror_pull_path), nil)
Runtime::Logger.info "Mirror pull request response: #{response}"
response.code == Support::Api::HTTP_STATUS_OK
end
end
private
# Github client
#
# @return [Github::Client]
# @return [Octokit::Client]
def github_client
@github_client ||= Github.new(oauth_token: github_personal_access_token)
@github_client ||= Octokit::Client.new(access_token: github_personal_access_token)
end
end
end
......
# frozen_string_literal: true
require 'github_api'
require 'octokit'
require 'faker'
require 'base64'
module QA
context 'Verify', :github, :requires_admin, only: { subdomain: :staging } do
include Support::Api
describe 'Verify', :github, :requires_admin, only: { subdomain: :staging } do
describe 'Pipeline for project mirrors Github' do
let(:commit_message) { "Update #{github_data[:file_name]} - #{Time.now}" }
let(:project_name) { 'github-project-with-pipeline' }
let(:github_client) { Github::Client::Repos::Contents.new oauth_token: github_data[:access_token] }
let(:github_client) { Octokit::Client.new(access_token: github_data[:access_token]) }
let(:admin_api_client) { Runtime::API::Client.as_admin }
let(:user_api_client) { Runtime::API::Client.new(:gitlab, user: user) }
let(:github_data) do
{
access_token: Runtime::Env.github_access_token,
file_name: 'text_file.txt',
repo: 'gitlab-qa-github/test-project'
}
end
let(:group) do
Resource::Group.fabricate_via_api!
Resource::Group.fabricate_via_api! do |resource|
resource.api_client = admin_api_client
end
end
let(:user) do
......@@ -26,12 +33,14 @@ module QA
end
end
let(:import_project) do
let(:imported_project) do
EE::Resource::ImportRepoWithCiCd.fabricate_via_browser_ui! do |project|
project.import = true
project.name = project_name
project.group = group
project.github_personal_access_token = github_data[:access_token]
project.github_repository_path = github_data[:repo_name]
project.github_repository_path = github_data[:repo]
project.api_client = user_api_client
end
end
......@@ -39,80 +48,57 @@ module QA
# Create both tokens before logging in the first time so that we don't need to log out in the middle of the test
admin_api_client.personal_access_token
user_api_client.personal_access_token
group.add_member(user, Resource::Members::AccessLevel::OWNER)
Flow::Login.sign_in(as: user)
group.visit!
import_project
imported_project.reload! # import project and populate attributes
end
after do
remove_project
imported_project.remove_via_api!
group.remove_via_api!
user.remove_via_api!
end
it 'user commits to GitHub triggers CI pipeline', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/144' do
it(
'user commits to GitHub triggers CI pipeline',
testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/144'
) do
Page::Project::Menu.perform(&:click_ci_cd_pipelines)
Page::Project::Pipeline::Index.perform do |index|
expect(index).to have_no_pipeline, 'Expect to have NO pipeline before mirroring.'
edit_github_file
trigger_project_mirror
imported_project.trigger_project_mirror
index.wait_until(reload: false) { index.has_pipeline? }
expect(index).to have_content(commit_message), 'Expect new pipeline to have latest commit message from Github.'
expect(index).to have_content(commit_message), 'Expect new pipeline to have latest commit message from Github'
end
end
private
def github_data
{
access_token: Runtime::Env.github_access_token,
repo_owner: 'gitlab-qa-github',
repo_name: 'test-project',
file_name: 'text_file.txt'
}
end
def edit_github_file
Runtime::Logger.info "Making changes to Github file."
file = github_client.get github_data[:repo_owner], github_data[:repo_name], github_data[:file_name]
file_sha = file.body['sha']
file_path = file.body['path']
github_file_contents = -> { github_client.contents(github_data[:repo], path: github_data[:file_name]) }
file_contents = github_file_contents.call
file_sha = file_contents.sha
file_new_content = Faker::Lorem.sentence
github_client.update(github_data[:repo_owner], github_data[:repo_name], github_data[:file_name],
path: file_path, message: commit_message,
content: file_new_content,
sha: file_sha)
github_client.update_contents(
github_data[:repo],
github_data[:file_name],
commit_message,
file_sha,
file_new_content
)
Support::Retrier.retry_until(max_attempts: 5, sleep_interval: 2) do
Base64.decode64(github_client.get(user: github_data[:repo_owner], repo: github_data[:repo_name], path: file_path)&.content) == file_new_content
end
end
def import_project_id
request = Runtime::API::Request.new(user_api_client, import_project.api_get_path)
JSON.parse(get(request.url))['id']
contents = github_file_contents.call&.content
Base64.decode64(contents) == file_new_content
end
def trigger_project_mirror
Runtime::Logger.info "Triggering pull mirror request."
request = Runtime::API::Request.new(user_api_client, "/projects/#{import_project_id}/mirror/pull")
Support::Retrier.retry_until(max_attempts: 6, sleep_interval: 10) do
response = post(request.url, nil)
Runtime::Logger.info "Mirror pull request response: #{response}"
response.code == Support::Api::HTTP_STATUS_OK
end
end
def remove_project
delete_project_request = Runtime::API::Request.new(user_api_client, "/projects/#{CGI.escape("#{Runtime::Namespace.path}/#{import_project.name}")}")
delete delete_project_request.url
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment