milestoner 17.0.0 → 17.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +3 -1
- data/README.adoc +107 -58
- data/lib/milestoner/builders/ascii_doc.rb +32 -0
- data/lib/milestoner/builders/container.rb +2 -0
- data/lib/milestoner/builders/markdown.rb +32 -0
- data/lib/milestoner/cli/actions/build/format.rb +1 -1
- data/lib/milestoner/cli/actions/build/label.rb +1 -1
- data/lib/milestoner/cli/actions/build/version.rb +1 -1
- data/lib/milestoner/cli/actions/cache/delete.rb +1 -4
- data/lib/milestoner/cli/actions/cache/find.rb +1 -4
- data/lib/milestoner/cli/actions/publish.rb +1 -1
- data/lib/milestoner/cli/commands/build.rb +9 -4
- data/lib/milestoner/commits/enricher.rb +2 -3
- data/lib/milestoner/configuration/contract.rb +4 -3
- data/lib/milestoner/configuration/model.rb +2 -0
- data/lib/milestoner/configuration/transformers/build/template_paths.rb +1 -4
- data/lib/milestoner/configuration/transformers/citations/description.rb +8 -6
- data/lib/milestoner/configuration/transformers/citations/label.rb +8 -6
- data/lib/milestoner/configuration/transformers/gems/description.rb +4 -6
- data/lib/milestoner/configuration/transformers/gems/label.rb +5 -6
- data/lib/milestoner/configuration/transformers/gems/name.rb +4 -6
- data/lib/milestoner/configuration/transformers/gems/uri.rb +5 -6
- data/lib/milestoner/configuration/transformers/generator/label.rb +31 -0
- data/lib/milestoner/configuration/transformers/generator/uri.rb +31 -0
- data/lib/milestoner/configuration/transformers/project/author.rb +5 -4
- data/lib/milestoner/configuration/transformers/project/generator.rb +8 -1
- data/lib/milestoner/configuration/transformers/project/label.rb +4 -4
- data/lib/milestoner/configuration/transformers/project/name.rb +6 -4
- data/lib/milestoner/configuration/transformers/project/version.rb +5 -3
- data/lib/milestoner/container.rb +2 -1
- data/lib/milestoner/templates/layouts/page.adoc.erb +2 -0
- data/lib/milestoner/templates/layouts/page.html.erb +10 -2
- data/lib/milestoner/templates/layouts/page.md.erb +2 -0
- data/lib/milestoner/templates/layouts/page.stream.erb +1 -0
- data/lib/milestoner/templates/milestones/_commit.adoc.erb +1 -0
- data/lib/milestoner/templates/milestones/_commit.md.erb +1 -0
- data/lib/milestoner/templates/milestones/show.adoc.erb +9 -0
- data/lib/milestoner/templates/milestones/show.html.erb +2 -2
- data/lib/milestoner/templates/milestones/show.md.erb +9 -0
- data/lib/milestoner/templates/milestones/show.stream.erb +4 -0
- data/lib/milestoner/templates/public/page.css.erb +19 -2
- data/lib/milestoner/views/context.rb +2 -0
- data/lib/milestoner/views/milestones/show.rb +3 -2
- data/lib/milestoner.rb +1 -1
- data/milestoner.gemspec +3 -3
- data.tar.gz.sig +0 -0
- metadata +16 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2069b8a67bf9cf6a786fade18de6256506c610d44c73705f24803d758f606dac
|
4
|
+
data.tar.gz: 4f8001a067a33034cd76c378b4e9e6c95f450754354658bcbe3e51169f32bf05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aea11fff1c1b7d10e8910dafae3496b206f0df8be716ad0bb8fd708bf0eb70d3b29280d9b17373b5732c8af720bc4f81912e29584430dbd61959975f4a75c93f
|
7
|
+
data.tar.gz: cd130868800665f2fe370edb5cae1a4074672ed8f8743a1636baa74d4336f2681bf4af21efde43285408f836acf87ecd046d214a4f9edf1381957431ee1408c3
|
checksums.yaml.gz.sig
CHANGED
data/README.adoc
CHANGED
@@ -2,58 +2,78 @@
|
|
2
2
|
:toclevels: 5
|
3
3
|
:figure-caption!:
|
4
4
|
|
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
|
-
:gem_specification_link: link:https://guides.rubygems.org/specification-reference
|
8
|
+
:gem_specification_link: link:https://guides.rubygems.org/specification-reference[Gem Specification]
|
9
|
+
:gemsmith_link: link:https://alchemists.io/projects/gemsmith[Gemsmith]
|
9
10
|
:git_commit_anatomy_link: link:https://alchemists.io/articles/git_commit_anatomy[Git Commit Anatomy]
|
11
|
+
:git_link: link:https://git-scm.com[Git]
|
10
12
|
:git_lint_link: link:https://alchemists.io/projects/git-lint[Git Lint]
|
11
|
-
:
|
13
|
+
:hanami_link: link:https://hanamirb.org[Hanami]
|
14
|
+
:hanami_views_link: link:https://alchemists.io/articles/hanami_views[Hanami View]
|
15
|
+
:hanamismith_link: link:https://alchemists.io/projects/hanamismith[Hanamismith]
|
12
16
|
:lode_link: link:https://alchemists.io/projects/lode[Lode]
|
13
17
|
:markdown_link: link:https://daringfireball.net/projects/markdown[Markdown]
|
18
|
+
:ruby_link: link:https://www.ruby-lang.org[Ruby]
|
19
|
+
:rubygems_link: link:https://rubygems.org[RubyGems]
|
20
|
+
:rubysmith_link: link:https://alchemists.io/projects/rubysmith[Rubysmith]
|
14
21
|
:runcom_link: link:https://alchemists.io/projects/runcom[Runcom]
|
22
|
+
:strict_semantic_versioning_link: link:https://alchemists.io/articles/strict_semantic_versioning[Strict Semantic Versioning]
|
15
23
|
:string_formats_link: link:https://ruby-doc.org/3.3.0/format_specifications_rdoc.html[String Formats]
|
16
24
|
:versionaire_link: link:https://alchemists.io/projects/versionaire[Versionaire]
|
17
25
|
:xdg_link: link:https://alchemists.io/projects/xdg[XDG]
|
18
26
|
|
19
27
|
= Milestoner
|
20
28
|
|
21
|
-
Milestoner is a Command Line Interface (CLI) for
|
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.
|
22
30
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
31
|
+
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
|
+
|
33
|
+
Milestoner pairs well with the following gems:
|
34
|
+
|
35
|
+
* {git_lint_link}: Lints each {git_link} commit to ensure they are of high quality for historic inspection and release note generation.
|
36
|
+
* {rubysmith_link}: Automates building new {ruby_link} projects.
|
37
|
+
* {gemsmith_link}: Automates building new {rubygems_link} projects.
|
38
|
+
* {hanamismith_link}: Automates building new {hanami_link} projects.
|
27
39
|
|
28
40
|
toc::[]
|
29
41
|
|
30
42
|
== Screenshots
|
31
43
|
|
32
|
-
*
|
44
|
+
*ASCII Doc Format* (i.e. `milestoner build --format ascii_doc`)
|
33
45
|
|
34
|
-
image:https://alchemists.io/images/projects/milestoner/screenshots/build-
|
46
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-ascii_doc.png[Usage,width=787,height=257,role=focal_point]
|
35
47
|
|
36
|
-
|
48
|
+
*Markdown Format* (i.e. `milestoner build --format markdown`)
|
49
|
+
|
50
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-markdown.png[Usage,width=765,height=257,role=focal_point]
|
37
51
|
|
38
52
|
*Stream Format* (i.e. `milestoner build --format stream`)
|
39
53
|
|
40
|
-
image:https://alchemists.io/images/projects/milestoner/screenshots/build-stream.png[Usage,width=464,height=
|
54
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-stream.png[Usage,width=464,height=280,role=focal_point]
|
55
|
+
|
56
|
+
*Web Format* (i.e. `milestoner build --format web`)
|
57
|
+
|
58
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-collapsed.png[Usage,width=998,height=409,role=focal_point]
|
59
|
+
|
60
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/build-web-expanded.png[Usage,width=983,height=701,role=focal_point]
|
41
61
|
|
42
62
|
== Features
|
43
63
|
|
44
|
-
* Uses
|
45
|
-
link:https://semver.org[Semantic Versioning].
|
64
|
+
* Uses {versionaire_link} for {strict_semantic_versioning_link}. Example:
|
46
65
|
** Format: `+<major>.<minor>.<patch>+`.
|
47
66
|
** Example: `0.0.0`.
|
48
|
-
* Ensures
|
49
|
-
* Ensures
|
67
|
+
* Ensures {git_link} commits since last tag (or initialization of repository) are included in the release notes.
|
68
|
+
* 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):
|
50
69
|
** image:https://alchemists.io/images/projects/milestoner/icons/commits/fixed.png[Fixed] Fixed
|
51
70
|
** image:https://alchemists.io/images/projects/milestoner/icons/commits/added.png[Added] Added
|
52
71
|
** image:https://alchemists.io/images/projects/milestoner/icons/commits/updated.png[Updated] Updated
|
53
72
|
** image:https://alchemists.io/images/projects/milestoner/icons/commits/removed.png[Removed] Removed
|
54
73
|
** image:https://alchemists.io/images/projects/milestoner/icons/commits/refactored.png[Refactored] Refactored
|
55
|
-
* Ensures
|
56
|
-
* Provides automatic versioning based on last
|
74
|
+
* 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} templates.
|
57
77
|
|
58
78
|
== Requirements
|
59
79
|
|
@@ -123,6 +143,9 @@ commit:
|
|
123
143
|
domain: https://github.com
|
124
144
|
format: asciidoc
|
125
145
|
uri: "%<domain>s/%<owner>s/%<name>s/commit/%<id>s"
|
146
|
+
generator:
|
147
|
+
label:
|
148
|
+
uri:
|
126
149
|
profile:
|
127
150
|
domain: https://github.com
|
128
151
|
uri: "%<domain>s/%<id>s"
|
@@ -146,46 +169,53 @@ tracker:
|
|
146
169
|
The above can be customized as follows:
|
147
170
|
|
148
171
|
* `avatar`: Manages team member avatar information.
|
149
|
-
** `domain`: The domain of your team member avatars.
|
150
|
-
** `uri`: The URI format for linking to avatars as formatted using {string_formats_link}. The `id` is dynamically calculated via the `external_id` of the user stored in the {lode_link} cache.
|
172
|
+
** `domain`: Required. The domain of your team member avatars. Default: GitHub.
|
173
|
+
** `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.
|
151
174
|
* `build`: Manages release note builds.
|
152
|
-
** `format`: The build output format. Multiple formats are supported.
|
153
|
-
** `layout`: The layout used by {hanami_views_link} when building release notes.
|
154
|
-
** `root`: The output location. This can be a relative or absolute path.
|
175
|
+
** `format`: Required. The build output format. Multiple formats are supported. Default: web.
|
176
|
+
** `layout`: Required. The layout used by the {hanami_views_link} gem when building release notes. Default: page.
|
177
|
+
** `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.
|
155
178
|
* `commit`: Manages commit categories, emojis, and hyperlinks.
|
156
|
-
** `categories`: 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: []`.
|
157
|
-
*** `emoji`: The emoji associated with the label for output purposes.
|
158
|
-
*** `label`: 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.
|
159
|
-
** `domain`: The
|
160
|
-
** `format`: Defines the default format used for rendering commit messages unless specified in the commit trailer metadata which takes higher precedence.
|
161
|
-
** `uri`: The URI format for linking to commits as formatted using {string_formats_link}. The `id` is dynamically calculated via the commit SHA of each commit analyzed at runtime.
|
179
|
+
** `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: []`.
|
180
|
+
*** `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.
|
181
|
+
*** `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.
|
182
|
+
** `domain`: Required. The {git_link} repository domain for all commits. Default: GitHub.
|
183
|
+
** `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}.
|
184
|
+
** `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.
|
185
|
+
* `generator`: Manages generator information.
|
186
|
+
** `label`: Required. The label of the generator used for all software milestones. Default: Milestoner.
|
187
|
+
** `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.
|
162
188
|
* `profile`: Manages team member profile information.
|
163
|
-
** `domain`: The domain of your
|
164
|
-
** `uri`: 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.
|
189
|
+
** `domain`: Required. The domain of your {git_link} repository. Default: GitHub.
|
190
|
+
** `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.
|
165
191
|
* `project`: Manages project information.
|
166
|
-
** `author`:
|
167
|
-
** `description`: Optional. The project description. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} summary, {cff_link} abstract
|
168
|
-
** `generator`:
|
169
|
-
** `label`: Optional. The project label. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} metadata label, {cff_link} title
|
170
|
-
** `name`:
|
171
|
-
** `owner`:
|
172
|
-
** `uri`: Optional. The project URI. Dynamically calculated by the {etcher_link} gem in the following order: {gem_specification_link} homepage
|
173
|
-
** `version`:
|
192
|
+
** `author`: Required. The project author. Dynamically calculated by the {etcher_link} gem in the following order: This value or {git_link} configuration user name.
|
193
|
+
** `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.
|
194
|
+
** `generator`: ⚠️ Deprecated and will be removed in the next major version. Please use the `generator` configuration section mentioned above instead.
|
195
|
+
** `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.
|
196
|
+
** `name`: Required. The project name. Dynamically calculated by the {etcher_link} gem in the following order: This value or {gem_specification_link} name.
|
197
|
+
** `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.
|
198
|
+
** `uri`: Optional. The project URI. Dynamically calculated by the {etcher_link} gem in the following order: This value or {gem_specification_link} homepage.
|
199
|
+
** `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.
|
174
200
|
* `review`: Manages code review information.
|
175
|
-
** `domain`: The domain of your code review service.
|
176
|
-
** `uri`: The URI format for linking to code reviews as formatted using {string_formats_link}. 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
|
177
|
-
* `tracker`: Allows you to customize the issue tracker service you are using.
|
178
|
-
** `domain`: The domain of your issue tracker service.
|
179
|
-
** `uri`: The URI format for linking to issues as formatted using {string_formats_link}. The `id` is dynamically calculated via the commit `Issue` trailer as linted by {git_lint_link}.
|
201
|
+
** `domain`: Required. The domain of your code review service. Default: GitHub.
|
202
|
+
** `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.
|
203
|
+
* `tracker`: Required. Allows you to customize the issue tracker service you are using. Default: GitHub.
|
204
|
+
** `domain`: Required. The domain of your issue tracker service. Default: GitHub.
|
205
|
+
** `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}.
|
180
206
|
|
181
|
-
💡 If you ever need to know what your
|
207
|
+
💡 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.
|
182
208
|
|
183
209
|
=== Config
|
184
210
|
|
185
|
-
|
211
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/usage-config.png[Usage,width=632,height=352,role=focal_point]
|
212
|
+
|
213
|
+
Milestoner can be configured via the command line using: `milestoner config`. This allows you to create, edit, view, and/or delete your global or local configuration as desired. The configuration is managed by the {runcom_link} gem which is built atop the {xdg_link} gem for managing global or local configurations. Please read the documentation of each gem to learn more.
|
186
214
|
|
187
215
|
=== Cache
|
188
216
|
|
217
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/usage-cache.png[Usage,width=625,height=318,role=focal_point]
|
218
|
+
|
189
219
|
Milestoner's cache allows you to enrich user information (i.e. authors, collaborators, etc) by storing information in a `PStore` database as managed by the {lode_link} gem. Cache location, as with the Config, is managed by the {runcom_link} gem.
|
190
220
|
|
191
221
|
User information should be sourced from whatever service you use for managing your source code. For example, when using GitHub, your workflow might look like this:
|
@@ -229,11 +259,13 @@ Once team member information is stored in your cache, you'll be able to build re
|
|
229
259
|
|
230
260
|
=== Build
|
231
261
|
|
232
|
-
|
262
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/usage-build.png[Usage,width=679,height=437,role=focal_point]
|
263
|
+
|
264
|
+
The build command allows you to quickly build release notes to check the current status of your project or deploy a new milestone. By default, the build command uses either the default or custom configuration as documented in the _Configuration_ section above. This means, when using the defaults, you can immediately build the release notes for your project in a temporary directory:
|
233
265
|
|
234
266
|
[source,bash]
|
235
267
|
----
|
236
|
-
milestoner build --format
|
268
|
+
milestoner build --format web
|
237
269
|
# 🟢 Building milestone...
|
238
270
|
# 🟢 Milestone built: /Users/bkuhlmann/Engineering/OSS/milestoner/tmp/milestone
|
239
271
|
----
|
@@ -244,7 +276,7 @@ Check out the help documentation (i.e. `milestoner build --help`) for addition u
|
|
244
276
|
|
245
277
|
==== Automatic Versioning
|
246
278
|
|
247
|
-
As mentioned earlier, the calculation of version information happens automatically for you based on your last
|
279
|
+
As mentioned earlier, the calculation of version information happens automatically for you based on your last {git_link} tag and any {git_link} commit trailer metadata used. If none of this information is present, then the default version of `0.0.0` is used instead. All of this information is available to you via the following command:
|
248
280
|
|
249
281
|
[source,bash]
|
250
282
|
----
|
@@ -262,7 +294,7 @@ milestoner build --format stream
|
|
262
294
|
milestoner build --format stream --version 1.2.3
|
263
295
|
----
|
264
296
|
|
265
|
-
By default, automatic versioning is based on your last known
|
297
|
+
By default, automatic versioning is based on your last known {git_link} tag and the version is bumped based on {git_link} commit trailer information from untagged commits (i.e. those commits created since the last tag). All of this is managed via the {versionaire_link} gem. To ensure automatic versioning works properly, you only need to add the `Milestone` {git_link} commit trailer with a value of: `patch`, `minor`, or `major`. Here's an example assuming you have published Version 1.0.0:
|
266
298
|
|
267
299
|
....
|
268
300
|
# First commit.
|
@@ -305,20 +337,26 @@ Given the above, the resulting version would be: 2.0.0. This is because the high
|
|
305
337
|
|
306
338
|
==== Templates
|
307
339
|
|
308
|
-
Build template functionality is powered by {hanami_views_link} which means you can customize the HTML structure, CSS style, and more. The quickest way to get started is to copy the `templates` folder structure -- included with this gem -- to your preferred {runcom_link} configuration. For example, this gem's template structure is:
|
340
|
+
Build template functionality is powered by the {hanami_views_link} gem which means you can customize the HTML structure, CSS style, and more. The quickest way to get started is to copy the `templates` folder structure -- included with this gem -- to your preferred {runcom_link} configuration. For example, this gem's template structure is:
|
309
341
|
|
310
342
|
....
|
311
343
|
lib/milestoner/templates
|
312
344
|
├── layouts
|
345
|
+
│ ├── page.adoc.erb
|
313
346
|
│ ├── page.html.erb
|
347
|
+
│ ├── page.md.erb
|
314
348
|
│ └── page.stream.erb
|
315
349
|
├── milestones
|
316
350
|
│ ├── _avatar.html.erb
|
351
|
+
│ ├── _commit.adoc.erb
|
317
352
|
│ ├── _commit.html.erb
|
353
|
+
│ ├── _commit.md.erb
|
318
354
|
│ ├── _commit.stream.erb
|
319
355
|
│ ├── _icon.html.erb
|
320
356
|
│ ├── _profile.html.erb
|
357
|
+
│ ├── show.adoc.erb
|
321
358
|
│ ├── show.html.erb
|
359
|
+
│ ├── show.md.erb
|
322
360
|
│ └── show.stream.erb
|
323
361
|
└── public
|
324
362
|
└── page.css.erb
|
@@ -333,9 +371,23 @@ cp -r <milestoner_gem_root>/lib/milestoner/templates $HOME/.config/milestoner/te
|
|
333
371
|
|
334
372
|
Milestoner searches your {runcom_link} configuration first and, if templates are detected, will be used instead. Otherwise, Milestoner will fall 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.
|
335
373
|
|
374
|
+
==== Web Format
|
375
|
+
|
376
|
+
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.
|
377
|
+
|
378
|
+
*Wit Basic Git Commit*
|
379
|
+
|
380
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/web_format-overview.png[Usage,width=1228,height=808,role=focal_point]
|
381
|
+
|
382
|
+
*With Git Commit Notes and Trailers*
|
383
|
+
|
384
|
+
image:https://alchemists.io/images/projects/milestoner/screenshots/web_format-notes_and_collaborators.png[Usage,width=1228,height=808,role=focal_point]
|
385
|
+
|
386
|
+
Each milestone is meant to provide you with the right amount of statistical information you can make informed decisions.
|
387
|
+
|
336
388
|
== Security
|
337
389
|
|
338
|
-
To securely sign your
|
390
|
+
To securely sign your {git_link} tags, install and configure https://www.gnupg.org[GPG]:
|
339
391
|
|
340
392
|
[source,bash]
|
341
393
|
----
|
@@ -358,8 +410,7 @@ To obtain your key, run the following and take the part after the forward slash:
|
|
358
410
|
gpg --list-keys | grep pub
|
359
411
|
....
|
360
412
|
|
361
|
-
Add your key to your global (or local)
|
362
|
-
enabled. Example:
|
413
|
+
Add your key to your global (or local) {git_link} configuration and ensure GPG signing for your tag is enabled. Example:
|
363
414
|
|
364
415
|
....
|
365
416
|
[tag]
|
@@ -369,10 +420,8 @@ enabled. Example:
|
|
369
420
|
....
|
370
421
|
|
371
422
|
Now, when publishing a new milestone (i.e. `milestoner --publish <version>`), the signing of your
|
372
|
-
|
373
|
-
|
374
|
-
link:https://gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html#Invoking-GPG_002dAGENT[GPG
|
375
|
-
Agent] in the background (highly recommend).
|
423
|
+
{git_link} tag will happen automatically. You will be prompted for the GPG Passphrase each time unless you are running the
|
424
|
+
link:https://gnupg.org/documentation/manuals/gnupg/Invoking-GPG_002dAGENT.html#Invoking-GPG_002dAGENT[GPG Agent] in the background (highly recommend).
|
376
425
|
|
377
426
|
== Development
|
378
427
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module Builders
|
5
|
+
# Builds Markdown page output.
|
6
|
+
class ASCIIDoc
|
7
|
+
include Milestoner::Import[:input]
|
8
|
+
|
9
|
+
using Refinements::Pathname
|
10
|
+
|
11
|
+
def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
|
12
|
+
@view = view
|
13
|
+
@enricher = enricher
|
14
|
+
super(**)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call at: Time.now.utc
|
18
|
+
input.build_root.join("index.adoc").make_ancestors.tap { |path| write path, at }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :view, :enricher
|
24
|
+
|
25
|
+
def write path, at
|
26
|
+
enricher.call.fmap do |commits|
|
27
|
+
path.write view.call commits:, at:, layout: input.build_layout, format: :adoc
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -8,6 +8,8 @@ module Milestoner
|
|
8
8
|
module Container
|
9
9
|
extend Dry::Container::Mixin
|
10
10
|
|
11
|
+
register(:ascii_doc, memoize: true) { ASCIIDoc.new }
|
12
|
+
register(:markdown, memoize: true) { Markdown.new }
|
11
13
|
register(:stream, memoize: true) { Stream.new }
|
12
14
|
register(:web, memoize: true) { Web.new }
|
13
15
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Milestoner
|
4
|
+
module Builders
|
5
|
+
# Builds Markdown page output.
|
6
|
+
class Markdown
|
7
|
+
include Milestoner::Import[:input]
|
8
|
+
|
9
|
+
using Refinements::Pathname
|
10
|
+
|
11
|
+
def initialize(view: Views::Milestones::Show.new, enricher: Commits::Enricher.new, **)
|
12
|
+
@view = view
|
13
|
+
@enricher = enricher
|
14
|
+
super(**)
|
15
|
+
end
|
16
|
+
|
17
|
+
def call at: Time.now.utc
|
18
|
+
input.build_root.join("index.md").make_ancestors.tap { |path| write path, at }
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :view, :enricher
|
24
|
+
|
25
|
+
def write path, at
|
26
|
+
enricher.call.fmap do |commits|
|
27
|
+
path.write view.call commits:, at:, layout: input.build_layout, format: :md
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -12,7 +12,7 @@ module Milestoner
|
|
12
12
|
|
13
13
|
description "Set output format."
|
14
14
|
|
15
|
-
on %w[-f --format], argument: "[KIND]", allow: %w[stream web]
|
15
|
+
on %w[-f --format], argument: "[KIND]", allow: %w[ascii_doc markdown stream web]
|
16
16
|
|
17
17
|
default { Container[:configuration].build_format }
|
18
18
|
|
@@ -16,7 +16,7 @@ module Milestoner
|
|
16
16
|
|
17
17
|
on %w[-l --label], argument: "[TEXT]"
|
18
18
|
|
19
|
-
default {
|
19
|
+
default { Container[:configuration].project_label }
|
20
20
|
|
21
21
|
def call(label = nil) = input.project_label = label || default
|
22
22
|
end
|
@@ -21,7 +21,7 @@ module Milestoner
|
|
21
21
|
|
22
22
|
on %w[-v --version], argument: "[VERSION]"
|
23
23
|
|
24
|
-
default {
|
24
|
+
default { Container[:configuration].project_version }
|
25
25
|
|
26
26
|
def call(version = nil) = input.project_version = Version(version || default)
|
27
27
|
end
|
@@ -9,7 +9,7 @@ module Milestoner
|
|
9
9
|
# Handles the building of milestone output.
|
10
10
|
class Build < Sod::Command
|
11
11
|
include Import[:input, :logger, :kernel]
|
12
|
-
include Builders::Import[:stream, :web]
|
12
|
+
include Builders::Import[:ascii_doc, :markdown, :stream, :web]
|
13
13
|
|
14
14
|
using Refinements::Pathname
|
15
15
|
|
@@ -23,15 +23,18 @@ module Milestoner
|
|
23
23
|
on Actions::Build::Format
|
24
24
|
on Actions::Build::Root
|
25
25
|
|
26
|
+
# :reek:TooManyStatements
|
26
27
|
def call
|
27
28
|
log_info "Building milestone..."
|
28
29
|
|
29
30
|
format = input.build_format
|
30
31
|
|
31
32
|
case format
|
33
|
+
when "ascii_doc" then build_ascii_doc
|
34
|
+
when "markdown" then build_markdown
|
32
35
|
when "stream" then build_stream
|
33
36
|
when "web" then build_web
|
34
|
-
else
|
37
|
+
else logger.abort "Invalid build format: #{format}."
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -39,6 +42,10 @@ module Milestoner
|
|
39
42
|
|
40
43
|
attr_reader :view, :enricher
|
41
44
|
|
45
|
+
def build_ascii_doc = log_info("Milestone built: #{ascii_doc.call}.")
|
46
|
+
|
47
|
+
def build_markdown = log_info("Milestone built: #{markdown.call}.")
|
48
|
+
|
42
49
|
def build_stream
|
43
50
|
kernel.puts
|
44
51
|
stream.call
|
@@ -47,8 +54,6 @@ module Milestoner
|
|
47
54
|
def build_web = log_info "Milestone built: #{web.call}."
|
48
55
|
|
49
56
|
def log_info(message) = logger.info { message }
|
50
|
-
|
51
|
-
def log_error(message) = logger.error { message }
|
52
57
|
end
|
53
58
|
end
|
54
59
|
end
|
@@ -27,7 +27,6 @@ module Milestoner
|
|
27
27
|
@categorizer = categorizer
|
28
28
|
@model = model
|
29
29
|
super(**)
|
30
|
-
@commands = %i[author body collaborators format issue milestone notes review signers uri]
|
31
30
|
end
|
32
31
|
|
33
32
|
def call
|
@@ -38,12 +37,12 @@ module Milestoner
|
|
38
37
|
|
39
38
|
private
|
40
39
|
|
41
|
-
attr_reader :categorizer, :model
|
40
|
+
attr_reader :categorizer, :model
|
42
41
|
|
43
42
|
def record_for(commit) = model.for(commit, **build_attributes(commit))
|
44
43
|
|
45
44
|
def build_attributes commit
|
46
|
-
|
45
|
+
infused_keys.each.with_object({}) do |command, attributes|
|
47
46
|
attributes[command] = __send__(command).call commit
|
48
47
|
end
|
49
48
|
end
|
@@ -23,15 +23,16 @@ module Milestoner
|
|
23
23
|
required(:commit_domain).filled :string
|
24
24
|
required(:commit_format).filled :string
|
25
25
|
required(:commit_uri).filled :string
|
26
|
+
required(:generator_label).filled :string
|
27
|
+
required(:generator_uri).filled :string
|
26
28
|
required(:profile_domain).filled :string
|
27
29
|
required(:profile_uri).filled :string
|
28
30
|
required(:project_author).filled :string
|
29
|
-
optional(:project_description).
|
30
|
-
required(:project_generator).filled :string
|
31
|
+
optional(:project_description).maybe :string
|
31
32
|
optional(:project_label).filled :string
|
32
33
|
required(:project_name).filled :string
|
33
34
|
optional(:project_owner).filled :string
|
34
|
-
optional(:project_uri).
|
35
|
+
optional(:project_uri).maybe :string
|
35
36
|
required(:project_version).filled Etcher::Types::Version
|
36
37
|
required(:review_domain).filled :string
|
37
38
|
required(:review_uri).filled :string
|
@@ -3,6 +3,7 @@
|
|
3
3
|
require "cff"
|
4
4
|
require "dry/monads"
|
5
5
|
require "pathname"
|
6
|
+
require "refinements/hash"
|
6
7
|
|
7
8
|
module Milestoner
|
8
9
|
module Configuration
|
@@ -12,6 +13,8 @@ module Milestoner
|
|
12
13
|
class Description
|
13
14
|
include Dry::Monads[:result]
|
14
15
|
|
16
|
+
using Refinements::Hash
|
17
|
+
|
15
18
|
def initialize key = :project_description,
|
16
19
|
path: Pathname.pwd.join("CITATION.cff"),
|
17
20
|
citation: CFF::File
|
@@ -20,16 +23,15 @@ module Milestoner
|
|
20
23
|
@citation = citation
|
21
24
|
end
|
22
25
|
|
23
|
-
def call
|
26
|
+
def call content
|
27
|
+
content.fetch_value(key) { citation.open(path).abstract }
|
28
|
+
.then { |value| value unless String(value).empty? }
|
29
|
+
.then { |value| Success content.merge!(key => value) }
|
30
|
+
end
|
24
31
|
|
25
32
|
private
|
26
33
|
|
27
34
|
attr_reader :key, :path, :citation
|
28
|
-
|
29
|
-
def process content
|
30
|
-
content.fetch(key) { citation.open(path).abstract }
|
31
|
-
.then { |value| String(value).empty? ? content : content.merge!(key => value) }
|
32
|
-
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|