Our rake file for automating release notes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'youtrack' | |
require 'ostruct' | |
module Build | |
class YouTrack | |
class View | |
attr_reader :issues, :by_department, :by_relevance | |
def initialize(issues) | |
@issues = issues | |
@by_department = department(issues) | |
@by_relevance = relevance(issues) | |
end | |
private | |
def department(issues) | |
create_view(issues, proc { |issue| issue.departments }) | |
end | |
def relevance(issues) | |
create_view(issues, proc { |issue| issue.relevant_to }) | |
end | |
def create_view(issues, group_by) | |
view = issues.inject({}) do |memo, issue| | |
group_by.call(issue).each do |rel| | |
previous_value = memo.fetch(rel, []) | |
new_value = previous_value << issue | |
memo[rel] = new_value.sort_by(&:issue_id) | |
end | |
memo | |
end | |
Hash[view.sort] | |
end | |
end | |
class << self | |
NOT_FOUND = proc { { 'value' => nil } } | |
def fixed_issues(from, to) | |
resource = client.issues | |
maybe_patch_unreleased_methods(resource) | |
query = query(from, to) | |
puts "Getting issue list from YouTrack using query: #{query}" | |
issues = resource.list(filter: query, max: 1000) | |
issues = force_list(issues) | |
transformed = transform(issues) | |
View.new(transformed) | |
end | |
private | |
def client | |
@client ||= Youtrack::Client.new do |c| | |
c.url = 'your-url' | |
c.login = 'your-user' | |
c.password = 'your-pw' | |
c.connect! | |
end | |
end | |
def maybe_patch_unreleased_methods(issues) | |
return if issues.respond_to?(:list) | |
warn 'Patching #list method' | |
# Get a list of issues for a search query. | |
# | |
# attributes | |
# filter string A query to search for issues. | |
# with string List of fields that should be included in the result. | |
# max integer Maximum number of issues to get. If not provided, only 10 issues will be returned by default. | |
# after integer A number of issues to skip before getting a list of issues. | |
# | |
def issues.list(attributes = {}) | |
attributes[:max] ||= 10 | |
get("issue?#{URI.encode_www_form(attributes)}") | |
end | |
end | |
def query(from, to) | |
"project: HECO_comWORK Fixed in build: #{from} .. #{to} Department: -KEINE #{excluded_subsystems}" | |
end | |
def excluded_subsystems | |
spec = ENV['RELEASE_NOTES_EXCLUDE_SUBSYSTEMS'] | |
return unless spec | |
spec = spec.split(',') | |
return if spec.empty? | |
"Subsystem: #{spec.map { |s| "-{#{s}}" }.join(' ')}" | |
end | |
def force_list(issues) | |
issues = issues.to_hash['issueCompacts']['issue'] rescue [] | |
([] << issues).flatten(1) | |
end | |
def transform(issues) | |
issues.map do |x| | |
field = x['field'] | |
project = field.find { |f| f['name'] == 'projectShortName' }['value'] | |
number = field.find { |f| f['name'] == 'numberInProject' }['value'] | |
issue_id = "#{project}-#{number}" | |
subsystem = subsystem(field) | |
summary = field.find { |f| f['name'] == 'summary' }['value'] | |
info = field.find(NOT_FOUND) { |f| f['name'] == 'Release Infotext' }['value'] | |
departments = arrayify(field, 'Department') | |
relevant_to = arrayify(field, 'Relevant to') | |
OpenStruct.new(issue_id: issue_id, | |
subsystem: subsystem, | |
summary: summary, | |
info: info, | |
departments: departments, | |
relevant_to: relevant_to) | |
end | |
end | |
def subsystem(field) | |
value = field.find { |f| f['name'] == 'Subsystem' }['value'] | |
return nil if value == 'No Subsystem' | |
value | |
end | |
def arrayify(field, key) | |
value = field.find(NOT_FOUND) { |f| f['name'] == key }['value'] | |
return [] if value.nil? | |
([value]).flatten.sort | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment