Purpose
This automatically sets up merge conflicts in the following 7 different scenarios
What it does
- Sets up a local repository based on
flightjs/flight
from the GDK - Creates numerous branches with various changes in them (modified, added, removed files)
- Creates numerous MRs between the created branches for the purpose of creating conflicts
To Use
- Make sure you have
httparty
andbyebug
gems installed globally - Copy/paste this file anywhere
- Fill out your GITLAB_TOKEN and LOCAL_PATH information. Make sure the GDK is running.
- Use it by running
ruby conflicts.rb
to setup all 7 scenarios - Locally, you can toggle feature flags on and off to see the data in the UI. We are currently using
display_merge_conflicts_in_diff
- After each use, tear everything down by running
ruby conflicts.rb delete
** You might be asked for a local username and password when cloning the repository locally. You also might be asked
#!/usr/bin/env ruby
require 'httparty'
require 'byebug'
GITLAB_API = 'http://localhost:3000/api/v4'
GITLAB_TOKEN = '' # Fill this out
PROJECT_ID = 6 # flightjs/flight
LOCAL_PATH = '/absolute/path/to/test-conflicts/flight' # Keep 'test-conflicts/flight' here, but specify where you want those folders to end up, ie: ~/Desktop
HEADERS = { "PRIVATE-TOKEN" => GITLAB_TOKEN }
# Don't forget to enable feature flag :display_merge_conflicts_in_diff
# 7 scenarios to cover
def setup_local_repository
# Requires username and password
`mkdir -p #{LOCAL_PATH.gsub('/flight', '')}`
`cd #{LOCAL_PATH.gsub('/flight', '')} && git clone http://127.0.0.1:3000/flightjs/flight.git`
end
def pull_remote
`cd #{LOCAL_PATH} && git pull origin`
end
def modify_file(filename, branch, text)
`cd #{LOCAL_PATH} && git checkout #{branch}`
File.open("#{LOCAL_PATH}/#{filename}", 'w') do |f|
f.puts text
f.close
end
`cd #{LOCAL_PATH} && git add . && git commit -m "New thing" && git push origin #{branch}`
end
def remove_file(filename, branch)
`cd #{LOCAL_PATH} && git checkout #{branch} && rm #{filename} && git rm #{filename} && git commit -m "Remove a thing" && git push origin #{branch}`
end
def rename_file(filename, new_filename, branch)
`cd #{LOCAL_PATH} && git checkout #{branch} && mv #{filename} #{new_filename} && git add #{new_filename} && git commit -m "Rename a thing" && git push origin #{branch}`
end
def add_file(filename, branch, text)
`cd #{LOCAL_PATH} && git checkout #{branch} && touch #{filename}`
File.open("#{LOCAL_PATH}/#{filename}", 'w') do |f|
f.puts text
f.close
end
`cd #{LOCAL_PATH} && git add #{filename} && git commit -m "Add a new file" && git push origin #{branch}`
end
def setup_scenario_1
new_target_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-1-target",
"ref" => "master"
})
new_source_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-1-source",
"ref" => "master"
})
if new_target_branch.success? || new_source_branch.success?
pull_remote
# Make a change in the source branch and commit
modify_file('Makefile', 'scenario-1-source', 'making a change')
# Make the same change in the target branch and commit
modify_file('Makefile', 'scenario-1-target', 'totally different text')
# Open MR
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-1-source",
"target_branch" => "scenario-1-target",
"title" => "Scenario 1 Conflict MR",
"description" => "User A has modified a file that User B has already modified in the same place in the target branch",
"labels" => "teardown"
})
else
raise "Could not create Scenario 1 target branch: #{new_target_branch.parsed_response} or source branch: #{new_source_branch.parsed_response}"
end
end
def setup_scenario_2
new_target_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-2-target",
"ref" => "master"
})
if new_target_branch.success?
pull_remote
# Remove the file (Makefile) in the target branch and commit
remove_file('Makefile', 'scenario-2-target')
# Open MR
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-1-source",
"target_branch" => "scenario-2-target",
"title" => "Scenario 2 Conflict MR",
"description" => "User A has modified a file that User B has already deleted in the same place in the target branch",
"labels" => "teardown"
})
else
raise "Could not create Scenario 2 target branch: #{new_target_branch.parsed_response}"
end
end
def setup_scenario_3
new_source_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-3-source",
"ref" => "master"
})
if new_source_branch.success?
pull_remote
# Remove the file (Makefile) in source branch and commit
remove_file('Makefile', 'scenario-3-source')
# Open MR
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-3-source",
"target_branch" => "scenario-1-target",
"title" => "Scenario 3 Conflict MR",
"description" => "User A has deleted a file that User B has already modified in the same place in the target branch",
"labels" => "teardown"
})
else
raise "Could not create Scenario 3 source branch: #{new_source_branch.parsed_response}"
end
end
def setup_scenario_4
new_target_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-4-target",
"ref" => "master"
})
new_source_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-4-source",
"ref" => "master"
})
if new_target_branch.success? || new_source_branch.success?
pull_remote
# Rename a file in the source branch and commit
rename_file('Makefile', 'Makefile2', 'scenario-4-source')
# Rename the same file differently in the target branch and commit
rename_file('Makefile', 'Makefile9', 'scenario-4-target')
# Open MR
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-4-source",
"target_branch" => "scenario-4-target",
"title" => "Scenario 4 Conflict MR",
"description" => "User A has renamed a file that User B has already renamed differently in the target branch",
"labels" => "teardown"
})
else
raise "Could not create Scenario 4 target branch: #{new_target_branch.parsed_response} or source branch: #{new_source_branch.parsed_response}"
end
end
def setup_scenario_5
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-3-source",
"target_branch" => "scenario-4-target",
"title" => "Scenario 5 Conflict MR",
"description" => "User A has removed a file that User B has renamed in the target branch",
"labels" => "teardown"
})
end
def setup_scenario_6
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-4-source",
"target_branch" => "scenario-2-target",
"title" => "Scenario 6 Conflict MR",
"description" => "User A has renamed a file that User B has removed in the target branch",
"labels" => "teardown"
})
end
def setup_scenario_7
new_target_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-7-target",
"ref" => "master"
})
new_source_branch = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches",
headers: HEADERS, body: {
"branch" => "scenario-7-source",
"ref" => "master"
})
if new_target_branch.success? || new_source_branch.success?
pull_remote
# Add a file in source branch and commit
add_file('MegaFile', 'scenario-7-source', 'Some text for you')
# Add the same file with different content in the target branch and commit
add_file('MegaFile', 'scenario-7-target', 'Completely different file, kinda')
# Open MR
new_mr = HTTParty.post(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests",
headers: HEADERS, body: {
"source_branch" => "scenario-7-source",
"target_branch" => "scenario-7-target",
"title" => "Scenario 7 Conflict MR",
"description" => "User A has added a file that User B has already added with different content in the target branch",
"labels" => "teardown"
})
else
raise "Could not create Scenario 7 target branch: #{new_target_branch.parsed_response} or source branch: #{new_source_branch.parsed_response}"
end
end
if ARGV.empty?
# Setup local repository
setup_local_repository
# Scenario 1 - User A modified file, User B modified target branches file in the same place
setup_scenario_1
# # Scenario 2 - User A modified file, User b deleted file in the target branch
# # This reuses scenario-1-source as the modified file branch
setup_scenario_2
# # Scenario 3 - User A removes the file, User B modified it in the target branch
# # This reuses scenario-1-target since it was modified after setting up scenario 1
setup_scenario_3
# # Scenario 4 - User A renamed a file in source, User B renamed the same file in a different way in the target
setup_scenario_4
# # Scenario 5 - User A removed the file in source, User B renamed the file in target
# # This reuses the removed file in scenario-3-source and the renamed file in scenario-4-target
setup_scenario_5
# # Scenario 6 - User A renamed the file in source, User B removed it in the target
# # This reuses the scenario-4-source and the scenario-2-target
setup_scenario_6
# # Scenario 7 - User A created a new file in source, User B created the same file with different content in target
setup_scenario_7
else
# Cleanup
# Remove local repository
`rm -rf #{LOCAL_PATH.gsub('/flight', '')}`
# Remove scenario 1 target branch based on name
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-1-target", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-2-target", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-4-target", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-7-target", headers: HEADERS)
# Remove scenario 1 source branch
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-1-source", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-3-source", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-4-source", headers: HEADERS)
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/repository/branches/scenario-7-source", headers: HEADERS)
# Delete any MR created
mrs = HTTParty.get(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests?labels=teardown", headers: HEADERS)
mrs.each do |mr|
HTTParty.delete(GITLAB_API + "/projects/#{PROJECT_ID}/merge_requests/#{mr['iid']}", headers: HEADERS)
end
end