milestoner 17.11.0 → 18.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.adoc +183 -79
  4. data/lib/milestoner/builders/ascii_doc.rb +30 -10
  5. data/lib/milestoner/builders/container.rb +1 -0
  6. data/lib/milestoner/builders/feed.rb +46 -0
  7. data/lib/milestoner/builders/markdown.rb +30 -10
  8. data/lib/milestoner/builders/stream.rb +19 -8
  9. data/lib/milestoner/builders/web.rb +46 -16
  10. data/lib/milestoner/cli/actions/build/basename.rb +27 -0
  11. data/lib/milestoner/cli/actions/build/format.rb +4 -4
  12. data/lib/milestoner/cli/actions/build/label.rb +3 -3
  13. data/lib/milestoner/cli/actions/build/layout.rb +3 -3
  14. data/lib/milestoner/cli/actions/build/max.rb +24 -0
  15. data/lib/milestoner/cli/actions/build/root.rb +3 -3
  16. data/lib/milestoner/cli/actions/build/stylesheet.rb +36 -0
  17. data/lib/milestoner/cli/actions/build/tail.rb +26 -0
  18. data/lib/milestoner/cli/actions/build/version.rb +7 -3
  19. data/lib/milestoner/cli/actions/cache/delete.rb +1 -1
  20. data/lib/milestoner/cli/actions/cache/find.rb +2 -2
  21. data/lib/milestoner/cli/actions/cache/info.rb +1 -1
  22. data/lib/milestoner/cli/actions/cache/list.rb +2 -2
  23. data/lib/milestoner/cli/actions/next.rb +2 -2
  24. data/lib/milestoner/cli/actions/publish.rb +19 -4
  25. data/lib/milestoner/cli/commands/build.rb +15 -25
  26. data/lib/milestoner/cli/commands/cache.rb +1 -1
  27. data/lib/milestoner/commits/categorizer.rb +2 -2
  28. data/lib/milestoner/commits/enricher.rb +1 -1
  29. data/lib/milestoner/commits/enrichers/body.rb +2 -2
  30. data/lib/milestoner/commits/enrichers/format.rb +2 -2
  31. data/lib/milestoner/commits/enrichers/issue.rb +2 -2
  32. data/lib/milestoner/commits/enrichers/milestone.rb +1 -1
  33. data/lib/milestoner/commits/enrichers/note.rb +2 -2
  34. data/lib/milestoner/commits/enrichers/review.rb +2 -2
  35. data/lib/milestoner/commits/enrichers/uri.rb +2 -2
  36. data/lib/milestoner/commits/tagger.rb +78 -0
  37. data/lib/milestoner/configuration/contract.rb +30 -8
  38. data/lib/milestoner/configuration/defaults.yml +49 -24
  39. data/lib/milestoner/configuration/model.rb +17 -8
  40. data/lib/milestoner/configuration/transformers/build/template_paths.rb +4 -4
  41. data/lib/milestoner/configuration/transformers/citations/description.rb +5 -3
  42. data/lib/milestoner/configuration/transformers/citations/label.rb +2 -3
  43. data/lib/milestoner/configuration/transformers/citations/uri.rb +48 -0
  44. data/lib/milestoner/configuration/transformers/gems/description.rb +8 -2
  45. data/lib/milestoner/configuration/transformers/gems/label.rb +6 -3
  46. data/lib/milestoner/configuration/transformers/gems/name.rb +8 -2
  47. data/lib/milestoner/configuration/transformers/gems/uri.rb +12 -3
  48. data/lib/milestoner/configuration/transformers/generator/label.rb +2 -2
  49. data/lib/milestoner/configuration/transformers/generator/uri.rb +2 -2
  50. data/lib/milestoner/configuration/transformers/generator/version.rb +2 -2
  51. data/lib/milestoner/configuration/transformers/project/author.rb +5 -2
  52. data/lib/milestoner/configuration/transformers/project/label.rb +2 -2
  53. data/lib/milestoner/configuration/transformers/project/version.rb +2 -2
  54. data/lib/milestoner/configuration/transformers/syndication/link.rb +33 -0
  55. data/lib/milestoner/container.rb +20 -16
  56. data/lib/milestoner/models/commit.rb +2 -0
  57. data/lib/milestoner/models/tag.rb +8 -0
  58. data/lib/milestoner/renderers/universal.rb +2 -2
  59. data/lib/milestoner/syndication/builder.rb +120 -0
  60. data/lib/milestoner/syndication/refine.rb +25 -0
  61. data/lib/milestoner/syndication/shared.rb +25 -0
  62. data/lib/milestoner/tags/creator.rb +11 -33
  63. data/lib/milestoner/tags/publisher.rb +13 -5
  64. data/lib/milestoner/tags/pusher.rb +22 -13
  65. data/lib/milestoner/templates/layouts/page.html.erb +7 -1
  66. data/lib/milestoner/templates/layouts/page.xml.erb +11 -0
  67. data/lib/milestoner/templates/milestones/_avatar.adoc.erb +1 -0
  68. data/lib/milestoner/templates/milestones/_avatar.html.erb +1 -1
  69. data/lib/milestoner/templates/milestones/_avatar.md.erb +2 -0
  70. data/lib/milestoner/templates/milestones/_avatar.xml.erb +5 -0
  71. data/lib/milestoner/templates/milestones/_commit.adoc.erb +1 -1
  72. data/lib/milestoner/templates/milestones/_commit.html.erb +18 -8
  73. data/lib/milestoner/templates/milestones/_commit.md.erb +1 -1
  74. data/lib/milestoner/templates/milestones/_commit.xml.erb +84 -0
  75. data/lib/milestoner/templates/milestones/_icon.adoc.erb +1 -0
  76. data/lib/milestoner/templates/milestones/_icon.html.erb +2 -2
  77. data/lib/milestoner/templates/milestones/_icon.md.erb +5 -0
  78. data/lib/milestoner/templates/milestones/_icon.xml.erb +5 -0
  79. data/lib/milestoner/templates/milestones/_profile.adoc.erb +1 -0
  80. data/lib/milestoner/templates/milestones/_profile.md.erb +1 -0
  81. data/lib/milestoner/templates/milestones/_profile.xml.erb +5 -0
  82. data/lib/milestoner/templates/milestones/_tag.adoc.erb +13 -0
  83. data/lib/milestoner/templates/milestones/_tag.html.erb +82 -0
  84. data/lib/milestoner/templates/milestones/_tag.md.erb +18 -0
  85. data/lib/milestoner/templates/milestones/_tag.stream.erb +14 -0
  86. data/lib/milestoner/templates/milestones/_tag.xml.erb +27 -0
  87. data/lib/milestoner/templates/milestones/show.adoc.erb +1 -11
  88. data/lib/milestoner/templates/milestones/show.html.erb +1 -46
  89. data/lib/milestoner/templates/milestones/show.md.erb +1 -11
  90. data/lib/milestoner/templates/milestones/show.stream.erb +1 -11
  91. data/lib/milestoner/templates/milestones/show.xml.erb +1 -0
  92. data/lib/milestoner/templates/public/page.css.erb +111 -60
  93. data/lib/milestoner/views/context.rb +7 -4
  94. data/lib/milestoner/views/milestones/show.rb +4 -29
  95. data/lib/milestoner/views/parts/commit.rb +8 -8
  96. data/lib/milestoner/views/parts/tag.rb +51 -0
  97. data/milestoner.gemspec +8 -7
  98. data.tar.gz.sig +0 -0
  99. metadata +58 -22
  100. metadata.gz.sig +3 -3
  101. data/lib/milestoner/configuration/transformers/project/generator.rb +0 -35
  102. data/lib/milestoner/configuration/transformers/project/name.rb +0 -21
  103. data/lib/milestoner/configuration/transformers/uri/avatar.rb +0 -20
  104. data/lib/milestoner/configuration/transformers/uri/commit.rb +0 -23
  105. data/lib/milestoner/configuration/transformers/uri/profile.rb +0 -20
  106. data/lib/milestoner/configuration/transformers/uri/review.rb +0 -23
  107. data/lib/milestoner/configuration/transformers/uri/tracker.rb +0 -23
  108. data/lib/milestoner/error.rb +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1255acd044e29091a00367789d4195504041d78cdcb3af87476706515573557
4
- data.tar.gz: 4a86d410450bc65f58c7d3adcfb26dc9bf9cf85a8ee750b529975a5293c3af47
3
+ metadata.gz: 76e4ef8c308033e3c5cba943cb70576e5d007e9ece3c4fa7f04bfd3f850e375d
4
+ data.tar.gz: 62337b7d1b1b2a6a1dcc86c4ea56561e8c0366340b5a26acfda02db9df08025b
5
5
  SHA512:
6
- metadata.gz: 65e1f365abd930edc196776f5845461b0ea109afd096215e029bb5caed4e166827c9271ee092404675fc8bcdb00171ad160287e11884b09363eeaa53a3d5d724
7
- data.tar.gz: 67cb01e24f0eecbe9f7fba9d4257e12f7acbd4d8e4c9fe100853b71549a5ff26acbdecb12030228b6143c865f678c93a5d63946413cdc835e1feff141e326035
6
+ metadata.gz: 4746fbaef4b0e92976ab68a072f034caa50d1e72d0c7719e922cbd9b2740dafb47adae19bdf31d097a048e34c7a9f3ba7b40da64266b592ba4548ee5442c6926
7
+ data.tar.gz: accaea8fc8770d2fe8c7129140b634f7787352055359fe592f8412025860c9c26e25eceb07fcb2e2a97d8796899367e5f0e9779799585f7cc5138142e6f33d4f
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -5,28 +5,34 @@
5
5
  :ascii_doc_link: link:https://asciidoctor.org/docs/what-is-asciidoc[ASCII Doc]
6
6
  :cff_link: link:https://github.com/citation-file-format/ruby-cff[CFF]
7
7
  :etcher_link: link:https://alchemists.io/projects/etcher[Etcher]
8
+ :firefox_link: link:https://www.mozilla.org/en-US/firefox[Firefox]
8
9
  :gem_specification_link: link:https://guides.rubygems.org/specification-reference[Gem Specification]
9
10
  :gemsmith_link: link:https://alchemists.io/projects/gemsmith[Gemsmith]
10
11
  :git_commit_anatomy_link: link:https://alchemists.io/articles/git_commit_anatomy[Git Commit Anatomy]
11
12
  :git_link: link:https://git-scm.com[Git]
12
13
  :git_lint_link: link:https://alchemists.io/projects/git-lint[Git Lint]
14
+ :git_trailers_link: link:https://alchemists.io/articles/git_trailers[Git Trailers]
13
15
  :hanami_link: link:https://hanamirb.org[Hanami]
14
16
  :hanami_views_link: link:https://alchemists.io/articles/hanami_views[Hanami Views]
15
17
  :hanamismith_link: link:https://alchemists.io/projects/hanamismith[Hanamismith]
18
+ :iterm_link: link:https://iterm2.com[iTerm 2]
16
19
  :lode_link: link:https://alchemists.io/projects/lode[Lode]
17
20
  :markdown_link: link:https://daringfireball.net/projects/markdown[Markdown]
21
+ :marked_link: link:https://marked2app.com[Marked 2]
22
+ :net_news_wire_link: link:https://netnewswire.com[NetNewsWire]
18
23
  :ruby_link: link:https://www.ruby-lang.org[Ruby]
19
24
  :rubygems_link: link:https://rubygems.org[RubyGems]
20
25
  :rubysmith_link: link:https://alchemists.io/projects/rubysmith[Rubysmith]
21
26
  :runcom_link: link:https://alchemists.io/projects/runcom[Runcom]
22
27
  :strict_semantic_versioning_link: link:https://alchemists.io/articles/strict_semantic_versioning[Strict Semantic Versioning]
23
28
  :string_formats_link: link:https://ruby-doc.org/3.3.0/format_specifications_rdoc.html[String Formats]
29
+ :syndication_link: link:https://alchemists.io/articles/syndication[Syndication]
24
30
  :versionaire_link: link:https://alchemists.io/projects/versionaire[Versionaire]
25
31
  :xdg_link: link:https://alchemists.io/projects/xdg[XDG]
26
32
 
27
33
  = Milestoner
28
34
 
29
- Milestoner is a pure {git_link} based Command Line Interface (CLI) for software deployment automation that is agnostic of the programming language or source control service you use (i.e. GitHub, GitLab, Bitbucket, etc). Each milestone (i.e. {git_link} tag) includes the automatic generation of feature rich release notes sourced from the {git_link} commits that make up the milestone. Finally, each milestone adheres to {strict_semantic_versioning_link} so your milestones remain consistent.
35
+ Milestoner is a pure {git_link} based Command Line Interface (CLI) for software deployment automation that is agnostic of the programming language or source control service you use (i.e. GitHub, GitLab, Bitbucket, etc). Each milestone (i.e. {git_link} tag) includes the automatic generation of feature rich release notes sourced from the {git_link} commits that make up the tag. Finally, each milestone adheres to {strict_semantic_versioning_link} so your milestones remain consistent.
30
36
 
31
37
  You can use Milestoner to inspect the current state of the next milestone, celebrate the team members that contribute to each milestone, and share information with stakeholders with minimal effort. By having a tool, like Milestoner, you can automate software releases in a consistent and reliable fashion. 🎉
32
38
 
@@ -41,30 +47,53 @@ toc::[]
41
47
 
42
48
  == Screenshots
43
49
 
44
- *ASCII Doc Format* (i.e. `milestoner build --format ascii_doc`)
50
+ The following are screenshots of using this gem to render release notes for the {lode_link} gem. Even though {lode_link} is used for example purposes, please keep in mind that Milestoner can be used for _any project, any programming language_.
45
51
 
46
- image:https://alchemists.io/images/projects/milestoner/screenshots/build-ascii_doc.png[Usage,width=787,height=257,role=focal_point]
52
+ === ASCII Doc Format
47
53
 
48
- *Markdown Format* (i.e. `milestoner build --format markdown`)
54
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-ascii_doc-rendered.png[Release Notes,width=890,height=742,role=focal_point]
49
55
 
50
- image:https://alchemists.io/images/projects/milestoner/screenshots/build-markdown.png[Usage,width=765,height=257,role=focal_point]
56
+ * *Command*: `milestoner build --format ascii_doc`
57
+ * *Renderer*: {ascii_doc_link}
51
58
 
52
- *Stream Format* (i.e. `milestoner build --format stream`)
59
+ === Feed Format
53
60
 
54
- image:https://alchemists.io/images/projects/milestoner/screenshots/build-stream.png[Usage,width=464,height=280,role=focal_point]
61
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-feed-rendered-collapsed.png[Release Notes,width=1121,height=1154,role=focal_point]
55
62
 
56
- *Web Format* (i.e. `milestoner build --format web`)
63
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-feed-rendered-expanded.png[Release Notes,width=1121,height=1154,role=focal_point]
57
64
 
58
- image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-collapsed.png[Usage,width=998,height=409,role=focal_point]
65
+ * *Command*: `milestoner build --format feed`
66
+ * *Renderer*: {net_news_wire_link}
59
67
 
60
- image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-expanded.png[Usage,width=983,height=701,role=focal_point]
68
+ === Markdown Format
69
+
70
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-markdown-rendered.png[Release Notes,width=712,height=717,role=focal_point]
71
+
72
+ * *Command*: `milestoner build --format markdown`
73
+ * *Renderer*: {marked_link}
74
+
75
+ === Stream Format
76
+
77
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-stream.png[Release Notes,width=451,height=370,role=focal_point]
78
+
79
+ * *Command*: `milestoner build --format stream`
80
+ * *Renderer*: {iterm_link}
81
+
82
+ === Web Format
83
+
84
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-collapsed.png[Release Notes,width=1150,height=878,role=focal_point]
85
+
86
+ image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-expanded.png[Release Notes,width=1150,height=878,role=focal_point]
87
+
88
+ * *Command*: `milestoner build --format web`
89
+ * *Renderer*: {firefox_link}
61
90
 
62
91
  == Features
63
92
 
64
93
  * Uses {versionaire_link} for {strict_semantic_versioning_link}. Example:
65
94
  ** Format: `+<major>.<minor>.<patch>+`.
66
95
  ** Example: `0.0.0`.
67
- * Ensures {git_link} commits since last tag (or initialization of repository) are included in the release notes.
96
+ * Defaults to including {git_link} commits since last tag (or initialization of repository) when building release notes. This can be customized further if desired.
68
97
  * Ensures {git_link} commit messages are grouped by prefix, in order defined, for categorization. For more details, see link:https://alchemists.io/projects/git-lint/#_commit_subject_prefix[Git Lint Commit Subject Prefix]. Defaults (can be customized):
69
98
  ** image:https://alchemists.io/images/projects/milestoner/icons/commits/fixed.png[Fixed] Fixed
70
99
  ** image:https://alchemists.io/images/projects/milestoner/icons/commits/added.png[Added] Added
@@ -72,8 +101,8 @@ image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-exp
72
101
  ** image:https://alchemists.io/images/projects/milestoner/icons/commits/removed.png[Removed] Removed
73
102
  ** image:https://alchemists.io/images/projects/milestoner/icons/commits/refactored.png[Refactored] Refactored
74
103
  * Ensures {git_link} commit messages are alphabetically sorted for release note categorization and readability.
75
- * Provides automatic versioning based on last {git_link} tag and current commit trailers. See {git_commit_anatomy_link} for details.
76
- * Supports multiple release note build formats: {ascii_doc_link}, {markdown_link}, Stream (console), and Web (HTML). Each are fully customizable via your personal {xdg_link} configuration and {hanami_views_link}.
104
+ * Provides automatic versioning based on last {git_link} tag and {git_trailers_link}. See {git_commit_anatomy_link} for details.
105
+ * Supports multiple build formats: {ascii_doc_link}, {syndication_link}, {markdown_link}, Stream (console), and Web (HTML). Each are fully customizable via your personal {xdg_link} and {hanami_views_link} configuration.
77
106
 
78
107
  == Requirements
79
108
 
@@ -122,89 +151,122 @@ The default configuration is:
122
151
  [source,yaml]
123
152
  ----
124
153
  avatar:
125
- domain: https://avatars.githubusercontent.com
126
- uri: "%<domain>s/u/%<id>s"
154
+ uri: "https://avatars.githubusercontent.com/u/%<id>s"
127
155
  build:
128
- format: web
129
- layout: page
130
- root: tmp/milestone
156
+ basename: "index"
157
+ format: "stream"
158
+ layout: "page"
159
+ max: 1
160
+ root: "tmp/milestones"
161
+ stylesheet: "page"
162
+ tail: "head"
131
163
  commit:
132
164
  categories:
133
- - emoji: ✅
134
- label: Fixed
135
- - emoji: 🟢
136
- label: Added
137
- - emoji: 🔼
138
- label: Updated
139
- - emoji: ⛔️
140
- label: Removed
141
- - emoji: 🔁
142
- label: Refactored
143
- domain: https://github.com
144
- format: asciidoc
145
- uri: "%<domain>s/%<owner>s/%<name>s/commit/%<id>s"
146
- generator:
147
- label:
148
- uri:
149
- version:
165
+ - emoji: ""
166
+ label: "Fixed"
167
+ - emoji: "🟢"
168
+ label: "Added"
169
+ - emoji: "🔼"
170
+ label: "Updated"
171
+ - emoji: "⛔️"
172
+ label: "Removed"
173
+ - emoji: "🔁"
174
+ label: "Refactored"
175
+ format: "asciidoc"
176
+ uri: "https://github.com/%<project_owner>s/%<project_name>s/commit/%<id>s"
177
+ organization:
178
+ label: "Undefined"
179
+ uri: "https://undefined.io"
150
180
  profile:
151
- domain: https://github.com
152
- uri: "%<domain>s/%<id>s"
181
+ uri: "https://github.com/%<id>s"
153
182
  project:
154
- author:
155
- description:
156
- generator:
157
- label:
158
- name:
159
- owner:
183
+ owner: "undefined"
160
184
  uri:
161
- version:
185
+ home: "%<organization_uri>s/projects/%<project_name>s"
186
+ version: "%<project_uri_home>s/versions/%<id>s"
162
187
  review:
163
- domain: https://github.com
164
- uri: "%<domain>s/%<owner>s/%<name>s/pulls/%<id>s"
188
+ uri: "https://github.com/%<project_owner>s/%<project_name>s/pulls/%<id>s"
189
+ syndication:
190
+ categories:
191
+ - label: "Milestones"
192
+ name: "milestones"
193
+ entry:
194
+ label: "%<id>s"
195
+ uri: "%<project_uri_version>s"
196
+ id: "%<project_uri_version>s"
197
+ label: "%<organization_label>s: %<project_label>s"
198
+ links:
199
+ - label: "%<organization_label>s: %<project_label>s (web)"
200
+ mime: "text/html"
201
+ relation: "alternate"
202
+ uri: "%<project_uri_home>s/versions"
203
+ - label: "%<organization_label>s: %<project_label>s (feed)"
204
+ mime: "application/atom+xml"
205
+ relation: "self"
206
+ uri: "%<project_uri_home>s/versions.xml"
165
207
  tracker:
166
- domain: https://github.com
167
- uri: "%<domain>s/%<owner>s/%<name>s/issues/%<id>s"
208
+ uri: "https://github.com/%<project_owner>s/%<project_name>s/issues/%<id>s"
168
209
  ----
169
210
 
170
211
  The above can be customized as follows:
171
212
 
172
- * `avatar`: Manages team member avatar information.
173
- ** `domain`: Required. The domain of your team member avatars. Default: GitHub.
213
+ * `avatar`: Manages team member avatar details.
174
214
  ** `uri`: Required. The URI format for linking to avatars as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the `external_id` of the user stored in the {lode_link} cache.
175
- * `build`: Manages release note builds.
176
- ** `format`: Required. The build output format. Multiple formats are supported. Default: web.
177
- ** `layout`: Required. The layout used by {hanami_views_link} when building release notes. Default: page.
178
- ** `root`: Required. The output location. This can be a relative or absolute path. Defaults to the `tmp` directory of your current project. The path is automatically created if missing.
179
- * `commit`: Manages commit categories, emojis, and hyperlinks.
180
- ** `categories`: Required. By default, only five categories are supported which pairs well with the {git_lint_link} gem. Category order is important with the first taking precedence over the second and so forth. Special characters are allowed for prefixes but should be enclosed in quotes. To disable categories, use an empty array. Example: `categories: []`.
215
+ * `build`: Manages build details.
216
+ ** `basename`: Required. The build file basename. Default: `index`. Used to customize the built file name.
217
+ ** `format`: Required. The build output format. Default: `stream`. Used to determine what format to build the release notes as. Multiple formats are supported.
218
+ ** `layout`: Required. The {hanami_views_link} layout used when building release notes. Default: page. This can be disabled when using `false` or customized further -- via your own {xdg_link} configuration -- when providing your own templates and/or partials.
219
+ ** `max`: Required. The maximum number of {git_link} tags to build. Default: 1. By default, you are limited to building release notes for changes (commits) since the last tag but you can increase the maximum to build release notes for as many tags as you like.
220
+ ** `root`: Required. The the root build directory. Default: `tmp/milestones`. This can be a relative or absolute path and defaults your current project. The path is automatically created if missing.
221
+ ** `stylesheet`: Required. The stylesheet basename which is only used by the _web_ format. Default: `page`. This can be a relative path (i.e. `../page`) which is especially handy when build `max` is set to a number greater than one so the release notes for each tag you build loads the stylesheet properly. The path is automatically created if missing.
222
+ * `commit`: Manages commit categories, emojis, hyperlinks, and formatting.
223
+ ** `categories`: Required. Defaults to five categories which pairs well with the {git_lint_link} gem. Category order is important with the first taking precedence over the second and so forth. Special characters are allowed for prefixes but should be enclosed in quotes. To disable categories, use an empty array. Example: `categories: []`.
181
224
  *** `emoji`: Required. The emoji associated with the label for output purposes. _Used by the {ascii_doc_link}, {markdown_link}, and stream build formats_. Defaults to the provided emojis.
182
225
  *** `label`: Required. Allows you to customize the category label. All commits are grouped by label which equates to the prefix, or first word, used in each commit message. The defaults pair well with the {git_lint_link} gem. Defaults to the provided labels.
183
- ** `domain`: Required. The {git_link} repository domain for all commits. Default: GitHub.
184
- ** `format`: Required. Defines the default format used for rendering commit messages unless specified in the commit trailer metadata which takes higher precedence. Default: {ascii_doc_link}.
185
- ** `uri`: Required. The URI format for linking to commits as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the commit SHA of each commit analyzed at runtime.
186
- * `generator`: Manages generator information.
226
+ ** `format`: Required. Defines the default format used for rendering commit messages unless specified in the commit trailer metadata which takes higher precedence. Default: `asciidoc`.
227
+ ** `uri`: Required. The URI for linking to commits as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the commit SHA of each commit analyzed at runtime.
228
+ * `generator`: Manages generator details.
187
229
  ** `label`: Required. The label of the generator used for all software milestones. Default: Milestoner.
188
230
  ** `uri`: Required. The URI of the generator used for all software milestones. Defaults to Milestoner's homepage URL as provided by the {gem_specification_link} of this project.
189
231
  ** `version`: Required. The version of the generator used for all software milestones. Defaults to Milestoner's current version as provided by the {gem_specification_link} of this project.
190
- * `profile`: Manages team member profile information.
191
- ** `domain`: Required. The domain of your {git_link} repository. Default: GitHub.
192
- ** `uri`: Required. The URI format for linking to profiles as formatted using {string_formats_link}. The `id` is dynamically calculated via the `handle` of the user stored in the {lode_link} cache. Default: GitHub.
193
- * `project`: Manages project information.
232
+ * `loaded_at`: Required. Dynamically calculated when the configuration is loaded and is generally meant to represent current time. You can customize this value but is not recommended.
233
+ * `organization`: Manages organization details.
234
+ ** `label`: Required. The organization's label. Can be used within other keys via {string_formats_link} and is meant for branding purposes.
235
+ ** `uri`: Required. The organization's home page URI. Can be used within other keys via {string_formats_link}.
236
+ * `profile`: Manages team member profile details.
237
+ ** `uri`: Required. The URI format for linking to profiles as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the `handle` of the user stored in the {lode_link} cache.
238
+ * `project`: Manages project details.
194
239
  ** `author`: Required. The project author. Dynamically calculated by the {etcher_link} gem in the following order: This value or {git_link} configuration user name.
195
240
  ** `description`: Optional. The project description. Dynamically calculated by the {etcher_link} gem in the following order: This value, {gem_specification_link} summary, or {cff_link} abstract.
196
- ** `generator`: ⚠️ Deprecated and will be removed in the next major version. Please use the `generator` configuration section mentioned above instead.
197
241
  ** `label`: Optional. The project label. Dynamically calculated by the {etcher_link} gem in the following order: This value, {gem_specification_link} metadata label, or {cff_link} title.
198
242
  ** `name`: Required. The project name. Dynamically calculated by the {etcher_link} gem in the following order: This value or {gem_specification_link} name.
199
- ** `owner`: Optional. The project owner. This is your source code organization or user handle. Used when formatting URLs (mentioned above). Despite being optional, it is strongly recommended you configure this value so all links are formatted properly.
200
- ** `uri`: Optional. The project URI. Dynamically calculated by the {etcher_link} gem in the following order: This value or {gem_specification_link} homepage.
201
- ** `version`: Required. The project version. Dynamically calculated based on the last {git_link} tag of your project and {git_link} `Milestone` commit trailer metadata. The default is: `0.0.0`. For more on this see, the _Automatic Versioning_ section below. You can configure a value but, keep in mind, the value will be used for _all_ deployments and release notes. Better to let this gem compute this for you.
202
- * `review`: Manages code review information.
203
- ** `domain`: Required. The domain of your code review service. Default: GitHub.
204
- ** `uri`: Required. The URI format for linking to code reviews as formatted using {string_formats_link}. Default: GitHub. The `id` is currently a _placeholder_ for future feature support when API support is added. For now this links to _all_ code reviews with the goal to link to individual code reviews based on issue tracker metadata from {git_link} commit trailers.
205
- * `tracker`: Required. Allows you to customize the issue tracker service you are using. Default: GitHub.
206
- ** `domain`: Required. The domain of your issue tracker service. Default: GitHub.
207
- ** `uri`: Required. The URI format for linking to issues as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the commit `Issue` trailer as linted by {git_lint_link}.
243
+ ** `owner`: Required. The project owner. This is your source code organization or user handle. Used when formatting URLs (mentioned above). Default: `undefined`. It is strongly recommended you configure this value so all links are formatted properly.
244
+ ** `uri`: Manages project URI details.
245
+ *** `home`: Required. The project home URI. Dynamically calculated by the {etcher_link} gem in the following order: This value, {gem_specification_link} homepage, or {cff_link} URL.
246
+ *** `icon`: Optional. The project icon URI. Used for branding. For example, you could use an organization specific URI: `"%<organization_uri>s/images/projects/%<project_name>s/favicon.ico"`.
247
+ *** `logo`: Optional. The project logo URI. Used for branding. For example, you could use an organization specific URI: `"%<organization_uri>s/images/projects/%<project_name>s/logo.png"`.
248
+ *** `version`: Required. The project version URI. Defaults to the versions folder of your project home URI. This ensures all release notes link back to your project.
249
+ ** `version`: Required. The project version. Dynamically calculated based on the last {git_link} tag of your project and {git_link} `Milestone` commit trailer metadata. The default is: `0.0.0`. For more on this see, the _Automatic Versioning_ section below. You can configure a value but is _not recommended_ since any custom value you supply will be used for _all_ deployments and release notes. You're better off letting this gem compute this for you.
250
+ * `review`: Manages code review details.
251
+ ** `uri`: Required. The URI format for linking to code reviews as formatted using {string_formats_link}. Default: GitHub. The `id` is currently a _placeholder_ for future feature support when API support is added. For now this links to _all_ code reviews with the goal to link to individual code reviews based on {git_trailers_link}.
252
+ * `syndication`: Manages syndicated feed details when used with the `feed` build format.
253
+ ** `categories`: Required. Manages category details.
254
+ *** `label`: Required. The category label. Default: Milestones.
255
+ *** `name`: Required. The category name. Default: milestone.
256
+ ** `entry`: Required. Manages feed entry details which are the details of each {git_link} tag.
257
+ *** `label`: Required. The entry label. Default: `%<id>s`. Automatically calculated, at runtime, for the current version.
258
+ *** `uri`: Required. The entry URI. The full URI to your project version. The default uses your project version URI. If customized, ensure you include `%<id>s` so the URI can properly link to the calculated version at runtime.
259
+ ** `id`: The ID of your feed which, per Atom specification, should be the the URI of your project (including version) which is why this defaults to your project version URI. If customized, ensure the `%<id>s` is included for proper runtime calculation.
260
+ ** `label`: The label of your feed and is what people will see when subscribing to your feed. Defaults to dynamic string formatting based on existing configuration values.
261
+ ** `links`: Required. Provides links to HTML and XML versions of your feed. This can be an array of links but generally you only need HTML and XML formats.
262
+ *** `label`: Required. The link label. Defaults to dynamic string formatting based on existing configuration values.
263
+ *** `mime`: Required. The mime type. Defaults to HTML and XML.
264
+ *** `relation`: Required. Identifies the relation of the link which can either be `self` (i.e. XML) or `alternate` (i.e. HTML).
265
+ *** `uri`: Required. The link URI to follow for more information. Defaults to dynamic string formatting based on existing configuration values.
266
+ * `tracker`: Required. Managed issue tracker details.
267
+ ** `uri`: Required. The URI format for linking to issues as formatted using {string_formats_link}. Default: GitHub. The `id` is dynamically calculated via the commit `Issue` trailer as linted by {git_lint_link}. When no ID can be found, this will default to _All_ issues.
268
+
269
+ As hinted at above, all URIs (including syndication), support {string_formats_link}. This means you can use the `%<key>s` format -- replacing `key` with the key of your choice -- to customize your configuration further.
208
270
 
209
271
  💡 If you ever need to know what your current configuration looks like you can jump into your applications IRB console and inspect `Milestoner::Container[:configuration]` to see full details.
210
272
 
@@ -259,6 +321,10 @@ milestoner cache --info
259
321
 
260
322
  Once team member information is stored in your cache, you'll be able to build release notes which automatically link to GitHub user information without constantly hitting the GitHub API. _Users are identified by name so the full author name used for each commit message needs to match the same user name as stored in your source repository hosting service._
261
323
 
324
+ If you don't update your cache, your release note display a question mark (?) and _unknown_ for team members as highlighted below:
325
+
326
+ image:https://alchemists.io/images/projects/milestoner/screenshots/no_cache.png[Usage,width=851,height=571,role=focal_point]
327
+
262
328
  === Build
263
329
 
264
330
  image:https://alchemists.io/images/projects/milestoner/screenshots/usage-build.png[Usage,width=679,height=437,role=focal_point]
@@ -272,7 +338,28 @@ milestoner build --format web
272
338
  # 🟢 Milestone built: /Users/bkuhlmann/Engineering/OSS/milestoner/tmp/milestone
273
339
  ----
274
340
 
275
- 💡 The above command is so useful that I use the following `msb` (i.e. Milestoner Build) Bash alias: `rm -rf tmp/milestone && milestoner build --format html && open tmp/milestone/index.html`. This allows me to quickly rebuild release notes for any project and immediately view them in my default browser.
341
+ The above command is so useful that I use the following `msw` (i.e. Milestoner Web) Bash alias to build currest release notes or release notes for several tags:
342
+
343
+ [source,bash]
344
+ ----
345
+ # Label: Milestoner (web)
346
+ # Description: Build milestone(s) in web format.
347
+ # Parameters: $1 (optional): Maximum tags to build. Default: 1.
348
+ msw() {
349
+ local max=${1:-1}
350
+
351
+ rm -rf tmp/milestones
352
+
353
+ if [[ "$max" == 1 ]]; then
354
+ milestoner build --max "$max" --format web && open "tmp/milestones/index.html"
355
+ else
356
+ milestoner build --max "$max" --stylesheet "../page" --format web
357
+ ruby -run -e httpd "tmp/milestones" --port 3030 &
358
+ open "http://localhost:3030"
359
+ fg
360
+ fi
361
+ }
362
+ ----
276
363
 
277
364
  Check out the help documentation (i.e. `milestoner build --help`) for addition usage that explains what command line options you can use to overwrite the current configuration.
278
365
 
@@ -347,19 +434,36 @@ lib/milestoner/templates
347
434
  │ ├── page.adoc.erb
348
435
  │ ├── page.html.erb
349
436
  │ ├── page.md.erb
350
- └── page.stream.erb
437
+ ├── page.stream.erb
438
+ │ └── page.xml.erb
351
439
  ├── milestones
440
+ │ ├── _avatar.adoc.erb
352
441
  │ ├── _avatar.html.erb
442
+ │ ├── _avatar.md.erb
443
+ │ ├── _avatar.xml.erb
353
444
  │ ├── _commit.adoc.erb
354
445
  │ ├── _commit.html.erb
355
446
  │ ├── _commit.md.erb
356
447
  │ ├── _commit.stream.erb
448
+ │ ├── _commit.xml.erb
449
+ │ ├── _icon.adoc.erb
357
450
  │ ├── _icon.html.erb
451
+ │ ├── _icon.md.erb
452
+ │ ├── _icon.xml.erb
453
+ │ ├── _profile.adoc.erb
358
454
  │ ├── _profile.html.erb
455
+ │ ├── _profile.md.erb
456
+ │ ├── _profile.xml.erb
457
+ │ ├── _tag.adoc.erb
458
+ │ ├── _tag.html.erb
459
+ │ ├── _tag.md.erb
460
+ │ ├── _tag.stream.erb
461
+ │ ├── _tag.xml.erb
359
462
  │ ├── show.adoc.erb
360
463
  │ ├── show.html.erb
361
464
  │ ├── show.md.erb
362
- └── show.stream.erb
465
+ ├── show.stream.erb
466
+ │ └── show.xml.erb
363
467
  └── public
364
468
  └── page.css.erb
365
469
  ....
@@ -371,11 +475,11 @@ This means you could, for example, copy all of this gem's templates to your own
371
475
  cp -r <milestoner_gem_root>/lib/milestoner/templates $HOME/.config/milestoner/templates
372
476
  ----
373
477
 
374
- Milestoner searches your {runcom_link} configuration first and, if templates are detected, will be used instead. Otherwise, Milestoner falls back to it's own templates. Once {runcom_link} has calculated all possible template locations, {hanami_views_link} handle the final loading and evaluation of your templates.
478
+ Milestoner searches your {runcom_link} configuration first and, if templates are detected, will be used instead. Otherwise, Milestoner falls back to it's own templates. Once {runcom_link} has calculated all possible template locations, {hanami_views_link} handles the final loading and evaluation of your templates.
375
479
 
376
480
  ==== Web Format
377
481
 
378
- Of all the build formats supported, the web format is the most powerful, feature rich, and is why it's the default format. The following showcases _some_ of the information rendered in this format based on commit activity.
482
+ Of all the build formats supported, the web format is the most powerful and feature rich. The following showcases _some_ of the information rendered in this format based on commit activity.
379
483
 
380
484
  *Wit Basic Git Commit*
381
485
 
@@ -4,28 +4,48 @@ require "refinements/pathname"
4
4
 
5
5
  module Milestoner
6
6
  module Builders
7
- # Builds Markdown page output.
7
+ # Builds ASCII Doc output.
8
8
  class ASCIIDoc
9
- include Milestoner::Import[:input]
9
+ include Milestoner::Import[:settings, :logger]
10
10
 
11
11
  using Refinements::Pathname
12
12
 
13
- def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
13
+ def initialize(tagger: Commits::Tagger.new, view: Views::Milestones::Show.new, **)
14
+ @tagger = tagger
14
15
  @view = view
15
- @enricher = enricher
16
16
  super(**)
17
17
  end
18
18
 
19
- def call = input.build_root.join("index.adoc").make_ancestors.tap { |path| write path }
19
+ def call
20
+ tagger.call
21
+ .fmap { |tags| build tags }
22
+ .alt_map { |message| failure message }
23
+ end
20
24
 
21
25
  private
22
26
 
23
- attr_reader :view, :enricher
27
+ attr_reader :tagger, :view
28
+
29
+ def build tags
30
+ tags.each { |tag| write tag }
31
+ settings.build_root
32
+ end
33
+
34
+ def write tag
35
+ path = make_path tag
36
+
37
+ path.write view.call(tag:, layout: settings.build_layout, format: :adoc)
38
+ logger.info { "Built: #{path}." }
39
+ end
40
+
41
+ def make_path tag
42
+ version = settings.build_max == 1 ? "" : tag.version
43
+ settings.build_root.join(version, settings.build_basename).make_ancestors.sub_ext ".adoc"
44
+ end
24
45
 
25
- def write path
26
- enricher.call.fmap do |commits|
27
- path.write view.call commits:, layout: input.build_layout, format: :adoc
28
- end
46
+ def failure message
47
+ logger.error { message }
48
+ message
29
49
  end
30
50
  end
31
51
  end
@@ -9,6 +9,7 @@ module Milestoner
9
9
  extend Containable
10
10
 
11
11
  register(:ascii_doc) { ASCIIDoc.new }
12
+ register(:feed) { Feed.new }
12
13
  register(:markdown) { Markdown.new }
13
14
  register(:stream) { Stream.new }
14
15
  register(:web) { Web.new }
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/monads"
4
+ require "refinements/pathname"
5
+
6
+ module Milestoner
7
+ module Builders
8
+ # Builds syndicated feed output.
9
+ class Feed
10
+ include Milestoner::Import[:settings, :logger]
11
+ include Dry::Monads[:result]
12
+
13
+ using Refinements::Pathname
14
+
15
+ def initialize(tagger: Commits::Tagger.new, syndicator: Syndication::Builder.new, **)
16
+ @tagger = tagger
17
+ @syndicator = syndicator
18
+ super(**)
19
+ end
20
+
21
+ def call
22
+ tagger.call
23
+ .bind { |tags| syndicator.call tags }
24
+ .fmap { |body| write body }
25
+ .alt_map { |message| failure message }
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :tagger, :syndicator
31
+
32
+ def write body
33
+ root = settings.build_root
34
+ path = root.join(settings.build_basename).make_ancestors.sub_ext(".xml").write body
35
+
36
+ logger.info { "Built: #{path}." }
37
+ root
38
+ end
39
+
40
+ def failure message
41
+ logger.error { message }
42
+ message
43
+ end
44
+ end
45
+ end
46
+ end
@@ -4,28 +4,48 @@ require "refinements/pathname"
4
4
 
5
5
  module Milestoner
6
6
  module Builders
7
- # Builds Markdown page output.
7
+ # Builds Markdown output.
8
8
  class Markdown
9
- include Milestoner::Import[:input]
9
+ include Milestoner::Import[:settings, :logger]
10
10
 
11
11
  using Refinements::Pathname
12
12
 
13
- def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
13
+ def initialize(tagger: Commits::Tagger.new, view: Views::Milestones::Show.new, **)
14
+ @tagger = tagger
14
15
  @view = view
15
- @enricher = enricher
16
16
  super(**)
17
17
  end
18
18
 
19
- def call = input.build_root.join("index.md").make_ancestors.tap { |path| write path }
19
+ def call
20
+ tagger.call
21
+ .fmap { |tags| build tags }
22
+ .alt_map { |message| failure message }
23
+ end
20
24
 
21
25
  private
22
26
 
23
- attr_reader :view, :enricher
27
+ attr_reader :tagger, :view
28
+
29
+ def build tags
30
+ tags.each { |tag| write tag }
31
+ settings.build_root
32
+ end
33
+
34
+ def write tag
35
+ path = make_path tag
36
+
37
+ path.write view.call(tag:, layout: settings.build_layout, format: :md)
38
+ logger.info { "Built: #{path}." }
39
+ end
40
+
41
+ def make_path tag
42
+ version = settings.build_max == 1 ? "" : tag.version
43
+ settings.build_root.join(version, settings.build_basename).make_ancestors.sub_ext ".md"
44
+ end
24
45
 
25
- def write path
26
- enricher.call.fmap do |commits|
27
- path.write view.call commits:, layout: input.build_layout, format: :md
28
- end
46
+ def failure message
47
+ logger.error { message }
48
+ message
29
49
  end
30
50
  end
31
51
  end
@@ -6,26 +6,37 @@ module Milestoner
6
6
  module Builders
7
7
  # Builds I/O stream output.
8
8
  class Stream
9
- include Milestoner::Import[:input, :kernel]
9
+ include Milestoner::Import[:settings, :logger, :io]
10
10
 
11
11
  using Refinements::Pathname
12
12
 
13
- def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
13
+ def initialize(tagger: Commits::Tagger.new, view: Views::Milestones::Show.new, **)
14
+ @tagger = tagger
14
15
  @view = view
15
- @enricher = enricher
16
16
  super(**)
17
17
  end
18
18
 
19
19
  def call
20
- enricher.call.fmap do |commits|
21
- kernel.puts view.call(commits:, layout: input.build_layout, format: :stream).to_s
22
- kernel
23
- end
20
+ tagger.call
21
+ .fmap { |tags| build tags }
22
+ .alt_map { |message| failure message }
24
23
  end
25
24
 
26
25
  private
27
26
 
28
- attr_reader :view, :enricher
27
+ attr_reader :tagger, :view
28
+
29
+ def build tags
30
+ tags.each { |tag| write tag }
31
+ io
32
+ end
33
+
34
+ def write(tag) = io.write view.call(tag:, layout: settings.build_layout, format: :stream)
35
+
36
+ def failure message
37
+ logger.error { message }
38
+ message
39
+ end
29
40
  end
30
41
  end
31
42
  end