• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sue445 / gitlab_mr_release / #2105

09 Sep 2025 02:23PM UTC coverage: 40.351% (-43.0%) from 83.333%
#2105

push

web-flow
Add cooldown setting for Dependabot updates

46 of 114 relevant lines covered (40.35%)

0.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.59
/lib/gitlab_mr_release/cli.rb
1
require "gitlab_mr_release"
1✔
2
require "thor"
1✔
3
require "dotenv"
1✔
4

5
module GitlabMrRelease
1✔
6
  class CLI < Thor
1✔
7
    include Thor::Actions
1✔
8

9
    GITLAB_ENV_FILES = %w(.env.gitlab ~/.env.gitlab)
1✔
10

11
    DEFAULT_TITLE_TEMPLATE = "Release <%= Time.now %> <%= source_branch %> -> <%= target_branch %>"
1✔
12

13
    def self.source_root
1✔
14
      "#{__dir__}/../templates"
×
15
    end
16

17
    desc "version", "Show gitlab_mr_release version"
1✔
18
    def version
1✔
19
      puts GitlabMrRelease::VERSION
×
20
    end
21

22
    desc "init", "Copy setting files to current directory"
1✔
23
    def init
1✔
24
      copy_file ".env.gitlab", ".env.gitlab"
×
25
      copy_file "gitlab_mr_release.md.erb", "gitlab_mr_release.md.erb"
×
26
    end
27

28
    desc "create", "Create merge requrst"
1✔
29
    option :source, aliases: "-s", desc: "Source branch (e.g. develop)"
1✔
30
    option :target, aliases: "-t", desc: "Target branch (e.g. master)"
1✔
31
    option :title,  desc: "MergeRequest title (default. 'Release :timestamp :source -> :target')"
1✔
32
    option :labels, aliases: "-l", desc: "Labels for MR as a comma-separated list  (e.g. 'label1,label2')"
1✔
33
    def create
1✔
34
      Dotenv.load(*GITLAB_ENV_FILES)
×
35

36
      assert_env("GITLAB_API_ENDPOINT")
×
37
      assert_env("GITLAB_API_PRIVATE_TOKEN")
×
38
      assert_env("GITLAB_PROJECT_NAME")
×
39

40
      assert_option_or_env(:source, "DEFAULT_SOURCE_BRANCH")
×
41
      assert_option_or_env(:target, "DEFAULT_TARGET_BRANCH")
×
42

43
      template = File.read(template_file)
×
44

45
      project = GitlabMrRelease::Project.new(
×
46
        api_endpoint:  ENV["GITLAB_API_ENDPOINT"],
47
        private_token: ENV["GITLAB_API_PRIVATE_TOKEN"],
48
        project_name:  ENV["GITLAB_PROJECT_NAME"],
49
      )
50

51
      unless project.api_version >= 4
×
52
        raise InvalidApiVersionError, "'#{ENV["GITLAB_API_ENDPOINT"]}' seems not to be GitLab API v4+. gitlab_mr_release requires GitLab API v4+"
×
53
      end
54

55
      mr = project.create_merge_request(
×
56
        source_branch: source_branch,
57
        target_branch: target_branch,
58
        labels:        labels,
59
        title:         generate_title,
60
        template:      template,
61
      )
62

63
      mr_url = "#{project.web_url}/merge_requests/#{mr.iid}"
×
64

65
      message = <<-EOS
×
66
MergeRequest is created
67

68
[Title] #{mr.title}
69

70
[Description]
71
#{mr.description}
72

73
[Url] #{mr_url}
74
      EOS
75

76
      puts message
×
77
    end
78

79
    private
1✔
80

81
    no_commands do
1✔
82
      def assert_env(name)
1✔
83
        if !ENV[name] || ENV[name].empty?
×
84
          puts "Error: Environment variable #{name} is required"
×
85
          exit!
×
86
        end
87
      end
88

89
      def assert_option_or_env(option_name, env_name)
1✔
90
        option_or_env!(option_name, env_name)
×
91
      end
92

93
      def generate_title
1✔
94
        return options[:title] if options[:title]
×
95

96
        generate_default_title(
×
97
          title_template: ENV["DEFAULT_TITLE"],
98
          source_branch:  source_branch,
99
          target_branch:  target_branch,
100
          )
101
      end
102

103
      def generate_default_title(title_template:, source_branch:, target_branch:)
1✔
104
        title_template ||= DEFAULT_TITLE_TEMPLATE
×
105
        ERB.new(title_template).result(binding).strip
×
106
      end
107

108
      def template_file
1✔
109
        ENV["TEMPLATE_FILE"] || "#{__dir__}/../templates/gitlab_mr_release.md.erb"
×
110
      end
111

112
      def source_branch
1✔
113
        option_or_env(:source, "DEFAULT_SOURCE_BRANCH")
×
114
      end
115

116
      def target_branch
1✔
117
        option_or_env(:target, "DEFAULT_TARGET_BRANCH")
×
118
      end
119

120
      def labels
1✔
121
        option_or_env(:labels, "DEFAULT_LABELS")
×
122
      end
123

124
      def option_or_env(option_name, env_name, default = nil)
1✔
125
        return options[option_name] if options[option_name] && !options[option_name].empty?
×
126
        return ENV[env_name] if ENV[env_name] && !ENV[env_name].empty?
×
127
        default
×
128
      end
129

130
      def option_or_env!(option_name, env_name)
1✔
131
        value = option_or_env(option_name, env_name)
×
132
        return value if value
×
133

134
        puts "Error: --#{option_name} or #{env_name} is either required!"
×
135
        exit!
×
136
      end
137
    end
138
  end
139
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc