Commit 26a51b67 authored by Sean Carroll's avatar Sean Carroll Committed by Dmytro Zaporozhets

Add `ref`, `milestones` and `released_at` to release yml

Part of https://gitlab.com/gitlab-org/gitlab/-/issues/223135

See merge request https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34913
parent b210a501
---
title: Add ref, released_at, milestones to release yml
merge_request: 34943
author:
type: added
---
title: Expose ref, milestones, released_at to releaser-cli
merge_request: 35115
author:
type: added
...@@ -5,6 +5,8 @@ module Gitlab ...@@ -5,6 +5,8 @@ module Gitlab
module Build module Build
class Releaser class Releaser
BASE_COMMAND = 'release-cli create' BASE_COMMAND = 'release-cli create'
SINGLE_FLAGS = %i[name description tag_name ref released_at].freeze
ARRAY_FLAGS = %i[milestones].freeze
attr_reader :config attr_reader :config
...@@ -14,10 +16,21 @@ module Gitlab ...@@ -14,10 +16,21 @@ module Gitlab
def script def script
command = BASE_COMMAND.dup command = BASE_COMMAND.dup
config.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") } 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}\"") } }
[command] [command]
end end
private
def single_flags
config.slice(*SINGLE_FLAGS)
end
def array_commands
config.slice(*ARRAY_FLAGS)
end
end end
end end
end end
......
...@@ -12,8 +12,9 @@ module Gitlab ...@@ -12,8 +12,9 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[tag_name name description assets].freeze ALLOWED_KEYS = %i[tag_name name description ref released_at milestones assets].freeze
attributes %i[tag_name name assets].freeze attributes %i[tag_name name ref milestones assets].freeze
attr_reader :released_at
# Attributable description conflicts with # Attributable description conflicts with
# ::Gitlab::Config::Entry::Node.description # ::Gitlab::Config::Entry::Node.description
...@@ -29,8 +30,25 @@ module Gitlab ...@@ -29,8 +30,25 @@ module Gitlab
validations do validations do
validates :config, allowed_keys: ALLOWED_KEYS validates :config, allowed_keys: ALLOWED_KEYS
validates :tag_name, presence: true validates :tag_name, type: String, presence: true
validates :description, type: String, presence: true validates :description, type: String, presence: true
validates :milestones, array_of_strings_or_string: true, allow_blank: true
validate do
next unless config[:released_at]
begin
@released_at = DateTime.iso8601(config[:released_at])
rescue ArgumentError
errors.add(:released_at, "must be a valid datetime")
end
end
validate do
next unless config[:ref]
unless Commit.reference_valid?(config[:ref])
errors.add(:ref, "must be a valid ref")
end
end
end end
def value def value
......
...@@ -13,13 +13,15 @@ describe Gitlab::Ci::Build::Releaser do ...@@ -13,13 +13,15 @@ describe Gitlab::Ci::Build::Releaser do
name: 'Release $CI_COMMIT_SHA', name: 'Release $CI_COMMIT_SHA',
description: 'Created using the release-cli $EXTRA_DESCRIPTION', description: 'Created using the release-cli $EXTRA_DESCRIPTION',
tag_name: 'release-$CI_COMMIT_SHA', tag_name: 'release-$CI_COMMIT_SHA',
ref: '$CI_COMMIT_SHA' ref: '$CI_COMMIT_SHA',
milestones: %w[m1 m2 m3],
released_at: '2020-07-15T08:00:00Z'
} }
} }
end end
it 'generates the script' do it 'generates the script' do
expect(subject).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"']) expect(subject).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" --released-at "2020-07-15T08:00:00Z" --milestone "m1" --milestone "m2" --milestone "m3"'])
end end
end end
...@@ -27,10 +29,12 @@ describe Gitlab::Ci::Build::Releaser do ...@@ -27,10 +29,12 @@ describe Gitlab::Ci::Build::Releaser do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:node_name, :node_value, :result) do where(:node_name, :node_value, :result) do
'name' | 'Release $CI_COMMIT_SHA' | 'release-cli create --name "Release $CI_COMMIT_SHA"' :name | 'Release $CI_COMMIT_SHA' | 'release-cli create --name "Release $CI_COMMIT_SHA"'
'description' | 'Release-cli $EXTRA_DESCRIPTION' | 'release-cli create --description "Release-cli $EXTRA_DESCRIPTION"' :description | 'Release-cli $EXTRA_DESCRIPTION' | 'release-cli create --description "Release-cli $EXTRA_DESCRIPTION"'
'tag_name' | 'release-$CI_COMMIT_SHA' | 'release-cli create --tag-name "release-$CI_COMMIT_SHA"' :tag_name | 'release-$CI_COMMIT_SHA' | 'release-cli create --tag-name "release-$CI_COMMIT_SHA"'
'ref' | '$CI_COMMIT_SHA' | 'release-cli create --ref "$CI_COMMIT_SHA"' :ref | '$CI_COMMIT_SHA' | 'release-cli create --ref "$CI_COMMIT_SHA"'
:milestones | %w[m1 m2 m3] | 'release-cli create --milestone "m1" --milestone "m2" --milestone "m3"'
:released_at | '2020-07-15T08:00:00Z' | 'release-cli create --released-at "2020-07-15T08:00:00Z"'
end end
with_them do with_them do
......
...@@ -5,10 +5,7 @@ require 'spec_helper' ...@@ -5,10 +5,7 @@ require 'spec_helper'
describe Gitlab::Ci::Config::Entry::Release do describe Gitlab::Ci::Config::Entry::Release do
let(:entry) { described_class.new(config) } let(:entry) { described_class.new(config) }
describe 'validation' do shared_examples_for 'a valid entry' do
context 'when entry config value is correct' do
let(:config) { { tag_name: 'v0.06', description: "./release_changelog.txt" } }
describe '#value' do describe '#value' do
it 'returns release configuration' do it 'returns release configuration' do
expect(entry.value).to eq config expect(entry.value).to eq config
...@@ -22,6 +19,20 @@ describe Gitlab::Ci::Config::Entry::Release do ...@@ -22,6 +19,20 @@ describe Gitlab::Ci::Config::Entry::Release do
end end
end end
shared_examples_for 'reports error' do |message|
it 'reports error' do
expect(entry.errors)
.to include message
end
end
describe 'validation' do
context 'when entry config value is correct' do
let(:config) { { tag_name: 'v0.06', description: "./release_changelog.txt" } }
it_behaves_like 'a valid entry'
end
context "when value includes 'assets' keyword" do context "when value includes 'assets' keyword" do
let(:config) do let(:config) do
{ {
...@@ -36,38 +47,116 @@ describe Gitlab::Ci::Config::Entry::Release do ...@@ -36,38 +47,116 @@ describe Gitlab::Ci::Config::Entry::Release do
} }
end end
describe '#value' do it_behaves_like 'a valid entry'
it 'returns release configuration' do
expect(entry.value).to eq config
end end
context "when value includes 'name' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME"
}
end end
describe '#valid?' do it_behaves_like 'a valid entry'
it 'is valid' do
expect(entry).to be_valid
end end
context "when value includes 'ref' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME",
ref: 'b3235930aa443112e639f941c69c578912189bdd'
}
end end
it_behaves_like 'a valid entry'
end end
context "when value includes 'name' keyword" do context "when value includes 'released_at' keyword" do
let(:config) do let(:config) do
{ {
tag_name: 'v0.06', tag_name: 'v0.06',
description: "./release_changelog.txt", description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME" name: "Release $CI_TAG_NAME",
released_at: '2019-03-15T08:00:00Z'
} }
end end
describe '#value' do it_behaves_like 'a valid entry'
it 'returns release configuration' do
expect(entry.value).to eq config
end end
context "when value includes 'milestones' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME",
milestones: milestones
}
end end
describe '#valid?' do context 'for an array of milestones' do
it 'is valid' do let(:milestones) { %w[m1 m2 m3] }
expect(entry).to be_valid
it_behaves_like 'a valid entry'
end end
context 'for a single milestone' do
let(:milestones) { 'm1' }
it_behaves_like 'a valid entry'
end
end
context "when value includes 'ref' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME",
ref: 'b3235930aa443112e639f941c69c578912189bdd'
}
end
it_behaves_like 'a valid entry'
end
context "when value includes 'released_at' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME",
released_at: '2019-03-15T08:00:00Z'
}
end
it_behaves_like 'a valid entry'
end
context "when value includes 'milestones' keyword" do
let(:config) do
{
tag_name: 'v0.06',
description: "./release_changelog.txt",
name: "Release $CI_TAG_NAME",
milestones: milestones
}
end
context 'for an array of milestones' do
let(:milestones) { %w[m1 m2 m3] }
it_behaves_like 'a valid entry'
end
context 'for a single milestone' do
let(:milestones) { 'm1' }
it_behaves_like 'a valid entry'
end end
end end
...@@ -76,37 +165,61 @@ describe Gitlab::Ci::Config::Entry::Release do ...@@ -76,37 +165,61 @@ describe Gitlab::Ci::Config::Entry::Release do
context 'when value of attribute is invalid' do context 'when value of attribute is invalid' do
let(:config) { { description: 10 } } let(:config) { { description: 10 } }
it 'reports error' do it_behaves_like 'reports error', 'release description should be a string'
expect(entry.errors)
.to include 'release description should be a string'
end
end end
context 'when release description is missing' do context 'when release description is missing' do
let(:config) { { tag_name: 'v0.06' } } let(:config) { { tag_name: 'v0.06' } }
it 'reports error' do it_behaves_like 'reports error', "release description can't be blank"
expect(entry.errors)
.to include "release description can't be blank"
end
end end
context 'when release tag_name is missing' do context 'when release tag_name is missing' do
let(:config) { { description: "./release_changelog.txt" } } let(:config) { { description: "./release_changelog.txt" } }
it 'reports error' do it_behaves_like 'reports error', "release tag name can't be blank"
expect(entry.errors)
.to include "release tag name can't be blank"
end
end end
context 'when there is an unknown key present' do context 'when there is an unknown key present' do
let(:config) { { test: 100 } } let(:config) { { test: 100 } }
it 'reports error' do it_behaves_like 'reports error', 'release config contains unknown keys: test'
expect(entry.errors) end
.to include 'release config contains unknown keys: test'
context 'when `released_at` is not a valid date' do
let(:config) { { released_at: 'ABC123' } }
it_behaves_like 'reports error', 'release released at must be a valid datetime'
end end
context 'when `ref` is not valid' do
let(:config) { { ref: 'ABC123' } }
it_behaves_like 'reports error', 'release ref must be a valid ref'
end
context 'when `milestones` is not an array of strings' do
let(:config) { { milestones: [1, 2, 3] } }
it_behaves_like 'reports error', 'release milestones should be an array of strings or a string'
end
context 'when `released_at` is not a valid date' do
let(:config) { { released_at: 'ABC123' } }
it_behaves_like 'reports error', 'release released at must be a valid datetime'
end
context 'when `ref` is not valid' do
let(:config) { { ref: 'ABC123' } }
it_behaves_like 'reports error', 'release ref must be a valid ref'
end
context 'when `milestones` is not an array of strings' do
let(:config) { { milestones: [1, 2, 3] } }
it_behaves_like 'reports error', 'release milestones should be an array of strings or a string'
end end
end end
end end
......
...@@ -1397,6 +1397,9 @@ module Gitlab ...@@ -1397,6 +1397,9 @@ module Gitlab
tag_name: "$CI_COMMIT_TAG", tag_name: "$CI_COMMIT_TAG",
name: "Release $CI_TAG_NAME", name: "Release $CI_TAG_NAME",
description: "./release_changelog.txt", description: "./release_changelog.txt",
ref: 'b3235930aa443112e639f941c69c578912189bdd',
released_at: '2019-03-15T08:00:00Z',
milestones: %w[m1 m2 m3],
assets: { assets: {
links: [ links: [
{ {
......
...@@ -668,7 +668,7 @@ RSpec.describe API::Runner, :clean_gitlab_redis_shared_state do ...@@ -668,7 +668,7 @@ RSpec.describe API::Runner, :clean_gitlab_redis_shared_state do
{ {
"name" => "release", "name" => "release",
"script" => "script" =>
["release-cli create --ref \"$CI_COMMIT_SHA\" --name \"Release $CI_COMMIT_SHA\" --tag-name \"release-$CI_COMMIT_SHA\" --description \"Created using the release-cli $EXTRA_DESCRIPTION\""], ["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\""],
"timeout" => 3600, "timeout" => 3600,
"when" => "on_success", "when" => "on_success",
"allow_failure" => false "allow_failure" => false
......
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