create_issues.rb (159 lines of code) (raw):

require 'gitlab' require 'yaml' require 'erb' require 'date' require_relative 'fiscal_date_helper' require_relative 'milestone_helper' dry_run = false today = Date.today project_id = ENV['CI_PROJECT_ID'] api_token = ENV['GITLAB_API_PRIVATE_TOKEN'] class IssueCreator def initialize(today) @today = today end def run(api_token, project_id) connect(api_token) puts 'Loading content from config/issues.yml' @issues = YAML.load(ERB.new(File.read('config/issues.yml')).result) puts 'Content loaded successfully.' puts 'Walking issues to create...' @issues['issues'].each do |issue| if issue['day_of_month'] ## Using Day of Month Value today_date = @today.strftime('%-d') if today_date == issue['day_of_month'].to_s puts '* ' << issue['name'] << ' should be created on the ' << issue['day_of_month'].to_s << ' day of the month.' puts '** Today is the ' << today_date create(issue['name'], issue['template'], issue['scope'], "Monthly", project_id) end end if issue['day_of_week'] ## Using Day of week value today_day = @today.strftime('%a') if today_day == issue['day_of_week'].to_s puts '* ' << issue['name'] << ' should be created every ' << issue['day_of_week'].to_s << '.' puts '** Today is ' << today_day create(issue['name'], issue['template'], issue['scope'], 'Weekly', project_id) end end if issue['quarterly'] ## Using Quarterly fiscal_quarter_start = %w[02 05 08 11] fiscal_quarter_end = %w[04 07 10 01] month = @today.strftime('%m') today_date = @today.strftime('%d') # First Day of Quarter if issue['quarterly'] == 'first_day_of_quarter' && today_date == '01' && (fiscal_quarter_start.include? month) create(issue['name'], issue['template'], issue['scope'], 'Quarterly', project_id) end # Last Day of Quarter if issue['quarterly'] == 'last_day_of_quarter' && today_date == '28' && (fiscal_quarter_end.include? month) create(issue['name'], issue['template'], issue['scope'], 'Quarterly', project_id) end # First Day of Last Month of Quarter if issue['quarterly'] == 'first_day_of_last_month_of_quarter' && today_date == '01' && (fiscal_quarter_end.include? month) create(issue['name'], issue['template'], issue['scope'], 'Quarterly', project_id) end end if issue['day_of_year'] ## Using Yearly days = Array(issue['day_of_year']) if days.include? @today.yday create(issue['name'], issue['template'], issue['scope'], issue['frequency'] || 'Yearly', project_id) end end end puts 'Run Complete.' end def connect(api_token) puts 'Connecting to GitLab...' @gitlab = Gitlab.client( endpoint: 'https://gitlab.com/api/v4', private_token: api_token ) @user = @gitlab.user puts 'Connection successful. Connected user email: ' << @user.email end def upcoming_milestone @upcoming_milestone ||= MilestoneHelper.upcoming_milestone @upcoming_milestone end def previous_milestone @previous_milestone ||= MilestoneHelper.previous_milestone @previous_milestone end # replace keywords MILESTONE and PREVIOUS_MILESTONE in a string for a numeric value def replace_milestone(text = "") text = text.gsub('<MILESTONE>', upcoming_milestone) text = text.gsub('<PREVIOUS_MILESTONE>', previous_milestone) text end def create(name, template_name, scope, frequency, project_id) frequency_text = '' case frequency when 'Monthly' frequency_text = Date::MONTHNAMES[@today.month] when 'Weekly' frequency_text = 'Week ' + @today.cweek.to_s when 'Quarterly' frequency_text = 'Quarterly' when 'Yearly' frequency_text = 'Yearly' when 'Biannually' frequency_text = 'Biannually' end if scope == 'all' ## implies we don't need to use an ERB template just regular issue templates template = File.open('.gitlab/issue_templates/' << template_name).read puts '** Template loaded...' description = ERB.new(template, 0, '>').result(binding) puts '** Description generated...' description = replace_milestone(description) issue_title = replace_milestone(name) puts '** Milestone keywords replaced...' @gitlab.create_issue(project_id, issue_title + ' : ' + frequency_text, { description: description, assignee_id: @user.id }) puts '** ' << issue_title << ' issue created.' end end end # Mock GitLab user and service class UserMock def initialize @email = 'mockuser@gitlab.com' @id = 1234 end attr_accessor :email, :id end class GitLabMock def initialize @user = UserMock.new() end def create_issue(project, title, options) puts 'Would have created issue:' puts ' Project: ' + project puts ' Title: ' + title puts ' Content: \n' + options[:description] + '\n\n' end attr_accessor :user end # Override issue creator to use GitLab mock class IssueCreatorTest < IssueCreator def connect(api_token) puts 'Connecting to GitLab...' @gitlab = GitLabMock.new() @user = @gitlab.user puts 'Connection successful. Connected user email: ' << @user.email end end if $PROGRAM_NAME == __FILE__ # Override with mock if we are doing a dry run ARGV.each do |arg| if arg == '--dry-run' dry_run = true api_token = 'mocktoken' project_id = 'mockproject' (1..12).each do |m| # Simulate every month of the year (1..28).each do |d| # Simulate every day of the month # No day_of_month in issues.yml are after the 28th which makes it simple # to not trigger an invalid date here in this dry-run test. today = Date::strptime(d.to_s + '-' + m.to_s + '-2020', '%d-%m-%Y') if today issue_creator = IssueCreatorTest.new(today) issue_creator.run(api_token, project_id) end end end end end unless dry_run issue_creator = IssueCreator.new(today) issue_creator.run(api_token, project_id) end end