shopify_empty_gem 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0d36dcab1b3e476be2898bdf40c4805e64ed38371020d3c37d0282d33720d7a2
4
- data.tar.gz: a94723daea6353f087b41b1dbfc0c48f70a8b95b5bcd66ed445cafb8d1658639
3
+ metadata.gz: 8e52f8fc30567f058b24f22850d42202590664c0d2059c46885ea56b97ebce5f
4
+ data.tar.gz: c8b77d7ccd7f43e3ac908c4369d03ac2b4e7bf9edd7819e579d0c2f1535b61df
5
5
  SHA512:
6
- metadata.gz: 64e81b8188f76b3fcfa4dd01c947fe13db43c10b64aff78ee3ce1deb9994e14f5e86a928ff99ca1026cf0c3920cc341b16169f9020eebbf95723d729fdb5a5db
7
- data.tar.gz: dbb3d932670f26751fcf8bb767a55e29fc0542e7a560e17c50e0f2b8ffcec68d003ee43ca343f166cc69c5f862bd0895ef814cb7cac99ecb728f21d5ece42a3f
6
+ metadata.gz: 53f6959f88d236eb86d27cd0fcf8dd71866eb980f3b63612f98b17e17fcca603376a2c94768eacd0b047a62dee10fbdd2953ad5a323165fd9b6606966dd4cd59
7
+ data.tar.gz: 2c1677e3b6ec2aae883a853128445dc1ed3336741827a459082862256e56b1b426418f30b89e0834dd475ec106623d8ee0ff57faf1e76a934c84e8ff51e50faa
data/Gemfile.lock ADDED
@@ -0,0 +1,22 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ shopify_empty_gem (0.1.2)
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.2"
3
3
  end
@@ -0,0 +1,143 @@
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
+ spec = Gem::Specification.load(spec_path)
96
+ if RubygemsAPI.published?(spec.name, spec.version)
97
+ puts "#{spec.name} version #{spec.version} is already published."
98
+ exit 0
99
+ elsif !spec.metadata['allowed_push_host']
100
+ puts "Can't release the gem: spec.metadata['allowed_push_host'] must be defined."
101
+ exit 1
102
+ else
103
+ is_successful = Git.tag_and_push(spec.version) do
104
+
105
+ if release_command.any?
106
+ # If a custom release command is called with this script, just execute the custom command
107
+ system(*release_command)
108
+ else
109
+ # TODO: If mechanism to check if account has mfa enabled, do the check here (is otp required?)
110
+
111
+ # TODO: Notify user via Slack to enter OTP in web app
112
+ # QUESTIONS:
113
+ # How do we know who to notify?
114
+
115
+
116
+
117
+ # Start polling web app's endpoint
118
+ otp = Poll.fetch_otp(gem_name: spec.name)
119
+
120
+ # Set the environment variable to the user inputted OTP code
121
+ # See: https://guides.rubygems.org/command-reference/ under otp option for environment variable
122
+ #
123
+ # According to the docs: https://ruby-doc.org/core-3.1.0/Kernel.html#method-i-spawn
124
+ # The keys and values passed to spawn (or system), except for `nil`, must be strings.
125
+ # So we're calling `to_s` on the `otp_code` just to be safe.
126
+ #
127
+ # 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
128
+ # Instead of re-building and re-tagging the gem, we'll complete the last step of the `rake release` command => (gem push)
129
+ system(
130
+ {'GEM_HOST_OTP_CODE' => temp_otp_code.to_s},
131
+ 'bundle',
132
+ 'exec',
133
+ 'rake',
134
+ 'release'
135
+ )
136
+
137
+ # TODO: What if OTP has expired? Add mechanism to retry.
138
+ end
139
+ end
140
+ is_successful ? exit(0) : exit(1)
141
+ end
142
+
143
+
@@ -0,0 +1,4 @@
1
+ deploy:
2
+ override:
3
+ - lib/snippets/release-gem-with-otp shopify_empty_gem.gemspec 008596
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.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
- autorequire:
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
@@ -44,7 +44,7 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: 12.3.3
47
- description:
47
+ description:
48
48
  email:
49
49
  - admins@shopify.com
50
50
  executables: []
@@ -53,15 +53,18 @@ 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
62
65
  metadata:
63
66
  allowed_push_host: https://rubygems.org
64
- post_install_message:
67
+ post_install_message:
65
68
  rdoc_options: []
66
69
  require_paths:
67
70
  - lib
@@ -76,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
76
79
  - !ruby/object:Gem::Version
77
80
  version: '0'
78
81
  requirements: []
79
- rubygems_version: 3.2.32
80
- signing_key:
82
+ rubygems_version: 3.2.20
83
+ signing_key:
81
84
  specification_version: 4
82
85
  summary: Empty gem for testing purposes
83
86
  test_files: []