73e04c7691362a882cee43e10895ef9a92526680
[releng/global-jjb.git] / docs / jjb / lf-release-jobs.rst
1 .. _lf-global-jjb-release:
2
3 Self-Serve Release Jobs
4 =======================
5
6 Self-serve release jobs allow project committers to direct Jenkins to
7 promote a jar file, container image or Python package from a staging
8 area to a release area.
9
10 To use the self-release process, create a releases/ or .releases/
11 directory at the root of the project repository, add one release yaml
12 file to it, and submit a change set with that release yaml file.  The
13 required contents of the release yaml file are different for each type
14 of release, see the schemas and examples shown below.  The version in
15 the release yaml file must be a valid Semantic Versioning (SemVer)
16 string, matching either the pattern "v#.#.#" or "#.#.#" where "#" is
17 one or more digits.  Upon merge of the change, Jenkins will sign the
18 reference extrapolated by log_dir and promote the artifact.
19
20 .. note::
21
22    The release file regex is: (releases\/.*\.yaml|\.releases\/.*\.yaml).
23    In words, the directory name can be ".releases" or "releases"; the file
24    name can be anything with suffix ".yaml".
25
26 The build node for all release jobs must be CentOS, which supports the
27 sigul client for accessing a signing server. The build node for
28 container release jobs must have Docker installed.
29
30 A Jenkins admin user can also trigger a release job via the "Build
31 with parameters" action, removing the need to create and merge a
32 release yaml file.  The user must enter parameters in the same way as
33 a release yaml file, except for the special USE_RELEASE_FILE and
34 DRY_RUN check boxes. The user must uncheck the USE_RELEASE_FILE check
35 box if the job should run without a release file, instead passing the
36 required information as build parameters. The user can check the
37 DRY_RUN check box to test the job while skipping upload of files to
38 the release repository.
39
40 For example, the parameters for a Maven release are as follows::
41
42     GERRIT_BRANCH = master
43     VERSION = 1.0.0
44     LOG_DIR = example-project-maven-stage-master/17/
45     DISTRIBUTION_TYPE = maven
46     USE_RELEASE_FILE = false
47     DRY_RUN = false
48
49 Maven Release Files
50 -------------------
51
52 An example of a maven release file appears below.
53
54 .. code-block:: none
55
56     $ cat releases/maven-release.yaml
57     ---
58     distribution_type: maven
59     log_dir: example-project-maven-stage-master/17/
60     project: example-project
61     version: 1.0.0
62
63
64 The following parameters must appear in a maven release yaml file.
65
66 :Required Parameters:
67
68     :distribution_type: Must be "maven".
69     :log_dir: The suffix of the logs URL reported on completion by the
70         Jenkins stage job that created and pushed the artifact
71         to the staging repository.  For example, use value
72         "example-project-maven-stage-master/17" for the logs URL
73         https://logs.lf-project.org/production/vex-sjc-lfp-jenkins-prod-1/example-project-maven-stage-master/17
74     :project: The name of the project.
75     :version: The semantic version string used for the artifact.
76
77 The JSON schema for a maven release file appears below.
78
79 .. code-block:: none
80
81     ---
82     $schema: "http://json-schema.org/schema#"
83     $id: "https://github.com/lfit/releng-global-jjb/blob/master/release-schema.yaml"
84
85     required:
86       - "distribution_type"
87       - "log_dir"
88       - "project"
89       - "version"
90
91     properties:
92       distribution_type:
93         type: "string"
94       log_dir:
95         type: "string"
96       project:
97         type: "string"
98       version:
99         type: "string"
100
101
102 Container Release Files
103 -----------------------
104
105 An example of a container release file appears below.
106
107 .. code-block:: none
108
109     $ cat releases/container-release.yaml
110     ---
111     distribution_type: container
112     container_release_tag: 1.0.0
113     container_pull_registry: nexus.onap.org:10003
114     container_push_registry: nexus.onap.org:10002
115     project: test
116     ref: d1b9cd2dd345fbeec0d3e2162e008358b8b663b2
117     containers:
118         - name: test-backend
119           version: 1.0.0-20190806T184921Z
120         - name: test-frontend
121           version: 1.0.0-20190806T184921Z
122
123
124 The following parameters must appear in a container release yaml file.
125
126 :Required Parameters:
127
128     :distribution_type: Must be "container".
129     :container_release_tag: The string to use as a Docker tag on all
130         released containers.
131     :container_pull_registry: The Nexus registry that supplies the staged
132         image(s).
133     :container_push_registry: The Nexus registry that receives the released
134         image(s).
135     :project: The name of the project.
136     :ref: The git commit reference (SHA-1 code) to tag with the version string.
137     :containers: A list of name and version (tag) pairs that specify the
138         Docker images in the container-pull registry to promote to the
139         container-push registry.
140
141 The JSON schema for a container release file appears below.
142
143 .. code-block:: none
144
145     ---
146     $schema: "http://json-schema.org/schema#"
147     $id: "https://github.com/lfit/releng-global-jjb/blob/master/release-container-schema.yaml"
148
149     required:
150       - "containers"
151       - "distribution_type"
152       - "project"
153       - "container_release_tag"
154       - "ref"
155
156     properties:
157       containers:
158         type: "array"
159         properties:
160           name:
161             type: "string"
162           version:
163             type: "string"
164         additionalProperties: false
165       distribution_type:
166         type: "string"
167       project:
168         type: "string"
169       container_release_tag:
170         type: "string"
171       container_pull_registry"
172         type: "string"
173       container_push_registry"
174         type: "string"
175       ref:
176         type: "string"
177
178
179 PyPI Release Files
180 ------------------
181
182 An example of a PyPI release file appears below.
183
184 .. code-block:: none
185
186     $ cat releases/pypi-release.yaml
187     ---
188     distribution_type: pypi
189     pypi_project: mypackage
190     python_version: '3.4'
191     version: 1.0.0
192
193
194 The following parameters must appear in the PyPI release yaml file.
195 These are not part of the Jenkins job definition to allow independent
196 self-release of a package maintained in a git repository with other
197 packages.
198
199 :Required Parameters:
200
201     :distribution_type: Must be "pypi".
202     :log_dir: The suffix of the logs URL reported on completion by the
203         Jenkins merge job that created and pushed the distribution files
204         to the staging repository.  For example, use value
205         "example-project-pypi-merge-master/17" for the logs URL
206         https://logs.lf-project.org/production/vex-sjc-lfp-jenkins-prod-1/example-project-pypi-merge-master/17
207     :pypi_project: The PyPI project name at the staging and
208         release repositories, for example "mypackage".
209     :python_version: The Python interpreter version to use for pip
210         "Requires-Python" compatibility checks, for example '3', '3.7' or 3.7.4.
211         Put valid decimal values such as 3 or 3.7 in quotes to pass schema validation.
212     :version: The semantic version string used for the package in the
213         setup.py file.
214
215 The JSON schema for a PyPI release file appears below.
216
217 .. code-block:: none
218
219     ---
220     $schema: "http://json-schema.org/schema#"
221     $id: "https://github.com/lfit/releng-global-jjb/blob/master/release-pypi-schema.yaml"
222
223     required:
224       - "distribution_type"
225       - "log_dir"
226       - "pypi_project"
227       - "python_version"
228       - "version"
229
230     properties:
231       distribution_type:
232         type: "string"
233       log_dir:
234         type: "string"
235       pypi_project:
236         type: "string"
237       python_version:
238         type: "string"
239       version:
240         type: "string"
241
242
243 PackageCloud Release Files
244 --------------------------
245
246 An example of a PackageCloud release file appears below.
247
248 .. code-block:: none
249
250     $ cat releases/packagecloud-release.yaml
251     ---
252     distribution_type: packagecloud
253     package_name:
254         - name: 'tree-1.6.0-10.el7.x86_64.rpm'
255         - name: 'test.rpm'
256
257 The following parameters must appear in the PackageCloud release yaml file.
258 These are not part of the Jenkins job definition to allow independent
259 self-release of a package maintained in a git repository with other
260 packages.
261
262 :Required Parameters:
263
264     :distribution_type: Must be "packagecloud".
265     :package_name: A list of names that specify the packages to promote.
266         (Found via jenkins log when using gem to initally push package up eg.
267         "Pushing /path/of/package/name-of-package.rpm... success!"
268         OR using rest api call with generated token from packagecloud.io
269         "curl https://packagecloud.io/api/v1/repos/test_user/test_repo/search?q=
270         | yq -r .[].filename"
271
272 The JSON schema for a PackageCloud release file appears below.
273
274 .. code-block:: none
275
276     ---
277     $schema: "http://json-schema.org/schema#"
278     $id: "https://github.com/lfit/releng-global-jjb/blob/master/packagecloud-release-schema"
279
280     required:
281       - "package_name"
282       - "distribution_type"
283
284     properties:
285       package_name:
286         type: "array"
287         properties:
288           name:
289             type: "string"
290     distribution_type:
291       type: "string"
292
293 Jenkins Jobs
294 ------------
295
296 An example of a Jenkins job configuration that uses the global-jjb
297 templates for maven and container release jobs appears next.
298
299 .. code-block:: none
300
301     - project:
302         name: my-project-release
303         project: my-project
304         project-name: my-project
305         build-node: centos7-docker-4c-4g
306         mvn-settings: my-project-settings
307         jobs:
308             - '{project-name}-gerrit-release-jobs'
309
310
311 .. note::
312
313    Release Engineers: please follow the setup guide below before adding the job definition.
314
315
316 JJB Macros
317 ----------
318
319 lf-release
320 ~~~~~~~~~~
321
322 Release verify and merge jobs are the same except for their scm,
323 trigger, and builders definition. This anchor is the common template.
324
325 JJB Templates
326 -------------
327
328 Release Merge
329 ~~~~~~~~~~~~~
330
331 This template supports Maven and Container release jobs.
332
333 :Template Name: {project-name}-release-merge
334
335 :Comment Trigger: remerge
336
337 :Required parameters:
338
339     :build-node: The node to run build on.
340     :jenkins-ssh-release-credential: Credential to use for SSH. (Generally set
341         in defaults.yaml)
342     :project: Git repository name
343     :project-name: Jenkins job name prefix
344
345 :Optional parameters:
346
347     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
348     :build-timeout: Timeout in minutes before aborting build. (default: 15)
349
350     :gerrit_merge_triggers: Override Gerrit Triggers.
351     :gerrit_trigger_file_paths: Override file paths filter which checks which
352         file modifications will trigger a build.
353         **default**::
354
355             - compare-type: REG_EXP
356               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
357
358
359 Release Verify
360 ~~~~~~~~~~~~~~
361
362 This template supports Maven and Container release jobs.
363
364 :Template Name: {project-name}-release-verify
365
366 :Comment Trigger: recheck|reverify
367
368 :Required Parameters:
369
370     :build-node: The node to run build on.
371     :jenkins-ssh-credential: Credential to use for SSH. (Generally set
372         in defaults.yaml)
373     :project: Git repository name
374     :project-name: Jenkins job name prefix
375
376 :Optional Parameters:
377
378     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
379     :build-node: The node to run build on.
380     :build-timeout: Timeout in minutes before aborting build. (default: 15)
381     :gerrit-skip-vote: Skip voting for this job. (default: false)
382     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
383
384     :gerrit_verify_triggers: Override Gerrit Triggers.
385     :gerrit_trigger_file_paths: Override file paths filter which checks which
386         file modifications will trigger a build.
387         **default**::
388
389             - compare-type: REG_EXP
390               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
391
392
393 PyPI Release Merge
394 ~~~~~~~~~~~~~~~~~~
395
396 Publishes a Python package on merge of a patch set with a release yaml
397 file. Checks the format of the version string, downloads the package
398 artifacts from the PyPI staging repository, uploads the package
399 artifacts to the PyPI release repository, tags the git repository,
400 signs the tag and pushes the tag to the git server. The release verify
401 template accepts neither a branch nor a stream parameter.
402
403 :Template Names:
404
405     - {project-name}-pypi-release-merge
406     - gerrit-pypi-release-merge
407     - github-pypi-release-merge
408
409 :Comment Trigger: remerge
410
411 :Required Parameters:
412
413     :build-node: The node to run build on, which must be Centos.
414     :jenkins-ssh-release-credential: Credential to use for SSH. (Generally set
415         in defaults.yaml)
416     :project: Git repository name
417     :project-name: Jenkins job name prefix
418
419 :Optional Parameters:
420
421     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
422     :build-timeout: Timeout in minutes before aborting build. (default: 15)
423     :disable-job: Whether to disable the job (default: false)
424     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
425     :pypi-stage-index: Base URL of the PyPI staging repository.
426         (default https://test.pypi.org/simple)
427     :pypi-repo: Key for the PyPI release repository in the .pypirc file,
428         should be the repository pypy.org. (default: pypi)
429     :use-release-file: Whether to use the release file. (default: true)
430
431
432 PyPI Release Verify
433 ~~~~~~~~~~~~~~~~~~~
434
435 Verifies a Python package project on creation of a patch set with a
436 release yaml file. Checks the contents of the release yaml file,
437 checks the format of the version string, and downloads the release
438 artifacts from the specified PyPI staging repository. The release
439 verify template accepts neither a branch nor a stream parameter.
440
441 :Template Names:
442
443     - {project-name}-pypi-release-verify
444     - gerrit-pypi-release-verify
445     - github-pypi-release-verify
446
447 :Comment Trigger: recheck
448
449 :Required Parameters:
450
451     :build-node: The node to run build on, which must be Centos.
452     :jenkins-ssh-credential: Credential to use for SSH. (Generally set
453         in defaults.yaml)
454     :project: Git repository name
455     :project-name: Jenkins job name prefix
456
457 :Optional Parameters:
458
459     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
460     :build-timeout: Timeout in minutes before aborting build. (default: 15)
461     :disable-job: Whether to disable the job (default: false)
462     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
463     :pypi-stage-index: Base URL of the PyPI staging repository.
464         (default https://test.pypi.org/simple)
465     :pypi-repo: Key for the PyPI release repository in the .pypirc file,
466         should be the repository pypy.org (default: pypi)
467     :use-release-file: Whether to use the release file. (default: true)
468
469
470 PackageCloud Release Verify
471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
472
473 This template supports PackageCloud release jobs.
474
475 :Template Name: {project-name}-packagecloud-verify
476
477 :Comment Trigger: recheck|reverify
478
479 :Required Parameters:
480
481     :build-node: The node to run build on.
482     :jenkins-ssh-credential: Credential to use for SSH. (Generally set
483         in defaults.yaml)
484     :project: Git repository name
485     :project-name: Jenkins job name prefix
486
487 :Optional Parameters:
488
489     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
490     :build-node: The node to run build on.
491     :build-timeout: Timeout in minutes before aborting build. (default: 15)
492     :gerrit-skip-vote: Skip voting for this job. (default: false)
493     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
494
495     :gerrit_verify_triggers: Override Gerrit Triggers.
496     :gerrit_trigger_file_paths: Override file paths filter which checks which
497         file modifications will trigger a build.
498         **default**::
499
500             - compare-type: REG_EXP
501               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
502
503
504 PackageCloud Release Merge
505 ~~~~~~~~~~~~~~~~~~~~~~~~~~
506
507 This template supports PackageCloud release jobs.
508
509 :template name: {project-name}-packagecloud-merge
510
511 :comment trigger: remerge
512
513 :required parameters:
514
515     :build-node: the node to run build on.
516     :jenkins-ssh-release-credential: credential to use for ssh. (generally set
517         in defaults.yaml)
518     :project: git repository name
519     :project-name: jenkins job name prefix
520
521 :optional parameters:
522
523     :build-days-to-keep: days to keep build logs in jenkins. (default: 7)
524     :build-timeout: timeout in minutes before aborting build. (default: 15)
525
526     :gerrit_merge_triggers: override gerrit triggers.
527     :gerrit_trigger_file_paths: override file paths filter which checks which
528         file modifications will trigger a build.
529         **default**::
530
531             - compare-type: reg_exp
532               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
533
534
535 Setup for LFID, Nexus, Jenkins and Gerrit
536 -----------------------------------------
537
538 This section is for the Linux Foundation release engineering team.
539
540 LFID
541 ~~~~
542
543 Create an ``lfid`` and an ``ssh-key``
544
545 ``YOUR_RELEASE_USERNAME`` for example: onap-release
546
547 ``YOUR_RELEASE_EMAIL`` for example: collab-it+onap-release@linuxfoundation.org
548
549 ssh-key example:
550
551 .. code-block:: bash
552
553    ssh-keygen -t rsa -C "collab-it+odl-release@linuxfoundation.org"  -f /tmp/odl-release
554
555
556 `Create an LFID with the above values <https://identity.linuxfoundation.org>`_
557
558
559 Nexus
560 ~~~~~
561
562 Create a Nexus account called ``'jenkins-release'`` with promote privileges.
563
564 .. image:: ../_static/nexus-promote-privs.png
565
566 Gerrit
567 ~~~~~~
568
569 Log into your Gerrit with ``YOUR_RELEASE_USERNAME``, upload the public
570 part of the ``ssh-key`` you created earlier. Log out of Gerrit and log
571 in again with your normal account for the next steps.
572
573
574 In Gerrit create a new group called ``self-serve-release`` and give it
575 direct push rights via ``All-Projects`` Add ``YOUR_RELEASE_USERNAME``
576 to group ``self-serve-release`` and group ``Non-Interactive Users``
577
578
579 In All project, grant group self-serve-release the following:
580
581 .. code-block:: none
582
583     [access "refs/heads/*"]
584       push = group self-serve-release
585     [access "refs/tags/*"]
586       createTag = group self-serve-release
587       createSignedTag = group self-serve-release
588       forgeCommitter = group self-serve-release
589       push = group self-serve-release
590
591
592 Jenkins
593 ~~~~~~~
594
595 Add a global credential to Jenkins called ``jenkins-release`` and set
596 the ID: ``'jenkins-release'`` as its value insert the private half of
597 the ``ssh-key`` that you created for your Gerrit user.
598
599 Add Global variables in Jenkins:
600 Jenkins configure -> Global properties -> Environment variables::
601
602     RELEASE_USERNAME = YOUR_RELEASE_USERNAME
603     RELEASE_EMAIL = YOUR_RELEASE_EMAIL
604
605
606 .. note::
607
608     Add these variables to your global-vars-$SILO.sh file or they will
609     be overwritten.
610
611 Jenkins configure -> Managed Files -> Add a New Config -> Custom File
612
613 .. code-block:: none
614
615     id: signing-pubkey
616     Name: SIGNING_PUBKEY (optional)
617     Comment: SIGNING_PUBKEY (optional)
618
619     Content: (Ask Andy for the public signing key)
620     -----BEGIN PGP PUBLIC KEY BLOCK-----
621
622
623 Add or edit the managed file in Jenkins called ``lftoolsini``,
624 appending a nexus section: Jenkins Settings -> Managed files -> Add
625 (or edit) -> Custom file
626
627 .. code-block:: none
628
629    [nexus.example.com]
630    username=jenkins-release
631    password=<plaintext password>
632
633 Ci-management
634 ~~~~~~~~~~~~~
635
636 Upgrade your project's global-jjb if needed, then add the following to
637 your global defaults file (e.g., jjb/defaults.yaml).
638
639 .. code-block:: none
640
641    jenkins-ssh-release-credential: jenkins-release