toys-release 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/docs/guide.md CHANGED
@@ -18,8 +18,6 @@ This user's guide covers all the features of Toys-Release in detail, including
18
18
  installation, normal operations, release pipeline customization, and a full
19
19
  configuration reference.
20
20
 
21
- **(This user's guide is still under construction.)**
22
-
23
21
  ## Conceptual overview
24
22
 
25
23
  Toys-Release is a comprehensive release pipeline system. It includes a set of
@@ -55,11 +53,11 @@ RubyGem, but does not require familiarity with Toys.
55
53
 
56
54
  Toys-Release must be installed into a GitHub repository. This involves:
57
55
 
58
- * Installing a Toys tool;
59
- * Writing a configuration file;
60
- * Defining a set of GitHub Actions workflows and a set of GitHub labels
61
- (a tool is provided to perform this step); and
62
- * Providing necessary credentials.
56
+ * Installing a Toys tool;
57
+ * Writing a configuration file;
58
+ * Defining a set of GitHub Actions workflows and a set of GitHub labels
59
+ (a tool is provided to perform this step); and
60
+ * Providing necessary credentials.
63
61
 
64
62
  ### Prerequisites
65
63
 
@@ -178,25 +176,97 @@ and interact with the process.
178
176
 
179
177
  Overall, the process looks like this:
180
178
 
181
- 1. A maintainer schedules a release by triggering the "Open release request"
179
+ 1. During development, commit messages for all commits should be formatted
180
+ according to the [Conventional Commits](https://conventionalcommits.org)
181
+ standard. This allows Toys-Release (and other similar tools) to interpret
182
+ the semantics of your changes and configure releases accordingly.
183
+
184
+ 2. A maintainer schedules a release by triggering the "Open release request"
182
185
  GitHub Action. This action analyzes the repository, looking for changes in
183
186
  each component, deciding which components have releasable updates,
184
187
  determining the semver version bump for each, and building a changelog. It
185
188
  then opens a pull request with the version and changelog updates.
186
189
 
187
- 2. The maintainer can either merge the pull request (possibly with manual
190
+ 3. The maintainer can either merge the pull request (possibly with manual
188
191
  modifications to the changelogs and/or version numbers to release) or close
189
192
  it unmerged.
190
193
 
191
- 3. If the pull request is merged, the release is automatically processed by
194
+ 4. If the pull request is merged, the release is automatically processed by
192
195
  additional GitHub Actions. The automation verifies that the GitHub checks
193
196
  pass, and runs the release pipeline.
194
197
 
195
- 4. The results of the run are reported back to the release pull request. If
198
+ 5. The results of the run are reported back to the release pull request. If
196
199
  the release failed, a GitHub issue is also automatically opened. A
197
200
  maintainer can retry a failed release by triggering the "Retry release"
198
201
  GitHub Action.
199
202
 
203
+ ### Commit message formatting
204
+
205
+ When using Toys-Release, you should format all commit messages according to the
206
+ [Conventional Commits](https://conventionalcommits.org) standard. This allows
207
+ Toys-Release (and other similar tools) to interpret the semantics of your
208
+ changes and configure releases accordingly. (Even if you are not using such
209
+ tools, Conventional Commits encapsulates good best practice for writing useful
210
+ commit messages.) Properly formatted conventional commit messages will
211
+ determine what kind of version bump Toys-Release uses when releasing those
212
+ changes, and the commit messages themselves will be used in the changelog that
213
+ Toys-Release generates.
214
+
215
+ Specifically, a change that adds a new feature, corresponding to a minor update
216
+ under [Semantic Versioning](https://semver.org), should have a commit message
217
+ tagged with `feat:`. For example:
218
+
219
+ ```
220
+ feat: You can now upload a cat photo
221
+ ```
222
+
223
+ A change that fixes a bug, corresponding to a patch change under Semver, should
224
+ have a commit message tagged with `fix:`. For example:
225
+
226
+ ```
227
+ fix: The app no longer crashes when a photo includes a dog instead of a cat
228
+ ```
229
+
230
+ A change that updates documentation should have a commit message tagged with
231
+ `docs:`. For example:
232
+
233
+ ```
234
+ docs: Emphasize that photos should include cats rather than dogs
235
+ ```
236
+
237
+ A breaking change, which would trigger a major update under Semver, can be
238
+ expressed using either the `BREAKING CHANGE:` tag, or an exclamation mark after
239
+ any other type of tag. Here are a few examples:
240
+
241
+ ```
242
+ BREAKING CHANGE: Rename the "add-photo" API to "add-cat-photo"
243
+ feat!: Raise an exception if a photo contains a dog instead of a cat
244
+ ```
245
+
246
+ A change that does not actually make any functional change, such as a git
247
+ repository configuration change, a CI change, or other admin-level change,
248
+ should be tagged with `chore:`. For example:
249
+
250
+ ```
251
+ chore: Attach a photo of a cat to the repo
252
+ ```
253
+
254
+ Other common tags might include `refactor:`, `style:`, `test:`, and others. See
255
+ https://conventionalcommits.org for more details and discussion.
256
+
257
+ By default, Toys-Release specifically recognizes the `feat:`, `fix:`, and
258
+ `docs:` tags, and uses them to configure releases and new versions. It also
259
+ recognizes breaking changes. It considers other tags to be non-significant for
260
+ release purposes. However, you can configure this behavior using the
261
+ **commit_tags** configuration field. See the
262
+ [configuration reference](#configuration-reference) for more details.
263
+
264
+ It is legal to have multiple conventional commit formatted messages in a single
265
+ commit message. Toys-Release will parse each commit message and use all
266
+ properly formatted conventional commit messages it finds. In most cases,
267
+ however, it is good practice to keep commits small and describable via a single
268
+ conventional commit message.
269
+
200
270
  ### Requesting releases
201
271
 
202
272
  To request a release, navigate to the Actions tab in the GitHub UI, select the
@@ -216,12 +286,16 @@ appending the version to the component name, separated by a colon.
216
286
  For example, to request releases of the `toys` and `toys-release` components,
217
287
  you can enter the following text into "Components to release":
218
288
 
219
- toys toys-release
289
+ ```sh
290
+ toys toys-release
291
+ ```
220
292
 
221
293
  To make the above request but specifically request version 0.3.0 of the
222
294
  `toys-release` component:
223
295
 
224
- toys toys-release:0.3.0
296
+ ```sh
297
+ toys toys-release:0.3.0
298
+ ```
225
299
 
226
300
  ### Managing release pull requests
227
301
 
@@ -242,46 +316,256 @@ workflow will have the `release: pending` label applied. This label signals the
242
316
  release automation that this is a release pull request. If you remove this
243
317
  label, the automation will not process the release.
244
318
 
245
- Finally, you can even create a release pull request manually. You must simply
246
- ensure that:
319
+ Finally, you can even create a release pull request manually, or using your own
320
+ tools or processes. You must simply ensure that:
247
321
 
248
- * The pull request has the `release: pending` label applied
249
- * The pull request merges as a single commit (i.e. "squashed")
250
- * For each component you want to release, the version and changelog are
251
- updated appropriately.
322
+ * The pull request has the `release: pending` label applied
323
+ * The pull request merges as a single commit (i.e. "squashed")
324
+ * For each component you want to release, the version and changelog are
325
+ updated appropriately.
252
326
 
253
327
  If you close a release pull request without merging, the release will be
254
328
  canceled. The automation will apply the `release: aborted` label to indicate
255
329
  this.
256
330
 
257
- ### Release results and logs
258
-
259
- (TODO)
331
+ ### Monitoring progress and results
332
+
333
+ After a release pull request is merged, a GitHub Actions workflow will trigger
334
+ and begin processing the release. You can follow the workflow logs if you want
335
+ detailed information on the progress of the release. Additionally, updates will
336
+ be posted to the pull request when the workflow begins and when it completes.
337
+ These updates will include a link to the workflow logs for your convenience.
338
+
339
+ After a workflow finishes, it will apply a label to the pull request indicating
340
+ the final result. A successful release will have the `release: complete` label,
341
+ while an unsuccessful release will have the `release: error` label. If an error
342
+ occurred, the workflow will also open an issue in the repository reporting the
343
+ failed release.
344
+
345
+ Most of the useful workflow logs will appear in the "Process release request"
346
+ job under the workflow. If you follow the logs, you will see the release goes
347
+ through the following stages:
348
+
349
+ * First, it publishes a comment to the pull request indicating that the
350
+ release is starting.
351
+ * Second, it polls the GitHub checks for the merge commit. Toys-Release will
352
+ perform a release only if all required checks pass, so the release job will
353
+ wait for them to complete. If any checks fail, the release will fail.
354
+ * Third, it runs a set of sanity checks, for example that it is looking at
355
+ the correct repository and commit, that there are no locally modified
356
+ files, and that the version numbers are set as expected.
357
+ * Next, it runs the release pipeline itself. It first does an analysis of
358
+ which steps in the pipeline should run, then runs those steps in order.
359
+ * Finally, it publishes a comment to the pull request reporting the final
360
+ result of the release.
260
361
 
261
362
  ### Troubleshooting and retrying releases
262
363
 
263
- (TODO)
364
+ If a release fails, generally an issue will be opened in the repository, and
365
+ the pull request will have the `release: error` label applied. Releases can
366
+ fail for a number of reasons, including:
367
+
368
+ * The GitHub checks for the commit representing the merge of the release pull
369
+ request, have failed or did not complete in a timely manner.
370
+ * A failure during the release pipeline, such as an error during the build or
371
+ publication of a release artifact.
372
+ * An intermittent failure of the release pipeline infrastructure, such as a
373
+ failure to obtain a VM to execute a GitHub Actions workflow.
374
+
375
+ If a failure occurs, the release workflow may have published some basic
376
+ information on the cause, to the release pull request. You can also find more
377
+ detailed information in the release logs, a link to which should also have been
378
+ published in the pull request comments. You should use this information to
379
+ troubleshoot the release.
380
+
381
+ In many cases, you can retry the release, possibly after doing something to
382
+ address the cause. For example, if the release failed because of a flaky test
383
+ in the GitHub checks, you can rerun the check, and once it passes, retry the
384
+ release. Or, if the release failed because of expired RubyGems credentials, you
385
+ can rotate the credentials (see [above](#provide-credentials)) and then retry
386
+ the release.
387
+
388
+ To retry a release, navigate to the Actions tab in the GitHub UI, select the
389
+ "Retry release" workflow, and click the "Run workflow" dropdown. This will open
390
+ a confirmation drop-down with a field for "Release PR number". Enter the number
391
+ of the *release pull request* here, and then click the "Run workflow" button to
392
+ retry the release.
393
+
394
+ When a failure takes place, it is possible that the release partially completed
395
+ but did not fully complete. For example, a GitHub release and tag may already
396
+ have been created, but the gem was not successfully pushed to RubyGems. When
397
+ you retry a release, the release script will automatically detect which release
398
+ steps were already completed, and will skip them.
399
+
400
+ If you need to "roll back" a failed release so it can be retried from a
401
+ different commit, currently you must manually roll back the version number and
402
+ changelog modification (i.e. roll back the changes in the release pull
403
+ request). You might also need to remove an existing GitHub tag and release if
404
+ they were already created.
405
+
406
+ ## Other features
264
407
 
265
408
  ### Documentation publication
266
409
 
267
- (TODO)
410
+ One of the optional features of the release pipeline is publication of Yardoc
411
+ reference documentation to GitHub Pages. This lets you host reference
412
+ documentation for your Ruby gem on your GitHub Pages site, under github.io. As
413
+ an example, of what this looks like you can see the reference documentation for
414
+ the Toys gem at https://dazuma.github.io/toys/gems/toys.
415
+
416
+ The features of this system are:
417
+
418
+ * Host generated Yardoc (or rdoc) documentation for every version of the gem.
419
+ * Host documentation for multiple gems per repository.
420
+ * Permanent GitHub Pages (github.io) URL for each gem, which redirects to the
421
+ documentation for the latest version.
422
+ * Automatically publish documentation with each release.
423
+
424
+ #### Setting up documentation publication
425
+
426
+ To set up documentation, do the following:
427
+
428
+ * [Install the release tool](#install-the-release-tool) as documented in the
429
+ main setup procedure. This provides access to the Toys-Release command line.
430
+
431
+ * Make sure you have a release config file. See the section on
432
+ [writing the configuration file](#write-the-configuration-file) for how to
433
+ get started here.
434
+
435
+ * For each gem that you want documented, include the configuration setting
436
+ `gh_pages_enabled: true` in the component's configuration. Alternately, you
437
+ can set `gh_pages_enabled: true` at the top level of the configuration file
438
+ to enable documenting for all components.
268
439
 
269
- ### Special commit tags
440
+ * Create a starting gh-pages branch by running:
270
441
 
271
- (TODO)
442
+ ```sh
443
+ toys release gen-gh-pages
444
+ ```
445
+
446
+ This will generate the gh-pages branch and push some key files to it,
447
+ notably a `404.html` that does the redirecting to the latest documentation
448
+ version. This may clobber any other gh-pages that you have present.
449
+
450
+ From this point on, any releases you do should also publish documentation to
451
+ your page. To find the page, use the URL
452
+ `https://<github-user>.github.io/<repo-name>/<component-name>`.
453
+
454
+ If you add or otherwise change your components, you can rerun the
455
+ `toys release gen-gh-pages` script to regenerate the files and update the
456
+ redirects. This will not affect any actual documentation you may have generated
457
+ previously.
458
+
459
+ #### Special configuration
460
+
461
+ There are a few configuration fields that affect documentation publication.
462
+
463
+ * **gh_pages_directory** is the directory name for this component in the
464
+ documentation URL. This takes the place of the `<component-name>` in the
465
+ URL. For example, if you set `gh_pages_directory: foo/bar` for your
466
+ component, the documentation will be generated under the URL:
467
+ `https://<github-user>.github.io/<repo-name>/foo/bar`.
468
+
469
+ Note that if you modify this field after previously generating
470
+ documentation for some releases, you will need to manually move the
471
+ previous documentation into the new directory.
472
+
473
+ * **gh_pages_version_var** is the name of the Javascript variable in the
474
+ `404.html` file that stores the latest version of this component's release.
475
+ You will generally not need to modify this unless the
476
+ automatically-generated variable name isn't unique for some reason.
477
+
478
+ See the [component configuration](#component-configuration) section for more
479
+ details.
480
+
481
+ ### Special commit messages
482
+
483
+ Several special cases can be handled via commit tags that are defined by
484
+ Toys-Release. These conventional commit messages can appear in a commit message
485
+ and affect the behavior of that and other commits.
486
+
487
+ * **semver-change:** This tag forces a certain semver change to apply to this
488
+ commit even if other commit tags say otherwise. For example, if a commit
489
+ describes a new feature, but you want it released as a patch version bump
490
+ rather than a minor version bump, you can include `semver-change: patch` in
491
+ the commit message. The full commit message might read thus:
492
+
493
+ ```
494
+ feat: Add a small button that doesn't do a lot
495
+ semver-change: patch
496
+ ```
497
+
498
+ Valid values for semver-change are `patch`, `minor`, `major`, and `none`.
499
+
500
+ The semver-change tag affects only the commit it is part of. If multiple
501
+ commits are included in a release, other commits in the release might still
502
+ upgrade the version bump to minor or higher.
503
+
504
+ * **revert-commit:** This tag indicates that the commit reverts, and thus
505
+ nullifies the effect of, an earlier commit, thus removing any version bump
506
+ and any changelog entries that would otherwise have been generated. Use the
507
+ SHA of the earlier commit as the content of the tag. For example:
508
+
509
+ ```
510
+ revert-commit: b10c6fb3363bd1335dcfbd671bdceae53cd55716
511
+ ```
512
+
513
+ A commit can combine revert-commit with other conventional commit tags. It
514
+ can even include multiple revert-commit tags if the commit reverts more than
515
+ one previous commit.
272
516
 
273
517
  ### Running on the command line
274
518
 
275
- (TODO)
519
+ The implementation of Toys-Release is done via Toys (i.e. command line) tools.
520
+ In most cases, you will use the GitHub Actions integration to manage your
521
+ releases, but you can also run the tools directly from the command line.
522
+
523
+ To do so, first make sure you have
524
+ [installed the release tool](#install-the-release-tool) as documented in the
525
+ main setup procedure. Then, the command line tools will be available as
526
+ subtools underneath `toys release`. For example, you could request a release
527
+ from the command line instead of a GitHub Action, by running the command
528
+ `toys release request`, and providing it the needed arguments and credentials.
529
+
530
+ As with all Toys-based tools, you can pass `--help` to any tool to get detailed
531
+ usage information. For example: `toys release request --help`. You can also run
532
+ `toys release --help` for a list of all the release-related tools.
533
+
534
+ The following are the available command line tools. You may recognize some of
535
+ these as tools you used during the [installation](#installation) procedure.
536
+
537
+ * **create-labels** Creates the GitHub labels used by the release system
538
+
539
+ * **gen-config** Generates an initial release configuration file
540
+
541
+ * **gen-gh-pages** Initializes the gh-pages branch for publishing
542
+ documentation
543
+
544
+ * **gen-workflows** Generates the GitHub Actions workflows used by
545
+ Toys-Release
546
+
547
+ * **perform** Runs the release pipeline from the command line. Assumes you
548
+ have already updated the version number and the changelog.
549
+
550
+ * **request** Analyzes the repository history and opens a release pull
551
+ request including any pending releases. This is the command line tool used
552
+ by the "Open release request" GitHub Action.
553
+
554
+ * **retry** Retries a failed release. This is the command line tool used by
555
+ the "Retry release" GitHub Action.
556
+
557
+ There are also internal (hidden) subtools called "_onclosed" and "_onpush".
558
+ These are the tools called by GitHub Actions automation in response to pull
559
+ request events, and you should generally not call them directly.
276
560
 
277
561
  ## The release pipeline
278
562
 
279
563
  Toys-Release features a highly configurable build pipeline. By default it is
280
564
  configured to handle most RubyGems packages, and will:
281
565
 
282
- * Tag and post a GitHub Release
283
- * Build a RubyGems package and push it to rubygems.org
284
- * Optionally build Yardoc documentation and push it to GitHub Pages
566
+ * Tag and post a GitHub Release
567
+ * Build a RubyGems package and push it to rubygems.org
568
+ * Optionally build Yardoc documentation and push it to GitHub Pages
285
569
 
286
570
  The pipeline system, however, lets you customize any aspect of the process, and
287
571
  even replace it with an entirely different process altogether, possibly even
@@ -292,23 +576,241 @@ configuration reference documentation.
292
576
 
293
577
  ### Pipeline steps
294
578
 
295
- (TODO)
579
+ A release pipeline is defined as an ordered series of **steps**. Each of these
580
+ steps may perform some task and/or exchange some data with other steps. For
581
+ example, a step might install a bundle, another might build a gem package, and
582
+ another might push a gem package built by a previous step to rubygems.org.
583
+
584
+ The behavior of a step is determined by the **type** of the step, and by
585
+ additional **configuration attributes** provided to the step. Each step also
586
+ has a unique **name** that lets you identify it and connect it to other steps.
587
+
588
+ When a pipeline is run, individual steps in the pipeline may or may not
589
+ actually execute, depending on whether they are needed. For example, the step
590
+ type that creates a GitHub release will always run if it is present in a
591
+ pipeline, but the step type that installs the bundle will normally run only if
592
+ another subsequent step *that will run* actually needs the bundle, and the step
593
+ type that builds the gem package will normally run only if a subsequent step
594
+ *that will run* actually uses the built package (e.g. to push it to RubyGems.)
595
+ The decision of whether or not a step will run depends on the step's
596
+ configuration, and the step dependencies configured into the pipeline.
597
+
598
+ We will cover, as an example, the [standard pipeline](#the-standard-pipeline)
599
+ for RubyGems releases below. First, however, we need to discuss how steps
600
+ depend on one another and pass data around.
296
601
 
297
602
  ### Inter-step communication and dependencies
298
603
 
299
- (TODO)
604
+ When a step runs, the working directory is set to the **component directory**
605
+ in a *clean* checkout of the release SHA in the repository. Any changes it
606
+ makes to the repository working directory are *not* preserved for other steps;
607
+ instead, it must explicitly "output" any files it needs to make available, and
608
+ other steps must explicitly access those files as "inputs". This is sometimes
609
+ done by the step's code, but can also be specified in the step's configuration.
610
+
611
+ For example, a step that builds a gem package should "output" the package so
612
+ that it is available to other steps that want to publish it. This simply
613
+ involves copying the relevant files to a special directory known as the output
614
+ directory for that step (identified by step name). The standard **build_gem**
615
+ step type does this in code. Alternatively, if you write a custom step that
616
+ builds an artifact, you can specify, via the **outputs** configuration, the
617
+ artifacts that you want made available. (See the
618
+ [output config reference](#step-output-configuration) for details.)
619
+
620
+ Then, a step can use a built artifact previously output by another step by
621
+ copying it from the previous step's output directory. Again, this can be done
622
+ in code, as by the standard **release_gem** step type. You can also specify,
623
+ via the **inputs** configuration, artifacts to copy from another step's output
624
+ into your working directory. (For details, see the
625
+ [input config reference](#step-input-configuration).)
626
+
627
+ When a step specifies the **inputs** configuration, any steps so referenced are
628
+ also automatically tagged as *dependencies* of the step. If the pipeline
629
+ determines the step should be run, then its dependencies are also marked as to
630
+ be run.
631
+
632
+ #### Inter-step communication example
633
+
634
+ Consider the following simple, if contrived, pipeline:
635
+
636
+ ```yaml
637
+ - name: create_file
638
+ type: command
639
+ command: ["touch", "my-file.txt"]
640
+ outputs:
641
+ - source_path: my-file.txt
642
+ - name: create_another_file
643
+ type: command
644
+ command: ["touch", "another-file.txt"]
645
+ outputs:
646
+ - source_path: another-file.txt
647
+ - name: show_file
648
+ type: command
649
+ command: ["cat", "my-file.txt"]
650
+ inputs:
651
+ - name: create_file
652
+ source_path: my-file.txt
653
+ run: true
654
+ ```
300
655
 
301
- ### The standard pipeline
656
+ This pipeline includes three steps. After each step, the git repository gets
657
+ reset, so any files created by the step are not initially available to
658
+ subsequent steps unless the step explicitly accesses them via inputs. Also note
659
+ that all three steps are of type "command", which do not run by default unless
660
+ something else causes them to run.
302
661
 
303
- (TODO)
662
+ Let's consider these steps starting with the last one.
304
663
 
305
- ### Custom steps
664
+ The third step, named `show_file`, looks for a file `my-file.txt` in the
665
+ *first* step's outputs, copies it into its working directory, and prints its
666
+ contents to the logs. It includes the `run: true` configuration which forces it
667
+ to run.
306
668
 
307
- (TODO)
669
+ Because the third step, `show_file`, copies an input from the first step,
670
+ `create_file`, the latter is a dependency of the former. And since the
671
+ `show_file` is forced to run, then `create_file` will also run. This step will
672
+ run first, because it is first in the list of steps, and it will create a file
673
+ and copy it to its outputs so the `show_file` can access it.
308
674
 
309
- ### Common pipeline modifications
675
+ The second step, `create_another_file`, would create another file and copy it
676
+ to its outputs. However, it neither is forced to run via `run: true` nor is
677
+ listed as a dependency of any other step that will run. Therefore, the second
678
+ step never runs at all.
310
679
 
311
- (TODO)
680
+ ### The standard pipeline
681
+
682
+ The default release pipeline illustrates the above features of steps. It
683
+ includes the following steps:
684
+
685
+ * **bundle**: Installs the bundle, and copies the `Gemfile.lock` to its
686
+ output directory. This step runs because the later step **build_yard**
687
+ declares it as a dependency and accesses the `Gemfile.lock`.
688
+ * **build_gem**: Builds the gem package, and copies the package file to its
689
+ output directory. This step runs because the later step **release_gem**
690
+ declares it as a dependency and accesses the built package.
691
+ * **build_yard**: Builds the Yardoc documentation. By default, this step uses
692
+ the `yard` gem from the bundle, and thus depends on the earlier **bundle**
693
+ step. It copies the `Gemfile.lock` output by the earlier step. After
694
+ building the documentation into the `doc` directory, it copies that
695
+ directory to its output directory. This step runs *if* the later step
696
+ **push_gh_pages**, which lists it as a dependency, runs.
697
+ * **release_github**: Pushes a release tag to GitHub and creates a GitHub
698
+ release. This step always runs and has no dependencies.
699
+ * **release_gem**: Pushes the built gem package to rubygems.org. This step
700
+ lists the earlier **build_gem** step as a dependency, and copies the built
701
+ gem package from that step's output.
702
+ * **push_gh_pages**: Pushes the built documentation to the `gh-pages` branch
703
+ so it shows up on the repository's GitHub Pages site. This step runs only
704
+ if the repository actually has a `gh-pages` branch and the release
705
+ configuration specifies that it should be pushed to. If this step does run,
706
+ it lists the earlier **build_yard** step as a dependency, and copies the
707
+ built documentation from that step's output.
708
+
709
+ Ultimately, this pipeline will create a GitHub release, push a RubyGems
710
+ package, and optionally push documentation.
711
+
712
+ ### Modifying the pipeline
713
+
714
+ If your releases have different requirements, you can modify the release
715
+ pipeline, by inserting steps, by modifying existing steps, or by replacing the
716
+ entire pipeline with a new pipeline. These modifications can be made globally
717
+ for all releases in a repository, or specifically for individual releasable
718
+ components, by adding configuration at the top level of the configuration (see
719
+ the [top level configuration reference](#top-level-configuration)) or
720
+ underneath a particular component's configuration (see the
721
+ [component configuration reference](#component-configuration)).
722
+
723
+ * To insert new steps, at the beginning or end of the pipeline, or before or
724
+ after specific named steps, use the **append_steps** and **prepend_steps**
725
+ configurations.
726
+ * To modify existing steps, use the **modify_steps** configuration. See the
727
+ reference on [build step modification](#build-step-modification).
728
+ * There is no specific way to delete an existing step. This is because a step
729
+ might be referenced by other steps. To ensure a step does not run, you can
730
+ modify it to change its type to `noop` (which has no behavior and does not
731
+ run by default) and ensure that no step depends on it.
732
+ * If your changes are more complex than can reasonably be expressed by
733
+ modifying the default pipeline, you can replace the pipeline completely
734
+ using the **steps** configuration.
735
+
736
+ #### Pipeline modification example
737
+
738
+ The `toys` gem itself has a customized release pipeline. This pipeline includes
739
+ a step that merges key classes from `toys-core`, such as DSL classes, into the
740
+ documentation for the `toys` gem.
741
+
742
+ The merging is actually performed by a toys tool called `copy-core-docs`
743
+ defined in the directory for the `toys` gem. The implementation itself isn't
744
+ important; what's important is that we want this merging to be part of the
745
+ release process.
746
+
747
+ The `releases.yml` for the toys repository includes this configuration for the
748
+ `toys` gem:
749
+
750
+ ```yaml
751
+ components:
752
+ - name: toys
753
+ prepend_steps:
754
+ - name: copy_core_docs
755
+ type: tool
756
+ tool: [copy-core-docs]
757
+ outputs: [core-docs]
758
+ modify_steps:
759
+ - name: build_yard
760
+ inputs: [copy_core_docs]
761
+ - name: build_gem
762
+ inputs: [copy_core_docs]
763
+ ```
764
+
765
+ Let's unpack what this is doing.
766
+
767
+ First, we note that we are not replacing the default pipeline completely; we
768
+ are only modifying it *for this one gem*. The other gems (`toys-core` and
769
+ `toys-release`) continue to use the default pipeline unmodified.
770
+
771
+ For the `toys` gem, then, we prepend one new step at the beginning of the
772
+ pipeline. The step is named `copy_core_docs`, and it runs the toys tool that
773
+ copies files (with some modifications to simplify them and make them suitable
774
+ for just documentation) from `toys-core` into the `toys` directory under the
775
+ `core-docs` subdirectory. This directory is not part of the include path, so
776
+ these files are not in the require path and do not interfere with the
777
+ functionality of the library. However, they are in the `.yardopts` file and are
778
+ used when documentation is built. We then copy this new directory to the
779
+ output for the `copy_core_docs` step, to preserve it for future steps.
780
+
781
+ Next, we modify the `build_yard` step to load the `copy_core_docs` output. This
782
+ brings those files back into our working directory when the Yardocs are built.
783
+ It also adds the `copy_core_docs` step to the dependencies of `build_yard` to
784
+ ensure it gets executed.
785
+
786
+ We also modify the `build_gem` step to load the `copy_core_docs` output. This
787
+ ensures that the files are also present when the gem is built, so that services
788
+ like rubydoc.info will have them available when they build the documentation.
789
+ Again, this also adds `copy_core_docs` to the dependencies of `build_gem`. As a
790
+ dependency of both `build_gem` and `build_yard`, this ensures that our new step
791
+ will indeed get executed. (It does not execute twice; Toys-Release ensures each
792
+ step is executed at most once, even if it is listed multiple times as a
793
+ dependency.)
794
+
795
+ #### Useful types for custom steps
796
+
797
+ The **command** and **tool** step types are both very useful when creating
798
+ custom steps. We've seen in the [example above](#pipeline-modification-example)
799
+ how a step of type **tool** is used in the customized release process for the
800
+ `toys` gem itself. The **command** type is similar; it executes a Unix command
801
+ rather than a Toys tool. These two types are very useful for performing
802
+ arbitrary behavior during a release.
803
+
804
+ Another step type that is occasionally useful is **noop**. This type has no
805
+ behavior; it doesn't *do* anything, but you can configure it with inputs and
806
+ outputs. This can be useful for consolidating data output by other steps. You
807
+ can, for example, configure a **noop** with multiple **inputs** from other
808
+ steps, configuring each input to copy to the noop's *output*. Now, all the
809
+ files from potentially multiple inputs are combined and can be referenced
810
+ conveniently via a single step's output.
811
+
812
+ See the reference below on [build step types](#build-step-types) for detailed
813
+ information on these and other step types and their configurations.
312
814
 
313
815
  ## Configuration reference
314
816
 
@@ -324,129 +826,137 @@ The top level of the yaml file is a dictionary that can include the following
324
826
  keys. Out of these, **repo**, **git_user_name**, and **git_user_email** are all
325
827
  required. The rest are optional.
326
828
 
327
- * **append_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
328
- A list of build steps to append to the end of the default build pipeline.
329
- This can be used to modify the default build pipeline instead of redefining
330
- the entire pipeline using the **steps** key.
331
-
332
- * **breaking_change_header**: *string* (optional) --
333
- A changelog entry prefix that appears when a change is marked as breaking.
334
- Default is `BREAKING CHANGE`.
335
-
336
- * **commit_tags**: *array of [CommitTagConfig](#commit-tag-configuration)* (optional) --
337
- A set of configurations defining how to interpret
338
- [conventional commit](https://conventionalcommits.org) tags, including how
339
- they trigger releases, bump versions, and generate changelog entries. See
340
- [commit tag configuration](#commit-tag-configuration) for details.
341
- If not included, Toys-Release will use a default configuration as follows:
342
-
343
- - tag: feat
344
- semver: minor
345
- header: ADDED
346
- - tag: fix
347
- semver: patch
348
- header: FIXED
349
- - tag: docs
350
- semver: patch
351
-
352
- * **components**: *array of [ComponentConfig](#component-configuration)* (optional) --
353
- An array of releasable components, usually RubyGems packages. See
354
- [Component Configuration](#component-configuration) for details on the format
355
- of each component. You can also use the name **gems** for this config key.
356
-
357
- * **coordinate_versions**: *boolean* (optional) --
358
- If set to true, this is a shorthand for setting up a coordination group
359
- containing all components in this repository. Defaults to *false*.
360
-
361
- * **coordination_groups**: *array of array of string* (optional) --
362
- A list of disjoint sets of component names. Each set defines a group of
363
- components that will always be released together with the same version
364
- number. That is, if one or more components in a set are released, the entire
365
- set is released, even components with no changes. This is useful for sets of
366
- gems, such as the Rails gems, that are always released together.
367
-
368
- * **enable_release_automation**: *boolean* (optional) --
369
- When enabled, the release pipeline runs automatically when a release pull
370
- request is merged. Defaults to *true*.
371
-
372
- * **gh_pages_enabled**: *boolean* (optional) --
373
- Whether to globally enable gh-pages publication for all releases. Defaults to
374
- *false*.
375
-
376
- * **git_user_email**: *string* (required) --
377
- The git `user.email` setting to use when making git commits.
378
-
379
- * **git_user_name**: *string* (required) --
380
- The git `user.name` setting to use when making git commits.
381
-
382
- * **main_branch**: *string* (optional) --
383
- The name of the main branch. Defaults to `main` if not provided.
384
-
385
- * **modify_steps**: *array of [BuildStepModification](#build-step-modification)* (optional) --
386
- A set of modifications to the default build steps. This can be used to modify
387
- the default build pipeline instead of redefining the entire pipeline using
388
- the **steps** key.
389
-
390
- * **no_significant_updates_notice**: *string* (optional) --
391
- A notice that appears in a changelog when a release is done but no other
392
- changelog entries are present. Default is `No significant updates.`
393
-
394
- * **prepend_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
395
- A list of build steps to prepend to the start of the default build pipeline.
396
- This can be used to modify the default build pipeline instead of redefining
397
- the entire pipeline using the **steps** key.
398
-
399
- * **release_branch_prefix**: *string* (optional) --
400
- The prefix for all release branch names. Defaults to `release`.
401
-
402
- * **release_aborted_label**: *string* (optional) --
403
- The name of the GitHub issue label that identifies aborted release pull
404
- requests. Defaults to `release: aborted`.
405
-
406
- * **release_complete_label**: *string* (optional) --
407
- The name of the GitHub issue label that identifies successfully completed
408
- release pull requests. Defaults to `release: complete`.
409
-
410
- * **release_error_label**: *string* (optional) --
411
- The name of the GitHub issue label that identifies release pull requests in
412
- an error state. Defaults to `release: error`.
413
-
414
- * **release_pending_label**: *string* (optional) --
415
- The name of the GitHub issue label that identifies pending release pull
416
- requests. Defaults to `release: pending`.
417
-
418
- * **repo**: *string* (required) --
419
- The GitHub repository name in the form `owner/repo`. For example, the Toys
420
- repo is `dazuma/toys`.
421
-
422
- * **required_checks**: *regexp/boolean* (optional) --
423
- Identifies which GitHub checks must pass as a prerequisite for a release. If
424
- a string is provided, it is interpreted as a Ruby regexp (PCRE) and
425
- identifies the check names. A boolean value of *true* (the default) means all
426
- checks must pass. A boolean value of *false* disables checking.
427
-
428
- * **required_checks_timeout**: *integer* (optional) --
429
- The time to wait, in seconds, for required checks to pass during release
430
- processing. Defaults to 900 (i.e. 15 minutes).
431
-
432
- * **signoff_commits**: *boolean* (optional) --
433
- Whether to make commits with `--signoff`. Set this to true if your repository
434
- has a policy that commits require signoff. Defaults to *false*.
435
-
436
- * **steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
437
- The build pipeline as a list of build steps. See
438
- [build step configuration](#build-step-configuration) for details on how to
439
- define the pipeline. If this is not included, Toys-Release will use a default
440
- pipeline as follows:
441
-
442
- - name: bundle
443
- - name: build_gem
444
- - name: build_yard
445
- - name: release_github
446
- - name: release_gem
447
- source: build_gem
448
- - name: push_gh_pages
449
- source: build_yard
829
+ * **append_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
830
+ A list of build steps to append to the end of the default build pipeline.
831
+ This can be used to modify the default build pipeline instead of redefining
832
+ the entire pipeline using the **steps** key.
833
+
834
+ * **breaking_change_header**: *string* (optional) --
835
+ A changelog entry prefix that appears when a change is marked as breaking.
836
+ Default is `BREAKING CHANGE`.
837
+
838
+ * **commit_tags**: *array of [CommitTagConfig](#commit-tag-configuration)* (optional) --
839
+ A set of configurations defining how to interpret
840
+ [conventional commit](https://conventionalcommits.org) tags, including how
841
+ they trigger releases, bump versions, and generate changelog entries. See
842
+ [commit tag configuration](#commit-tag-configuration) for details.
843
+ If not included, Toys-Release will use a default configuration as follows:
844
+
845
+ ```yaml
846
+ - tag: feat
847
+ semver: minor
848
+ header: ADDED
849
+ - tag: fix
850
+ semver: patch
851
+ header: FIXED
852
+ - tag: docs
853
+ semver: patch
854
+ ```
855
+
856
+ * **components**: *array of [ComponentConfig](#component-configuration)* (optional) --
857
+ An array of releasable components, usually RubyGems packages. See
858
+ [Component Configuration](#component-configuration) for details on the
859
+ format of each component. You can also use the name **gems** for this
860
+ config key.
861
+
862
+ * **coordinate_versions**: *boolean* (optional) --
863
+ If set to true, this is a shorthand for setting up a coordination group
864
+ containing all components in this repository. Defaults to *false*.
865
+
866
+ * **coordination_groups**: *array of array of string* (optional) --
867
+ A list of disjoint sets of component names. Each set defines a group of
868
+ components that will always be released together with the same version
869
+ number. That is, if one or more components in a set are released, the
870
+ entire set is released, even components with no changes. This is useful for
871
+ sets of gems, such as the Rails gems, that are always released together.
872
+
873
+ * **enable_release_automation**: *boolean* (optional) --
874
+ When enabled, the release pipeline runs automatically when a release pull
875
+ request is merged. Defaults to *true*.
876
+
877
+ * **gh_pages_enabled**: *boolean* (optional) --
878
+ Whether to globally enable gh-pages publication for all releases. Defaults
879
+ to *false*.
880
+
881
+ * **git_user_email**: *string* (required) --
882
+ The git `user.email` setting to use when making git commits.
883
+
884
+ * **git_user_name**: *string* (required) --
885
+ The git `user.name` setting to use when making git commits.
886
+
887
+ * **main_branch**: *string* (optional) --
888
+ The name of the main branch. Defaults to `main` if not provided.
889
+
890
+ * **modify_steps**: *array of [BuildStepModification](#build-step-modification)* (optional) --
891
+ A set of modifications to the default build steps. This can be used to
892
+ modify the default build pipeline instead of redefining the entire pipeline
893
+ using the **steps** key.
894
+
895
+ * **no_significant_updates_notice**: *string* (optional) --
896
+ A notice that appears in a changelog when a release is done but no other
897
+ changelog entries are present. Default is `No significant updates.`
898
+
899
+ * **prepend_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
900
+ A list of build steps to prepend to the start of the default build
901
+ pipeline. This can be used to modify the default build pipeline instead of
902
+ redefining the entire pipeline using the **steps** key.
903
+
904
+ * **release_branch_prefix**: *string* (optional) --
905
+ The prefix for all release branch names. Defaults to `release`.
906
+
907
+ * **release_aborted_label**: *string* (optional) --
908
+ The name of the GitHub issue label that identifies aborted release pull
909
+ requests. Defaults to `release: aborted`.
910
+
911
+ * **release_complete_label**: *string* (optional) --
912
+ The name of the GitHub issue label that identifies successfully completed
913
+ release pull requests. Defaults to `release: complete`.
914
+
915
+ * **release_error_label**: *string* (optional) --
916
+ The name of the GitHub issue label that identifies release pull requests in
917
+ an error state. Defaults to `release: error`.
918
+
919
+ * **release_pending_label**: *string* (optional) --
920
+ The name of the GitHub issue label that identifies pending release pull
921
+ requests. Defaults to `release: pending`.
922
+
923
+ * **repo**: *string* (required) --
924
+ The GitHub repository name in the form `owner/repo`. For example, the Toys
925
+ repo is `dazuma/toys`.
926
+
927
+ * **required_checks**: *regexp/boolean* (optional) --
928
+ Identifies which GitHub checks must pass as a prerequisite for a release.
929
+ If a string is provided, it is interpreted as a Ruby regexp (PCRE) and
930
+ identifies the check names. A boolean value of *true* (the default) means
931
+ all checks must pass. A boolean value of *false* disables checking.
932
+
933
+ * **required_checks_timeout**: *integer* (optional) --
934
+ The time to wait, in seconds, for required checks to pass during release
935
+ processing. Defaults to 900 (i.e. 15 minutes).
936
+
937
+ * **signoff_commits**: *boolean* (optional) --
938
+ Whether to make commits with `--signoff`. Set this to true if your
939
+ repository has a policy that commits require signoff. Defaults to *false*.
940
+
941
+ * **steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
942
+ The build pipeline as a list of build steps. See
943
+ [build step configuration](#build-step-configuration) for details on how to
944
+ define the pipeline. If this is not included, Toys-Release will use a
945
+ default pipeline as follows:
946
+
947
+ ```yaml
948
+ - name: bundle
949
+ - name: build_gem
950
+ - name: build_yard
951
+ - name: release_github
952
+ - name: release_gem
953
+ source: build_gem
954
+ - name: push_gh_pages
955
+ source: build_yard
956
+ ```
957
+
958
+ See the earlier section on [the standard pipeline](#the-standard-pipeline)
959
+ for a detailed description of the behavior of this default pipeline.
450
960
 
451
961
  ### Commit tag configuration
452
962
 
@@ -457,19 +967,19 @@ and how it should appear in the changelog. The format of the configuration is a
457
967
  dictionary with the keys documented here. The **tag** key is required; the
458
968
  remaining keys are optional and have defaults.
459
969
 
460
- * **header**: *string,null* (optional) --
461
- A prefix that appears before each changelog entry generated by this tag. The
462
- special value *null* suppresses changelog entry generation for this scope.
463
- Defaults to the tag itself in all caps.
970
+ * **header**: *string,null* (optional) --
971
+ A prefix that appears before each changelog entry generated by this tag.
972
+ The special value *null* suppresses changelog entry generation for this
973
+ scope. Defaults to the tag itself in all caps.
464
974
 
465
- * **scopes**: *array of [ScopeConfig](#scope-configuration)* (optional) --
466
- Overrides for conventional commit scopes.
975
+ * **scopes**: *array of [ScopeConfig](#scope-configuration)* (optional) --
976
+ Overrides for conventional commit scopes.
467
977
 
468
- * **semver**: *string* (optional) --
469
- The semver version bump implied by changes of this type. Possible values are
470
- `patch`, `minor`, `major`, and `none`. Default is `none`.
978
+ * **semver**: *string* (optional) --
979
+ The semver version bump implied by changes of this type. Possible values
980
+ are `patch`, `minor`, `major`, and `none`. Default is `none`.
471
981
 
472
- * **tag**: *string* (required) -- The conventional commit tag.
982
+ * **tag**: *string* (required) -- The conventional commit tag.
473
983
 
474
984
  #### Scope configuration
475
985
 
@@ -480,17 +990,17 @@ dependency-updating bots. Typically, `chore:` does not indicate a significant
480
990
  change that should trigger a release or appear in a changelog, but you might
481
991
  choose different behavior for dependency changes.
482
992
 
483
- * **header**: *string,null* (optional) --
484
- A prefix that appears before each changelog entry generated by this tag. The
485
- special value *null* suppresses changelog entry generation for this scope.
486
- Defaults to the same setting used by the tag.
993
+ * **header**: *string,null* (optional) --
994
+ A prefix that appears before each changelog entry generated by this tag.
995
+ The special value *null* suppresses changelog entry generation for this
996
+ scope. Defaults to the same setting used by the tag.
487
997
 
488
- * **scope**: *string* (required) -- The scope name.
998
+ * **scope**: *string* (required) -- The scope name.
489
999
 
490
- * **semver**: *string* (optional) --
491
- The semver version bump implied by changes of this type. Possible values are
492
- `patch`, `minor`, `major`, and `none`. Defaults to the same setting used by
493
- the tag.
1000
+ * **semver**: *string* (optional) --
1001
+ The semver version bump implied by changes of this type. Possible values
1002
+ are `patch`, `minor`, `major`, and `none`. Defaults to the same setting
1003
+ used by the tag.
494
1004
 
495
1005
  ### Component configuration
496
1006
 
@@ -498,87 +1008,90 @@ A component configuration specifies how a particular component (often a
498
1008
  RubyGems package) should be released. Its format is a dictionary with the keys
499
1009
  documented here.
500
1010
 
501
- * **append_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
502
- A list of build steps to append to the end of this component's build
503
- pipeline. This can be used to modify the build pipeline instead of redefining
504
- the entire pipeline using the **steps** key.
505
-
506
- * **changelog_path**: *string* (optional) --
507
- The path to the component's changelog file, relative to the component's
508
- directory. Default is `CHANGELOG.md`.
509
-
510
- * **directory**: *string* (optional) --
511
- The directory within the repository where this component is located. Defaults
512
- to the component name, unless there is exactly one component in this
513
- repository, in which case the default is the root of the repository, i.e.
514
- "`.`". This directory is used to identify when files related to this
515
- component have been changed, and is also used as a base directory for other
516
- paths related to the component.
517
-
518
- * **exclude_globs**: *array of string* (optional) --
519
- An array of globs identifying files or directories that should be ignored
520
- when identifying changes to this component. These paths are relative to the
521
- repo root.
522
-
523
- * **gh_pages_directory**: *string* (optional) --
524
- The directory in the `gh-pages` branch under which this component's
525
- documentation is published. The default is the component name.
526
-
527
- * **gh_pages_enabled**: *boolean* (optional) --
528
- Whether gh-pages documentation publishing is enabled for this component.
529
- Default is *true* if either **gh_pages_directory** or **gh_pages_version_var**
530
- is set explicitly; otherwise *false*.
531
-
532
- * **gh_pages_version_var**: *string* (optional) --
533
- The name of a Javascript variable within the `404.html` page under gh-pages
534
- that identifies the latest release of this component. Defaults to a variable
535
- name corresponding to the component name.
536
-
537
- * **include_globs**: *array of string* (optional) --
538
- An array of globs identifying additional files or directories, not located in
539
- the component's directory itself, that should signal changes to this
540
- component. This can be used, for example, if the repo has global files shared
541
- by multiple components, where a change in such a file should trigger releases
542
- for all those components. These paths are relative to the repo root.
543
-
544
- * **modify_steps**: *array of [BuildStepModification](#build-step-modification)* (optional) --
545
- A set of modifications to this component's build steps. This can be used to
546
- modify the build pipeline instead of redefining the entire pipeline using
547
- the **steps** key.
548
-
549
- * **name**: *string* (required) --
550
- The name of the component, e.g. the name of the RubyGems package if this
551
- component represents a gem.
552
-
553
- * **prepend_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
554
- A list of build steps to prepend to the start of this component's build
555
- pipeline. This can be used to modify the build pipeline instead of redefining
556
- the entire pipeline using the **steps** key.
557
-
558
- * **steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
559
- A way to override the complete build pipeline for this component. If not
560
- present, the default pipeline for the entire repository is used. (See the
561
- **steps** key under [Top level configuration](#top-level-configuration).)
562
-
563
- * **version_constant**: *string* (optional) --
564
- The fully-qualified name of the version constant. This is used to determine
565
- the current version of the component. The default uses the module implied by
566
- the component name. For example, if the component (gem) name is
567
- `toys-release`, this defaults to `Toys::Release::VERSION`.
568
-
569
- * **version_rb_path**: *string* (optional) --
570
- The path to a Ruby file that contains the current version of the component.
571
- This file *must* include Ruby code that looks like this:
572
-
573
- VERSION = "1.2.3"
1011
+ * **append_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
1012
+ A list of build steps to append to the end of this component's build
1013
+ pipeline. This can be used to modify the build pipeline instead of
1014
+ redefining the entire pipeline using the **steps** key.
1015
+
1016
+ * **changelog_path**: *string* (optional) --
1017
+ The path to the component's changelog file, relative to the component's
1018
+ directory. Default is `CHANGELOG.md`.
1019
+
1020
+ * **directory**: *string* (optional) --
1021
+ The directory within the repository where this component is located.
1022
+ Defaults to the component name, unless there is exactly one component in
1023
+ this repository, in which case the default is the root of the repository,
1024
+ i.e. "`.`". This directory is used to identify when files related to this
1025
+ component have been changed, and is also used as a base directory for other
1026
+ paths related to the component.
1027
+
1028
+ * **exclude_globs**: *array of string* (optional) --
1029
+ An array of globs identifying files or directories that should be ignored
1030
+ when identifying changes to this component. These paths are relative to the
1031
+ repo root.
1032
+
1033
+ * **gh_pages_directory**: *string* (optional) --
1034
+ The directory in the `gh-pages` branch under which this component's
1035
+ documentation is published. The default is the component name.
1036
+
1037
+ * **gh_pages_enabled**: *boolean* (optional) --
1038
+ Whether gh-pages documentation publishing is enabled for this component.
1039
+ Default is *true* if either **gh_pages_directory** or
1040
+ **gh_pages_version_var** is set explicitly; otherwise *false*.
1041
+
1042
+ * **gh_pages_version_var**: *string* (optional) --
1043
+ The name of a Javascript variable within the `404.html` page under gh-pages
1044
+ that identifies the latest release of this component. Defaults to an
1045
+ auto-generated variable name corresponding to the component name.
1046
+
1047
+ * **include_globs**: *array of string* (optional) --
1048
+ An array of globs identifying additional files or directories, not located
1049
+ in the component's directory itself, that should signal changes to this
1050
+ component. This can be used, for example, if the repo has global files
1051
+ shared by multiple components, where a change in such a file should trigger
1052
+ releases for all those components. These paths are relative to the repo
1053
+ root.
1054
+
1055
+ * **modify_steps**: *array of [BuildStepModification](#build-step-modification)* (optional) --
1056
+ A set of modifications to this component's build steps. This can be used to
1057
+ modify the build pipeline instead of redefining the entire pipeline using
1058
+ the **steps** key.
1059
+
1060
+ * **name**: *string* (required) --
1061
+ The name of the component, e.g. the name of the RubyGems package if this
1062
+ component represents a gem.
1063
+
1064
+ * **prepend_steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
1065
+ A list of build steps to prepend to the start of this component's build
1066
+ pipeline. This can be used to modify the build pipeline instead of
1067
+ redefining the entire pipeline using the **steps** key.
1068
+
1069
+ * **steps**: *array of [BuildStepConfig](#build-step-configuration)* (optional) --
1070
+ A way to override the complete build pipeline for this component. If not
1071
+ present, the default pipeline for the entire repository is used. (See the
1072
+ **steps** key under [Top level configuration](#top-level-configuration).)
1073
+
1074
+ * **version_constant**: *string* (optional) --
1075
+ The fully-qualified name of the version constant. This is used to determine
1076
+ the current version of the component. The default uses the module implied
1077
+ by the component name. For example, if the component (gem) name is
1078
+ `toys-release`, this defaults to `Toys::Release::VERSION`.
1079
+
1080
+ * **version_rb_path**: *string* (optional) --
1081
+ The path to a Ruby file that contains the current version of the component.
1082
+ This file *must* include Ruby code that looks like this:
1083
+
1084
+ ```ruby
1085
+ VERSION = "1.2.3"
1086
+ ```
574
1087
 
575
- where the string is the latest released version. (Prior to the initial
576
- release, this version should be `0.0.0`.) Typically, `VERSION` is a constant
577
- defined in the "base module" for the Ruby library.
1088
+ where the string is the latest released version. (Prior to the initial
1089
+ release, this version should be `0.0.0`.) Typically, `VERSION` is a
1090
+ constant defined in the "base module" for the Ruby library.
578
1091
 
579
- The default is `version.rb` within the lib path associated with the Ruby
580
- module implied by the component name. For example, if the component (gem)
581
- name is `toys-release`, this defaults to `lib/toys/release/version.rb`.
1092
+ The default is `version.rb` within the lib path associated with the Ruby
1093
+ module implied by the component name. For example, if the component (gem)
1094
+ name is `toys-release`, this defaults to `lib/toys/release/version.rb`.
582
1095
 
583
1096
  ### Build step configuration
584
1097
 
@@ -588,71 +1101,71 @@ define additional keys as documented under the section
588
1101
  [build step types](#build-step-types). For more introductory information, see
589
1102
  the section on [the release pipeline](#the-release-pipeline) above.
590
1103
 
591
- * **name**: *string* (optional) --
592
- The unique name of this build step in the build pipeline. If not explicitly
593
- provided, a unique name will be generated.
1104
+ * **name**: *string* (optional) --
1105
+ The unique name of this build step in the build pipeline. If not explicitly
1106
+ provided, a unique name will be generated.
594
1107
 
595
- * **type**: *string* (optional) --
596
- The type of build step, defining what it does. Possible values are:
597
- `build_gem`, `build_yard`, `bundle`, `command`, `noop`, `push_gh_pages`,
598
- `release_gem`, `release_github`, and `tool`. For more information, see the
599
- section [build step types](#build-step-types).
1108
+ * **type**: *string* (optional) --
1109
+ The type of build step, defining what it does. Possible values are:
1110
+ `build_gem`, `build_yard`, `bundle`, `command`, `noop`, `push_gh_pages`,
1111
+ `release_gem`, `release_github`, and `tool`. For more information, see the
1112
+ section [build step types](#build-step-types).
600
1113
 
601
- * **run**: *boolean* (optional) --
602
- Whether to force this step to run. Typically, build steps will run only if
603
- the build type determines that it should run, or if the step is a dependency
604
- of another step that will run. You can, however, force a step to run that
605
- would otherwise not do so by setting this key to *true*.
1114
+ * **run**: *boolean* (optional) --
1115
+ Whether to force this step to run. Typically, build steps will run only if
1116
+ the build type determines that it should run, or if the step is a
1117
+ dependency of another step that will run. You can, however, force a step to
1118
+ run that would otherwise not do so by setting this key to *true*.
606
1119
 
607
- * **inputs**: *array of [InputConfig](#step-input-configuration)* (optional) --
608
- Inputs to this step, indicating dependencies on other steps and files to copy
609
- from those steps' outputs.
1120
+ * **inputs**: *array of [InputConfig](#step-input-configuration)* (optional) --
1121
+ Inputs to this step, indicating dependencies on other steps and files to
1122
+ copy from those steps' outputs.
610
1123
 
611
- * **outputs**: *array of [OutputConfig](#step-output-configuration)* (optional) --
612
- Files to copy to this step's output so they become available to other steps.
1124
+ * **outputs**: *array of [OutputConfig](#step-output-configuration)* (optional) --
1125
+ Files to copy to this step's output so they become available to other steps.
613
1126
 
614
1127
  #### Step input configuration
615
1128
 
616
- A step input represents a dependency on another step: if this step is run, the
617
- other step will also be run. It also describes files that should be copied from
618
- the dependent step's output and made available to the depending step. This
619
- configuration is a dictionary supporting the following keys:
620
-
621
- * **collisions**: *string* (optional) --
622
- A symbolic value indicating what to do if a collision occurs between incoming
623
- and existing files. Possible values are:
624
-
625
- * `error`: (the default) Abort with an error
626
- * `keep`: Keep the existing file
627
- * `replace`: Replace the existing file with the incoming file
628
-
629
- * **dest**: *string or false* (optional) --
630
- A symbolic value indicating where to copy the dependent step's output to.
631
- Possible values are:
632
-
633
- * `component`: (the default) Copy files to the component directory
634
- * `repo_root`: Copy files to the repository root
635
- * `output`: Copy files to this step's output directory
636
- * `temp`: Copy files to this step's temp directory
637
- * `none`: Do not copy any files, but just declare a dependency
638
-
639
- * **dest_path**: *string* (optional) --
640
- The path in the destination to copy to. If **source_path** is provided,
641
- **dest_path** is the corresponding path in the destination. If **source_path**
642
- is not provided, **dest_path** is a directory into which the source contents
643
- are copied. If **dest_path** is not provided, it defaults to the effective
644
- value of **source_path**, i.e. things are copied into the same locations
645
- within the destination as they were in the source.
646
-
647
- * **name**: *string* (required) --
648
- The name of the step to depend on. The dependent step must be located earlier
649
- in the pipeline than the depending step.
650
-
651
- * **source_path**: *string* (optional) --
652
- The path of the file or directory to copy from the source output. Only this
653
- item (recursively, if a directory) is copied. If this key is not provided,
654
- *all* contents of the source output are copied (e.g. the default is
655
- effectively "`.`")
1129
+ A step input represents a dependency on another step: if this (depending) step
1130
+ is run, that other (dependent) step will also be run. It also describes files
1131
+ that should be copied from the dependent step's output and made available to
1132
+ the depending step. This configuration is a dictionary with the following keys:
1133
+
1134
+ * **collisions**: *string* (optional) --
1135
+ A symbolic value indicating what to do if a collision occurs between
1136
+ incoming and existing files. Possible values are:
1137
+
1138
+ * `error`: (the default) Abort with an error
1139
+ * `keep`: Keep the existing file
1140
+ * `replace`: Replace the existing file with the incoming file
1141
+
1142
+ * **dest**: *string or false* (optional) --
1143
+ A symbolic value indicating where to copy the dependent step's output to.
1144
+ Possible values are:
1145
+
1146
+ * `component`: (the default) Copy files to the component directory
1147
+ * `repo_root`: Copy files to the repository root
1148
+ * `output`: Copy files to this step's output directory
1149
+ * `temp`: Copy files to this step's temp directory
1150
+ * `none`: Do not copy any files, but just declare a dependency
1151
+
1152
+ * **dest_path**: *string* (optional) --
1153
+ The path in the destination to copy to. If **source_path** is provided,
1154
+ **dest_path** is the corresponding path in the destination. If
1155
+ **source_path** is not provided, **dest_path** is a directory into which
1156
+ the source contents are copied. If **dest_path** is not provided, it
1157
+ defaults to the effective value of **source_path**, i.e. things are copied
1158
+ into the same locations within the destination as they were in the source.
1159
+
1160
+ * **name**: *string* (required) --
1161
+ The name of the step to depend on. The dependent step must be located
1162
+ earlier in the pipeline than the depending step.
1163
+
1164
+ * **source_path**: *string* (optional) --
1165
+ The path of the file or directory to copy from the source output. Only this
1166
+ item (recursively, if a directory) is copied. If this key is not provided,
1167
+ *all* contents of the source output are copied (e.g. the default is
1168
+ effectively "`.`")
656
1169
 
657
1170
  #### Step output configuration
658
1171
 
@@ -660,155 +1173,157 @@ A step output represents files automatically copied to the step's output
660
1173
  directory after the step runs. This configuration is a dictionary supporting
661
1174
  the following keys:
662
1175
 
663
- * **collisions**: *string* (optional) --
664
- A symbolic value indicating what to do if a collision occurs between incoming
665
- and existing files. Possible values are:
1176
+ * **collisions**: *string* (optional) --
1177
+ A symbolic value indicating what to do if a collision occurs between incoming
1178
+ and existing files. Possible values are:
666
1179
 
667
- * `error`: (the default) Abort with an error
668
- * `keep`: Keep the existing file
669
- * `replace`: Replace the existing file with the incoming file
1180
+ * `error`: (the default) Abort with an error
1181
+ * `keep`: Keep the existing file
1182
+ * `replace`: Replace the existing file with the incoming file
670
1183
 
671
- * **dest_path**: *string* (optional) --
672
- The path in the output directory to copy to. If **source_path** is provided,
673
- **dest_path** is the corresponding path in the output. If **source_path** is
674
- not provided, **dest_path** is a directory into which the source contents are
675
- copied. If **dest_path** is not provided, it defaults to the effective value
676
- of **source_path**, i.e. things are copied into the same locations within the
677
- output as they were in the source.
1184
+ * **dest_path**: *string* (optional) --
1185
+ The path in the output directory to copy to. If **source_path** is
1186
+ provided, **dest_path** is the corresponding path in the output. If
1187
+ **source_path** is not provided, **dest_path** is a directory into which
1188
+ the source contents are copied. If **dest_path** is not provided, it
1189
+ defaults to the effective value of **source_path**, i.e. things are copied
1190
+ into the same locations within the output as they were in the source.
678
1191
 
679
- * **source**: *string* (optional) --
680
- A symbolic value indicating where to copy from. Possible values are:
1192
+ * **source**: *string* (optional) --
1193
+ A symbolic value indicating where to copy from. Possible values are:
681
1194
 
682
- * `component`: (the default) Copy files from the component directory
683
- * `repo_root`: Copy files from the repository root
684
- * `temp`: Copy files from this step's temp directory
1195
+ * `component`: (the default) Copy files from the component directory
1196
+ * `repo_root`: Copy files from the repository root
1197
+ * `temp`: Copy files from this step's temp directory
685
1198
 
686
- * **source_path**: *string* (optional) --
687
- The path of the file or directory to copy from the source. Only this item
688
- (recursively, if a directory) is copied. If this key is not provided, *all*
689
- contents of the source are copied (e.g. the default is effectively "`.`")
1199
+ * **source_path**: *string* (optional) --
1200
+ The path of the file or directory to copy from the source. Only this item
1201
+ (recursively, if a directory) is copied. If this key is not provided, *all*
1202
+ contents of the source are copied (e.g. the default is effectively "`.`")
690
1203
 
691
1204
  #### Build step types
692
1205
 
693
1206
  This is a list of the available build step types, including their behavior and
694
1207
  any additional configuration keys supported by each.
695
1208
 
696
- * **build_gem** -- A step that builds a gem package.
1209
+ * **build_gem** -- A step that builds a gem package.
697
1210
 
698
- This step builds the gem described by the properly named gemspec file for
699
- this component. The built package file is copied to this step's output. Other
700
- steps (such as **release_gem**) can declare it as an input to get access to
701
- the built package. This step does not run unless it is so declared as a
702
- dependency or unless it is requested explicitly.
1211
+ This step builds the gem described by the properly named gemspec file for
1212
+ this component. The built package file is copied to this step's output.
1213
+ Other steps (such as **release_gem**) can declare it as an input to get
1214
+ access to the built package. This step does not run unless it is declared
1215
+ as an input dependency, or unless it is requested explicitly using the
1216
+ **run** configuration.
703
1217
 
704
- * **build_yard** -- A step that builds Yardocs.
1218
+ * **build_yard** -- A step that builds Yardocs.
705
1219
 
706
- This step builds documentation using [YARD](https://yardoc.org). The built
707
- documentation is copied to this step's output in the directory `doc/`. Other
708
- steps (such as **push_gh_pages**) can declare it as an input to get access to
709
- the built documentation. This step does not run unless it is so declared as a
710
- dependency or unless it is requested explicitly.
1220
+ This step builds documentation using [YARD](https://yardoc.org). The built
1221
+ documentation is copied to this step's output in the directory `doc/`.
1222
+ Other steps (such as **push_gh_pages**) can declare it as an input to get
1223
+ access to the built documentation. This step does not run unless it is
1224
+ declared as an input dependency, or unless it is requested explicitly using
1225
+ the **run** configuration.
711
1226
 
712
- This step supports the following additional configuration keys:
1227
+ This step supports the following additional configuration keys:
713
1228
 
714
- * **bundle_step**: *string* (optional) --
715
- The name of the bundle step. Defaults to `bundle`. This is used if the
716
- **uses_gems** key is *not* provided.
1229
+ * **bundle_step**: *string* (optional) --
1230
+ The name of the bundle step. Defaults to `bundle`. This is used if the
1231
+ **uses_gems** key is *not* provided.
717
1232
 
718
- * **uses_gems**: *array of (string or array of string)* (optional) --
719
- An array of gem specifications, each of which can be a simple gem name or
720
- an array including rubygems-style version requirements. These gems are
721
- provided to Yard, and can include gems such as `redcarpet` that may be
722
- needed for markup handling. If this key is included, the specified gems
723
- are installed directly; if not, the bundle step is declared as a
724
- dependency instead.
1233
+ * **uses_gems**: *array of (string or array of string)* (optional) --
1234
+ An array of gem specifications, each of which can be a simple gem name
1235
+ or an array including rubygems-style version requirements. These gems
1236
+ are provided to Yard, and can include gems such as `redcarpet` that may
1237
+ be needed for markup handling. If this key is included, the specified
1238
+ gems are installed directly; if not, the bundle step is declared as a
1239
+ dependency instead.
725
1240
 
726
- * **bundle** -- A step that installs the bundle in the component directory.
1241
+ * **bundle** -- A step that installs the bundle in the component directory.
727
1242
 
728
- This step copies the resulting `Gemfile.lock` to its output. Other steps can
729
- declare it as an input to get access to the `Gemfile.lock`. This step
730
- does not run unless it is so declared as a dependency or unless it is
731
- requested explicitly.
1243
+ This step copies the resulting `Gemfile.lock` to its output. Other steps
1244
+ can declare it as an input to get access to the `Gemfile.lock`. This step
1245
+ does not run unless it is declared as an input dependency, or unless it is
1246
+ requested explicitly using the **run** configuration.
732
1247
 
733
- This step supports the following additional configuration keys:
1248
+ This step supports the following additional configuration keys:
734
1249
 
735
- * **chdir**: *string* (optional) --
736
- Change to the specified directory (relative to the component directory)
737
- when installing the bundle. By default, runs in the component directory.
1250
+ * **chdir**: *string* (optional) --
1251
+ Change to the specified directory (relative to the component directory)
1252
+ when installing the bundle. Defaults to component directory.
738
1253
 
739
- * **command** -- A step that runs a command in the component directory.
1254
+ * **command** -- A step that runs a command in the component directory.
740
1255
 
741
- This step supports the following additional configuration keys:
1256
+ This step supports the following additional configuration keys:
742
1257
 
743
- * **chdir**: *string* (optional) --
744
- Change to the specified directory (relative to the component directory)
745
- when running the command. By default, runs in the component directory.
1258
+ * **chdir**: *string* (optional) --
1259
+ Change to the specified directory (relative to the component directory)
1260
+ when running the command. Defaults to component directory.
746
1261
 
747
- * **command**: *array of string* (required) --
748
- The command to run
1262
+ * **command**: *array of string* (required) --
1263
+ The command to run
749
1264
 
750
- * **continue_on_error**: *boolean* (optional) --
751
- If *true*, continue to run the pipeline if the command exits abnormally.
752
- If *false* (the default), the pipeline aborts.
1265
+ * **continue_on_error**: *boolean* (optional) --
1266
+ If *true*, continue to run the pipeline if the command exits
1267
+ abnormally. If *false* (the default), the pipeline aborts.
753
1268
 
754
- This step does not run unless it is requested explicitly using the **run**
755
- configuration or it is declared as a dependency.
1269
+ This step does not run unless it is requested explicitly using the **run**
1270
+ configuration, or it is declared as a dependency.
756
1271
 
757
- * **noop** -- A no-op step that does nothing. This type is usually configured
758
- with inputs and outputs and is used to collect or consolidate data from other
759
- steps.
1272
+ * **noop** -- A no-op step that does nothing. This type is usually configured
1273
+ with inputs and outputs and is used to collect or consolidate data from
1274
+ other steps.
760
1275
 
761
- This step does not run unless it is requested explicitly using the **run**
762
- configuration or it is declared as a dependency.
1276
+ This step does not run unless it is requested explicitly using the **run**
1277
+ configuration, or it is declared as a dependency.
763
1278
 
764
- * **push_gh_pages** -- A step that pushes documentation to the gh-pages branch.
1279
+ * **push_gh_pages** -- A step that pushes documentation to the gh-pages branch.
765
1280
 
766
- The documentation to publish should be under `doc/` in the output directory
767
- of a "source" step, normally the **build_yard** step. This source step is
768
- automatically declared as a dependency.
1281
+ The documentation to publish should be under `doc/` in the output directory
1282
+ of a "source" step, normally the **build_yard** step. This source step is
1283
+ automatically declared as a dependency.
769
1284
 
770
- This step supports the following additional configuration keys:
1285
+ This step supports the following additional configuration keys:
771
1286
 
772
- * **source**: *string* (optional) --
773
- The name of the source step. Defaults to `build_yard`.
1287
+ * **source**: *string* (optional) --
1288
+ The name of the source step. Defaults to `build_yard`.
774
1289
 
775
- This step runs if gh-pages publishing is enabled in the component.
1290
+ This step runs if gh-pages publishing is enabled for the component.
776
1291
 
777
- * **release_gem** -- A step that pushes a gem package to rubygems.org.
1292
+ * **release_gem** -- A step that pushes a gem package to rubygems.org.
778
1293
 
779
- The package must be provided under `pkg/` in the output directory of a
780
- "source" step, normally the **build_gem** step. This source step is
781
- automatically declared as a dependency.
1294
+ The package must be provided under `pkg/` in the output directory of a
1295
+ "source" step, normally the **build_gem** step. This source step is
1296
+ automatically declared as a dependency.
782
1297
 
783
- This step supports the following additional configuration keys:
1298
+ This step supports the following additional configuration keys:
784
1299
 
785
- * **source**: *string* (optional) --
786
- The name of the source step. Defaults to `build_gem`.
1300
+ * **source**: *string* (optional) --
1301
+ The name of the source step. Defaults to `build_gem`.
787
1302
 
788
- This step runs if a correctly-named gemspec file is present in the component
789
- directory.
1303
+ This step runs if a correctly-named gemspec file is present in the component
1304
+ directory.
790
1305
 
791
- * **release_github** -- A step that creates a git tag and GitHub release.
1306
+ * **release_github** -- A step that creates a git tag and GitHub release.
792
1307
 
793
- This step always runs if present in the pipeline.
1308
+ This step always runs if present in the pipeline.
794
1309
 
795
- * **tool** -- A step that runs a Toys tool in the component directory.
1310
+ * **tool** -- A step that runs a Toys tool in the component directory.
796
1311
 
797
- This step supports the following additional configuration keys:
1312
+ This step supports the following additional configuration keys:
798
1313
 
799
- * **chdir**: *string* (optional) --
800
- Change to the specified directory (relative to the component directory)
801
- when running the tool. By default, runs in the component directory.
1314
+ * **chdir**: *string* (optional) --
1315
+ Change to the specified directory (relative to the component directory)
1316
+ when running the tool. Defaults to component directory.
802
1317
 
803
- * **continue_on_error**: *boolean* (optional) --
804
- If *true*, continue to run the pipeline if the tool exits abnormally. If
805
- *false* (the default), the pipeline aborts.
1318
+ * **continue_on_error**: *boolean* (optional) --
1319
+ If *true*, continue to run the pipeline if the tool exits abnormally.
1320
+ If *false* (the default), the pipeline aborts.
806
1321
 
807
- * **tool**: *array of string* (required) --
808
- The tool to run
1322
+ * **tool**: *array of string* (required) --
1323
+ The tool to run
809
1324
 
810
- This step does not run unless it is requested explicitly using the **run**
811
- configuration or it is declared as a dependency.
1325
+ This step does not run unless it is requested explicitly using the **run**
1326
+ configuration, or it is declared as a dependency.
812
1327
 
813
1328
  #### Build step modification
814
1329
 
@@ -819,11 +1334,11 @@ below.
819
1334
  The **name** and **type** fields filter the steps to modify. If neither is
820
1335
  provided, *all* steps are modified.
821
1336
 
822
- * **name**: *string* (optional) --
823
- Modify only the step with this unique name.
1337
+ * **name**: *string* (optional) --
1338
+ Modify only the step with this unique name.
824
1339
 
825
- * **type**: *string* (optional) --
826
- Modify only steps matching this type.
1340
+ * **type**: *string* (optional) --
1341
+ Modify only steps matching this type.
827
1342
 
828
1343
  All other keys represent changes to the configuration of matching steps. You
829
1344
  can provide either the *null* value to delete the key, or a new full value for