class Shipit::Cli::Work
Attributes
Public Class Methods
@param issue_id
[Integer] The issue GitLab IID @param target_branch [String] “master”, “develop”… @param global_options
[Hash] A hash of options
- dry_run : If true will not perform the commands - client : an instance of the GitLab client
# File lib/shipit/cli/work.rb, line 13 def initialize(issue_id, global_options) @issue_id = issue_id @global_options = global_options @client = global_options.fetch(:client) end
Public Instance Methods
@return [Boolean]
# File lib/shipit/cli/work.rb, line 43 def dry_run? global_options["dry_run"] == true end
-
Get issue : docs.gitlab.com/ee/api/issues.html#single-issue
-
Validate issue properties
-
Create branch : docs.gitlab.com/ee/api/branches.html#create-repository-branch
-
First commit : docs.gitlab.com/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions
-
New merge request : docs.gitlab.com/ee/api/merge_requests.html#create-mr
# File lib/shipit/cli/work.rb, line 24 def perform(target_branch) # 1. Load issue issue = fetch_remote_issue(issue_id).to_hash # 2. Validate issue validate_issue(issue) # 3. Add additional issue attributes enhanced_issue = enhance_issue(issue, target_branch) # 4. Create remote branch & checkout create_source_branch(enhanced_issue) # 5. Create merge request create_merge_request(enhanced_issue) # 6. Motivation! puts "" Shipit::Cli.ascii rescue => e exit_now! e end
Private Instance Methods
# File lib/shipit/cli/work.rb, line 65 def create_merge_request(issue) return if dry_run? opts = issue.slice("source_branch", "target_branch", "assignee_id", "labels", "milestone_id", "remove_source_branch") client.create_merge_request(project_path, issue["merge_request_title"], opts) rescue Gitlab::Error => e exit_now! "There was a problem creating your merge request on the GitLab server. Please do it manually.\nError : #{e.message}" end
# File lib/shipit/cli/work.rb, line 56 def create_source_branch(issue) commands = Shipit::Cli::Git.run(command: :new, branch: issue["source_branch"], message: issue["first_commit_message"], target_branch: issue["target_branch"], dry_run: global_options["dry_run"]) raise "There was an error creating your working branch.\nPROTIP: Review the previous trace and fix the errors before retrying." if !dry_run? && commands.any? { |c| c == false } end
Branch names are constructed like so : {label}-{assignee initials}-{issue id}-{issue title}
@return [String]
# File lib/shipit/cli/work.rb, line 113 def define_source_branch_name [first_label, assignee_initials, @id, issue_title].compact.join("-") end
# File lib/shipit/cli/work.rb, line 85 def enhance_issue(issue, target_branch) # 1. Build properties issue_id = issue["iid"] labels = issue["labels"].join(", ") assignee = issue["assignees"].first sane_title = issue["title"].gsub(/[^0-9A-Za-z ,.]/, '').strip assignee_initials = assignee["name"].split.map(&:first).join.downcase.gsub(/[^a-z]/, '').strip assignee_id = assignee["id"] issue_title = sane_title.parameterize[0..20] first_commit_message = "[#{labels}] Fixes ##{issue_id} - #{sane_title}" mr_title = "[WIP] [#{labels}] ##{issue_id} - #{sane_title}" # 2. Add to issue properties issue["source_branch"] = [issue["labels"].first.gsub(/\s+/, ""), assignee_initials, issue_id, issue_title].compact.join("-") issue["first_commit_message"] = first_commit_message issue["target_branch"] = target_branch issue["merge_request_title"] = mr_title issue["assignee_id"] = assignee_id issue["milestone_id"] = issue["milestone"]["id"] issue["remove_source_branch"] = true issue["labels"] = labels issue end
@param id [Integer] The issue IID to fetch from GitLab
# File lib/shipit/cli/work.rb, line 50 def fetch_remote_issue(id) client.issue(project_path, id) rescue Gitlab::Error::NotFound => e exit_now! "Issue #{id} not found for project #{project_name} on the remote GitLab server." end
@return [String]
# File lib/shipit/cli/work.rb, line 118 def project_git_url @project_git_url ||= `git config --local remote.origin.url`.chomp end
@return [String]
# File lib/shipit/cli/work.rb, line 123 def project_name @project_name ||= project_git_url.split("/").last.gsub(".git", "") end
@return [String]
# File lib/shipit/cli/work.rb, line 128 def project_namespace @project_namespace ||= project_git_url.split(":").last.split("/").first end
@return [String]
# File lib/shipit/cli/work.rb, line 133 def project_path @project_path ||= [project_namespace, project_name].join("/") end
@param issue [Hash] A hash of properties @return true if issue if valid
# File lib/shipit/cli/work.rb, line 77 def validate_issue(issue) errors = [] errors << "Assignee missing" if issue["assignees"].empty? # returns an array of assignees (Array of hash) errors << "Milestone missing" if issue["milestone"].to_s.empty? # returns a hash with the milestone properties errors << "Labels missing" if issue["labels"].empty? # returns an array of strings exit_now!("Invalid remote GitLab issue. Please fix the following warnings : #{errors.join(", ")}") if errors.any? end