retag 0.1.1 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91558c109a6f2bf1cc988a0bf375404ca035c229d0abd031fd52cbe084cc1d23
4
- data.tar.gz: be5c10c2e9d85588f412b81c92fb22dfcac5117360e47c9bd20eb02d8219f992
3
+ metadata.gz: c3eecc35217225b65ef71c75cc8cf5c5ee199291eadcc61b97a58b4899ab4ae3
4
+ data.tar.gz: 372810234ee2c03c9829ff86e11ee2b8942831d1fbc18c0ab9e19e34bd5985c3
5
5
  SHA512:
6
- metadata.gz: 3093e65db866569cc3a28ffc09ce9b97241d6fb7c3e4793ff880e24a521b83bc4861ee172a27ef8d7e99d71c639da30fbbff7614574712bc5804525f48d5bd68
7
- data.tar.gz: 7381e35cc1934e8a78e9a4514a8f6dd3863e3744c5f516c083ccd88255dbe2b25b4eba111f69430fc1b91d8d80e98923d19c3cb298379404f7f268555efd3419
6
+ metadata.gz: 3bd613b85fee317a71a86fa8fff244826e06ca3d02be87e5ac3297ad418c569e895a9ba6e09349e121b749ca7e4f44b00c245b684867f3f8a8925071f8f36a97
7
+ data.tar.gz: c12042f6c60820062ab9761ab749ebe904ad843af76f1ef06a9666e9b0c851b436499ca8f3ad787a6961546a022a74c5cd06717eb0012296f9320b906cc42bb9
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in retag.gemspec
6
+ gemspec
7
+
8
+ # gem "rake", "~> 13.0"
9
+
10
+ # gem "rspec", "~> 3.0"
11
+
12
+ # gem "rubocop", "~> 1.21"
13
+
data/Gemfile.lock ADDED
@@ -0,0 +1,121 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ retag (0.1.4)
5
+ activesupport (~> 6.0)
6
+ colorize
7
+ gitlab
8
+ json
9
+ thor
10
+ uri
11
+ yaml
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ activesupport (6.1.4.4)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
22
+ addressable (2.8.0)
23
+ public_suffix (>= 2.0.2, < 5.0)
24
+ ansi (1.5.0)
25
+ ast (2.4.2)
26
+ colorize (0.8.1)
27
+ concurrent-ruby (1.1.9)
28
+ crack (0.4.5)
29
+ rexml
30
+ diff-lcs (1.5.0)
31
+ docile (1.4.0)
32
+ gitlab (4.18.0)
33
+ httparty (~> 0.18)
34
+ terminal-table (>= 1.5.1)
35
+ hashdiff (1.0.1)
36
+ httparty (0.20.0)
37
+ mime-types (~> 3.0)
38
+ multi_xml (>= 0.5.2)
39
+ i18n (1.8.11)
40
+ concurrent-ruby (~> 1.0)
41
+ json (2.6.1)
42
+ mime-types (3.4.1)
43
+ mime-types-data (~> 3.2015)
44
+ mime-types-data (3.2022.0105)
45
+ minitest (5.15.0)
46
+ multi_xml (0.6.0)
47
+ parallel (1.21.0)
48
+ parser (3.1.0.0)
49
+ ast (~> 2.4.1)
50
+ public_suffix (4.0.6)
51
+ rainbow (3.1.1)
52
+ rake (13.0.6)
53
+ regexp_parser (2.2.0)
54
+ rexml (3.2.5)
55
+ rspec (3.10.0)
56
+ rspec-core (~> 3.10.0)
57
+ rspec-expectations (~> 3.10.0)
58
+ rspec-mocks (~> 3.10.0)
59
+ rspec-core (3.10.1)
60
+ rspec-support (~> 3.10.0)
61
+ rspec-expectations (3.10.2)
62
+ diff-lcs (>= 1.2.0, < 2.0)
63
+ rspec-support (~> 3.10.0)
64
+ rspec-mocks (3.10.2)
65
+ diff-lcs (>= 1.2.0, < 2.0)
66
+ rspec-support (~> 3.10.0)
67
+ rspec-support (3.10.3)
68
+ rspec_junit_formatter (0.5.1)
69
+ rspec-core (>= 2, < 4, != 2.12.0)
70
+ rubocop (1.25.0)
71
+ parallel (~> 1.10)
72
+ parser (>= 3.1.0.0)
73
+ rainbow (>= 2.2.2, < 4.0)
74
+ regexp_parser (>= 1.8, < 3.0)
75
+ rexml
76
+ rubocop-ast (>= 1.15.1, < 2.0)
77
+ ruby-progressbar (~> 1.7)
78
+ unicode-display_width (>= 1.4.0, < 3.0)
79
+ rubocop-ast (1.15.1)
80
+ parser (>= 3.0.1.1)
81
+ ruby-progressbar (1.11.0)
82
+ simplecov (0.21.2)
83
+ docile (~> 1.1)
84
+ simplecov-html (~> 0.11)
85
+ simplecov_json_formatter (~> 0.1)
86
+ simplecov-console (0.9.1)
87
+ ansi
88
+ simplecov
89
+ terminal-table
90
+ simplecov-html (0.12.3)
91
+ simplecov_json_formatter (0.1.3)
92
+ terminal-table (3.0.2)
93
+ unicode-display_width (>= 1.1.1, < 3)
94
+ thor (1.2.1)
95
+ tzinfo (2.0.4)
96
+ concurrent-ruby (~> 1.0)
97
+ unicode-display_width (2.1.0)
98
+ uri (0.11.0)
99
+ webmock (3.14.0)
100
+ addressable (>= 2.8.0)
101
+ crack (>= 0.3.2)
102
+ hashdiff (>= 0.4.0, < 2.0.0)
103
+ yaml (0.2.0)
104
+ zeitwerk (2.5.3)
105
+
106
+ PLATFORMS
107
+ x86_64-linux
108
+
109
+ DEPENDENCIES
110
+ bundler (~> 2.2, >= 2.2.1)
111
+ rake
112
+ retag!
113
+ rspec
114
+ rspec_junit_formatter
115
+ rubocop
116
+ simplecov
117
+ simplecov-console
118
+ webmock
119
+
120
+ BUNDLED WITH
121
+ 2.2.33
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'retag'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
16
+
data/bin/retag ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+ require 'thor'
5
+ require 'colorize'
6
+ require 'retag'
7
+
8
+ ENV_PREFIX = 'RETAG'
9
+
10
+ $logger = ActiveSupport::TaggedLogging.new(Retag::Logger.new(STDOUT))
11
+ $logger.level = :info
12
+
13
+
14
+
15
+ class RepoCommand < Thor
16
+ desc "tag <project> <tag>", "Create tag in Gitlab project"
17
+ long_desc <<-LONGDESC
18
+ LONGDESC
19
+ option :force, default: false,
20
+ required: false,
21
+ type: :boolean,
22
+ desc: "Override Gitlab tag if exists"
23
+
24
+ option :ref, default: ENV.fetch("#{ENV_PREFIX}_TAG_REF", 'master'),
25
+ required: true,
26
+ type: :string,
27
+ desc: "Gtilab refspec from which create tag"
28
+
29
+ option :message, default: nil,
30
+ type: :string,
31
+ desc: "Tag message"
32
+
33
+ def tag(project, tag)
34
+ opts = options.to_h.dup
35
+ $logger.level = :debug if opts['verbose']
36
+
37
+ begin
38
+ Gitlab.client.delete_tag(project, tag).inspect
39
+ rescue Gitlab::Error::NotFound
40
+ # Success: there is no such tag
41
+ end if opts['force']
42
+
43
+ puts Gitlab.client.create_tag(project, tag, options['ref'], options['message']).inspect
44
+ end
45
+ end
46
+
47
+ class DockerCommand < Thor
48
+ desc "tag", "Tag Docker image without downloading"
49
+ long_desc <<-LONGDESC
50
+ LONGDESC
51
+ option :image, default: ENV.fetch("#{ENV_PREFIX}_TAG_IMAGE", nil),
52
+ required: true,
53
+ desc: "Env: #{ENV_PREFIX}_TAG_IMAGE. Full image to be tagged. Ex: docker.rnds.pro/aggredator/service-uprid3:latest"
54
+
55
+ option :tag, default: ENV.fetch("#{ENV_PREFIX}_TAG_TAG", nil),
56
+ required: true,
57
+ desc: "Env: #{ENV_PREFIX}_TAG_TAG. New tag"
58
+
59
+ option :suffix, default: ENV.fetch("#{ENV_PREFIX}_TAG_SUFFIX", nil),
60
+ required: false,
61
+ desc: "Env: #{ENV_PREFIX}_TAG_SUFFIX. Optional suffix added to image tag: <image>:<tag>[-<suffix>].
62
+ Example:
63
+ # retag tag --image=registry/image:0a4bfc5 --tag v1.2.3 --suffix stable is equivalent to
64
+ docker tag registry/image:0a4bfc5-stable registry/image:v1.2.3
65
+ "
66
+
67
+ def tag(*_args)
68
+ opts = options.to_h.dup
69
+ $logger.level = :debug if opts['verbose']
70
+
71
+ img, tag = opts['image'].split(':')
72
+ tag ||= 'latest'
73
+ tag = opts['suffix'].present? ? "#{tag}-#{opts['suffix']}" : tag
74
+
75
+ image = ::Retag::Image.new(img, tag)
76
+ image.retag!(opts['tag'])
77
+ end
78
+
79
+ end
80
+
81
+ class ReleaseCommand < Thor
82
+ default_command :release
83
+
84
+ desc "release", "Release projects bundler from release.yml manifest"
85
+ long_desc <<-LONGDESC
86
+ LONGDESC
87
+ option :config, default: ENV.fetch("#{ENV_PREFIX}_RELEASE_CONFIG", './release.yml'),
88
+ required: true,
89
+ desc: "Env: #{ENV_PREFIX}_RELEASE_CONFIG. Path to release manifest"
90
+
91
+ option :name, default: ENV.fetch("#{ENV_PREFIX}_RELEASE_NAME", nil),
92
+ required: false,
93
+ desc: "Env: #{ENV_PREFIX}_RELEASE_NAME. Name of the current release"
94
+
95
+ def release(*_args)
96
+ opts = options.to_h.dup
97
+ $logger.level = :debug if opts['verbose']
98
+
99
+ config = YAML.load_file(File.expand_path(opts['config']))
100
+ config['release'] = opts['name'] || config['release']
101
+
102
+ release = config['release'].to_s
103
+ suffix = config['suffix']
104
+ branch = config['branch']
105
+
106
+ services = config['services'].map do|(name, cfg)|
107
+ Retag::Service.new(name, cfg, release, suffix: cfg.fetch('suffix', suffix), branch: cfg.fetch('branch', branch)) unless name.start_with?('.')
108
+ end.compact
109
+
110
+ tag_message = "Release #{release} at #{DateTime.now.iso8601}"
111
+
112
+ $logger.info "*** Starting '#{tag_message.colorize(mode: :bold)}'...".colorize(:cyan)
113
+
114
+ services.each do |srv|
115
+ $logger.tagged(srv.name.colorize(:yellow), "#{srv.revision.colorize(mode: :bold)}@#{srv.branch}") do
116
+ $logger.info "#{'==>'.colorize(mode: :bold, color: :white)} Releasing service #{srv.name.colorize(mode: :bold)} from #{srv.repo.repo} at #{srv.branch.colorize(mode: :bold)}:".colorize(:green)
117
+ $logger.shift do
118
+ srv.images.each do |img|
119
+ $logger.info ">>> Image #{img.image}"
120
+
121
+ $logger.shift do
122
+ $logger.info "From ".ljust(5) + "[#{img.tag.colorize(:yellow)}]: ".ljust(35) + img.full
123
+ newimg = img.retag!(release)
124
+ $logger.info "To ".ljust(5) + "[#{newimg.tag.colorize(:yellow)}]: ".ljust(35) + newimg.full
125
+ end
126
+
127
+ $logger.info ">>> Repo #{srv.repo.repo}"
128
+
129
+ $logger.shift do
130
+ $logger.info "From ".ljust(5) + "[#{srv.revision.colorize(:yellow)}]: ".ljust(35) + "#{srv.repo.repo}~#{srv.revision}@#{srv.branch}"
131
+ newimg = img.retag!(release)
132
+ $logger.info "To ".ljust(5) + "[#{release.colorize(:yellow)}]: ".ljust(35) + "#{srv.repo.repo}~#{srv.revision}@#{release}"
133
+ end
134
+
135
+ srv.repo.tag!(release, message: tag_message)
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ $logger.info "*** Completed '#{tag_message.colorize(mode: :bold)}'".colorize(:cyan)
142
+
143
+ end
144
+
145
+ end
146
+
147
+
148
+ class Cli < Thor
149
+
150
+ def self.exit_on_failure?
151
+ true
152
+ end
153
+
154
+ package_name "Retag is cli to manipulate docker images in handy way.
155
+
156
+ # Gitlab authorization
157
+ Using GITLAB_API_ENDPOINT and GITLAB_API_PRIVATE_TOKEN environment variable used for authorization
158
+
159
+ #{File.basename(__FILE__)}"
160
+
161
+ class_option :verbose, type: :boolean
162
+
163
+ desc 'version', 'Display version'
164
+ map %w[-v --version] => :version
165
+
166
+ def version
167
+ say Retag::VERSION
168
+ end
169
+
170
+ desc "repo SUBCOMMAND ...ARGS", "Manage git repository stuffs"
171
+ subcommand "repo", RepoCommand
172
+
173
+ desc "docker SUBCOMMAND ...ARGS", "Manage docker stuffs"
174
+ subcommand "docker", DockerCommand
175
+
176
+ desc "release SUBCOMMAND ...ARGS", "Manage releases"
177
+ subcommand "release", ReleaseCommand
178
+ end
179
+
180
+ ::Cli.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/retag/image.rb CHANGED
@@ -35,18 +35,6 @@ module Retag
35
35
  Image.new(image, newtag)
36
36
  end
37
37
 
38
- def pull(img = full)
39
- cmd!("docker pull -q #{img}")
40
- end
41
-
42
- def push(img = full)
43
- cmd!("docker push -q #{img}")
44
- end
45
-
46
- def rm(img = full)
47
- cmd!("docker rmi #{img}")
48
- end
49
-
50
38
  end
51
39
  end
52
40
 
data/lib/retag/repo.rb ADDED
@@ -0,0 +1,43 @@
1
+
2
+ module Retag
3
+ class Repo
4
+
5
+ include Utils
6
+ attr_reader :repo, :branch, :revision, :name
7
+
8
+ def initialize(repo, branch)
9
+ @repo = repo
10
+ @branch = branch
11
+ @gitlab = Gitlab.client
12
+ end
13
+
14
+ def tag!(tag, message: nil)
15
+ begin
16
+ result = @gitlab.tag(name, tag)
17
+ if result.to_h.dig('commit', 'short_id').to_s == revision
18
+ # Success: tag with same revision already exists
19
+ return true
20
+ end
21
+ rescue Gitlab::Error::NotFound
22
+ # Success: there is no such tag
23
+ end
24
+
25
+ @gitlab.create_tag(name, tag, revision, message)
26
+ end
27
+
28
+ def name
29
+ @name ||= @repo.split(':').last.gsub('.git', '')
30
+ end
31
+
32
+ def revision
33
+ @revision ||= begin
34
+ rev_name_pair = cmd!("git ls-remote #{repo} #{branch}", capture: true).split("\n").select{|line| line[/\/#{branch}$/] }.first
35
+ raise "There is no #{branch} revision at #{repo}" if rev_name_pair.nil?
36
+ rev, _name = rev_name_pair.split
37
+ rev[0..7]
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+
data/lib/retag/service.rb CHANGED
@@ -1,15 +1,18 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
1
3
  module Retag
2
4
  class Service
3
5
 
4
6
  include Retag::Utils
5
7
 
6
- attr_reader :name, :config, :repo, :branch, :release, :suffix
8
+ attr_reader :name, :config, :repo, :release, :suffix
9
+
10
+ delegate :revision, :branch, to: :repo
7
11
 
8
- def initialize(name, config, release, suffix: )
12
+ def initialize(name, config, release, branch:, suffix:)
9
13
  @name = name
10
14
  @config = config
11
- @repo = config['repo']
12
- @branch = config['branch']
15
+ @repo = Retag::Repo.new(config['repo'], branch)
13
16
  @release = release
14
17
  @suffix = suffix
15
18
  end
@@ -17,33 +20,6 @@ module Retag
17
20
  def images
18
21
  @images ||= config['images'].map{|img| Retag::Image.new(img, revision, suffix: @suffix) }
19
22
  end
20
-
21
- def pull
22
- images.each(&:pull)
23
- end
24
-
25
- def push
26
- images.each(&:push)
27
- end
28
-
29
- def rm
30
- images.each(&:rm)
31
- end
32
-
33
- def release!(tag = release)
34
- images.each do |image|
35
- image.retag!(tag)
36
- end
37
- end
38
-
39
- def revision
40
- @revision ||= begin
41
- rev, _name = cmd!("git ls-remote #{repo} #{branch}", capture: true).split("\n").select{|line| line["heads/#{branch}"] }.first.split
42
- rev[0..7]
43
- end
44
- end
45
-
46
-
47
23
  end
48
24
  end
49
25
 
data/lib/retag/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Retag
4
4
 
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.5'
6
6
 
7
7
  end
8
8
 
data/lib/retag.rb CHANGED
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support'
4
+ require 'gitlab'
4
5
  require_relative 'retag/version'
5
6
  require_relative 'retag/logger'
6
7
  require_relative 'retag/utils'
7
8
  require_relative 'retag/image'
9
+ require_relative 'retag/repo'
8
10
  require_relative 'retag/service'
9
11
 
10
12
  module Retag
data/retag.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/retag/version'
4
+
5
+ Gem::Specification.new 'retag' do |spec|
6
+ spec.version = ENV['BUILDVERSION'].to_i > 0 ? "#{Retag::VERSION}.#{ENV['BUILDVERSION'].to_i}" : Retag::VERSION
7
+ spec.authors = ['Samoilenko Yuri']
8
+ spec.email = ['kinnalru@gmail.com']
9
+ spec.description = spec.summary = 'Retag is cli to manipulate docker images in handy way'
10
+ spec.homepage = 'https://github.com/RnD-Soft/retag'
11
+ spec.license = 'MIT'
12
+
13
+ spec.required_ruby_version = '>= 2.5.0'
14
+ spec.metadata['homepage_uri'] = spec.homepage
15
+ spec.metadata['source_code_uri'] = 'https://github.com/RnD-Soft/retag'
16
+
17
+ spec.files = Dir['bin/**/*', 'lib/**/*', 'sig/**/*', 'Gemfile*', 'LICENSE', 'README.md', '*.gemspec']
18
+
19
+ spec.bindir = 'bin'
20
+ spec.executables = spec.files.grep(%r{^bin/retag}) {|f| File.basename(f) }
21
+ spec.require_paths = ['lib']
22
+
23
+ spec.add_development_dependency 'bundler', '~> 2.2', '>= 2.2.1'
24
+ spec.add_development_dependency 'rake'
25
+ spec.add_development_dependency 'rspec'
26
+ spec.add_development_dependency 'rspec_junit_formatter'
27
+ spec.add_development_dependency 'rubocop'
28
+ spec.add_development_dependency 'simplecov'
29
+ spec.add_development_dependency 'simplecov-console'
30
+ spec.add_development_dependency 'webmock'
31
+
32
+ spec.add_runtime_dependency 'activesupport', '~> 6.0'
33
+ spec.add_runtime_dependency 'colorize'
34
+ spec.add_runtime_dependency 'json'
35
+ spec.add_runtime_dependency 'thor'
36
+ spec.add_runtime_dependency 'uri'
37
+ spec.add_runtime_dependency 'yaml'
38
+ spec.add_runtime_dependency 'gitlab'
39
+
40
+ end
41
+
data/sig/retag.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Retag
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samoilenko Yuri
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-20 00:00:00.000000000 Z
11
+ date: 2022-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -212,21 +212,44 @@ dependencies:
212
212
  - - ">="
213
213
  - !ruby/object:Gem::Version
214
214
  version: '0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: gitlab
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
215
229
  description: Retag is cli to manipulate docker images in handy way
216
230
  email:
217
231
  - kinnalru@gmail.com
218
- executables: []
232
+ executables:
233
+ - retag
219
234
  extensions: []
220
235
  extra_rdoc_files: []
221
236
  files:
237
+ - Gemfile
238
+ - Gemfile.lock
222
239
  - LICENSE
223
240
  - README.md
241
+ - bin/console
242
+ - bin/retag
243
+ - bin/setup
224
244
  - lib/retag.rb
225
245
  - lib/retag/image.rb
226
246
  - lib/retag/logger.rb
247
+ - lib/retag/repo.rb
227
248
  - lib/retag/service.rb
228
249
  - lib/retag/utils.rb
229
250
  - lib/retag/version.rb
251
+ - retag.gemspec
252
+ - sig/retag.rbs
230
253
  homepage: https://github.com/RnD-Soft/retag
231
254
  licenses:
232
255
  - MIT