From d9b5d95bbdf238415d55d9fb5a61326c7fd0df7c Mon Sep 17 00:00:00 2001 From: Stan Hu <stanhu@gmail.com> Date: Sat, 2 May 2020 16:39:44 -0700 Subject: [PATCH] Fix db:check-schema in forks and shallow clones The `regenerate-schema` script attempts to find the merge base between the source and branch SHA to determine the right `db/structure.sql` to apply the migrations in the merge request. However, to get the merge base, we need the target SHA and the history between the source and target SHAs. Instead of downloading it via a curl request, we fetch the target branch and check out the `db/structure.sql` from there. Closes https://gitlab.com/gitlab-org/gitlab/-/issues/216214 --- scripts/regenerate-schema | 50 +++++++++++++++------------------------ 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/scripts/regenerate-schema b/scripts/regenerate-schema index b63a75cdc835..cedd612f766f 100755 --- a/scripts/regenerate-schema +++ b/scripts/regenerate-schema @@ -2,7 +2,7 @@ # frozen_string_literal: true -require 'net/http' +require 'open3' require 'uri' class SchemaRegenerator @@ -56,35 +56,15 @@ class SchemaRegenerator # Get clean schema from remote servers # # This script might run in CI, using a shallow clone, so to checkout - # the file, download it from the server. + # the file, fetch the target branch from the server. def remote_checkout_clean_schema return false unless project_url + return false unless target_project_url - uri = URI.join("#{project_url}/", 'raw/', "#{merge_base}/", FILENAME) + run %Q[git remote add target_project #{target_project_url}.git] + run %Q[git fetch target_project #{target_branch}:#{target_branch}] - download_schema(uri) - end - - ## - # Download the schema from the given +uri+. - def download_schema(uri) - puts "Downloading #{uri}..." - - Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| - request = Net::HTTP::Get.new(uri.request_uri) - http.read_timeout = 500 - http.request(request) do |response| - raise("Failed to download file: #{response.code} #{response.message}") if response.code.to_i != 200 - - File.open(FILENAME, 'w') do |io| - response.read_body do |chunk| - io.write(chunk) - end - end - end - end - - true + local_checkout_clean_schema end ## @@ -150,15 +130,17 @@ class SchemaRegenerator # When the command failed an exception is raised. def run(cmd) puts "\e[32m$ #{cmd}\e[37m" - ret = system(cmd) - puts "\e[0m" - raise("Command failed") unless ret + stdout_str, stderr_str, status = Open3.capture3(cmd) + puts "#{stdout_str}#{stderr_str}\e[0m" + raise("Command failed: #{stderr_str}") unless status.success? + + stdout_str end ## # Return the base commit between source and target branch. def merge_base - @merge_base ||= `git merge-base #{target_branch} #{source_ref}`.chomp + @merge_base ||= run("git merge-base #{target_branch} #{source_ref}").chomp end ## @@ -179,11 +161,17 @@ class SchemaRegenerator end ## - # Return the project URL from CI environment variable. + # Return the source project URL from CI environment variable. def project_url ENV['CI_PROJECT_URL'] end + ## + # Return the target project URL from CI environment variable. + def target_project_url + ENV['CI_MERGE_REQUEST_PROJECT_URL'] + end + ## # Return whether the script is running from CI def ci? -- GitLab