60ec72c1f23fe4bfb9d678dbab99c9e083a23639
[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" or "3.7.0".
211     :version: The semantic version string used for the package in the
212         setup.py file.
213
214 The JSON schema for a PyPI release file appears below.
215
216 .. code-block:: none
217
218     ---
219     $schema: "http://json-schema.org/schema#"
220     $id: "https://github.com/lfit/releng-global-jjb/blob/master/release-pypi-schema.yaml"
221
222     required:
223       - "distribution_type"
224       - "log_dir"
225       - "pypi_project"
226       - "python_version"
227       - "version"
228
229     properties:
230       distribution_type:
231         type: "string"
232       log_dir:
233         type: "string"
234       pypi_project:
235         type: "string"
236       python_version:
237         type: "string"
238       version:
239         type: "string"
240
241
242 Jenkins Jobs
243 ------------
244
245 An example of a Jenkins job configuration that uses the global-jjb
246 templates for maven and container release jobs appears next.
247
248 .. code-block:: none
249
250     - project:
251         name: my-project-release
252         project: my-project
253         project-name: my-project
254         build-node: centos7-docker-4c-4g
255         mvn-settings: my-project-settings
256         jobs:
257             - '{project-name}-gerrit-release-jobs'
258
259
260 .. note::
261
262    Release Engineers: please follow the setup guide below before adding the job definition.
263
264
265 JJB Macros
266 ----------
267
268 lf-release
269 ~~~~~~~~~~
270
271 Release verify and merge jobs are the same except for their scm,
272 trigger, and builders definition. This anchor is the common template.
273
274 JJB Templates
275 -------------
276
277 Release Merge
278 ~~~~~~~~~~~~~
279
280 This template supports Maven and Container release jobs.
281
282 :Template Name: {project-name}-release-merge
283
284 :Comment Trigger: remerge
285
286 :Required parameters:
287
288     :build-node: The node to run build on.
289     :jenkins-ssh-release-credential: Credential to use for SSH. (Generally set
290         in defaults.yaml)
291     :project: Git repository name
292     :project-name: Jenkins job name prefix
293
294 :Optional parameters:
295
296     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
297     :build-timeout: Timeout in minutes before aborting build. (default: 15)
298
299     :gerrit_merge_triggers: Override Gerrit Triggers.
300     :gerrit_trigger_file_paths: Override file paths filter which checks which
301         file modifications will trigger a build.
302         **default**::
303
304             - compare-type: REG_EXP
305               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
306
307
308 Release Verify
309 ~~~~~~~~~~~~~~
310
311 This template supports Maven and Container release jobs.
312
313 :Template Name: {project-name}-release-verify
314
315 :Comment Trigger: recheck|reverify
316
317 :Required Parameters:
318
319     :build-node: The node to run build on.
320     :jenkins-ssh-credential: Credential to use for SSH. (Generally set
321         in defaults.yaml)
322     :project: Git repository name
323     :project-name: Jenkins job name prefix
324
325 :Optional Parameters:
326
327     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
328     :build-node: The node to run build on.
329     :build-timeout: Timeout in minutes before aborting build. (default: 15)
330     :gerrit-skip-vote: Skip voting for this job. (default: false)
331     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
332
333     :gerrit_verify_triggers: Override Gerrit Triggers.
334     :gerrit_trigger_file_paths: Override file paths filter which checks which
335         file modifications will trigger a build.
336         **default**::
337
338             - compare-type: REG_EXP
339               pattern: '(releases\/.*\.yaml|\.releases\/.*\.yaml)'
340
341
342 PyPI Release Merge
343 ~~~~~~~~~~~~~~~~~~
344
345 Publishes a Python package on merge of a patch set with a release yaml
346 file. Checks the format of the version string, downloads the package
347 artifacts from the PyPI staging repository, uploads the package
348 artifacts to the PyPI release repository, tags the git repository,
349 signs the tag and pushes the tag to the git server. The release verify
350 template accepts neither a branch nor a stream parameter.
351
352 :Template Names:
353
354     - {project-name}-pypi-release-merge
355     - gerrit-pypi-release-merge
356     - github-pypi-release-merge
357
358 :Comment Trigger: remerge
359
360 :Required Parameters:
361
362     :build-node: The node to run build on, which must be Centos.
363     :jenkins-ssh-release-credential: Credential to use for SSH. (Generally set
364         in defaults.yaml)
365     :project: Git repository name
366     :project-name: Jenkins job name prefix
367
368 :Optional Parameters:
369
370     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
371     :build-timeout: Timeout in minutes before aborting build. (default: 15)
372     :disable-job: Whether to disable the job (default: false)
373     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
374     :pypi-stage-index: Base URL of the PyPI staging repository.
375         (default https://test.pypi.org/simple)
376     :pypi-repo: Key for the PyPI release repository in the .pypirc file,
377         should be the repository pypy.org. (default: pypi)
378     :use-release-file: Whether to use the release file. (default: true)
379
380
381 PyPI Release Verify
382 ~~~~~~~~~~~~~~~~~~~
383
384 Verifies a Python package project on creation of a patch set with a
385 release yaml file. Checks the contents of the release yaml file,
386 checks the format of the version string, and downloads the release
387 artifacts from the specified PyPI staging repository. The release
388 verify template accepts neither a branch nor a stream parameter.
389
390 :Template Names:
391
392     - {project-name}-pypi-release-verify
393     - gerrit-pypi-release-verify
394     - github-pypi-release-verify
395
396 :Comment Trigger: recheck
397
398 :Required Parameters:
399
400     :build-node: The node to run build on, which must be Centos.
401     :jenkins-ssh-credential: Credential to use for SSH. (Generally set
402         in defaults.yaml)
403     :project: Git repository name
404     :project-name: Jenkins job name prefix
405
406 :Optional Parameters:
407
408     :build-days-to-keep: Days to keep build logs in Jenkins. (default: 7)
409     :build-timeout: Timeout in minutes before aborting build. (default: 15)
410     :disable-job: Whether to disable the job (default: false)
411     :git-url: URL clone project from. (default: $GIT_URL/$PROJECT)
412     :pypi-stage-index: Base URL of the PyPI staging repository.
413         (default https://test.pypi.org/simple)
414     :pypi-repo: Key for the PyPI release repository in the .pypirc file,
415         should be the repository pypy.org (default: pypi)
416     :use-release-file: Whether to use the release file. (default: true)
417
418
419 Setup for LFID, Nexus, Jenkins and Gerrit
420 -----------------------------------------
421
422 This section is for the Linux Foundation release engineering team.
423
424 LFID
425 ~~~~
426
427 Create an ``lfid`` and an ``ssh-key``
428
429 ``YOUR_RELEASE_USERNAME`` for example: onap-release
430
431 ``YOUR_RELEASE_EMAIL`` for example: collab-it+onap-release@linuxfoundation.org
432
433 ssh-key example:
434
435 .. code-block:: bash
436
437    ssh-keygen -t rsa -C "collab-it+odl-release@linuxfoundation.org"  -f /tmp/odl-release
438
439
440 `Create an LFID with the above values <https://identity.linuxfoundation.org>`_
441
442
443 Nexus
444 ~~~~~
445
446 Create a Nexus account called ``'jenkins-release'`` with promote privileges.
447
448 .. image:: ../_static/nexus-promote-privs.png
449
450 Gerrit
451 ~~~~~~
452
453 Log into your Gerrit with ``YOUR_RELEASE_USERNAME``, upload the public
454 part of the ``ssh-key`` you created earlier. Log out of Gerrit and log
455 in again with your normal account for the next steps.
456
457
458 In Gerrit create a new group called ``self-serve-release`` and give it
459 direct push rights via ``All-Projects`` Add ``YOUR_RELEASE_USERNAME``
460 to group ``self-serve-release`` and group ``Non-Interactive Users``
461
462
463 In All project, grant group self-serve-release the following:
464
465 .. code-block:: none
466
467     [access "refs/heads/*"]
468       push = group self-serve-release
469     [access "refs/tags/*"]
470       createTag = group self-serve-release
471       createSignedTag = group self-serve-release
472       forgeCommitter = group self-serve-release
473       push = group self-serve-release
474
475
476 Jenkins
477 ~~~~~~~
478
479 Add a global credential to Jenkins called ``jenkins-release`` and set
480 the ID: ``'jenkins-release'`` as its value insert the private half of
481 the ``ssh-key`` that you created for your Gerrit user.
482
483 Add Global variables in Jenkins:
484 Jenkins configure -> Global properties -> Environment variables::
485
486     RELEASE_USERNAME = YOUR_RELEASE_USERNAME
487     RELEASE_EMAIL = YOUR_RELEASE_EMAIL
488
489
490 .. note::
491
492     Add these variables to your global-vars-$SILO.sh file or they will
493     be overwritten.
494
495 Jenkins configure -> Managed Files -> Add a New Config -> Custom File
496
497 .. code-block:: none
498
499     id: signing-pubkey
500     Name: SIGNING_PUBKEY (optional)
501     Comment: SIGNING_PUBKEY (optional)
502
503     Content: (Ask Andy for the public signing key)
504     -----BEGIN PGP PUBLIC KEY BLOCK-----
505
506
507 Add or edit the managed file in Jenkins called ``lftoolsini``,
508 appending a nexus section: Jenkins Settings -> Managed files -> Add
509 (or edit) -> Custom file
510
511 .. code-block:: none
512
513    [nexus.example.com]
514    username=jenkins-release
515    password=<plaintext password>
516
517 Ci-management
518 ~~~~~~~~~~~~~
519
520 Upgrade your project's global-jjb if needed, then add the following to
521 your global defaults file (e.g., jjb/defaults.yaml).
522
523 .. code-block:: none
524
525    jenkins-ssh-release-credential: jenkins-release