Our rake file for automating release notes.
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