...
 
Commits (3)
......@@ -51,6 +51,7 @@ rubocop:
- schedules
- triggers
script:
- env
- bundle exec rubocop
specs:
......
......@@ -19,6 +19,13 @@ unless ENV['CI'] || Rake.application.top_level_tasks.include?('default') || Rele
abort('Please use the master branch and make sure you are up to date.'.colorize(:red))
end
namespace :auto_deploy do
desc "Create auto-deploy branches from the latest green commit on gitlab-ee and omnibus-gitlab"
task :create_branches do
ReleaseTools::Services::AutoDeployBranchService.new.create_auto_deploy_branches!
end
end
namespace :green_master do
desc "Trigger a green master build for EE"
task :ee, [:trigger_build] do |_t, args|
......
......@@ -97,6 +97,8 @@ require 'release_tools/release_managers/sync_result'
require 'release_tools/release_managers/schedule'
require 'release_tools/remote_repository'
require 'release_tools/security_patch_issue'
require 'release_tools/services/branch_service'
require 'release_tools/services/auto_deploy_branch_service'
require 'release_tools/services/monthly_preparation_service'
require 'release_tools/services/security_preparation_service'
require 'release_tools/services/upstream_merge_service'
......
......@@ -3,9 +3,11 @@
module ReleaseTools
class Commits
attr_reader :project
MAX_COMMITS_TO_CHECK = 100
def initialize(project)
def initialize(project, client = ReleaseTools::GitlabClient)
@project = project
@client = client
end
def latest_successful
......@@ -15,8 +17,8 @@ module ReleaseTools
private
def commit_list
@commit_list ||= ReleaseTools::GitlabDevClient.commits(
@project.dev_path,
@commit_list ||= @client.commits(
@project.path,
{
per_page: 1,
ref_name: 'master'
......@@ -24,8 +26,11 @@ module ReleaseTools
end
def filter_for_green_builds
commit_counter = 0
commit_list.auto_paginate do |commit|
commit = ReleaseTools::GitlabDevClient.commit(@project, ref: commit.id)
commit_counter += 1
abort("Examined #{MAX_COMMITS_TO_CHECK} commits, but could not find a passing build for #{@project.path}, aborting") if commit_counter > MAX_COMMITS_TO_CHECK
commit = @client.commit(@project, ref: commit.id)
return commit if commit.status == "success"
end
end
......
# frozen_string_literal: true
module ReleaseTools
module Services
class AutoDeployBranchService < BranchService
def initialize
@version = client.current_milestone.title.tr('.', '-')
end
def create_auto_deploy_branches!
# Find passing commits before creating branches
commit_ee = branch_commit(Project::GitlabEe)
commit_omnibus = branch_commit(Project::OmnibusGitlab)
create_branch(Project::GitlabEe, branch_name, commit_ee)
create_branch(Project::OmnibusGitlab, branch_name, commit_omnibus)
end
private
def branch_name
"#{@version}-auto-deploy-1234-ee"
end
def branch_commit(project)
ReleaseTools::Commits.new(project).latest_successful.id
end
end
end
end
# frozen_string_literal: true
module ReleaseTools
module Services
class BranchService
private
def client
ReleaseTools::GitlabClient
end
def ignoring_duplicates(&block)
yield
rescue Gitlab::Error::Conflict, Gitlab::Error::BadRequest => ex
if ex.message.match?('already exists')
# no-op for idempotency
else
raise
end
end
def create_branch(project, branch, commit = 'master')
$stdout.puts "Creating `#{branch}` on `#{project.path}`"
return if dry_run?
ignoring_duplicates do
client.create_branch(branch, commit, project)
end
end
end
end
end
......@@ -2,7 +2,7 @@
module ReleaseTools
module Services
class MonthlyPreparationService
class MonthlyPreparationService < BranchService
def initialize(version)
@version = version
end
......@@ -21,36 +21,10 @@ module ReleaseTools
ce_branch = @version.stable_branch(ee: false)
ee_branch = @version.stable_branch(ee: true)
create_stable_branch(Project::GitlabEe, ee_branch)
create_stable_branch(Project::GitlabCe, ce_branch)
create_stable_branch(Project::OmnibusGitlab, ee_branch)
create_stable_branch(Project::OmnibusGitlab, ce_branch)
end
private
def client
ReleaseTools::GitlabClient
end
def ignoring_duplicates(&block)
yield
rescue Gitlab::Error::Conflict, Gitlab::Error::BadRequest => ex
if ex.message.match?('already exists')
# no-op for idempotency
else
raise
end
end
def create_stable_branch(project, branch)
$stdout.puts "Creating `#{branch}` on `#{project.path}`"
return if dry_run?
ignoring_duplicates do
client.create_branch(branch, 'master', project)
end
create_branch(Project::GitlabEe, ee_branch)
create_branch(Project::GitlabCe, ce_branch)
create_branch(Project::OmnibusGitlab, ee_branch)
create_branch(Project::OmnibusGitlab, ce_branch)
end
end
end
......
---
http_interactions:
- request:
method: get
uri: https://gitlab.com/api/v4/projects/gitlab-org%2Fgitlab-ce/milestones?state=active
body:
encoding: US-ASCII
string: ''
headers:
Accept:
- application/json
Content-Type:
- application/x-www-form-urlencoded
User-Agent:
- Gitlab Ruby Gem 4.10.0
Private-Token:
- "[GITLAB_API_PRIVATE_TOKEN]"
response:
status:
code: 200
message: OK
headers:
Server:
- nginx
Date:
- Mon, 25 Mar 2019 16:00:13 GMT
Content-Type:
- application/json
Content-Length:
- '274'
Cache-Control:
- max-age=0, private, must-revalidate
Etag:
- W/"df03bf47b63ffc70cf11a3ce0ff2465b"
Link:
- <https://gitlab.com/api/v4/projects/gitlab%2Dorg%2Fgitlab%2Dce/milestones?id=gitlab-org%2Fgitlab-ce&page=1&per_page=20&state=active>;
rel="first", <https://gitlab.com/api/v4/projects/gitlab%2Dorg%2Fgitlab%2Dce/milestones?id=gitlab-org%2Fgitlab-ce&page=1&per_page=20&state=active>;
rel="last"
Vary:
- Origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Next-Page:
- ''
X-Page:
- '1'
X-Per-Page:
- '20'
X-Prev-Page:
- ''
X-Request-Id:
- E5CdfAunLY4
X-Runtime:
- '0.100971'
X-Total:
- '1'
X-Total-Pages:
- '1'
Strict-Transport-Security:
- max-age=31536000
Ratelimit-Limit:
- '600'
Ratelimit-Observed:
- '1'
Ratelimit-Remaining:
- '599'
Ratelimit-Reset:
- '1553529673'
Ratelimit-Resettime:
- Tue, 25 Mar 2019 16:01:13 GMT
body:
encoding: UTF-8
string: '[{"id":22434,"iid":15,"project_id":13083,"title":"Support","description":"","state":"active","created_at":"2015-08-27T00:08:51.317Z","updated_at":"2015-08-27T00:08:51.317Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/gitlab-org/gitlab-ce/milestones/15"}]'
http_version:
recorded_at: Mon, 25 Mar 2019 16:00:13 GMT
- request:
method: get
uri: https://gitlab.com/api/v4/groups/gitlab-org/milestones?state=active
body:
encoding: US-ASCII
string: ''
headers:
Accept:
- application/json
Content-Type:
- application/x-www-form-urlencoded
User-Agent:
- Gitlab Ruby Gem 4.10.0
Private-Token:
- "[GITLAB_API_PRIVATE_TOKEN]"
response:
status:
code: 200
message: OK
headers:
Server:
- nginx
Date:
- Mon, 25 Mar 2019 16:00:14 GMT
Content-Type:
- application/json
Content-Length:
- '5538'
Cache-Control:
- max-age=0, private, must-revalidate
Etag:
- W/"a7f0c77df2880ccb85efc8878ed21b45"
Link:
- <https://gitlab.com/api/v4/groups/gitlab%2Dorg/milestones?id=gitlab-org&page=1&per_page=20&state=active>;
rel="first", <https://gitlab.com/api/v4/groups/gitlab%2Dorg/milestones?id=gitlab-org&page=1&per_page=20&state=active>;
rel="last"
Vary:
- Origin
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Next-Page:
- ''
X-Page:
- '1'
X-Per-Page:
- '20'
X-Prev-Page:
- ''
X-Request-Id:
- tarlrUdsV68
X-Runtime:
- '0.149129'
X-Total:
- '17'
X-Total-Pages:
- '1'
Strict-Transport-Security:
- max-age=31536000
Ratelimit-Limit:
- '600'
Ratelimit-Observed:
- '2'
Ratelimit-Remaining:
- '598'
Ratelimit-Reset:
- '1553529674'
Ratelimit-Resettime:
- Tue, 25 Mar 2019 16:01:14 GMT
body:
encoding: UTF-8
string: '[{"id":731039,"iid":38,"group_id":9970,"title":"12.4","description":"","state":"active","created_at":"2018-12-07T12:41:53.212Z","updated_at":"2019-01-16T19:50:51.218Z","due_date":"2019-10-22","start_date":"2019-09-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/38"},{"id":731038,"iid":37,"group_id":9970,"title":"12.3","description":"","state":"active","created_at":"2018-12-07T12:40:55.400Z","updated_at":"2019-01-16T19:50:20.313Z","due_date":"2019-09-22","start_date":"2019-08-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/37"},{"id":697412,"iid":36,"group_id":9970,"title":"GitLab
Contribute 2019","description":"","state":"active","created_at":"2018-11-01T19:34:18.417Z","updated_at":"2019-02-12T16:00:22.375Z","due_date":"2019-05-22","start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/36"},{"id":693521,"iid":35,"group_id":9970,"title":"12.2","description":"","state":"active","created_at":"2018-10-30T16:48:32.567Z","updated_at":"2019-01-16T19:50:02.455Z","due_date":"2019-08-22","start_date":"2019-07-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/35"},{"id":693520,"iid":34,"group_id":9970,"title":"12.1","description":"","state":"active","created_at":"2018-10-30T16:47:58.826Z","updated_at":"2019-01-16T19:49:34.922Z","due_date":"2019-07-22","start_date":"2019-06-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/34"},{"id":693518,"iid":33,"group_id":9970,"title":"12.0","description":"","state":"active","created_at":"2018-10-30T16:47:37.975Z","updated_at":"2019-01-16T19:49:11.208Z","due_date":"2019-06-22","start_date":"2019-05-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/33"},{"id":679969,"iid":32,"group_id":9970,"title":"FY20
Q4","description":"","state":"active","created_at":"2018-10-18T10:21:37.935Z","updated_at":"2019-02-12T15:58:08.709Z","due_date":"2020-01-22","start_date":"2019-11-01","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/32"},{"id":679968,"iid":31,"group_id":9970,"title":"FY20
Q3","description":"","state":"active","created_at":"2018-10-18T10:20:59.406Z","updated_at":"2019-02-12T15:58:21.572Z","due_date":"2019-10-22","start_date":"2019-08-01","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/31"},{"id":679966,"iid":30,"group_id":9970,"title":"FY20
Q2","description":"","state":"active","created_at":"2018-10-18T10:19:56.042Z","updated_at":"2019-02-12T15:59:19.546Z","due_date":"2019-07-22","start_date":"2019-05-01","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/30"},{"id":655280,"iid":28,"group_id":9970,"title":"11.11","description":"","state":"active","created_at":"2018-09-21T19:08:37.027Z","updated_at":"2019-01-16T19:48:19.411Z","due_date":"2019-05-22","start_date":"2019-04-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/28"},{"id":655279,"iid":27,"group_id":9970,"title":"11.10","description":"","state":"active","created_at":"2018-09-21T19:08:16.261Z","updated_at":"2019-01-16T19:47:43.573Z","due_date":"2019-04-22","start_date":"2019-03-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/27"},{"id":610592,"iid":24,"group_id":9970,"title":"Awaiting
further demand","description":"Indicates that an issue has been triaged, but
is not yet on the backlog because it is awaiting further demand from customers.","state":"active","created_at":"2018-08-01T12:23:44.946Z","updated_at":"2018-08-01T12:23:44.946Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/24"},{"id":523180,"iid":18,"group_id":9970,"title":"11.9","description":"","state":"active","created_at":"2018-05-09T14:56:19.024Z","updated_at":"2019-01-16T19:47:18.008Z","due_date":"2019-03-22","start_date":"2019-02-08","web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/18"},{"id":490705,"iid":14,"group_id":9970,"title":"Backlog","description":"Issues
that we want to do but are not planned right now. Open for contribution from
the community.","state":"active","created_at":"2018-03-22T13:09:23.767Z","updated_at":"2018-10-30T14:56:54.069Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/14"},{"id":427855,"iid":11,"group_id":9970,"title":"Next
4-7 releases","description":"Bigger issues we plan to ship in the next 4-7
releases, but don''t have a designated release yet. \r\n\r\nDO NOT add small
changes, bugs, regressions to this milestone.","state":"active","created_at":"2017-12-11T16:26:55.828Z","updated_at":"2018-08-17T11:09:43.594Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/11"},{"id":427853,"iid":10,"group_id":9970,"title":"Next
3-4 releases","description":"Bigger issues we plan to ship in the next 3-4
releases, but don''t have a designated release yet. \r\n\r\nDO NOT add small
changes, bugs, regressions to this milestone.","state":"active","created_at":"2017-12-11T16:26:33.141Z","updated_at":"2018-08-17T11:10:05.065Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/10"},{"id":381642,"iid":6,"group_id":9970,"title":"Next
7-13 releases","description":"Bigger issues we plan to ship in the next 7-13
releases, but don''t have a designated release yet. \r\n\r\nDO NOT add small
changes, bugs, regressions to this milestone.","state":"active","created_at":"2017-09-26T10:12:43.523Z","updated_at":"2018-08-17T11:09:54.916Z","due_date":null,"start_date":null,"web_url":"https://gitlab.com/groups/gitlab-org/-/milestones/6"}]'
http_version:
recorded_at: Mon, 25 Mar 2019 16:00:14 GMT
recorded_with: VCR 2.9.3
# frozen_string_literal: true
require 'spec_helper'
describe ReleaseTools::Services::AutoDeployBranchService do
# Unset the `TEST` environment variable that gets set by default
def without_dry_run(&block)
ClimateControl.modify(TEST: nil) do
yield
end
end
let(:internal_client) { spy('ReleaseTools::GitlabClient') }
let(:branch_commit) { double(latest_successful: double(id: '1234')) }
subject(:service) do
VCR.use_cassette('milestones/active') do
described_class.new
end
end
before do
allow(service).to receive(:client).and_return(internal_client)
end
describe '#create_auto_deploy_branches!' do
it 'creates auto-deploy branches for gitlab-ee and gitlab-ce' do
expect(ReleaseTools::Commits).to receive(:new).and_return(branch_commit).twice
expect(internal_client).to receive(:create_branch).with(
'11-10-auto-deploy-1234-ee',
'1234',
ReleaseTools::Project::OmnibusGitlab
)
expect(internal_client).to receive(:create_branch).with(
'11-10-auto-deploy-1234-ee',
'1234',
ReleaseTools::Project::GitlabEe
)
without_dry_run do
service.create_auto_deploy_branches!
end
end
end
end