Add MAKE_PARALLEL_JOBS parameter
[ci-management.git] / jjb / global-macros.yaml
1 # Copyright (c) 2020 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
5 #
6 #     http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 ---
15 # Global macros.
16
17 #### PARAMETERS
18 # Keep 'parameter' entries ordered alphabetically, please.
19 - parameter:
20     name: arch-parameter
21     parameters:
22       - string:
23           name: ARCH
24           default: '{arch}'
25           description: "Architecture parameter"
26
27 - parameter:
28     name: compiler-parameter
29     parameters:
30       - string:
31           name: CC
32           default: '{cc}'
33           description: "CC parameter, can be gnu or clang"
34
35 - parameter:
36     name: make-parallel-jobs-parameter
37     parameters:
38       - string:
39           name: MAKE_PARALLEL_JOBS
40           default: '{make-parallel-jobs}'
41           description: "The number of cores to use for builds."
42
43 - parameter:
44     name: csit-fail-on-crc-mismatch-parameter
45     parameters:
46       - string:
47           name: FDIO_CSIT_FAIL_ON_CRC_MISMATCH
48           default: '{fail-on-crc-mismatch}'
49           description: "If true, CRC is checked, else compatibility is tested."
50
51 - parameter:
52     name: csit-perf-trial-duration-parameter
53     parameters:
54       - string:
55           name: CSIT_PERF_TRIAL_DURATION
56           default: "{csit-perf-trial-duration}"
57           description: "Duration of a trial measurement in BMRR tests."
58
59 - parameter:
60     name: csit-perf-trial-multiplicity-parameter
61     parameters:
62       - string:
63           name: CSIT_PERF_TRIAL_MULTIPLICITY
64           default: "{csit-perf-trial-multiplicity}"
65           description: "Number of subsamples for BMRR tests."
66
67 - parameter:
68     name: gerrit-csit-refspec-parameter
69     parameters:
70       - string:
71           name: CSIT_REF
72           default: ''
73           # yamllint disable-line rule:line-length
74           description: "GERRIT_REFSPEC parameter to override separately cloned CSIT repository, leave empty for autodetection / no override."
75
76 - parameter:
77     name: gerrit-event-comment-text-parameter
78     parameters:
79       - string:
80           name: GERRIT_EVENT_COMMENT_TEXT
81           default: ''
82           # yamllint disable-line rule:line-length
83           description: "GERRIT_EVENT_COMMENT_TEXT parameter not given by trigger"
84
85 - parameter:
86     name: gerrit-event-type-parameter
87     parameters:
88       - string:
89           name: GERRIT_EVENT_TYPE
90           default: ''
91           description: "GERRIT_EVENT_TYPE parameter not given by trigger"
92
93 - parameter:
94     name: gerrit-parameter
95     parameters:
96       - string:
97           name: GERRIT_BRANCH
98           default: '{branch}'
99           description: "JJB configured GERRIT_BRANCH parameter"
100
101 - parameter:
102     name: gerrit-project-parameter
103     parameters:
104       - string:
105           name: GERRIT_PROJECT
106           default: '{project}'
107           description: "GERRIT_PROJECT parameter if not given by trigger"
108
109 - parameter:
110     name: gerrit-refspec-parameter
111     parameters:
112       - string:
113           name: GERRIT_REFSPEC
114           default: '{refspec}'
115           description: "GERRIT_REFSPEC parameter not given by trigger"
116
117 - parameter:
118     name: is-csit-vpp-job-parameter
119     parameters:
120       - string:
121           name: IS_CSIT_VPP_JOB
122           default: '{is-csit-vpp-job}'
123           description: "Parameter is True if this is a CSIT vpp job."
124
125 - parameter:
126     name: maven-exec
127     parameters:
128       - string:
129           name: MVN
130           # yamllint disable-line rule:line-length
131           default: '/w/tools/hudson.tasks.Maven_MavenInstallation/{maven-version}/bin/mvn'
132           description: 'Maven selector to be used by shell scripts'
133
134 - parameter:
135     name: maven-project-parameter
136     parameters:
137       - string:
138           name: MAVEN_SELECTOR
139           default: '{maven}'
140           description: 'Maven selector to be used by shell scripts'
141
142 - parameter:
143     name: os-parameter
144     parameters:
145       - string:
146           name: OS
147           default: '{os}'
148           description: "OS parameter"
149
150 - parameter:
151     name: project-parameter
152     parameters:
153       - string:
154           name: PROJECT
155           default: '{project}'
156           # yamllint disable-line rule:line-length
157           description: "JJB configured PROJECT parameter to identify a Gerrit project"
158
159 - parameter:
160     name: repo-name-parameter
161     parameters:
162       - string:
163           name: REPO_NAME
164           default: '{repo-name}'
165           description: 'Name of repo to which to publish packaging'
166
167 - parameter:
168     name: stream-parameter
169     parameters:
170       - string:
171           name: STREAM
172           default: '{stream}'
173           description: "Stream job parameter to be used in shell scripts."
174
175 - parameter:
176     name: topo-parameter
177     parameters:
178       - string:
179           name: TOPO
180           default: '{topo}'
181           description: "Topology parameter"
182 # [end] Keep 'parameter' entries ordered alphabetically, please.
183
184 #### SCMS
185 # Keep 'scm' entries ordered alphabetically, please.
186 - scm:
187     name: gerrit-trigger-scm
188     scm:
189       - git:
190           credentials-id: '{credentials-id}'
191           url: '$GIT_BASE'
192           refspec: '{refspec}'
193           branches:
194             - 'origin/$GERRIT_BRANCH'
195           skip-tag: true
196           choosing-strategy: '{choosing-strategy}'
197
198 - scm:
199     name: gerrit-trigger-scm-recursive
200     scm:
201       - git:
202           credentials-id: '{credentials-id}'
203           url: '$GIT_BASE'
204           refspec: '{refspec}'
205           branches:
206             - 'origin/$GERRIT_BRANCH'
207           skip-tag: true
208           choosing-strategy: '{choosing-strategy}'
209           submodule:
210             recursive: '{submodule-recursive}'
211
212 - scm:
213     name: git-scm
214     scm:
215       - git:
216           credentials-id: '{credentials-id}'
217           url: '$GIT_BASE'
218           refspec: ''
219           branches:
220             - 'origin/{branch}'
221           skip-tag: true
222           wipe-workspace: true
223 # [end] Keep 'scm' entries ordered alphabetically, please.
224
225 #### WRAPPERS
226 # Keep 'wrapper' entries ordered alphabetically, please.
227 - wrapper:
228     name: build-timeout
229     wrappers:
230       - timeout:
231           type: absolute
232           timeout: 360
233           fail: true
234
235 - wrapper:
236     # This wrapper is required for all jobs as it configures the wrappers
237     # needed by the fd.io infra.
238     name: fdio-infra-wrappers
239     wrappers:
240       - timeout:
241           type: absolute
242           timeout: '{build-timeout}'
243           timeout-var: 'BUILD_TIMEOUT'
244           fail: true
245       - timestamps
246       - ssh-agent-credentials:
247           users:
248             - 'jenkins-gerrit-credentials'
249       - jclouds:
250           single-use: true
251       - openstack:
252           single-use: true
253
254 - wrapper:
255     # This wrapper is used for all jobs that require no-activity timeouts
256     name: fdio-infra-wrappers-non-activity-timeout
257     wrappers:
258       - timeout:
259           type: no-activity
260           timeout: '{build-timeout}'
261           fail: true
262       - timestamps
263       - ssh-agent-credentials:
264           users:
265             - 'jenkins-gerrit-credentials'
266       - jclouds:
267           single-use: true
268       - openstack:
269           single-use: true
270 # [end] Keep 'wrapper' entries ordered alphabetically, please.
271
272 #### TRIGGERS
273 # Keep 'trigger' entries ordered alphabetically, please.
274 - trigger:
275     name: gerrit-trigger-checkstyle
276     # Comes from VPP, some verify jobs wait for checkstyle to pass.
277     # This macro is to be used for such verify jobs which are voting.
278     triggers:
279       - gerrit:
280           server-name: 'Primary'
281           trigger-on:
282             - comment-added-contains-event:
283                 comment-contains-value: 'checkstyle_success'
284           projects:
285             - project-compare-type: 'ANT'
286               project-pattern: '{name}'
287               branches:
288                 - branch-compare-type: 'ANT'
289                   branch-pattern: '**/{branch}'
290
291 - trigger:
292     name: gerrit-trigger-checkstyle-nonvoting
293     # Comes from VPP, some verify jobs wait for checkstyle to pass.
294     # This macro is to be used for such verify jobs which are non-voting.
295     triggers:
296       - gerrit:
297           server-name: 'Primary'
298           trigger-on:
299             - comment-added-contains-event:
300                 comment-contains-value: 'checkstyle_success'
301           projects:
302             - project-compare-type: 'ANT'
303               project-pattern: '{name}'
304               branches:
305                 - branch-compare-type: 'ANT'
306                   branch-pattern: '**/{branch}'
307           skip-vote:
308             successful: true
309             failed: true
310             unstable: true
311             notbuilt: true
312           override-votes: true
313           gerrit-build-successful-verified-value: 1
314           gerrit-build-failed-verified-value: 1
315           gerrit-build-unstable-verified-value: 1
316           gerrit-build-notbuilt-verified-value: 1
317
318 - trigger:
319     name: gerrit-trigger-csit-perftest
320     # Manual trigger common for csit-vpp and vpp-csit perf jobs.
321     triggers:
322       - gerrit:
323           server-name: 'Primary'
324           trigger-on:
325             - comment-added-contains-event:
326                 comment-contains-value: '{trigger-word}'
327           projects:
328             - project-compare-type: 'ANT'
329               project-pattern: '{project}'
330               branches:
331                 - branch-compare-type: 'ANT'
332                   branch-pattern: '**/{branch}'
333           skip-vote:
334             successful: '{skip-vote}'
335             failed: '{skip-vote}'
336             unstable: '{skip-vote}'
337             notbuilt: '{skip-vote}'
338
339 - trigger:
340     name: gerrit-trigger-csit-vpp-devicetest-full
341     # Comes from CSIT, for automatic jobs running "device" tests with VPP builds.
342     # The job acts as an automatic verify job for CSIT contributions.
343     triggers:
344       - gerrit:
345           server-name: 'Primary'
346           trigger-on:
347             - patchset-created-event:
348                 exclude-drafts: 'true'
349                 exclude-trivial-rebase: 'false'
350                 exclude-no-code-change: 'false'
351             - draft-published-event
352             - comment-added-contains-event:
353                 comment-contains-value: 'recheck'
354             - comment-added-contains-event:
355                 comment-contains-value: 'reverify'
356             - comment-added-contains-event:
357                 comment-contains-value: 'csit-devicetest'
358           projects:
359             - project-compare-type: 'ANT'
360               project-pattern: '{project}'
361               branches:
362                 - branch-compare-type: 'ANT'
363                   branch-pattern: '**/{branch}'
364           skip-vote:
365             successful: '{skip-vote}'
366             failed: '{skip-vote}'
367             unstable: '{skip-vote}'
368             notbuilt: '{skip-vote}'
369
370 - trigger:
371     name: gerrit-trigger-csit-vpp-devicetest-manual
372     # Comes from CSIT, for manual jobs running "device" tests with VPP builds.
373     # The job acts as a manual (optional) verify job for CSIT contributions.
374     triggers:
375       - gerrit:
376           server-name: 'Primary'
377           trigger-on:
378             - comment-added-contains-event:
379                 comment-contains-value: 'csit-devicetest'
380           projects:
381             - project-compare-type: 'ANT'
382               project-pattern: '{project}'
383               branches:
384                 - branch-compare-type: 'ANT'
385                   branch-pattern: '**/{branch}'
386           skip-vote:
387             successful: '{skip-vote}'
388             failed: '{skip-vote}'
389             unstable: '{skip-vote}'
390             notbuilt: '{skip-vote}'
391
392 - trigger:
393     name: gerrit-trigger-manually-triggered
394     triggers:
395       - gerrit:
396           server-name: 'Primary'
397           trigger-on:
398             - comment-added-contains-event:
399                 comment-contains-value: '{comment-trigger-value}'
400           projects:
401             - project-compare-type: 'ANT'
402               project-pattern: '{name}'
403               branches:
404                 - branch-compare-type: 'ANT'
405                   branch-pattern: '**/{branch}'
406
407 - trigger:
408     name: gerrit-trigger-patch-merged
409     triggers:
410       - gerrit:
411           server-name: 'Primary'
412           trigger-on:
413             - change-merged-event
414             - comment-added-contains-event:
415                 comment-contains-value: 'remerge'
416           projects:
417             - project-compare-type: 'ANT'
418               project-pattern: '{name}'
419               branches:
420                 - branch-compare-type: 'ANT'
421                   branch-pattern: '**/{branch}'
422           # Force Jenkins always vote the values it should already have voted
423           # during the prior verify phase
424           override-votes: true
425           gerrit-build-started-verified-value: 1
426           gerrit-build-successful-verified-value: 1
427           gerrit-build-failed-verified-value: 1
428           gerrit-build-unstable-verified-value: 1
429           gerrit-build-notbuilt-verified-value: 1
430           gerrit-build-started-codereview-value: 0
431           gerrit-build-successful-codereview-value: 0
432           gerrit-build-failed-codereview-value: 0
433           gerrit-build-unstable-codereview-value: 0
434           gerrit-build-notbuilt-codereview-value: 0
435
436 - trigger:
437     name: gerrit-trigger-patch-submitted
438     triggers:
439       - gerrit:
440           server-name: 'Primary'
441           trigger-on:
442             - patchset-created-event:
443                 exclude-drafts: 'true'
444                 exclude-trivial-rebase: 'false'
445                 exclude-no-code-change: 'false'
446             - draft-published-event
447             - comment-added-contains-event:
448                 comment-contains-value: 'recheck'
449             - comment-added-contains-event:
450                 comment-contains-value: 'reverify'
451           projects:
452             - project-compare-type: 'ANT'
453               project-pattern: '{name}'
454               branches:
455                 - branch-compare-type: 'ANT'
456                   branch-pattern: '**/{branch}'
457
458 - trigger:
459     name: gerrit-trigger-os-patch-merged
460     triggers:
461       - gerrit:
462           server-name: 'Primary'
463           trigger-on:
464             - comment-added-contains-event:
465                 comment-contains-value: 'os-merge'
466           projects:
467             - project-compare-type: 'ANT'
468               project-pattern: '{name}'
469               branches:
470                 - branch-compare-type: 'ANT'
471                   branch-pattern: '**/{branch}'
472           # Force Jenkins always vote the values it should already have voted
473           # during the prior verify phase
474           override-votes: true
475           gerrit-build-started-verified-value: 1
476           gerrit-build-successful-verified-value: 1
477           gerrit-build-failed-verified-value: 1
478           gerrit-build-unstable-verified-value: 1
479           gerrit-build-notbuilt-verified-value: 1
480           gerrit-build-started-codereview-value: 0
481           gerrit-build-successful-codereview-value: 0
482           gerrit-build-failed-codereview-value: 0
483           gerrit-build-unstable-codereview-value: 0
484           gerrit-build-notbuilt-codereview-value: 0
485
486 - trigger:
487     name: gerrit-trigger-os-trivial-patch-submitted
488     triggers:
489       - gerrit:
490           server-name: 'Primary'
491           trigger-on:
492             - comment-added-contains-event:
493                 comment-contains-value: 'os-check'
494             - comment-added-contains-event:
495                 comment-contains-value: 'os-verify'
496           projects:
497             - project-compare-type: 'ANT'
498               project-pattern: '{name}'
499               branches:
500                 - branch-compare-type: 'ANT'
501                   branch-pattern: '**/{branch}'
502
503 - trigger:
504     name: gerrit-trigger-trivial-patch-submitted
505     triggers:
506       - gerrit:
507           server-name: 'Primary'
508           trigger-on:
509             - patchset-created-event:
510                 exclude-drafts: 'true'
511                 exclude-trivial-rebase: 'false'
512                 exclude-no-code-change: 'true'
513             - draft-published-event
514             - comment-added-contains-event:
515                 comment-contains-value: 'recheck'
516             - comment-added-contains-event:
517                 comment-contains-value: 'reverify'
518           projects:
519             - project-compare-type: 'ANT'
520               project-pattern: '{name}'
521               branches:
522                 - branch-compare-type: 'ANT'
523                   branch-pattern: '**/{branch}'
524
525 - trigger:
526     name: gerrit-trigger-trivial-patch-submitted-skip-vote
527     triggers:
528       - gerrit:
529           server-name: 'Primary'
530           trigger-on:
531             - patchset-created-event:
532                 exclude-drafts: 'true'
533                 exclude-trivial-rebase: 'false'
534                 exclude-no-code-change: 'true'
535             - draft-published-event
536             - comment-added-contains-event:
537                 comment-contains-value: 'recheck'
538             - comment-added-contains-event:
539                 comment-contains-value: 'reverify'
540           projects:
541             - project-compare-type: 'ANT'
542               project-pattern: '{name}'
543               branches:
544                 - branch-compare-type: 'ANT'
545                   branch-pattern: '**/{branch}'
546           skip-vote:
547             successful: true
548             failed: true
549             unstable: true
550             notbuilt: true
551
552 - trigger:
553     name: gerrit-trigger-vpp-csit-devicetest-full
554     # Comes from VPP, for automated jobs running "device" tests with CSIT code.
555     # The job acts as an automatic verify job for VPP contributions.
556     triggers:
557       - gerrit:
558           server-name: 'Primary'
559           trigger-on:
560             - comment-added-contains-event:
561                 comment-contains-value: 'checkstyle_success'
562             - comment-added-contains-event:
563                 comment-contains-value: 'devicetest'
564           projects:
565             - project-compare-type: 'ANT'
566               project-pattern: '{name}'
567               branches:
568                 - branch-compare-type: 'ANT'
569                   branch-pattern: '**/{branch}'
570           skip-vote:
571             successful: '{skip-vote}'
572             failed: '{skip-vote}'
573             unstable: '{skip-vote}'
574             notbuilt: '{skip-vote}'
575
576 - trigger:
577     name: gerrit-trigger-vpp-csit-devicetest-manual
578     # Comes from VPP, for manual jobs running "device" tests with CSIT code.
579     # The job acts as a manual (optional) verify job for VPP contributions.
580     triggers:
581       - gerrit:
582           server-name: 'Primary'
583           trigger-on:
584             - comment-added-contains-event:
585                 comment-contains-value: 'devicetest'
586           projects:
587             - project-compare-type: 'ANT'
588               project-pattern: '{name}'
589               branches:
590                 - branch-compare-type: 'ANT'
591                   branch-pattern: '**/{branch}'
592           skip-vote:
593             successful: '{skip-vote}'
594             failed: '{skip-vote}'
595             unstable: '{skip-vote}'
596             notbuilt: '{skip-vote}'
597 # [end] Keep 'trigger' entries ordered alphabetically, please.
598
599 #### PUBLISHERS
600 # Keep 'publisher' entries ordered alphabetically, please.
601 - publisher:
602     name: archive-artifacts
603     publishers:
604       - archive:
605           artifacts: '{artifacts}'
606           allow-empty: true
607           fingerprint: true
608           latest-only: true
609
610 - publisher:
611     name: email-notification
612     publishers:
613       - email-ext:
614           recipients: 'nobody@projectrotterdam.info'
615           reply-to: ''
616           content-type: default
617           # yamllint disable-line rule:line-length
618           subject: '{email-prefix} $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!'
619           body: |
620               $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:
621
622               Check console output at $BUILD_URL to view the results.
623           unstable: true
624           fixed: true
625           send-to:
626             - developers
627             - recipients
628
629 - publisher:
630     name: fdio-infra-shiplogs
631     # To archive things, the job will need to create an "archives" directory in
632     # the workspace and this macro will handle copying the contents of the
633     # archives directory.
634     #
635     # Uses the build parameter ARCHIVE_ARTIFACTS if not empty to find files to
636     # archive. You can pass globstar patterns for example "**/*.xml **/*.log" as
637     # the archive pattern. This is a space separated list of files to archive.
638     #
639     # Also ensure that the workspace is cleaned up at the end of the build.
640     publishers:
641       - postbuildscript:
642           builders:
643             - role: BOTH
644               build-on:
645                 - ABORTED
646                 - FAILURE
647                 - NOT_BUILT
648                 - SUCCESS
649                 - UNSTABLE
650               build-steps:
651                 - shell: !include-raw: include-raw-deploy-archives.sh
652                 - maven-target:
653                     maven-version: '{maven-version}'
654                     pom: '.archives/deploy-archives.xml'
655                     goals: 'clean deploy -V -B -q -Dmaven.repo.local=/tmp/r'
656                     settings: 'jenkins-log-archives-settings'
657                     settings-type: cfp
658                     global-settings: 'global-settings'
659                     global-settings-type: cfp
660                 - description-setter:
661                     regexp: '^Build logs: .*'
662           mark-unstable-if-failed: true
663       - workspace-cleanup:
664           fail-build: false
665
666 - publisher:
667     name: jacoco-report
668     publishers:
669       - jacoco:
670           exec-pattern: '**/**.exec'
671           class-pattern: '**/classes'
672           source-pattern: '**/src/main/java'
673           # yamllint disable-line rule:line-length
674           exclusion-pattern: '**/gen**,**/generated-sources/**,**/yang-gen**,**/pax/**'
675           status-update: true
676           targets:
677             - branch:
678               healthy: 10
679               unhealthy: 20
680             - method:
681               healthy: 50
682               unhealthy: 40
683
684 - publisher:
685     name: retry-build-on-builder-error
686     publishers:
687       - naginator:
688           max-failed-builds: 1
689
690 - publisher:
691     name: robot-report
692     publishers:
693       - robot:
694           output-path: '{output-path}'
695           other-files: ''
696 # [end] Keep 'publisher' entries ordered alphabetically, please.
697
698 #### BUILDERS
699 # Keep 'builder' entries ordered alphabetically, please.
700 - builder:
701     name: ci-management-check-unicode
702     builders:
703       - shell: |
704           $WORKSPACE/scripts/check-unicode.sh jjb/
705
706 - property:
707     name: fdio-infra-properties
708     properties:
709       - build-discarder:
710           days-to-keep: '{build-days-to-keep}'
711           num-to-keep: '{build-num-to-keep}'
712
713 - builder:
714     name: packer-validate
715     builders:
716       - config-file-provider:
717           files:
718             - file-id: 'packer-cloud-env'
719               variable: 'CLOUDENV'
720       # yamllint disable rule:line-length
721       - shell: |
722           #!/bin/bash
723           cd packer
724           varfiles="../packer/vars/*"
725           templates="../packer/templates/*"
726           provision="../packer/provision/*.sh"
727           for v in $varfiles; do
728               [[ "${v##*/}" =~ ^(cloud-env.*)$ ]] && continue
729               for t in $templates; do
730                   export PACKER_LOG="yes" && \
731                   export PACKER_LOG_PATH="packer-validate-${v##*/}-${t##*/}.log" && \
732                               packer.io validate -var-file=$CLOUDENV \
733                               -var-file=$v $t
734                   if [ $? -ne 0 ]; then
735                      break
736                   fi
737               done
738           done
739           for p in $provision; do
740               /bin/bash -n $p > provision-validate-${p##*/}.log 2>&1
741               if [ $? -ne 0 ]; then
742                  break
743               fi
744           done
745       # yamllint enable
746
747 - builder:
748     name: packer-build
749     builders:
750       - config-file-provider:
751           files:
752             - file-id: 'packer-cloud-env'
753               variable: 'CLOUDENV'
754       - shell: |
755           #!/bin/bash
756           cd packer
757           export PACKER_LOG="yes" && \
758           export PACKER_LOG_PATH="packer-build.log" && \
759                       packer.io build -var-file=$CLOUDENV \
760                       -var-file=../packer/vars/{platform}.json \
761                       ../packer/templates/{template}.json
762
763 - builder:
764     name: provide-maven-settings
765     builders:
766       - config-file-provider:
767           files:
768             - file-id: '{global-settings-file}'
769               variable: 'GLOBAL_SETTINGS_FILE'
770             - file-id: '{settings-file}'
771               variable: 'SETTINGS_FILE'
772 # [end] Keep 'builder' entries ordered alphabetically, please.