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