Loading .gitlab-ci.yml +7 −0 Original line number Diff line number Diff line Loading @@ -23,3 +23,10 @@ deploy: - tools/deploy-rubygem.sh only: - tags release: stage: deploy script: - tools/update-changelog.rb "${CI_COMMIT_TAG}" only: - tags tools/update-changelog.rb 0 → 100755 +108 −0 Original line number Diff line number Diff line #!/usr/bin/env ruby require "uri" require "net/http" require "openssl" require "json" require "optparse" GitlabError = Class.new(StandardError) GitlabClientError = Class.new(GitlabError) def gitlab_client(path, method, body = nil) url = URI("https://gitlab.com#{path}") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = case method when :get Net::HTTP::Get.new(url) when :post Net::HTTP::Post.new(url) when :put Net::HTTP::Put.new(url) else raise "Unknown method: #{method}" end request["content-type"] = "application/json" request["PRIVATE-TOKEN"] = ENV["GITLAB_TOKEN"] request.body = JSON.dump(body) if body response = http.request(request) case response when Net::HTTPSuccess JSON.parse(response.read_body) when Net::HTTPClientError raise GitlabClientError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}" else raise GitLabError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}" end end def list_commits_for_tag(tag) commits = %x[git rev-list --no-merges $(git describe --tags --abbrev=0 #{tag}^)..#{tag}].lines commits.map(&:chomp) end def get_mrs_for_commit(commit_id) gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/repository/commits/#{commit_id}/merge_requests", :get) end def create_release_for_tag(tag, description) req_body = { tag_name: tag, description: description } gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/releases", :post, req_body) end def update_release_for_tag(tag, description) req_body = { description: description } gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/releases/#{tag}", :put, req_body) end def get_unique_mrs_for_tag(tag) commit_ids = list_commits_for_tag(tag) dup_mrs = commit_ids.map { |commit_id| get_mrs_for_commit(commit_id) }.flatten uniq_mrs = dup_mrs.uniq { |mr| mr["iid"] } uniq_mrs.sort { |mr| mr["iid"] }.reverse end options = {} OptionParser.new do |opts| opts.banner = "Usage: update-changelog.rb [options] tag" opts.on("-d", "--[no-]dry-run", "Display only. Do not update release notes.") do |d| options[:dry_run] = d end end.parse! # Check required conditions unless ARGV.length == 1 puts optparse exit(-1) end tag = ARGV.first changelog = get_unique_mrs_for_tag(tag).map { |mr| "* #{mr["web_url"]}: #{mr["title"]}" }.join("\n") if changelog.empty? raise "No new changes found" end changelog = "## Changes in #{tag}\n\n" + changelog if options[:dry_run] puts changelog exit end begin create_release_for_tag(tag, changelog) puts "Created release: https://gitlab.com/gitlab-org/labkit-ruby/-/releases##{tag}" rescue GitlabClientError update_release_for_tag(tag, changelog) puts "Updated release: https://gitlab.com/gitlab-org/labkit-ruby/-/releases##{tag}" end Loading
.gitlab-ci.yml +7 −0 Original line number Diff line number Diff line Loading @@ -23,3 +23,10 @@ deploy: - tools/deploy-rubygem.sh only: - tags release: stage: deploy script: - tools/update-changelog.rb "${CI_COMMIT_TAG}" only: - tags
tools/update-changelog.rb 0 → 100755 +108 −0 Original line number Diff line number Diff line #!/usr/bin/env ruby require "uri" require "net/http" require "openssl" require "json" require "optparse" GitlabError = Class.new(StandardError) GitlabClientError = Class.new(GitlabError) def gitlab_client(path, method, body = nil) url = URI("https://gitlab.com#{path}") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = case method when :get Net::HTTP::Get.new(url) when :post Net::HTTP::Post.new(url) when :put Net::HTTP::Put.new(url) else raise "Unknown method: #{method}" end request["content-type"] = "application/json" request["PRIVATE-TOKEN"] = ENV["GITLAB_TOKEN"] request.body = JSON.dump(body) if body response = http.request(request) case response when Net::HTTPSuccess JSON.parse(response.read_body) when Net::HTTPClientError raise GitlabClientError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}" else raise GitLabError, "HTTP #{response.code} for #{method} #{url}: #{response.read_body}" end end def list_commits_for_tag(tag) commits = %x[git rev-list --no-merges $(git describe --tags --abbrev=0 #{tag}^)..#{tag}].lines commits.map(&:chomp) end def get_mrs_for_commit(commit_id) gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/repository/commits/#{commit_id}/merge_requests", :get) end def create_release_for_tag(tag, description) req_body = { tag_name: tag, description: description } gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/releases", :post, req_body) end def update_release_for_tag(tag, description) req_body = { description: description } gitlab_client("/api/v4/projects/gitlab-org%2flabkit-ruby/releases/#{tag}", :put, req_body) end def get_unique_mrs_for_tag(tag) commit_ids = list_commits_for_tag(tag) dup_mrs = commit_ids.map { |commit_id| get_mrs_for_commit(commit_id) }.flatten uniq_mrs = dup_mrs.uniq { |mr| mr["iid"] } uniq_mrs.sort { |mr| mr["iid"] }.reverse end options = {} OptionParser.new do |opts| opts.banner = "Usage: update-changelog.rb [options] tag" opts.on("-d", "--[no-]dry-run", "Display only. Do not update release notes.") do |d| options[:dry_run] = d end end.parse! # Check required conditions unless ARGV.length == 1 puts optparse exit(-1) end tag = ARGV.first changelog = get_unique_mrs_for_tag(tag).map { |mr| "* #{mr["web_url"]}: #{mr["title"]}" }.join("\n") if changelog.empty? raise "No new changes found" end changelog = "## Changes in #{tag}\n\n" + changelog if options[:dry_run] puts changelog exit end begin create_release_for_tag(tag, changelog) puts "Created release: https://gitlab.com/gitlab-org/labkit-ruby/-/releases##{tag}" rescue GitlabClientError update_release_for_tag(tag, changelog) puts "Updated release: https://gitlab.com/gitlab-org/labkit-ruby/-/releases##{tag}" end