capistrano-fiesta 1.4.1 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/capistrano-fiesta.gemspec +1 -0
- data/lib/capistrano/fiesta/announcement.rb +32 -0
- data/lib/capistrano/fiesta/auto_composed_story.rb +15 -0
- data/lib/capistrano/fiesta/editor.rb +6 -5
- data/lib/capistrano/fiesta/github.rb +5 -0
- data/lib/capistrano/fiesta/release.rb +32 -0
- data/lib/capistrano/fiesta/report.rb +53 -29
- data/lib/capistrano/fiesta/story.rb +8 -7
- data/lib/capistrano/fiesta/template.rb +21 -0
- data/lib/capistrano/fiesta/version.rb +1 -1
- data/lib/capistrano/tasks/fiesta.rake +35 -14
- data/lib/capistrano/templates/draft.erb +0 -4
- metadata +20 -3
- data/lib/capistrano/fiesta/draft.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d2c67bd3f3a7967e8c0d2e21ac1cad88572c1c4
|
4
|
+
data.tar.gz: bff17d6f9c990d1196cea630f61acdb4861d6764
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ef2d2eef7c9c4dcc79e9c1906394b6bbd0eaac76d3f9d9e2a24b2047892e88b473d65dfadae9abce0e4d787f24057b62b0a2c2afb01f441cf5ab9e4b85e70a2
|
7
|
+
data.tar.gz: 7c106e2d4245732539088c88f5425228401c8b453e32804de58942d6b7a48fe3113fbafe43ce17a1403f03876cc1750a2dcfd297ea963fc37593a99132731045
|
data/capistrano-fiesta.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
+
spec.add_dependency "attr_extras", "~> 5.2"
|
22
23
|
spec.add_dependency "capistrano", "~> 3.1"
|
23
24
|
spec.add_dependency "octokit", "~> 4.1"
|
24
25
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "attr_extras/explicit"
|
2
|
+
require "capistrano/fiesta/slack_dummy"
|
3
|
+
|
4
|
+
module Capistrano
|
5
|
+
module Fiesta
|
6
|
+
class Announcement
|
7
|
+
extend AttrExtras.mixin
|
8
|
+
pattr_initialize :text, :config
|
9
|
+
|
10
|
+
def post
|
11
|
+
client.post(options)
|
12
|
+
text
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def options
|
18
|
+
config.merge(payload: payload)
|
19
|
+
end
|
20
|
+
|
21
|
+
def payload
|
22
|
+
config.fetch(:payload, {}).merge(text: text)
|
23
|
+
end
|
24
|
+
|
25
|
+
def client
|
26
|
+
Slackistrano
|
27
|
+
rescue NameError
|
28
|
+
SlackDummy.new
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Fiesta
|
3
|
+
class AutoComposedStory < Story
|
4
|
+
SCREENSHOT_TAG = "#"
|
5
|
+
|
6
|
+
def release_note
|
7
|
+
release_note_in_body
|
8
|
+
end
|
9
|
+
|
10
|
+
def images
|
11
|
+
pr.body.to_s.scan(/https?:\/\/\S*\.(?:png|jpg|gif)#{SCREENSHOT_TAG}/i)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -1,11 +1,11 @@
|
|
1
|
+
require "attr_extras/explicit"
|
1
2
|
require "tempfile"
|
2
3
|
|
3
4
|
module Capistrano
|
4
5
|
module Fiesta
|
5
6
|
class Editor
|
6
|
-
|
7
|
-
|
8
|
-
end
|
7
|
+
extend AttrExtras.mixin
|
8
|
+
pattr_initialize :content, [:comment]
|
9
9
|
|
10
10
|
def compose
|
11
11
|
create_temp_file
|
@@ -16,7 +16,8 @@ module Capistrano
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def create_temp_file
|
19
|
-
file <<
|
19
|
+
file << content
|
20
|
+
file << "# #{comment}\n\n" if comment
|
20
21
|
file.close
|
21
22
|
end
|
22
23
|
|
@@ -37,7 +38,7 @@ module Capistrano
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def file
|
40
|
-
@
|
41
|
+
@_file ||= Tempfile.new(["fiesta", ".md"])
|
41
42
|
end
|
42
43
|
end
|
43
44
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "attr_extras/explicit"
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
module Fiesta
|
5
|
+
class Release
|
6
|
+
extend AttrExtras.mixin
|
7
|
+
pattr_initialize [:repo, :name, :stories]
|
8
|
+
|
9
|
+
def post
|
10
|
+
github.create_release(repo, tag, name: name, body: body)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def name
|
16
|
+
@name ||= Time.now.to_i.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def tag
|
20
|
+
"release-#{name}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def body
|
24
|
+
stories.map(&:to_markdown).join("\n")
|
25
|
+
end
|
26
|
+
|
27
|
+
def github
|
28
|
+
@_github ||= Github.client
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,44 +1,72 @@
|
|
1
|
-
Encoding.default_internal = Encoding.default_external =
|
1
|
+
Encoding.default_internal = Encoding.default_external = "utf-8"
|
2
2
|
|
3
|
+
require "attr_extras/explicit"
|
4
|
+
require "capistrano/fiesta/announcement"
|
3
5
|
require "capistrano/fiesta/github"
|
4
|
-
require "capistrano/fiesta/
|
6
|
+
require "capistrano/fiesta/template"
|
5
7
|
require "capistrano/fiesta/editor"
|
6
8
|
require "capistrano/fiesta/logger"
|
7
|
-
require "capistrano/fiesta/slack_dummy"
|
8
9
|
require "capistrano/fiesta/story"
|
10
|
+
require "capistrano/fiesta/auto_composed_story"
|
11
|
+
require "capistrano/fiesta/release"
|
9
12
|
|
10
13
|
module Capistrano
|
11
14
|
module Fiesta
|
12
15
|
class Report
|
13
|
-
|
16
|
+
extend AttrExtras.mixin
|
17
|
+
pattr_initialize :github_url, [:last_release, :comment, :auto_compose]
|
18
|
+
attr_query :auto_compose?
|
14
19
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
20
|
+
def announce(config = {})
|
21
|
+
return Logger.warn("Announcement blank, nothing posted to Slack") if nothing_to_announce?
|
22
|
+
Announcement.new(text, config).post
|
18
23
|
end
|
19
24
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
options[:payload] = options.fetch(:payload, {}).merge(text: text)
|
24
|
-
chat.post(options)
|
25
|
-
text
|
25
|
+
def create_release(name = nil)
|
26
|
+
return Logger.warn "No new stories, skipping GitHub release" if stories.none?
|
27
|
+
Release.new(repo: repo, name: name, stories: stories).post
|
26
28
|
end
|
27
29
|
|
28
|
-
def
|
29
|
-
|
30
|
-
name ||= Time.now.to_i.to_s
|
31
|
-
github.create_release(repo, "release-#{name}", name: name, body: stories.map(&:to_markdown).join("\n"))
|
30
|
+
def stories
|
31
|
+
@_stories ||= fetch_stories
|
32
32
|
end
|
33
33
|
|
34
34
|
private
|
35
35
|
|
36
|
+
def fetch_stories
|
37
|
+
if auto_compose?
|
38
|
+
merged_pull_requests.map { |pr| AutoComposedStory.new(pr) }
|
39
|
+
else
|
40
|
+
merged_pull_requests.map { |pr| Story.new(pr) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def nothing_to_announce?
|
45
|
+
stories.none? || text.nil? || text.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def text
|
49
|
+
@_text ||= render_text
|
50
|
+
end
|
51
|
+
|
52
|
+
def render_text
|
53
|
+
if auto_compose?
|
54
|
+
template
|
55
|
+
else
|
56
|
+
editor.compose
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
36
60
|
def editor
|
37
|
-
Editor.new(
|
61
|
+
Editor.new(template, comment: comment)
|
38
62
|
end
|
39
63
|
|
40
|
-
def
|
41
|
-
|
64
|
+
def template
|
65
|
+
Template.new(stories_with_release_notes).render
|
66
|
+
end
|
67
|
+
|
68
|
+
def stories_with_release_notes
|
69
|
+
stories.find_all(&:release_note)
|
42
70
|
end
|
43
71
|
|
44
72
|
def merged_pull_requests
|
@@ -49,21 +77,17 @@ module Capistrano
|
|
49
77
|
end
|
50
78
|
|
51
79
|
def repo
|
52
|
-
|
80
|
+
github_url.match(/github.com[:\/](\S+\/\S+)\.git/)[1]
|
53
81
|
end
|
54
82
|
|
55
83
|
def last_released_at
|
56
|
-
|
84
|
+
if last_release
|
85
|
+
Time.parse(last_release + "Z00:00").iso8601
|
86
|
+
end
|
57
87
|
end
|
58
88
|
|
59
89
|
def github
|
60
|
-
@
|
61
|
-
end
|
62
|
-
|
63
|
-
def chat
|
64
|
-
Slackistrano
|
65
|
-
rescue NameError
|
66
|
-
SlackDummy.new
|
90
|
+
@_github ||= Github.client
|
67
91
|
end
|
68
92
|
end
|
69
93
|
end
|
@@ -1,20 +1,21 @@
|
|
1
|
+
require "attr_extras/explicit"
|
2
|
+
|
1
3
|
module Capistrano
|
2
4
|
module Fiesta
|
3
5
|
class Story
|
4
|
-
|
5
|
-
|
6
|
-
end
|
6
|
+
extend AttrExtras.mixin
|
7
|
+
pattr_initialize :pr
|
7
8
|
|
8
9
|
def release_note
|
9
10
|
(release_note_in_body || title).strip
|
10
11
|
end
|
11
12
|
|
12
13
|
def images
|
13
|
-
|
14
|
+
pr.body.to_s.scan(/https?:\/\/\S*\.(?:png|jpg|gif)/i)
|
14
15
|
end
|
15
16
|
|
16
17
|
def url
|
17
|
-
|
18
|
+
pr.html_url
|
18
19
|
end
|
19
20
|
|
20
21
|
def to_markdown
|
@@ -24,11 +25,11 @@ module Capistrano
|
|
24
25
|
private
|
25
26
|
|
26
27
|
def title
|
27
|
-
@pr.title.to_s.sub(/\[Delivers #\S+\]\z/,
|
28
|
+
@_title ||= pr.title.to_s.sub(/\[Delivers #\S+\]\z/, "")
|
28
29
|
end
|
29
30
|
|
30
31
|
def release_note_in_body
|
31
|
-
@pr.body.to_s[/_Release\snote
|
32
|
+
@_release_note_in_body ||= pr.body.to_s[/_Release\snote\:?\s(.+)_/m, 1]
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "attr_extras/explicit"
|
2
|
+
require "erb"
|
3
|
+
|
4
|
+
module Capistrano
|
5
|
+
module Fiesta
|
6
|
+
class Template
|
7
|
+
extend AttrExtras.mixin
|
8
|
+
pattr_initialize :stories
|
9
|
+
|
10
|
+
def render
|
11
|
+
ERB.new(File.read(erb), nil, "-").result(binding)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def erb
|
17
|
+
File.join(File.expand_path("../../templates", __FILE__), "draft.erb")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,40 +1,61 @@
|
|
1
1
|
namespace :fiesta do
|
2
|
-
desc
|
2
|
+
desc "Generate a fiesta report and announce it"
|
3
3
|
task :run do
|
4
|
-
|
5
|
-
|
4
|
+
if master_branch?
|
5
|
+
invoke "fiesta:generate"
|
6
|
+
invoke "fiesta:announce"
|
7
|
+
end
|
6
8
|
end
|
7
9
|
|
8
|
-
desc
|
10
|
+
desc "Generate a fiesta report"
|
9
11
|
task :generate do
|
10
12
|
run_locally do
|
11
|
-
set :fiesta_report,
|
12
|
-
info "Deploying #{report.stories.size} new story(ies)"
|
13
|
+
set :fiesta_report, build_report
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
|
-
desc
|
17
|
+
desc "Announce a fiesta report"
|
17
18
|
task :announce do
|
18
19
|
run_locally do
|
19
20
|
report.announce(slack_params)
|
20
|
-
report.create_release
|
21
|
+
report.create_release(timestamp)
|
21
22
|
Capistrano::Fiesta::Logger.logs.each { |log| warn log }
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
26
|
+
def build_report
|
27
|
+
Capistrano::Fiesta::Report.new(repo_url, report_options)
|
28
|
+
end
|
29
|
+
|
25
30
|
def report
|
26
31
|
fetch(:fiesta_report)
|
27
32
|
end
|
28
33
|
|
34
|
+
def report_options
|
35
|
+
{
|
36
|
+
last_release: last_release,
|
37
|
+
comment: fetch(:fiesta_comment),
|
38
|
+
auto_compose: fetch(:fiesta_auto_compose)
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
29
42
|
def last_release
|
30
43
|
last_release = nil
|
31
44
|
on roles(:web).first do
|
32
45
|
last_release_path = capture("readlink #{current_path}")
|
33
|
-
last_release = last_release_path.split(
|
46
|
+
last_release = last_release_path.split("/").last
|
34
47
|
end
|
35
48
|
last_release
|
36
49
|
end
|
37
50
|
|
51
|
+
def master_branch?
|
52
|
+
fetch(:branch) == "master"
|
53
|
+
end
|
54
|
+
|
55
|
+
def timestamp
|
56
|
+
fetch(:release_timestamp)
|
57
|
+
end
|
58
|
+
|
38
59
|
def slack_params
|
39
60
|
{
|
40
61
|
team: fetch(:slack_team),
|
@@ -42,13 +63,13 @@ namespace :fiesta do
|
|
42
63
|
webhook: fetch(:slack_webhook),
|
43
64
|
via_slackbot: fetch(:slack_via_slackbot),
|
44
65
|
payload: {
|
45
|
-
channel: fetch(:fiesta_slack_channel) ||
|
46
|
-
username: fetch(:fiesta_slack_username) ||
|
47
|
-
icon_emoji:
|
66
|
+
channel: fetch(:fiesta_slack_channel) || "releases",
|
67
|
+
username: fetch(:fiesta_slack_username) || "New Releases",
|
68
|
+
icon_emoji: ":tada:"
|
48
69
|
}
|
49
70
|
}
|
50
71
|
end
|
51
72
|
end
|
52
73
|
|
53
|
-
before
|
54
|
-
after
|
74
|
+
before "deploy:starting", "fiesta:generate"
|
75
|
+
after "deploy:finished", "fiesta:announce"
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-fiesta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Balvig
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: attr_extras
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.2'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: capistrano
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,13 +183,16 @@ files:
|
|
169
183
|
- capistrano-fiesta.gemspec
|
170
184
|
- lib/capistrano-fiesta.rb
|
171
185
|
- lib/capistrano/fiesta.rb
|
172
|
-
- lib/capistrano/fiesta/
|
186
|
+
- lib/capistrano/fiesta/announcement.rb
|
187
|
+
- lib/capistrano/fiesta/auto_composed_story.rb
|
173
188
|
- lib/capistrano/fiesta/editor.rb
|
174
189
|
- lib/capistrano/fiesta/github.rb
|
175
190
|
- lib/capistrano/fiesta/logger.rb
|
191
|
+
- lib/capistrano/fiesta/release.rb
|
176
192
|
- lib/capistrano/fiesta/report.rb
|
177
193
|
- lib/capistrano/fiesta/slack_dummy.rb
|
178
194
|
- lib/capistrano/fiesta/story.rb
|
195
|
+
- lib/capistrano/fiesta/template.rb
|
179
196
|
- lib/capistrano/fiesta/version.rb
|
180
197
|
- lib/capistrano/tasks/fiesta.rake
|
181
198
|
- lib/capistrano/templates/draft.erb
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require "erb"
|
2
|
-
|
3
|
-
module Capistrano
|
4
|
-
module Fiesta
|
5
|
-
class Draft
|
6
|
-
attr_reader :comment, :stories
|
7
|
-
|
8
|
-
def initialize(comment:, stories: [])
|
9
|
-
@comment, @stories = comment, stories
|
10
|
-
end
|
11
|
-
|
12
|
-
def render
|
13
|
-
ERB.new(File.read(template), nil, '-').result(binding)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def template
|
19
|
-
File.join(File.expand_path('../../templates', __FILE__), 'draft.erb')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|