hillary 0.0.1
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 +15 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/hillary.gemspec +31 -0
- data/lib/hillary/railtie.rb +9 -0
- data/lib/hillary/repo/version.rb +94 -0
- data/lib/hillary/repo.rb +131 -0
- data/lib/hillary/shellable.rb +39 -0
- data/lib/hillary/slug/bucket.rb +32 -0
- data/lib/hillary/slug.rb +105 -0
- data/lib/hillary/tasks/rails/ci.rake +18 -0
- data/lib/hillary/version.rb +3 -0
- data/lib/hillary.rb +5 -0
- data/spec/hillary/repo/version_spec.rb +241 -0
- data/spec/hillary/repo_spec.rb +135 -0
- data/spec/hillary/slug/bucket_spec.rb +43 -0
- data/spec/hillary/slug_spec.rb +160 -0
- data/spec/hillary_spec.rb +7 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/contexts/git_repository.rb +49 -0
- metadata +201 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZTRlYjMzNTBmYmZjZmM4Yzc0NjhkZDlhZDFlYzhkNDZiZjUwYjlhZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NWM5ZTRhMzk2MzQwMWUyMzQ3M2E4Y2M3ZTQ4NGRjM2Y5MTBmYzk5OQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OTRjMjRkYzlkNDYxNTk0NTIyZWQ4YTVjNzkyZTE2MjI2NTM4ZjUyMTMzY2Ez
|
10
|
+
OTcxZDM1NjUxZDc1MGFkMGUzNmZlOTg4NTJjNTRmYTdkYTJjNDAyMGY2NWI1
|
11
|
+
YjE5ZWIxYzk4ZmU0ZjBkY2I4MzMxYTRjZGU1MzE2ZmVjMDkyYzk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YmI5NjRkMzM1ZmM3MDg2ZjJiMjM0MDhhZjlhYjA4MjA4ZmU4NjY4ODFkNzFk
|
14
|
+
NmQzOTk5MDkyZDdjM2Y3ZmNiZjcxYTM4OTEwZjY4MWY4ZjBmM2E4NWY2N2Ix
|
15
|
+
YWU5M2Q1OGRkZmNmNTRlNDNjZWRlYTVmMjc2NmU3MmE0ZDZlMjI=
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
spec/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Allen Madsen
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Hillary
|
2
|
+
|
3
|
+
A project managing gem.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'hillary'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install hillary
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( https://github.com/secondrotation/hillary/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/hillary.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hillary/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hillary"
|
8
|
+
spec.version = Hillary::VERSION
|
9
|
+
spec.authors = ["Allen Madsen"]
|
10
|
+
spec.email = ["blatyo@gmail.com"]
|
11
|
+
spec.summary = %q{Project manager for common project tasks.}
|
12
|
+
spec.description = %q{Project manager for common project tasks. Slugging and tagging so far.}
|
13
|
+
spec.homepage = "https://github.com/secondrotation/hillary"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "grit"
|
22
|
+
spec.add_dependency 'pry-debugger'
|
23
|
+
spec.add_dependency 'pry-rails'
|
24
|
+
spec.add_dependency 'bundler-audit'
|
25
|
+
spec.add_dependency 'fog'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
spec.add_development_dependency "timecop"
|
30
|
+
spec.add_development_dependency "rspec"
|
31
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require_relative '../repo'
|
2
|
+
|
3
|
+
module Hillary
|
4
|
+
class Repo
|
5
|
+
class Version
|
6
|
+
BRANCHES = [
|
7
|
+
DEV = 'dev',
|
8
|
+
MASTER = 'master'
|
9
|
+
]
|
10
|
+
|
11
|
+
InvalidRepositoryState = Class.new(StandardError)
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def create!(repo = Repo.new('.'), options = {})
|
15
|
+
options = {production: ENV['PRODUCTION']}.merge(options)
|
16
|
+
|
17
|
+
version = new(repo, options)
|
18
|
+
|
19
|
+
if version.master?
|
20
|
+
if version.production?
|
21
|
+
repo.create_production_tag
|
22
|
+
else
|
23
|
+
repo.create_rc_tag
|
24
|
+
end
|
25
|
+
|
26
|
+
version.validate!
|
27
|
+
end
|
28
|
+
|
29
|
+
version
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(repo, options = {})
|
34
|
+
@repo = repo
|
35
|
+
@options = options
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
master? ? tag : sha
|
40
|
+
end
|
41
|
+
|
42
|
+
def branch
|
43
|
+
@branch ||= @repo.head.name
|
44
|
+
end
|
45
|
+
|
46
|
+
def tag
|
47
|
+
@tag ||= production? ? production_tag : rc_tag
|
48
|
+
end
|
49
|
+
|
50
|
+
def sha
|
51
|
+
@sha ||= @repo.head.commit.sha
|
52
|
+
end
|
53
|
+
|
54
|
+
def rc_tag
|
55
|
+
@rc_tag ||= begin
|
56
|
+
rc_tag = @repo.last_rc_tag
|
57
|
+
rc_tag.name if rc_tag && rc_tag.commit.sha == sha
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias_method :rc_tag?, :rc_tag
|
61
|
+
|
62
|
+
def production_tag
|
63
|
+
@production_tag ||= begin
|
64
|
+
production_tag = @repo.last_production_tag
|
65
|
+
production_tag.name if production_tag && production_tag.commit.sha == @repo.last_rc_tag.commit.sha
|
66
|
+
end
|
67
|
+
end
|
68
|
+
alias_method :production_tag?, :production_tag
|
69
|
+
|
70
|
+
def sluggable?
|
71
|
+
BRANCHES.include?(branch)
|
72
|
+
end
|
73
|
+
|
74
|
+
def master?
|
75
|
+
branch == MASTER
|
76
|
+
end
|
77
|
+
|
78
|
+
def dev?
|
79
|
+
branch == DEV
|
80
|
+
end
|
81
|
+
|
82
|
+
def production?
|
83
|
+
@options[:production]
|
84
|
+
end
|
85
|
+
|
86
|
+
def validate!
|
87
|
+
if !@options[:production] && !rc_tag?
|
88
|
+
raise InvalidRepositoryState,
|
89
|
+
"Last RC tag '#{@repo.last_rc_tag.name}' did not point to the current head '#{branch}' (#{sha})"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
data/lib/hillary/repo.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'grit'
|
2
|
+
require 'pathname'
|
3
|
+
require_relative 'repo/version'
|
4
|
+
|
5
|
+
module Hillary
|
6
|
+
class Repo
|
7
|
+
DirtyProjectError = Class.new(StandardError)
|
8
|
+
MissingHeadError = Class.new(StandardError)
|
9
|
+
|
10
|
+
PRODUCTION_TAG_FORMAT = "%Y_%m_%d_%H_%M_%S"
|
11
|
+
RC_TAG_FORMAT = "RC#{PRODUCTION_TAG_FORMAT}"
|
12
|
+
PRODUCTION_TAG_REGEX = /^\d{4}(_\d{2}){5}$/
|
13
|
+
RC_TAG_REGEX = /^RC\d{4}(_\d{2}){5}$/
|
14
|
+
|
15
|
+
attr_reader :name, :logger
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def rc_tag_name
|
19
|
+
DateTime.now.strftime(RC_TAG_FORMAT)
|
20
|
+
end
|
21
|
+
|
22
|
+
def production_tag_name
|
23
|
+
DateTime.now.strftime(PRODUCTION_TAG_FORMAT)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(dir, logger = Logger.new($stdout))
|
28
|
+
@name = Pathname.new(File.expand_path(dir)).basename
|
29
|
+
@repo = Grit::Repo.new(dir)
|
30
|
+
@logger = logger
|
31
|
+
logger.formatter = proc{|_, _, _, msg| msg + "\n"}
|
32
|
+
end
|
33
|
+
|
34
|
+
def head
|
35
|
+
repo.head
|
36
|
+
end
|
37
|
+
|
38
|
+
def checkout(ref)
|
39
|
+
raise DirtyProjectError, "Cannot checkout '#{ref}', #{name} is dirty." if dirty?
|
40
|
+
|
41
|
+
logger.info "Checking out #{ref} and updating from origin"
|
42
|
+
if !repo.objects([ref]).empty?
|
43
|
+
git.checkout({}, ref)
|
44
|
+
else
|
45
|
+
raise MissingHeadError, "Cannot checkout '#{ref}', because it doesn't exist."
|
46
|
+
end
|
47
|
+
|
48
|
+
git.pull({}, 'origin', ref)
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_rc_tag(branch_name = 'master', tag_name = self.class.rc_tag_name)
|
52
|
+
branch = repo.remotes.find{|branch| branch.name == "origin/#{branch_name}"}
|
53
|
+
tag_and_push(tag_name, branch)
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_production_tag(tag_name = self.class.production_tag_name)
|
57
|
+
rc_tag = last_rc_tag
|
58
|
+
tag_and_push(tag_name, rc_tag)
|
59
|
+
end
|
60
|
+
|
61
|
+
def tag_and_push(tag_name, ref, message = tag_name)
|
62
|
+
ref_name = ref.respond_to?(:name) ? ref.name : ref
|
63
|
+
commit = ref.respond_to?(:commit) ? ref.commit : ref
|
64
|
+
sha = commit.respond_to?(:sha) ? commit.sha : ref
|
65
|
+
|
66
|
+
git.fetch
|
67
|
+
logger.info "Tagging #{ref_name} (#{sha}) as #{tag_name}"
|
68
|
+
git.tag({a: tag_name, m: message}, sha)
|
69
|
+
push(tag_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def delete_last_rc_tag
|
73
|
+
delete_tag_and_push(last_rc_tag.name)
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete_last_production_tag
|
77
|
+
delete_tag_and_push(last_production_tag.name)
|
78
|
+
end
|
79
|
+
|
80
|
+
def delete_tag_and_push(tag_name)
|
81
|
+
git.fetch
|
82
|
+
logger.info "Deleting #{tag_name} locally"
|
83
|
+
git.tag({d: tag_name})
|
84
|
+
push(":refs/tags/#{tag_name}")
|
85
|
+
end
|
86
|
+
|
87
|
+
def commit_and_push(files, message)
|
88
|
+
logger.info "Adding files:", *files.map{|f| " #{f}"}
|
89
|
+
git.add({}, files)
|
90
|
+
logger.info "Committing with '#{message}'"
|
91
|
+
git.commit({m: message})
|
92
|
+
logger.info "Pushing changes to origin/head"
|
93
|
+
push('head')
|
94
|
+
end
|
95
|
+
|
96
|
+
def last_rc_tag
|
97
|
+
repo.tags.select{|tag| tag.name =~ RC_TAG_REGEX}.sort_by(&:name).last
|
98
|
+
end
|
99
|
+
|
100
|
+
def last_production_tag
|
101
|
+
repo.tags.select{|tag| tag.name =~ PRODUCTION_TAG_REGEX}.sort_by(&:name).last
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
attr_reader :repo
|
106
|
+
|
107
|
+
def push(ref)
|
108
|
+
flags = if ref[/^:/]
|
109
|
+
logger.info "Deleting #{ref} on origin"
|
110
|
+
{}
|
111
|
+
else
|
112
|
+
logger.info "Pushing #{ref} to origin"
|
113
|
+
{u: true}
|
114
|
+
end
|
115
|
+
|
116
|
+
git.push(flags, 'origin', ref)
|
117
|
+
end
|
118
|
+
|
119
|
+
def dirty?
|
120
|
+
[:added, :changed, :deleted].any?{|mod| !status.send(mod).empty?}
|
121
|
+
end
|
122
|
+
|
123
|
+
def git
|
124
|
+
repo.git
|
125
|
+
end
|
126
|
+
|
127
|
+
def status
|
128
|
+
repo.status
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Hillary
|
4
|
+
module Shellable
|
5
|
+
class ExecutionError < StandardError
|
6
|
+
attr_reader :command, :output, :status
|
7
|
+
|
8
|
+
def initialize(command, output, status)
|
9
|
+
message = "#{command}\n"\
|
10
|
+
"#{output}\n"\
|
11
|
+
"status: #{status}"
|
12
|
+
|
13
|
+
super(message)
|
14
|
+
|
15
|
+
@command = command
|
16
|
+
@output = output
|
17
|
+
@status = status
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def shell(command, options = {})
|
22
|
+
binding.pry
|
23
|
+
options = {ignore_errors: false, logger: Logger.new($stdout)}.merge(options)
|
24
|
+
logger = options[:logger]
|
25
|
+
logger.info(command)
|
26
|
+
|
27
|
+
output = `#{command} 2>1`
|
28
|
+
status = $?
|
29
|
+
|
30
|
+
unless status.success?
|
31
|
+
if options[:ignore_errors]
|
32
|
+
logger.error(output)
|
33
|
+
else
|
34
|
+
raise ExecutionError.new(command, output, status.exitstatus)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'fog'
|
2
|
+
|
3
|
+
module Hillary
|
4
|
+
class Slug
|
5
|
+
class Bucket
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize(name = ENV['SLUG_BUCKET'], access_key = ENV['AWS_S3_KEY_ID'], secret_key = ENV['AWS_S3_KEY_SECRET'])
|
9
|
+
@name = name
|
10
|
+
@storage = Fog::Storage.new(
|
11
|
+
provider: 'AWS',
|
12
|
+
aws_access_key_id: access_key,
|
13
|
+
aws_secret_access_key: secret_key
|
14
|
+
)
|
15
|
+
@directory = @storage.directories.get(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def write(name, file)
|
19
|
+
@directory.files.create(
|
20
|
+
key: name,
|
21
|
+
body: File.open(file),
|
22
|
+
public: false
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def copy(source, target)
|
27
|
+
source_file = @directory.files.get(source)
|
28
|
+
source_file.copy(@name, target)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/hillary/slug.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
require_relative 'slug/bucket'
|
4
|
+
require_relative 'repo'
|
5
|
+
require_relative 'shellable'
|
6
|
+
|
7
|
+
module Hillary
|
8
|
+
class Slug
|
9
|
+
include Shellable
|
10
|
+
|
11
|
+
attr_reader :branch, :version
|
12
|
+
|
13
|
+
SlugArchiveError = Class.new(StandardError)
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def build(path = File.expand_path('.'), version = Repo::Version.create!, options = {})
|
17
|
+
return unless version.sluggable?
|
18
|
+
|
19
|
+
new(path, version, options).tap{|slug| slug.build}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(path, version, options = {})
|
24
|
+
@path = path
|
25
|
+
@version = version
|
26
|
+
@logger = options[:logger] || Logger.new($stdout)
|
27
|
+
@bucket = options[:bucket] || Bucket.new
|
28
|
+
|
29
|
+
logger.formatter = proc{|_, _, _, msg| msg + "\n"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def build
|
33
|
+
if version.master?
|
34
|
+
copy_slug
|
35
|
+
else
|
36
|
+
create_slug
|
37
|
+
upload_slug
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def name
|
42
|
+
"#{project_name}_slug_#{version.name}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def canonical_name
|
46
|
+
"#{project_name}_slug_#{version.sha}"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
attr_reader :logger, :bucket, :path
|
51
|
+
|
52
|
+
def copy_slug
|
53
|
+
logger.info("Copying #{bucket.name}:/#{canonical_storage_slug_file} to #{bucket.name}:/#{storage_slug_file}")
|
54
|
+
bucket.copy(canonical_storage_slug_file, storage_slug_file)
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_slug
|
58
|
+
Dir.chdir(project_parent_directory) do
|
59
|
+
logger.info("Creating slug #{canonical_slug_file}")
|
60
|
+
shell("tar --exclude \".git\" --exclude \"vendor/bundle\" -zcvf #{canonical_slug_file} #{project_name}")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def upload_slug
|
65
|
+
logger.info("Uploading #{canonical_slug_file} to #{bucket.name}:/#{canonical_storage_slug_file}")
|
66
|
+
bucket.write(canonical_storage_slug_file, project_parent_directory.join(canonical_slug_file))
|
67
|
+
end
|
68
|
+
|
69
|
+
def slug_file
|
70
|
+
"#{name}.tar.gz"
|
71
|
+
end
|
72
|
+
|
73
|
+
def storage_slug_file
|
74
|
+
if version.master?
|
75
|
+
if version.production?
|
76
|
+
"production/#{slug_file}"
|
77
|
+
else
|
78
|
+
"rc/#{slug_file}"
|
79
|
+
end
|
80
|
+
elsif version.dev?
|
81
|
+
"dev/#{slug_file}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def canonical_slug_file
|
86
|
+
"#{canonical_name}.tar.gz"
|
87
|
+
end
|
88
|
+
|
89
|
+
def canonical_storage_slug_file
|
90
|
+
"dev/#{canonical_slug_file}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def project_directory
|
94
|
+
Pathname.new(path).expand_path
|
95
|
+
end
|
96
|
+
|
97
|
+
def project_parent_directory
|
98
|
+
project_directory.join('..').expand_path
|
99
|
+
end
|
100
|
+
|
101
|
+
def project_name
|
102
|
+
project_directory.basename.to_s
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'hillary/shellable'
|
2
|
+
|
3
|
+
namespace :ci do
|
4
|
+
desc 'Tags the current version (for master) and creates a slug'
|
5
|
+
task :build do
|
6
|
+
require 'hillary/slug'
|
7
|
+
|
8
|
+
# Environment variables: PRODUCTION, SLUG_BUCKET, AWS_S3_KEY_ID, AWS_S3_KEY_SECRET
|
9
|
+
Hillary::Slug.build
|
10
|
+
end
|
11
|
+
|
12
|
+
include Hillary::Shellable
|
13
|
+
|
14
|
+
desc 'Audit projects Gemfile.lock'
|
15
|
+
task :audit do
|
16
|
+
shell('bundle exec bundle-audit update && bundle exec bundle-audit', ignore_errors: true)
|
17
|
+
end
|
18
|
+
end
|