diff --git a/lib/gitlab/ci/build/releaser.rb b/lib/gitlab/ci/build/releaser.rb index 22a42e865e6ac8b02a375e41143f436d79d17769..866463f712164a78128ae948561aa302d03293d2 100644 --- a/lib/gitlab/ci/build/releaser.rb +++ b/lib/gitlab/ci/build/releaser.rb @@ -4,9 +4,32 @@ module Gitlab module Ci module Build class Releaser - BASE_COMMAND = 'release-cli create' - SINGLE_FLAGS = %i[name description tag_name tag_message ref released_at].freeze - ARRAY_FLAGS = %i[milestones].freeze + CREATE_BASE_COMMAND = 'release-cli create' + CREATE_SINGLE_FLAGS = %i[name description tag_name tag_message ref released_at].freeze + CREATE_ARRAY_FLAGS = %i[milestones].freeze + + RELEASE_CLI_REQUIRED_VERSION = '0.20.0' + GLAB_REQUIRED_VERSION = '1.50.0' + GLAB_COMMAND_CHECK_COMMAND = <<~BASH.freeze + if ! command -v glab &> /dev/null; then + echo "Error: glab command not found. Please use release-cli image #{RELEASE_CLI_REQUIRED_VERSION} or higher, or install glab #{GLAB_REQUIRED_VERSION} or higher." + exit 1 + fi + BASH + + GLAB_VERSION_CHECK_COMMAND = <<~BASH.freeze + if [ "$(printf "%s\n%s" "#{GLAB_REQUIRED_VERSION}" "$(glab --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')" | sort -V | head -n1)" = "#{GLAB_REQUIRED_VERSION}" ]; then + echo "Validating glab version. OK" + else + echo "Error: Please use release-cli image #{RELEASE_CLI_REQUIRED_VERSION} or higher, or install glab #{GLAB_REQUIRED_VERSION} or higher." + exit 1 + fi + BASH + + GLAB_LOGIN_COMMAND = 'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL' + GLAB_MAIN_COMMAND = 'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH' + GLAB_CREATE_COMMAND = "#{GLAB_MAIN_COMMAND} release create".freeze + GLAB_PUBLISH_TO_CATALOG_FLAG = '--publish-to-catalog' attr_reader :job, :config @@ -16,26 +39,51 @@ def initialize(job:) end def script - command = BASE_COMMAND.dup - single_flags.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") } - array_commands.each { |k, v| v.each { |elem| command.concat(" --#{k.to_s.singularize.dasherize} \"#{elem}\"") } } - asset_links.each { |link| command.concat(" --assets-link #{stringified_json(link)}") } - command.concat(" --catalog-publish") if catalog_publish? - - [command.freeze] + if catalog_publish? + [ + GLAB_COMMAND_CHECK_COMMAND, + GLAB_VERSION_CHECK_COMMAND, + GLAB_LOGIN_COMMAND, + glab_create_command_with_publish_to_catalog + ] + else + [create_command] + end end private - def single_flags - config.slice(*SINGLE_FLAGS) + def create_command + command = CREATE_BASE_COMMAND.dup + create_single_flags.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") } + create_array_commands.each { |k, v| v.each { |elem| command.concat(" --#{k.to_s.singularize.dasherize} \"#{elem}\"") } } + create_asset_links.each { |link| command.concat(" --assets-link #{stringified_json(link)}") } + command.freeze + end + + def glab_create_command_with_publish_to_catalog + command = GLAB_CREATE_COMMAND.dup + command.concat(" \"#{config[:tag_name]}\"") + command.concat(" --assets-links #{stringified_json(create_asset_links)}") if create_asset_links.present? + command.concat(" --milestone \"#{config[:milestones].join(',')}\"") if config[:milestones].present? + command.concat(" --name \"#{config[:name]}\"") if config[:name].present? + command.concat(" --notes \"#{config[:description]}\"") if config[:description].present? + command.concat(" --ref \"#{config[:ref]}\"") if config[:ref].present? + command.concat(" --tag-message \"#{config[:tag_message]}\"") if config[:tag_message].present? + command.concat(" --released-at \"#{config[:released_at]}\"") if config[:released_at].present? + command.concat(" #{GLAB_PUBLISH_TO_CATALOG_FLAG}") + command.freeze + end + + def create_single_flags + config.slice(*CREATE_SINGLE_FLAGS) end - def array_commands - config.slice(*ARRAY_FLAGS) + def create_array_commands + config.slice(*CREATE_ARRAY_FLAGS) end - def asset_links + def create_asset_links config.dig(:assets, :links) || [] end diff --git a/spec/lib/gitlab/ci/build/releaser_spec.rb b/spec/lib/gitlab/ci/build/releaser_spec.rb index e6408b22e72a70ec5503900a62701cb104df9da2..4639aa07114499a90477d6ba8227bd8d0d3cc42f 100644 --- a/spec/lib/gitlab/ci/build/releaser_spec.rb +++ b/spec/lib/gitlab/ci/build/releaser_spec.rb @@ -49,8 +49,16 @@ let(:job) { build(:ci_build, pipeline: pipeline, options: { release: config[:release] }) } - it 'generates the script with --catalog-publish' do - expect(script).to eq(["#{result_script} --catalog-publish"]) + it 'generates glab scripts' do + expect(script).to eq([ + "if ! command -v glab &> /dev/null; then\n echo \"Error: glab command not found. Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n", + "if [ \"$(printf \"%s\n%s\" \"1.50.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.50.0\" ]; then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n", + 'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL', + 'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH release create "release-$CI_COMMIT_SHA" ' \ + '--assets-links "[{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\",\"link_type\":\"other\",\"filepath\":\"/pretty/asset/1\"},{\"name\":\"asset2\",\"url\":\"https://example.com/assets/2\"}]" ' \ + '--milestone "m1,m2,m3" --name "Release $CI_COMMIT_SHA" --notes "Created using the release-cli $EXTRA_DESCRIPTION" ' \ + '--ref "$CI_COMMIT_SHA" --tag-message "Annotated tag message" --released-at "2020-07-15T08:00:00Z" --publish-to-catalog' + ]) end context 'when the FF ci_release_cli_catalog_publish_option is disabled' do @@ -58,7 +66,7 @@ stub_feature_flags(ci_release_cli_catalog_publish_option: false) end - it 'generates the script without --catalog-publish' do + it 'generates the release-cli script' do expect(script).to eq([result_script]) end end diff --git a/spec/lib/gitlab/ci/build/step_spec.rb b/spec/lib/gitlab/ci/build/step_spec.rb index e5af125a1a7fb94e64d3badffa25c95db3d8e7d8..49eadb568d2520b2e9b103312cb1d186097e8647 100644 --- a/spec/lib/gitlab/ci/build/step_spec.rb +++ b/spec/lib/gitlab/ci/build/step_spec.rb @@ -81,8 +81,30 @@ let(:pipeline) { create(:ci_pipeline, project: project) } let(:job) { create(:ci_build, :release_options, pipeline: pipeline) } - it 'returns the release-cli command line with --catalog-publish' do - expect(subject.script).to eq(["release-cli create --name \"Release $CI_COMMIT_SHA\" --description \"Created using the release-cli $EXTRA_DESCRIPTION\" --tag-name \"release-$CI_COMMIT_SHA\" --ref \"$CI_COMMIT_SHA\" --assets-link \"{\\\"name\\\":\\\"asset1\\\",\\\"url\\\":\\\"https://example.com/assets/1\\\"}\" --catalog-publish"]) + it 'returns glab scripts' do + expect(subject.script).to eq([ + "if ! command -v glab &> /dev/null; then\n echo \"Error: glab command not found. Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n", + "if [ \"$(printf \"%s\n%s\" \"1.50.0\" \"$(glab --version | grep -oE '[0-9]+.[0-9]+.[0-9]+')\" | sort -V | head -n1)\" = \"1.50.0\" ]; then\n echo \"Validating glab version. OK\"\nelse\n echo \"Error: Please use release-cli image 0.20.0 or higher, or install glab 1.50.0 or higher.\"\n exit 1\nfi\n", + 'glab auth login --job-token $CI_JOB_TOKEN --hostname $CI_SERVER_FQDN --api-protocol $CI_SERVER_PROTOCOL', + 'GITLAB_HOST=$CI_SERVER_URL glab -R $CI_PROJECT_PATH release create "release-$CI_COMMIT_SHA" ' \ + '--assets-links "[{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\"}]" ' \ + '--name "Release $CI_COMMIT_SHA" --notes "Created using the release-cli $EXTRA_DESCRIPTION" ' \ + '--ref "$CI_COMMIT_SHA" --publish-to-catalog' + ]) + end + + context 'when the FF ci_release_cli_catalog_publish_option is disabled' do + before do + stub_feature_flags(ci_release_cli_catalog_publish_option: false) + end + + it 'returns the release-cli script' do + expect(subject.script).to eq([ + "release-cli create --name \"Release $CI_COMMIT_SHA\" --description \"Created using the release-cli $EXTRA_DESCRIPTION\" " \ + "--tag-name \"release-$CI_COMMIT_SHA\" --ref \"$CI_COMMIT_SHA\" " \ + '--assets-link "{\"name\":\"asset1\",\"url\":\"https://example.com/assets/1\"}"' + ]) + end end end end