diff --git a/README.md b/README.md index cf17b6e..e204720 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,12 @@ One of the following environment variables need to be set: They must contain secrets which have to be configured in GitLab/GitHub to authenticate webhooks. +Optionally, you can also set the following variables: + +* `REDMINE_MERGE_REQUEST_LINKS_AFTER_MERGE_STATUS` - Name of issue status which should be set after the merge request is merged. +* `REDMINE_MERGE_REQUEST_LINKS_REDMINE_USER_ID` - ID of Redmine user who should change the status - used as journal author. +* `REDMINE_MERGE_REQUEST_LINKS_FIXING_KEYWORD_PATTERN` - Fixing keyword pattern. When set, the issue status is changed only when issue ID is preceeded with the fixing pattern. Example pattern: `(?:clos(?:e[sd]?|ing)|fix(?:e[sd]|ing)?|resolv(?:e[sd]?|ing))` + Export the environment variable(s) in your bash or webserver config. Examples with Phusion Passenger webserver can be found here: https://www.phusionpassenger.com/library/indepth/environment_variables.html diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index c9f95be..53cb4e7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -10,7 +10,7 @@ class MergeRequest < ActiveRecord::Base # update the author name only once. attr_readonly :author_name - after_save :scan_description_for_issue_ids + after_save :scan_description_for_issue_ids, :update_mentioned_issues_status def self.find_all_by_issue(issue) includes(:issues).where(issues: { id: issue.id }) @@ -31,4 +31,31 @@ def mentioned_issue_ids (value || '').scan(ISSUE_ID_REGEXP) end.uniq end + + def fixed_issue_ids(fixing_pattern) + fixed_issue_regexp = fixing_pattern + ISSUE_ID_REGEXP.source + [description, title].flat_map do |value| + (value || '').scan(/#{fixed_issue_regexp}/i) + end.uniq + end + + def update_mentioned_issues_status + redmine_user_id = ENV['REDMINE_MERGE_REQUEST_LINKS_REDMINE_USER_ID'] + after_merge_status = ENV['REDMINE_MERGE_REQUEST_LINKS_AFTER_MERGE_STATUS'] + fixing_pattern = ENV['REDMINE_MERGE_REQUEST_LINKS_FIXING_KEYWORD_PATTERN'] + if state != 'merged' || redmine_user_id.blank? || after_merge_status.blank? + return + end + issue_ids = fixing_pattern.present? ? fixed_issue_ids(fixing_pattern) : mentioned_issue_ids + issue_ids.map do |match| + issue = Issue.find_by_id(match[0]) + if issue.present? + issue.init_journal(User.find(redmine_user_id)) + issue.status = IssueStatus.find_by_name(after_merge_status) + unless issue.save + logger.warn("Issue ##{issue.id} could not be saved by merge request") if logger + end + end + end + end end