s3_gem_host 1.0.0
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 +7 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +235 -0
- data/.rubocop_todo.yml +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGES.md +2 -0
- data/CONTRIBUTING.md +18 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +80 -0
- data/MIT-LICENSE +18 -0
- data/README.md +81 -0
- data/Rakefile +8 -0
- data/lib/s3_gem_host.rb +7 -0
- data/lib/s3_gem_host/task_helper.rb +206 -0
- data/lib/s3_gem_host/version.rb +5 -0
- data/s3_gem_host.gemspec +26 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 891bc2b41619f6bb1cf73f340cf9eca5dff70759a4e42301ef98020d88edfd55
|
4
|
+
data.tar.gz: 84e48dd50ffb92dfba5afb80dfad1f5921e36dcb4385482a65aebc38a8843f7a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8ba0db102ee30a2ffdd295bf9db7ca66a0aa719c0b51091d92df20253c78da002600c08532dbea328d1515f0ae5c6c4cbeeb2cf1b2172b2ae89d43365306acb2
|
7
|
+
data.tar.gz: 0dc809cfa40d2e202cea884cea96e459e2200e6d1fb5d7496e2051cd4e8596b06b1b5ec0dd99280c7c96f6492f9382ef2b1f5c415bf0a9a0f56e1383bd07ca0a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,235 @@
|
|
1
|
+
# Run rubocop --auto-gen-config to generate .rubocop_todo.yml
|
2
|
+
# Run rubocop --auto-correct to have rubocop auto fix all offenses (Use this feature carefully!)
|
3
|
+
# Enable rubocop todos to go through them one by one
|
4
|
+
# For how to get started with rubocop, see: https://buildtoship.com/integrate-rubocop-in-your-workflow/
|
5
|
+
|
6
|
+
require:
|
7
|
+
- rubocop-rspec
|
8
|
+
|
9
|
+
inherit_from: .rubocop_todo.yml
|
10
|
+
|
11
|
+
AllCops:
|
12
|
+
TargetRubyVersion: 2.6
|
13
|
+
# Cop names are not displayed in offense messages by default. Change behavior
|
14
|
+
# by overriding DisplayCopNames, or by giving the -D/--display-cop-names
|
15
|
+
# option.
|
16
|
+
DisplayCopNames: true
|
17
|
+
# Style guide URLs are not displayed in offense messages by default. Change
|
18
|
+
# behavior by overriding DisplayStyleGuide, or by giving the
|
19
|
+
# -S/--display-style-guide option.
|
20
|
+
DisplayStyleGuide: true
|
21
|
+
# Exclude certain files
|
22
|
+
Exclude:
|
23
|
+
- 'vendor/**/*'
|
24
|
+
- 'db/**/*'
|
25
|
+
- 'tmp/**/*'
|
26
|
+
- 'bin/**/*'
|
27
|
+
- 'log/**/*'
|
28
|
+
- 'client/**/*'
|
29
|
+
- 'node_modules/**/*'
|
30
|
+
|
31
|
+
################################## Style ##################################
|
32
|
+
|
33
|
+
# Enable, Disable, and Edit styles below
|
34
|
+
# Default rubocop styles can be found at https://github.com/bbatsov/rubocop/blob/master/config/default.yml
|
35
|
+
# Copy styles from above url or .rubocop_todo.yml and only change specific rules (suggest using comments from both)
|
36
|
+
|
37
|
+
Style/AccessModifierDeclarations:
|
38
|
+
Enabled: false
|
39
|
+
|
40
|
+
Style/BlockDelimiters:
|
41
|
+
Exclude:
|
42
|
+
- '**/*.rb'
|
43
|
+
|
44
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
45
|
+
# SupportedStyles: nested, compact
|
46
|
+
Style/ClassAndModuleChildren:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
# Document classes and non-namespace modules.
|
50
|
+
Style/Documentation:
|
51
|
+
Exclude:
|
52
|
+
- 'spec/**/*'
|
53
|
+
- 'config/*'
|
54
|
+
- 'config/locales/*'
|
55
|
+
|
56
|
+
Style/FrozenStringLiteralComment:
|
57
|
+
Exclude:
|
58
|
+
- 'app/views/*'
|
59
|
+
|
60
|
+
Style/GuardClause:
|
61
|
+
Exclude:
|
62
|
+
- '**/*.rb'
|
63
|
+
|
64
|
+
Style/NumericPredicate:
|
65
|
+
Exclude:
|
66
|
+
- '**/*.rb'
|
67
|
+
|
68
|
+
# Cop supports --auto-correct.
|
69
|
+
Style/RedundantSelf:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
# Cop supports --auto-correct.
|
73
|
+
# Configuration parameters: AllowIfMethodIsEmpty.
|
74
|
+
Style/SingleLineMethods:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Style/TrailingCommaInArguments:
|
78
|
+
Exclude:
|
79
|
+
- 'spec/**/*'
|
80
|
+
- 'app/**/*'
|
81
|
+
|
82
|
+
Style/TrailingCommaInArrayLiteral:
|
83
|
+
Exclude:
|
84
|
+
- 'spec/**/*'
|
85
|
+
- 'app/**/*'
|
86
|
+
|
87
|
+
Style/TrailingCommaInHashLiteral:
|
88
|
+
Exclude:
|
89
|
+
- 'spec/**/*'
|
90
|
+
- 'app/**/*'
|
91
|
+
|
92
|
+
################################## Layout #################################
|
93
|
+
|
94
|
+
Layout/EmptyLinesAroundAccessModifier:
|
95
|
+
Enabled: false
|
96
|
+
|
97
|
+
Layout/IndentationConsistency:
|
98
|
+
EnforcedStyle: indented_internal_methods
|
99
|
+
|
100
|
+
# Checks the indentation of the first element in an array literal.
|
101
|
+
Layout/FirstArrayElementIndentation:
|
102
|
+
Enabled: false
|
103
|
+
|
104
|
+
Layout/FirstHashElementIndentation:
|
105
|
+
Exclude:
|
106
|
+
- '**/*.rb'
|
107
|
+
|
108
|
+
Layout/MultilineMethodCallIndentation:
|
109
|
+
Exclude:
|
110
|
+
- 'spec/**/*'
|
111
|
+
|
112
|
+
# Cop supports --auto-correct.
|
113
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth.
|
114
|
+
# SupportedStyles: aligned, indented
|
115
|
+
Layout/MultilineOperationIndentation:
|
116
|
+
EnforcedStyle: indented
|
117
|
+
|
118
|
+
################################## Lint ###################################
|
119
|
+
|
120
|
+
# Cop supports --auto-correct.
|
121
|
+
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
|
122
|
+
Lint/UnusedMethodArgument:
|
123
|
+
Exclude:
|
124
|
+
- 'config/initializers/sidekiq.rb'
|
125
|
+
- 'app/controllers/application_controller.rb'
|
126
|
+
|
127
|
+
################################## Metrics ################################
|
128
|
+
|
129
|
+
Metrics/AbcSize:
|
130
|
+
Max: 30
|
131
|
+
|
132
|
+
Metrics/BlockLength:
|
133
|
+
Max: 30
|
134
|
+
Exclude:
|
135
|
+
- 'spec/**/*.rb'
|
136
|
+
- 'config/**/*.rb'
|
137
|
+
- 'app/controllers/api/**/*'
|
138
|
+
|
139
|
+
Metrics/ClassLength:
|
140
|
+
Enabled: false
|
141
|
+
|
142
|
+
Metrics/CyclomaticComplexity:
|
143
|
+
Max: 9
|
144
|
+
|
145
|
+
Layout/LineLength:
|
146
|
+
Max: 120
|
147
|
+
Exclude:
|
148
|
+
- 'Gemfile'
|
149
|
+
|
150
|
+
# Configuration parameters: CountComments.
|
151
|
+
Metrics/MethodLength:
|
152
|
+
Max: 50
|
153
|
+
|
154
|
+
Metrics/ModuleLength:
|
155
|
+
Max: 250
|
156
|
+
|
157
|
+
Metrics/ParameterLists:
|
158
|
+
Enabled: false
|
159
|
+
|
160
|
+
Metrics/PerceivedComplexity:
|
161
|
+
Max: 10
|
162
|
+
|
163
|
+
################################## Naming #################################
|
164
|
+
|
165
|
+
Naming/HeredocDelimiterNaming:
|
166
|
+
Enabled: false
|
167
|
+
|
168
|
+
Naming/MethodParameterName:
|
169
|
+
Enabled: false
|
170
|
+
|
171
|
+
################################## RSpec ##################################
|
172
|
+
|
173
|
+
# Check that instances are not being stubbed globally
|
174
|
+
RSpec/AnyInstance:
|
175
|
+
Enabled: false
|
176
|
+
|
177
|
+
RSpec/ContextWording:
|
178
|
+
Enabled: false
|
179
|
+
|
180
|
+
RSpec/DescribeClass:
|
181
|
+
Exclude:
|
182
|
+
- 'spec/lib/tasks/**/*'
|
183
|
+
- 'spec/integration/*.rb'
|
184
|
+
|
185
|
+
# Configuration parameters: Max.
|
186
|
+
RSpec/ExampleLength:
|
187
|
+
Max: 25
|
188
|
+
|
189
|
+
RSpec/ExpectActual:
|
190
|
+
Exclude:
|
191
|
+
- 'spec/**/*.rb'
|
192
|
+
|
193
|
+
RSpec/FilePath:
|
194
|
+
Exclude:
|
195
|
+
- 'spec/karafka/**/*'
|
196
|
+
|
197
|
+
RSpec/MultipleExpectations:
|
198
|
+
Exclude:
|
199
|
+
- '**/*.rb'
|
200
|
+
|
201
|
+
Layout/SpaceAroundMethodCallOperator:
|
202
|
+
Enabled: true
|
203
|
+
|
204
|
+
Lint/RaiseException:
|
205
|
+
Enabled: true
|
206
|
+
|
207
|
+
Lint/StructNewOverride:
|
208
|
+
Enabled: true
|
209
|
+
|
210
|
+
Style/ExponentialNotation:
|
211
|
+
Enabled: true
|
212
|
+
|
213
|
+
Style/HashEachMethods:
|
214
|
+
Enabled: true
|
215
|
+
|
216
|
+
Style/HashTransformKeys:
|
217
|
+
Enabled: true
|
218
|
+
|
219
|
+
Style/HashTransformValues:
|
220
|
+
Enabled: true
|
221
|
+
|
222
|
+
RSpec/NestedGroups:
|
223
|
+
Max: 7
|
224
|
+
|
225
|
+
Lint/UnderscorePrefixedVariableName:
|
226
|
+
Enabled: false
|
227
|
+
|
228
|
+
RSpec/RepeatedExampleGroupBody:
|
229
|
+
Enabled: false
|
230
|
+
|
231
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
232
|
+
Enabled: true
|
233
|
+
|
234
|
+
Style/SlicingWithRange:
|
235
|
+
Enabled: true
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2020-05-09 13:29:52 -0700 using RuboCop version 0.82.0.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
s3_gem_host
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.6.6
|
data/.travis.yml
ADDED
data/CHANGES.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# Contributing
|
2
|
+
1. Create a feature branch for your change.
|
3
|
+
2. Push up your proposed changes to your feature branch.
|
4
|
+
* Ensure you have full test coverage. Untested code will not be merged in and code coverage is reported on all builds.
|
5
|
+
* Bump the version of the gem according to [Versioning](#versioning) below
|
6
|
+
* Breaking changes resulting in a major version bump will require more discussion, so please try to keep changes
|
7
|
+
fully backward-compatible unless you have a good reason not to.
|
8
|
+
* Update documentation in README.md and CHANGES.mb
|
9
|
+
2. Create a Pull Request with your change.
|
10
|
+
|
11
|
+
### Versioning
|
12
|
+
This gem follows Semantic Versioning (2.0):
|
13
|
+
|
14
|
+
Given a version number MAJOR.MINOR.PATCH, increment the:
|
15
|
+
|
16
|
+
MAJOR version when you make incompatible API changes,
|
17
|
+
MINOR version when you add functionality in a backwards compatible manner, and
|
18
|
+
PATCH version when you make backwards compatible bug fixes.
|
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 s3_gem_host.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
group :development, :test do
|
9
|
+
gem 'rspec'
|
10
|
+
gem 'rubocop', require: false
|
11
|
+
gem 'rubocop-rspec', require: false
|
12
|
+
gem 'simplecov', require: false
|
13
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
s3_gem_host (1.0.0)
|
5
|
+
aws-sdk-s3 (~> 1.64)
|
6
|
+
builder
|
7
|
+
bundler
|
8
|
+
rake
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
ast (2.4.0)
|
14
|
+
aws-eventstream (1.1.0)
|
15
|
+
aws-partitions (1.316.0)
|
16
|
+
aws-sdk-core (3.96.0)
|
17
|
+
aws-eventstream (~> 1, >= 1.0.2)
|
18
|
+
aws-partitions (~> 1, >= 1.239.0)
|
19
|
+
aws-sigv4 (~> 1.1)
|
20
|
+
jmespath (~> 1.0)
|
21
|
+
aws-sdk-kms (1.31.0)
|
22
|
+
aws-sdk-core (~> 3, >= 3.71.0)
|
23
|
+
aws-sigv4 (~> 1.1)
|
24
|
+
aws-sdk-s3 (1.64.0)
|
25
|
+
aws-sdk-core (~> 3, >= 3.83.0)
|
26
|
+
aws-sdk-kms (~> 1)
|
27
|
+
aws-sigv4 (~> 1.1)
|
28
|
+
aws-sigv4 (1.1.3)
|
29
|
+
aws-eventstream (~> 1.0, >= 1.0.2)
|
30
|
+
builder (3.2.4)
|
31
|
+
diff-lcs (1.3)
|
32
|
+
docile (1.3.2)
|
33
|
+
jmespath (1.4.0)
|
34
|
+
parallel (1.19.1)
|
35
|
+
parser (2.7.1.2)
|
36
|
+
ast (~> 2.4.0)
|
37
|
+
rainbow (3.0.0)
|
38
|
+
rake (13.0.1)
|
39
|
+
rexml (3.2.4)
|
40
|
+
rspec (3.9.0)
|
41
|
+
rspec-core (~> 3.9.0)
|
42
|
+
rspec-expectations (~> 3.9.0)
|
43
|
+
rspec-mocks (~> 3.9.0)
|
44
|
+
rspec-core (3.9.2)
|
45
|
+
rspec-support (~> 3.9.3)
|
46
|
+
rspec-expectations (3.9.2)
|
47
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
48
|
+
rspec-support (~> 3.9.0)
|
49
|
+
rspec-mocks (3.9.1)
|
50
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
51
|
+
rspec-support (~> 3.9.0)
|
52
|
+
rspec-support (3.9.3)
|
53
|
+
rubocop (0.83.0)
|
54
|
+
parallel (~> 1.10)
|
55
|
+
parser (>= 2.7.0.1)
|
56
|
+
rainbow (>= 2.2.2, < 4.0)
|
57
|
+
rexml
|
58
|
+
ruby-progressbar (~> 1.7)
|
59
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
60
|
+
rubocop-rspec (1.39.0)
|
61
|
+
rubocop (>= 0.68.1)
|
62
|
+
ruby-progressbar (1.10.1)
|
63
|
+
simplecov (0.18.5)
|
64
|
+
docile (~> 1.1)
|
65
|
+
simplecov-html (~> 0.11)
|
66
|
+
simplecov-html (0.12.2)
|
67
|
+
unicode-display_width (1.7.0)
|
68
|
+
|
69
|
+
PLATFORMS
|
70
|
+
ruby
|
71
|
+
|
72
|
+
DEPENDENCIES
|
73
|
+
rspec
|
74
|
+
rubocop
|
75
|
+
rubocop-rspec
|
76
|
+
s3_gem_host!
|
77
|
+
simplecov
|
78
|
+
|
79
|
+
BUNDLED WITH
|
80
|
+
2.1.4
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
2
|
+
a copy of this software and associated documentation files (the
|
3
|
+
"Software"), to deal in the Software without restriction, including
|
4
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
5
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
6
|
+
permit persons to whom the Software is furnished to do so, subject to
|
7
|
+
the following conditions:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be
|
10
|
+
included in all copies or substantial portions of the Software.
|
11
|
+
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
13
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
14
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
16
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
17
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
18
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# S3 Gem Host [](https://travis-ci.org/webandtech/s3_gem_host)
|
2
|
+
This gem provides rake tasks for publishing and managing Ruby gems hosted on Amazon S3.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this gem to your gem's Gemfile:
|
7
|
+
```ruby
|
8
|
+
# Gemfile
|
9
|
+
gem 's3_gem_host'
|
10
|
+
```
|
11
|
+
|
12
|
+
Require this bundler/gem_tasks (recommended) and this gem in your Rakefile
|
13
|
+
```ruby
|
14
|
+
# Rakefile
|
15
|
+
|
16
|
+
require 'bundler/gem_tasks' # Recommended
|
17
|
+
require 's3_gem_host'
|
18
|
+
```
|
19
|
+
|
20
|
+
Run `rake -T` and you should see this Gem's tasks available for use.
|
21
|
+
```
|
22
|
+
➜ rake -T
|
23
|
+
rake build # Build your-gem-x.x.x.gem into the pkg directory
|
24
|
+
rake clean # Remove any temporary products
|
25
|
+
rake clobber # Remove any generated files
|
26
|
+
rake install # Build and install your-gem-x.x.x.gem into system gems
|
27
|
+
rake install:local # Build and install your-gem-x.x.x.gem into system gems without network access
|
28
|
+
rake release[remote] # Create tag vx.x.x and build and push s3_gem_host-1.0.0.gem to rubygems.org
|
29
|
+
rake s3_gem_host:push # Publish a newly built gem version to S3
|
30
|
+
rake s3_gem_host:yank[version] # Remove a previously published gem version from S3
|
31
|
+
rake spec # Run RSpec code examples
|
32
|
+
```
|
33
|
+
|
34
|
+
## Configuration
|
35
|
+
|
36
|
+
Set the following environment variables (such as when using this gem in your CI/CD pipeline):
|
37
|
+
* `S3_GEM_HOST_AWS_ACCESS_KEY_ID`: The AWS Access Key ID to use to write to your S3 bucket
|
38
|
+
* `S3_GEM_HOST_AWS_SECRET_ACCESS_KEY`: The AWS Secret Access Key to use to write to your S3 bucket
|
39
|
+
* `S3_GEM_HOST_BUCKET`: The S3 bucket where you want to host your gems. This must be an existing S3 bucket. You
|
40
|
+
should create a new S3 bucket for hosting your gems. Multiple gems may be hosted in the same bucket.
|
41
|
+
* `S3_GEM_HOST_AWS_REGION`: The AWS region where your S3 bucket is hosted; defaults to 'us-east-1'
|
42
|
+
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
1. Create an S3 bucket to be your "gem server".
|
46
|
+
* Each gem you publish will maintain its own source via a root directory in this bucket.
|
47
|
+
|
48
|
+
2. You will need to provide https access to your S3 bucket to use it as a Bundler gem source as Bundler does not
|
49
|
+
support S3 sources natively. An easy way is to use a CloudFront distribution, which you can secure via http basic auth
|
50
|
+
using a Lambda Function. See [Wiki](https://github.com/webandtech/s3_gem_host/wiki) for instructions.
|
51
|
+
|
52
|
+
3. Your gem publishing pipleline should look something like this:
|
53
|
+
1. `bundle exec rake release:guard_clean` # from bundler/gem_tasks: check for any uncommitted files
|
54
|
+
2. `bundle exec rake build` # from bundler/gem_tasks: build your new gem file
|
55
|
+
3. `bundle exec rake release:source_control_push` # from bundler/gem_tasks: tag and push the new version to source control
|
56
|
+
4. `bundle exec rake s3_gem_host:push` # from this gem: push your gem to S3
|
57
|
+
* You will receive an error if you are missing any of the required ENV variables - see [Configuration](#configuration)
|
58
|
+
|
59
|
+
4. Use your gem via the `source` option. The root directory of the source is your gem name, i.e.
|
60
|
+
```ruby
|
61
|
+
# Gemfile
|
62
|
+
|
63
|
+
gem 'your-private-gem', source: 'https://username:password@yours3bucket/your-private-gem'
|
64
|
+
```
|
65
|
+
|
66
|
+
### Yanking a Gem
|
67
|
+
You can unpublish a gem from S3 using the `s3_gem_host:yank` Rake task. For example:
|
68
|
+
* `bundle exec rake s3_gem_host:yank[2.10.1]` will remove your gem version 2.10.1 from the S3 bucket and associated
|
69
|
+
index.
|
70
|
+
|
71
|
+
## How it works
|
72
|
+
|
73
|
+
1. The rake task `s3_gem_host:push` pulls down the current contents of your S3 bucket into a cache dir,
|
74
|
+
starting at `/{gem_name}`
|
75
|
+
2. Your newly built gem is copied into the cache dir
|
76
|
+
3. An index is created using the `gem generate_index` command
|
77
|
+
4. All files are pushed back up to S3
|
78
|
+
|
79
|
+
## Using your S3 Gem Host
|
80
|
+
|
81
|
+
See the [Wiki](https://github.com/webandtech/s3_gem_host/wiki).
|
data/Rakefile
ADDED
data/lib/s3_gem_host.rb
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
module S3GemHost
|
6
|
+
# Service used for S3 Gem Host rake tasks
|
7
|
+
class TaskHelper
|
8
|
+
include Rake::DSL
|
9
|
+
extend Rake::DSL
|
10
|
+
|
11
|
+
attr_accessor :aws_access_key_id, :aws_secret_access_key, :bucket_name, :aws_region
|
12
|
+
|
13
|
+
CACHE_DIR = './s3_gem_host_cache'
|
14
|
+
PACKAGE_DIR = './pkg'
|
15
|
+
|
16
|
+
def initialize(aws_access_key_id:, aws_secret_access_key:, bucket_name:, aws_region:)
|
17
|
+
self.aws_access_key_id = aws_access_key_id
|
18
|
+
self.aws_secret_access_key = aws_secret_access_key
|
19
|
+
self.bucket_name = bucket_name
|
20
|
+
self.aws_region = aws_region
|
21
|
+
end
|
22
|
+
|
23
|
+
# rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/BlockLength
|
24
|
+
def self.install
|
25
|
+
namespace :s3_gem_host do
|
26
|
+
desc 'Publish a newly built gem version to S3. Run `rake build` first.'
|
27
|
+
task :push do
|
28
|
+
unless ENV['S3_GEM_HOST_BUCKET'] && ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'] &&
|
29
|
+
ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY']
|
30
|
+
raise 'S3_GEM_HOST_BUCKET, S3_GEM_HOST_AWS_ACCESS_KEY_ID, and S3_GEM_HOST_AWS_SECRET_ACCESS_KEY '\
|
31
|
+
'are required to be set in ENV'
|
32
|
+
end
|
33
|
+
|
34
|
+
helper = S3GemHost::TaskHelper.new(
|
35
|
+
aws_access_key_id: ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'],
|
36
|
+
aws_secret_access_key: ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY'],
|
37
|
+
bucket_name: ENV['S3_GEM_HOST_BUCKET'],
|
38
|
+
aws_region: ENV['S3_GEM_HOST_AWS_REGION'] || 'us-east-1'
|
39
|
+
)
|
40
|
+
|
41
|
+
begin
|
42
|
+
helper.bootstrap_directories!
|
43
|
+
helper.clone_from_s3
|
44
|
+
helper.copy_in_gem
|
45
|
+
helper.create_index
|
46
|
+
helper.upload_to_s3
|
47
|
+
ensure
|
48
|
+
helper.cleanup!
|
49
|
+
end
|
50
|
+
|
51
|
+
rake_output_message "#{helper.built_gem_file} pushed to S3 successfully."
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Remove a previously published gem version from S3'
|
55
|
+
task :yank, [:version] do |_t, args|
|
56
|
+
raise ArgumentError, 'version is required' unless (version = args[:version])
|
57
|
+
|
58
|
+
unless ENV['S3_GEM_HOST_BUCKET'] && ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'] &&
|
59
|
+
ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY']
|
60
|
+
raise 'S3_GEM_HOST_BUCKET, S3_GEM_HOST_AWS_ACCESS_KEY_ID, and S3_GEM_HOST_AWS_SECRET_ACCESS_KEY '\
|
61
|
+
'are required to be set in ENV'
|
62
|
+
end
|
63
|
+
|
64
|
+
helper = S3GemHost::TaskHelper.new(
|
65
|
+
aws_access_key_id: ENV['S3_GEM_HOST_AWS_ACCESS_KEY_ID'],
|
66
|
+
aws_secret_access_key: ENV['S3_GEM_HOST_AWS_SECRET_ACCESS_KEY'],
|
67
|
+
bucket_name: ENV['S3_GEM_HOST_BUCKET'],
|
68
|
+
aws_region: ENV['S3_GEM_HOST_AWS_REGION'] || 'us-east-1'
|
69
|
+
)
|
70
|
+
|
71
|
+
begin
|
72
|
+
helper.bootstrap_directories!
|
73
|
+
helper.clone_from_s3
|
74
|
+
helper.delete_version!(version)
|
75
|
+
helper.create_index
|
76
|
+
helper.upload_to_s3
|
77
|
+
ensure
|
78
|
+
helper.cleanup!
|
79
|
+
end
|
80
|
+
|
81
|
+
rake_output_message "Yanked version #{version} from S3 successfully."
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
# rubocop:enable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/BlockLength
|
86
|
+
|
87
|
+
def bootstrap_directories!
|
88
|
+
cleanup!
|
89
|
+
|
90
|
+
mkdir CACHE_DIR
|
91
|
+
rake_output_message "created #{CACHE_DIR}"
|
92
|
+
|
93
|
+
gem_base_dir = "#{CACHE_DIR}/#{gem_name}"
|
94
|
+
mkdir gem_base_dir
|
95
|
+
rake_output_message "created #{gem_base_dir}"
|
96
|
+
|
97
|
+
gems_dir = "#{CACHE_DIR}/#{gem_name}/gems"
|
98
|
+
mkdir gems_dir
|
99
|
+
rake_output_message "created #{gems_dir}"
|
100
|
+
|
101
|
+
true
|
102
|
+
end
|
103
|
+
|
104
|
+
def built_gem_file
|
105
|
+
return @built_gem_file if @built_gem_file
|
106
|
+
|
107
|
+
built_gem_file = File.join('./pkg', "#{gem_name}-#{gem_version}.gem")
|
108
|
+
raise "Cannot find #{built_gem_file}" unless File.exist?(built_gem_file)
|
109
|
+
|
110
|
+
@built_gem_file = File.basename(built_gem_file)
|
111
|
+
end
|
112
|
+
|
113
|
+
def clone_from_s3
|
114
|
+
prefix = "#{gem_name}/gems/"
|
115
|
+
bucket.objects(prefix: prefix, delimiter: '/').each do |s3_obj|
|
116
|
+
next if s3_obj.key == prefix # skip the directory S3 object itself
|
117
|
+
|
118
|
+
new_file = File.join(CACHE_DIR, s3_obj.key)
|
119
|
+
s3_obj.download_file(new_file)
|
120
|
+
rake_output_message "copied #{s3_obj.key} to #{new_file}"
|
121
|
+
end
|
122
|
+
|
123
|
+
true
|
124
|
+
end
|
125
|
+
|
126
|
+
def copy_in_gem
|
127
|
+
# If the same gem file / version already exists in S3, stop release
|
128
|
+
if File.exist?("#{CACHE_DIR}/#{gem_name}/gems/#{built_gem_file}")
|
129
|
+
raise "This gem version already exists in the S3 bucket: #{self.bucket_name}"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Copy the built gem into the s3 cache dir
|
133
|
+
cp "./pkg/#{built_gem_file}", "#{CACHE_DIR}/#{gem_name}/gems"
|
134
|
+
rake_output_message "copied #{built_gem_file} to #{CACHE_DIR}/#{gem_name}/gems"
|
135
|
+
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
139
|
+
def delete_version!(version)
|
140
|
+
file = "#{CACHE_DIR}/#{gem_name}/gems/#{gem_name}-#{version}.gem"
|
141
|
+
raise "Gem #{File.basename(file)} could not be found" unless File.exist?(file)
|
142
|
+
|
143
|
+
rm_f file
|
144
|
+
obj = bucket.object(file.sub(%r{^#{CACHE_DIR}/}, ''))
|
145
|
+
obj.delete
|
146
|
+
|
147
|
+
true
|
148
|
+
end
|
149
|
+
|
150
|
+
def create_index
|
151
|
+
sh "cd #{CACHE_DIR}/#{gem_name} && gem generate_index ."
|
152
|
+
rake_output_message 'created gem version index'
|
153
|
+
|
154
|
+
true
|
155
|
+
end
|
156
|
+
|
157
|
+
def upload_to_s3
|
158
|
+
# Sync the local cache dir up to S3
|
159
|
+
files_to_upload = Dir["#{CACHE_DIR}/**/*"]
|
160
|
+
files_to_upload.each do |f|
|
161
|
+
next if File.directory?(f)
|
162
|
+
|
163
|
+
obj = bucket.object(f.sub(%r{^#{CACHE_DIR}/}, ''))
|
164
|
+
|
165
|
+
# Don't re-upload existing gem versions
|
166
|
+
next if File.extname(f) == '.gem' && obj.exists?
|
167
|
+
|
168
|
+
obj.upload_file(f)
|
169
|
+
rake_output_message "uploaded #{f} to S3"
|
170
|
+
end
|
171
|
+
|
172
|
+
true
|
173
|
+
end
|
174
|
+
|
175
|
+
def bucket
|
176
|
+
@bucket ||= Aws::S3::Resource.new(
|
177
|
+
credentials: Aws::Credentials.new(self.aws_access_key_id, self.aws_secret_access_key),
|
178
|
+
region: self.aws_region
|
179
|
+
).bucket(self.bucket_name)
|
180
|
+
end
|
181
|
+
|
182
|
+
def gem_name
|
183
|
+
gemspec.name
|
184
|
+
end
|
185
|
+
|
186
|
+
def gem_version
|
187
|
+
gemspec.version
|
188
|
+
end
|
189
|
+
|
190
|
+
def cleanup!
|
191
|
+
rm_rf(CACHE_DIR)
|
192
|
+
rake_output_message "deleted #{CACHE_DIR}"
|
193
|
+
|
194
|
+
true
|
195
|
+
end
|
196
|
+
|
197
|
+
def gemspec
|
198
|
+
return @gemspec if @gemspec
|
199
|
+
|
200
|
+
gemspecs = Dir[File.join(Dir.getwd, '{,*}.gemspec')]
|
201
|
+
raise 'Unable to find gemspec' unless gemspecs.any?
|
202
|
+
|
203
|
+
@gemspec = Bundler.load_gemspec(gemspecs.first)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
data/s3_gem_host.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 's3_gem_host/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 's3_gem_host'
|
9
|
+
spec.version = S3GemHost::VERSION
|
10
|
+
spec.authors = ['Aaron Severs']
|
11
|
+
spec.license = 'MIT'
|
12
|
+
|
13
|
+
spec.summary = 'Rake tasks to enable using Amazon S3 as a Ruby gem server'
|
14
|
+
spec.description = 'Provides Rake tasks to manage gem hosting on AWS S3 without the need for a separate gem '\
|
15
|
+
'server. This is especially useful for hosting private gems.'
|
16
|
+
spec.homepage = 'https://github.com/WebAndTech/s3_gem_host'
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
f.match(%r{^(test|spec|features)/})
|
20
|
+
end
|
21
|
+
|
22
|
+
spec.add_dependency 'aws-sdk-s3', '~> 1.64'
|
23
|
+
spec.add_dependency 'builder'
|
24
|
+
spec.add_dependency 'bundler'
|
25
|
+
spec.add_dependency 'rake'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: s3_gem_host
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aaron Severs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-05-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk-s3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.64'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.64'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: builder
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Provides Rake tasks to manage gem hosting on AWS S3 without the need
|
70
|
+
for a separate gem server. This is especially useful for hosting private gems.
|
71
|
+
email:
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".rubocop.yml"
|
79
|
+
- ".rubocop_todo.yml"
|
80
|
+
- ".ruby-gemset"
|
81
|
+
- ".ruby-version"
|
82
|
+
- ".travis.yml"
|
83
|
+
- CHANGES.md
|
84
|
+
- CONTRIBUTING.md
|
85
|
+
- Gemfile
|
86
|
+
- Gemfile.lock
|
87
|
+
- MIT-LICENSE
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- lib/s3_gem_host.rb
|
91
|
+
- lib/s3_gem_host/task_helper.rb
|
92
|
+
- lib/s3_gem_host/version.rb
|
93
|
+
- s3_gem_host.gemspec
|
94
|
+
homepage: https://github.com/WebAndTech/s3_gem_host
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubygems_version: 3.0.8
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Rake tasks to enable using Amazon S3 as a Ruby gem server
|
117
|
+
test_files: []
|