shopify_empty_gem 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: 0d36dcab1b3e476be2898bdf40c4805e64ed38371020d3c37d0282d33720d7a2
4
- data.tar.gz: a94723daea6353f087b41b1dbfc0c48f70a8b95b5bcd66ed445cafb8d1658639
3
+ metadata.gz: d441aad9a3c2ec985445da8160baa714b749991705f0b97a96dcf1f363d69f5a
4
+ data.tar.gz: ec104dcffea3c3b10446b144217180a2f46b1cc183e618bf90eb577ab1c72fd8
5
5
  SHA512:
6
- metadata.gz: 64e81b8188f76b3fcfa4dd01c947fe13db43c10b64aff78ee3ce1deb9994e14f5e86a928ff99ca1026cf0c3920cc341b16169f9020eebbf95723d729fdb5a5db
7
- data.tar.gz: dbb3d932670f26751fcf8bb767a55e29fc0542e7a560e17c50e0f2b8ffcec68d003ee43ca343f166cc69c5f862bd0895ef814cb7cac99ecb728f21d5ece42a3f
6
+ metadata.gz: d9f0dca6df745bc1e421b1825192b95264bb2477d9b8502e0ab39591ea9ac02aea0fbd8226a61632ee1cbdc931bb1dabc3ed90a452d890d22e1446c18577c580
7
+ data.tar.gz: 5f954188bb4ff6576f5ad27c8af44bf988cfb7b312afc67b458da437383defcc28fee8d642101569770a77b5999624ce3a77e78665aae6d67156fede02b0b99d
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ shopify_empty_gem (0.1.5)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (12.3.3)
10
+
11
+ PLATFORMS
12
+ -darwin-21
13
+ arm64-darwin-21
14
+ x86_64-linux
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 2)
18
+ rake (~> 12.3, >= 12.3.3)
19
+ shopify_empty_gem!
20
+
21
+ BUNDLED WITH
22
+ 2.2.22
@@ -1,3 +1,3 @@
1
1
  module ShopifyEmptyGem
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.5"
3
3
  end
@@ -0,0 +1,148 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'net/https'
4
+ require 'uri'
5
+ require 'json'
6
+
7
+ module RubygemsAPI
8
+ extend self
9
+
10
+ def published?(name, version)
11
+ uri = URI.parse("https://rubygems.org/api/v2/rubygems/#{name}/versions/#{version}.json")
12
+ Net::HTTP.get_response(uri).is_a?(Net::HTTPSuccess)
13
+ end
14
+ end
15
+
16
+ module Git
17
+ extend self
18
+
19
+ def tag_and_push(version)
20
+ if tag_exists?(version)
21
+ yield
22
+ else
23
+ tag(version) && yield && push_tags
24
+ end
25
+ end
26
+
27
+ def tag_exists?(version)
28
+ system('git', 'rev-parse', '--verify', "v#{version}^{commit}", out: File::NULL, err: File::NULL)
29
+ end
30
+
31
+ def tag(version)
32
+ puts "Running: git tag -m 'Version #{version}' v#{version}"
33
+ system('git', 'tag', '-m', "Version #{version}", "v#{version}")
34
+ end
35
+
36
+ def delete_tag(version)
37
+ puts "Running: git tag -d v#{version}"
38
+ system('git', 'tag', '-d', "v#{version}")
39
+ end
40
+
41
+ def push_tags
42
+ puts "Running: git push --tags"
43
+ system('git', 'push', '--tag')
44
+ end
45
+ end
46
+
47
+ module Poll
48
+ extend self
49
+
50
+ def fetch_otp(wait_time: 3, timeout_threshold: 300, gem_name:)
51
+ # The wait_time and time_threshold configs are temp placeholders, we can adjust as needed
52
+ # TODO: Consider whether we should implement exponential backoff
53
+ # Potential risk: Timing may be precarious given the 30 second time frame for otp expiry
54
+ # If we don't implement an exponential backoff strategy, will we accidentally DDOS ourselves?
55
+
56
+ puts "Polling for OTP code"
57
+ otp_code = nil
58
+ start_time = Time.now.utc
59
+
60
+ until Time.now.utc > start_time + timeout_threshold
61
+ # Printing '.' to the log to indicate each time we poll for an OTP code
62
+ # This will also help prevent timing out on Shipit
63
+ # Shipit's default task timeout is 5 minutes; if no new output is logged within 5 minutes, shipit will kill the task.
64
+ print "."
65
+
66
+ # Make GET request to web app's endpont
67
+ uri = URI('https://api.agify.io/') # TODO: update endpoint when web service is created
68
+ params = { :name => 'bella' }
69
+ # params = { :gem_name => gem_name }
70
+ uri.query = URI.encode_www_form(params)
71
+
72
+ res = Net::HTTP.get_response(uri)
73
+ otp_code = JSON.parse(res.body)["count"] if res.is_a?(Net::HTTPSuccess)
74
+
75
+ return otp_code if !otp_code.nil?
76
+
77
+ # TODO: Need to figure out what other responses we want to send back from web service when OTP does not exist
78
+ # TODO: How do we handle OTP submissions on the web app side?
79
+ # Do we persist the OTP for <x> time frame?
80
+ # Do we create a job to destroy the OTP code after <x> time frame?
81
+
82
+ sleep wait_time
83
+ end
84
+
85
+ # TODO: Opportunity for retry mechanism?
86
+ # Exiting script, as OTP was not retrieved - will lead to a failed deploy
87
+ exit(1)
88
+ end
89
+ end
90
+
91
+ puts "🚀 Kicking off the release-gem-with-otp script!!"
92
+
93
+ spec_path, temp_otp_code, *release_command = ARGV
94
+
95
+ puts "📝 The otp code is: #{temp_otp_code}"
96
+
97
+ spec = Gem::Specification.load(spec_path)
98
+ if RubygemsAPI.published?(spec.name, spec.version)
99
+ puts "#{spec.name} version #{spec.version} is already published."
100
+ exit 0
101
+ elsif !spec.metadata['allowed_push_host']
102
+ puts "Can't release the gem: spec.metadata['allowed_push_host'] must be defined."
103
+ exit 1
104
+ else
105
+ is_successful = Git.tag_and_push(spec.version) do
106
+
107
+ if release_command.any?
108
+ # If a custom release command is called with this script, just execute the custom command
109
+ system(*release_command)
110
+ else
111
+ # TODO: If mechanism to check if account has mfa enabled, do the check here (is otp required?)
112
+
113
+ # TODO: Notify user via Slack to enter OTP in web app
114
+ # QUESTIONS:
115
+ # How do we know who to notify?
116
+
117
+
118
+
119
+ # Start polling web app's endpoint
120
+ otp = Poll.fetch_otp(gem_name: spec.name)
121
+
122
+ # Set the environment variable to the user inputted OTP code
123
+ # See: https://guides.rubygems.org/command-reference/ under otp option for environment variable
124
+ #
125
+ # According to the docs: https://ruby-doc.org/core-3.1.0/Kernel.html#method-i-spawn
126
+ # The keys and values passed to spawn (or system), except for `nil`, must be strings.
127
+ # So we're calling `to_s` on the `otp_code` just to be safe.
128
+ #
129
+ # Since we've already tagged and built the gem with `bundle exec gem_push=no rake release`, the last step is to push the gem
130
+ # Instead of re-building and re-tagging the gem, we'll complete the last step of the `rake release` command => (gem push)
131
+ puts "💪 Preparing to release gem"
132
+ puts "🎉 Running 'bundle exec rake release' with otp code #{temp_otp_code}"
133
+
134
+ system(
135
+ {'GEM_HOST_OTP_CODE' => temp_otp_code.to_s},
136
+ 'bundle',
137
+ 'exec',
138
+ 'rake',
139
+ 'release'
140
+ )
141
+
142
+ # TODO: What if OTP has expired? Add mechanism to retry.
143
+ end
144
+ end
145
+ is_successful ? exit(0) : exit(1)
146
+ end
147
+
148
+
@@ -0,0 +1,4 @@
1
+ deploy:
2
+ override:
3
+ - lib/snippets/release-gem-with-otp shopify_empty_gem.gemspec 249493
4
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shopify_empty_gem
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
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-02-15 00:00:00.000000000 Z
11
+ date: 2022-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -53,9 +53,12 @@ extra_rdoc_files: []
53
53
  files:
54
54
  - ".gitignore"
55
55
  - Gemfile
56
+ - Gemfile.lock
56
57
  - Rakefile
57
58
  - lib/shopify_empty_gem.rb
58
59
  - lib/shopify_empty_gem/version.rb
60
+ - lib/snippets/release-gem-with-otp
61
+ - shipit.rubygems_otp.yml
59
62
  homepage: https://example.com
60
63
  licenses:
61
64
  - MIT