release_process.mdwn 56 KB
Newer Older
Tails developers's avatar
Tails developers committed
1
2
[[!meta title="Release process"]]

Tails developers's avatar
Tails developers committed
3
[[!toc levels=2]]
Tails developers's avatar
Tails developers committed
4

Tails developers's avatar
Tails developers committed
5
6
See the [[release_schedule]].

7
8
9
10
<div class="caution">
Read the remainder of this document from the branch used to prepare the release!
</div>

11
12
13
14
15
Requirements
============

To release Tails you'll need some packages installed:

16
* `tidy mktorrent transmission-cli`
intrigeri's avatar
intrigeri committed
17
* aufs DKMS module for your running kernel.
intrigeri's avatar
intrigeri committed
18
* [[!debpts squashfs-tools]] that honors `$SOURCE_DATE_EPOCH`.
19
  Install it from our custom `devel` APT suite.
intrigeri's avatar
intrigeri committed
20
* `tails-iuk` dependencies, including suggested packages (see
21
22
23
  `debian/control` in the `debian` branch of its repo)
* `tails-perl5lib` dependencies (same trick as `tails-iuk` to get the
  list)
24
25
* `po4a` _from Stretch_: the version in testing/sid extracts Markdown headings
   in a different way, which makes tons of strings fuzzy.
26

27
28
29
30
31
32
Environment
===========

Export the following environment variables to be able to copy'n'paste
the scripts snippets found on this page:

33
* version numbers (see [[contribute/release_schedule#versioning]]):
34

35
36
37
38
        export VERSION=$(dpkg-parsechangelog -SVersion)
        export TAG=$(echo "${VERSION:?}" | sed -e 's,~,-,')
        export PREVIOUS_VERSION=$(dpkg-parsechangelog --offset 1 --count 1 -SVersion)
        export PREVIOUS_TAG=$(echo "${PREVIOUS_VERSION:?}" | sed -e 's,~,-,')
39

40
* `NEXT_PLANNED_VERSION`: set to the version number of the next Tails release
41
  (e.g. 0.23 when releasing 0.22.1, and 1.3 when releasing 1.2)
42
* `NEXT_PLANNED_MAJOR_VERSION`: set to the version number of the next
43
44
45
46
47
48
49
50
  *major* Tails release; if you're preparing a RC for a major release,
  use that major release; otherwise, use whatever the next planned
  major release is
* `SECOND_NEXT_PLANNED_MAJOR_VERSION`: set to the version number of
  the second next *major* Tails release; e.g. if preparing the RC for
  the 3.9 major release, then set this to 3.12 (3.9 is the next major
  release, 3.10 and 3.11 are bugfix releases, 3.12 is a major
  release).
51
52
53
* `NEXT_PLANNED_MINOR_VERSION`: set to the version number of the next
  *minor* Tails release; if the next release is a point-release, use
  that one; otherwise, use `${VERSION}.1`
54
55
* `MAJOR_RELEASE`: set to 1 if preparing a major release or a release
  candidate for a major release, to 0 otherwise
56
* `ISOS`: the directory where one stores `tails-amd64-*`
57
  sub-directories like the ones downloaded with BitTorrent.
58
59
* `ARTIFACTS`: the directory where build artifacts (e.g.
  the `.packages` file) land.
60
61
* `MASTER_CHECKOUT`: a checkout of the `master` branch of the main
  Tails Git repository.
intrigeri's avatar
intrigeri committed
62
* `RELEASE_BRANCH=$(if [ "$MAJOR_RELEASE" = 1 ]; then echo -n testing; else echo -n stable; fi)`
63
64
* `RELEASE_CHECKOUT`: a checkout of the branch of the main Tails Git
  repository used to prepare the release (`stable` or `testing`).
65
* `TAILS_SIGNATURE_KEY=A490D0F4D311A4153E2BB7CADBB802B258ACD84F`
66
67
* `IUK_CHECKOUT`: a checkout of the relevant tag of the `iuk`
  Git repository.
68
69
* `PERL5LIB_CHECKOUT`: a checkout of the relevant tag of the
  `perl5lib` Git repository.
70
* `DIST`: either 'alpha' (for RC:s) or 'stable' (for actual releases)
intrigeri's avatar
intrigeri committed
71
72
* `export DEBEMAIL='tails@boum.org'`
* `export DEBFULLNAME='Tails developers'`
73
* `export WEBSITE_RELEASE_BRANCH="web/release-${TAG:?}"`
74

75
76
77
Pre-freeze
==========

78
79
The [[contribute/working_together/roles/release_manager]] role
documentation has more tasks that should be done early enough.
80
81
82
83
84
85

Coordinate with Debian security updates
---------------------------------------

See [[release_process/Debian_security_updates]].

86
87
88
89
90
91
Sanity check
============

Visit the [Jenkins RM view](https://jenkins.tails.boum.org/view/RM/)
and check that the jobs for the release branch have good enough results.

92
93
94
95
96
97
98
99
100
101
Freeze
======

Major release
-------------

If we are at freeze time for a major release:

1. Merge the `master` Git branch into `devel`:

102
        git checkout devel && git fetch origin && git merge --no-ff origin/master
103

intrigeri's avatar
intrigeri committed
104
105
2. [[Merge each APT overlay suite|APT_repository/custom#workflow-merge-overlays]]
   listed in the `devel` branch's `config/APT_overlays.d/` into the `devel`
106
107
108
109
110
111
112
113
114
   APT suite.

3. Merge the `devel` Git branch into the `testing` one:

        git checkout testing && git merge devel

   ... and check that the resulting `config/APT_overlays.d/` in the
   `testing` branch is empty.

115
116
4. [[Hard reset|APT_repository/custom#workflow-reset]] the `testing`
   custom APT suite to the current state of the `devel` one.
117

anonym's avatar
anonym committed
118
5. [[Freeze|APT_repository/time-based_snapshots#freeze]] the
119
120
121
122
   time-based APT repository snapshots that shall be used
   during the freeze.

6. Make it so the time-based APT repository snapshots are kept around
123
124
125
   long enough, by bumping their `Valid-Until` to 10 days after the
   next major release (the one _after_ the one you're preparing)'s
   scheduled date:
126
127
   [[APT_repository/time-based_snapshots#bump-expiration-date-for-all-snapshots]]

128
129
130
131
132
133
134
135

Point-release
-------------

If we are at freeze time for a point-release:

1. Merge the `master` Git branch into `stable`:

136
        git checkout stable && git fetch && git merge --no-ff origin/master
137

intrigeri's avatar
intrigeri committed
138
139
2. [[Merge each APT overlay suite|APT_repository/custom#workflow-merge-overlays]]
   listed in the `stable` branch's `config/APT_overlays.d/` into the `stable`
140
141
142
143
144
   APT suite.

Common steps for point and major releases
-----------------------------------------

145
Reset the release branch's `config/base_branch`:
146

147
        echo "${RELEASE_BRANCH:?}" > config/base_branch && \
148
           git commit config/base_branch \
149
               -m "Restore ${RELEASE_BRANCH:?}'s base branch."
150

151
152
153
154
155
156
157
158
Bootstrap manual testing coordination:

1. Create a pad.
2. Copy the [[manual test suite|contribute/release_process/test]]
   into it.
3. Send the pad URL to the usual testers (see `manual_testers.mdwn` in
   the `internal.git` repository).

Tails developers's avatar
Tails developers committed
159
160
161
Update included files
=====================

spriver's avatar
spriver committed
162
uBlock patterns and settings file
Tails developers's avatar
Tails developers committed
163
164
----------------

165
The patterns+settings file is stored as a SQLite text dump in
spriver's avatar
spriver committed
166
`config/chroot_local-includes/usr/share/tails/ublock-origin/ublock0.dump`.
Tails developers's avatar
Tails developers committed
167

168
169
170
171
172
173
174
1. Start Tails
2. Start *Tor Browser*
2. Click on the uBlock icon and then click on the gears icon to open
   the uBlock dashboard
3. Open the *3rd-party filters* tab
4. Click on the button *Update now* to update all filters
5. Close *Tor Browser*
175
176
177
178
7. Copy the `.tor-browser/profile.default/extension-data/ublock0.sqlite`
   from this Tor Browser instance into the root of Tails' Git repo and
   run the following command:

179
180
181
        ./bin/convert-ublock-settings ublock0.sqlite > \
            config/chroot_local-includes/usr/share/tails/ublock-origin/ublock0.dump \
        && git commit -m 'Update uBlock Origin patterns + settings file.' \
182
183
           config/chroot_local-includes/usr/share/tails/ublock-origin/ublock0.dump \
        && rm ublock0.sqlite
184

185
186
<a id="upgrade-custom-debs"></a>

Bessemer's avatar
Bessemer committed
187
Upgrade bundled binary Debian packages
Tails developers's avatar
Tails developers committed
188
189
--------------------------------------

190
191
192
193
194
195
196
197
198
199
200
201
Skip this section if you are preparing a point-release.

The goal here is to make sure the bundled binary Debian packages contain
up-to-date localization files, so:

 - If you are preparing a release candidate, build at least the packages
   that change user-visible strings, so that translators can use the RC
   to check the status of their work and identify what's left to do.
 - If you are preparing a major release, build at least the packages
   that got translation updates since the RC: we've sent a call for
   translation while releasing the RC so the least we can do is to
   incorporate the work that ensued into our final release :)
202

203
204
For each bundled Debian package, `cd` into the package's root
directory (e.g. a checkout of the `whisperback` repository),
intrigeri's avatar
intrigeri committed
205
import translations from Transifex and sanity-check them:
206
207

	cd whisperback
intrigeri's avatar
intrigeri committed
208
	"${RELEASE_CHECKOUT:?}"/import-translations && \
209
	"${RELEASE_CHECKOUT:?}"/submodules/jenkins-tools/slaves/check_po
210

intrigeri's avatar
intrigeri committed
211
Then, `git rm` the PO files that have issues (alternatively, if you
212
213
214
215
216
feel like it you can fix them but your changes will be overwritten
next time we import translations from Transifex).

And finally, commit:

217
    git add po && git commit \
218
	    -m "Update POT and PO files, pull updated translations from Transifex."
219

220
Then see the relevant release processes, and upload the packages to
221
the release branch's custom APT suite:
Tails developers's avatar
Tails developers committed
222

223
* [[tails-installer]]
224
* [[tails-greeter]]
225
* [[perl5lib]]
226
* [[persistence-setup]]
227
* [[tails-iuk]]
228
* whisperback:
229
230
  * follow [upstream release process](https://git-tails.immerda.ch/whisperback/plain/HACKING)
  * build a Debian package
Tails developers's avatar
Tails developers committed
231

intrigeri's avatar
intrigeri committed
232
233
Upgrade Tor Browser
-------------------
234
235
236

See the dedicated page: [[tor-browser]]

237
238
239
240
241
Upgrade Tor Browser AppArmor profile
------------------------------------

See the dedicated page: [[browser-apparmor-patch]]

242
Upgrade Thunderbird
243
244
---------------

245
See the dedicated page: [[thunderbird]]
246

247
248
Update PO files
---------------
249

250
251
252
Pull updated translations for languages translated in Transifex,
refresh the code PO files,
and commit the result, including new PO files:
253

254
	cd "${RELEASE_CHECKOUT:?}" && \
255
256
	./import-translations  && \
	./refresh-translations && \
257
	./submodules/jenkins-tools/slaves/check_po && \
258
	git add po && git commit -m 'Update PO files.'
259

260
261
262
263
264
265
If `check_po` complains:

* delete the offending PO files;
* send a note to <tails-l10n@boum.org> so that they get in touch with
  whoever can fix them.

266
267
When preparing an actual release
================================
268

269
270
271
272
273
274
If we're about to prepare an image for a final (non-RC) release, then
follow these instructions:

Major release
-------------

intrigeri's avatar
intrigeri committed
275
276
[[Merge each APT overlay suite|APT_repository/custom#workflow-merge-overlays]]
listed in the `testing` branch's `config/APT_overlays.d/` into the `testing`
277
custom APT suite.
278
279
280
281

Point-release
-------------

282
283
284
285
286
287
<div class="note">
For point-releases, we generally do not put any RC out, so freeze time
is the same as preparing the actual release. Hence, the following
steps have already been done above, and this section is a noop in the
general case.
</div>
288

intrigeri's avatar
intrigeri committed
289
290
[[Merge each APT overlay suite|APT_repository/custom#workflow-merge-overlays]]
listed in the `stable` branch's `config/APT_overlays.d/` into the `stable`
291
custom APT suite.
292

anonym's avatar
anonym committed
293
294
Update other base branches
==========================
295
296

1. Merge the release branch into `devel` following the instructions for
intrigeri's avatar
intrigeri committed
297
   [[merging base branches|APT_repository/custom#workflow-merge-main-branch]].
298

intrigeri's avatar
intrigeri committed
299
300
301
302
303
2. [[Thaw|APT_repository/time-based snapshots#thaw]], on the devel
   branch, the time-based APT repository snapshots that were used
   during the freeze.

3. Merge `devel` into `feature/buster`, *without* following the instructions for
intrigeri's avatar
intrigeri committed
304
   [[merging base branches|APT_repository/custom#workflow-merge-main-branch]].
305
306
   (For now `feature/buster` is handled as any other topic branch
   forked off `devel`: its base branch is set to `devel`.)
307
308
309
   If the merge conflicts don't look like something you feel confident
   resolving properly, abort this merge and let the Foundations
   Team know.
310

intrigeri's avatar
intrigeri committed
311
4. Ensure that the release, `devel` and `feature/buster` branches
312
313
   have the expected content in `config/APT_overlays.d/`: e.g. it must
   not list any overlay APT suite that has been merged already.
314

315
5. Push the modified branches to Git:
316

317
        git push origin                          \
318
           "${RELEASE_BRANCH:?}:${RELEASE_BRANCH:?}" \
319
           feature/buster:feature/buster       \
320
           devel:devel
321
322
323

Update more included files
==========================
324

325
326
Changelog
---------
Tails developers's avatar
Tails developers committed
327

328
329
330
Remove the placeholder entry for next release in `debian/changelog`,
and then:

331
	git checkout "${RELEASE_BRANCH:?}" && \
332
	./release ${VERSION:?} ${PREVIOUS_TAG:?}
Tails developers's avatar
Tails developers committed
333
334
335

This populates the Changelog with the Git log entries.

336
337
338
Then, launch an editor for the needed cleanup of the result:

	dch -e
Tails developers's avatar
Tails developers committed
339

340
341
342
343
Then, gather other useful information from:

* every custom bundled package's own Changelog (Greeter, Persistent
  Volume Assistant, etc.);
344
* the diff between the previous version's `.packages` file and the one
345
346
347
348
349
  from the to-be-released ISO; look for:
  - security fixes
  - new upstream releases of applications mentioned in [[doc/about/features]]
  - new upstream releases of other important components such as the
    Linux kernel
350
* the "Fix committed" section on the *Release Manager View for ${VERSION:?}*
351
  in Redmine.
352

353
Finally, sanity check the version and commit:
Tails developers's avatar
Tails developers committed
354

355
356
	if [ "$(dpkg-parsechangelog -SVersion)" = "${VERSION:?}" ]; then
	    git commit debian/changelog -m "Update changelog for ${VERSION:?}."
357
	else
358
	    echo 'Error: version mismatch: please compare ${VERSION:?} with the last entry in debian/changelog'
359
	fi
Tails developers's avatar
Tails developers committed
360

Bessemer's avatar
Bessemer committed
361
Included website
362
363
----------------

Tails developers's avatar
Tails developers committed
364
365
366
367
368
369
### Merge master

Merge `master` into the branch used for the release:

	git fetch origin && git merge origin/master

370
371
### version number

372
373
If preparing a RC, skip this part.

374
In the branch used to build the release, update the `wiki/src/inc/*` files to
375
match the *version number* and *date* of the new release. Set the date
Tails developers's avatar
Tails developers committed
376
at least 24 hours in the future! Between tests and mirror synchronization,
377
the build will not be released on the same day. Try to make sure it
378
matches the date of the future signature.
379

sajolida's avatar
sajolida committed
380
	RELEASE_DATE='2015-11-03'
Tails developers's avatar
Tails developers committed
381

382
383
384
	echo "${VERSION:?}"      > wiki/src/inc/stable_amd64_version.html
	echo -n "${RELEASE_DATE:?}" > wiki/src/inc/stable_amd64_date.html
	sed -ri "s%news/version_.*]]%news/version_${VERSION:?}]]%" wiki/src/inc/stable_amd64_release_notes.*
385
	${EDITOR:?} wiki/src/inc/*.html
elouann's avatar
elouann committed
386
	./build-website
387
	git commit wiki/src/inc/ -m "Update version and date for ${VERSION:?}."
Tails developers's avatar
Tails developers committed
388

389
390
Website translations
--------------------
391

392
393
394
395
Refresh the website PO files and commit the ones corresponding to
pages that were added or changed accordingly to changes coming with
the new release. This e.g. ensures that the RC call for translation
points translators to up-to-date PO files:
396

elouann's avatar
elouann committed
397
	./build-website && git add wiki/src && git commit -m 'Update website PO files.'
398
	git push origin "${RELEASE_BRANCH:?}:${RELEASE_BRANCH:?}"
399

400
401
402
Call for translation
====================

403
404
405
406
407
408
If at freeze time, send a call for translations to tails-l10n, making it clear what
Git branch the translations must be based on, and what are the
priorities. Also, add a few words to remember the translation teams
using Git that they should regularly contact Transifex translators,
as detailed on the [[documentation for
translators|contribute/how/translate]].
409

410
To get a list of changes on the website:
411

intrigeri's avatar
intrigeri committed
412
    git diff --stat ${PREVIOUS_TAG:?}.. -- \
413
        wiki/src/'*'.{mdwn,html} \
anonym's avatar
anonym committed
414
415
416
417
418
        ':!wiki/src/blueprint*' \
        ':!wiki/src/contribute*' \
        ':!wiki/src/inc' \
        ':!wiki/src/news*' \
        ':!wiki/src/security*'
419

420
Enable OpenPGP signing
Tails developers's avatar
Tails developers committed
421
422
======================

423
424
425
426
427
428
429
430
431
432
433
434
### If you have an OpenPGP smart card

If you have an OpenPGP smart card (i.e. if you are one of the usual
release managers) go fetch it. Remember to only plug it when needed! A
pro tip is to never plug it unless prompted which `gpg` will do for
you. Then just unplug it as soon as the `.sig` is done.

### Otherwise: importing the signing key

This is only relevant when the master key has been reassembled,
e.g. for signing a Tails emergency release where none of the usual
release managers are available.
435

Tails developers's avatar
Tails developers committed
436
You should never import the Tails signing key into your own keyring,
437
438
and a good practice is to import it to a tmpfs to limit the risks that
the private key material is written to disk:
Tails developers's avatar
Tails developers committed
439
440

    export GNUPGHOME=$(mktemp -d)
441
442
443
444
    sudo mount -t ramfs ramfs "${GNUPGHOME:?}"
    sudo chown $(id -u):$(id -g) "${GNUPGHOME:?}"
    sudo chmod 0700 "${GNUPGHOME:?}"
    gpg --homedir ${HOME:?}/.gnupg --export ${TAILS_SIGNATURE_KEY:?} | gpg --import
Tails developers's avatar
Tails developers committed
445
446
447
448
449
    gpg --import path/to/private-key

Let's also ensure that strong digest algorithms are used for our
signatures, like the defaults we set in Tails:

450
    cp config/chroot_local-includes/etc/skel/.gnupg/gpg.conf "${GNUPGHOME:?}"
Tails developers's avatar
Tails developers committed
451

452
453
454
455
456
457
458
459
460
461
Build the almost-final image
============================

1. [[Build an ISO image|contribute/build]] from the release branch.
2. Carefully read the build logs to make sure nothing bad happened.
3. Keep at least the resulting ISO image and the manifest of needed
   packages until the end of this release process.
4. Record where the manifest of needed packages is stored:

        export PACKAGES_MANIFEST=XXX ; \
462
        [ -f "${PACKAGES_MANIFEST:?}" ] || echo "ERROR: PACKAGES_MANIFEST is incorrect"
463
464


465
466
467
Tag the release in Git
======================

468
469
	git tag -u "${TAILS_SIGNATURE_KEY:?}" \
	  -m "tagging version ${VERSION:?}" "${TAG:?}" && \
470
	git push origin "${TAG:?}" "${RELEASE_BRANCH:?}"
471
472
473
474
475
476
477

(Pushing the tag is needed so that the APT repository is updated, and
the Tails APT configuration works at build and boot time. It might be
premature, as testing might reveal critical issues, but this is
a signed tag, so it can be overridden later. Yes, there is room for
improvement here.)

478
479
480
481
XXX: From this push of a tag, the builds in Jenkins fail because we prevent it
to continue if the last debian/changelog entry has a tag. There are workarounds
we need to decide and implement.

482
483
484
Prepare the versioned APT suites
================================

intrigeri's avatar
intrigeri committed
485
* [[Prepare the versioned APT suite in our custom APT repository|APT_repository/custom#workflow-post-tag]].
486

487
* Prepare tagged snapshots of upstream APT repositories:
488

489
          ./bin/tag-apt-snapshots "${PACKAGES_MANIFEST:?}" "${TAG:?}"
490

491
  Note:
492

493
494
  - This command can take a while (about a dozen minutes).
  - It's expected that the packages that were pulled from our
intrigeri's avatar
intrigeri committed
495
    [[custom APT repository|APT_repository/custom]] are
496
    listed under "some packages were not found anywhere" (because we
intrigeri's avatar
intrigeri committed
497
    are currently not using time-based snapshots for our custom APT
intrigeri's avatar
intrigeri committed
498
    repository). However, _no other package should be on that list_.
intrigeri's avatar
intrigeri committed
499
    Now, we have a "safety" net, in case you don't notice such a problem: if
500
501
    other packages are missing, the next build (that will use the
    newly created partial, tagged APT repository) will fail.
502

Tails developers's avatar
Tails developers committed
503
504
505
Build images
============

506
507
508
Sanity check
------------

509
510
511
Verify that the Tor Browser release used in Tails still is the most
recent. Also look if there's a new `-buildX` tag for the targeted
Tor Browser version in these Git repositories:
512
513
514
515

* <https://gitweb.torproject.org/builders/tor-browser-bundle.git>
* <https://gitweb.torproject.org/tor-browser.git>

516
A new tag may indicate that a new Tor Browser release is imminent.
517
518
519

Better catch this before people spend time doing manual tests.

Bessemer's avatar
Bessemer committed
520
521
SquashFS file order
-------------------
Tails developers's avatar
Tails developers committed
522

523
1. Burn the almost final ISO image to a DVD.
524
525
1. Boot this DVD **on bare metal**.
1. Add `profile` to the kernel command-line.
526
527
1. Login.
1. Wait for the "Tor is ready" notification.
intrigeri's avatar
intrigeri committed
528
1. Start *Tor Browser*.
Tails developers's avatar
Tails developers committed
529
1. A few minutes later, once the `boot-profile` process has been
530
   killed, retrieve the new sort file from `/var/log/boot-profile`.
intrigeri's avatar
intrigeri committed
531
1. Backup the old sort file: `cp config/binary_rootfs/squashfs.sort{,.old}`
532
1. Copy the new sort file to `config/binary_rootfs/squashfs.sort`.
533
534
535
536
537
1. Cleanup a bit:
   - remove `var/log/live/config.pipe`: otherwise the boot is broken
     or super-slow
   - remove the bits about `kill-boot-profile` at the end: they're
     only useful when profiling the boot
intrigeri's avatar
intrigeri committed
538
1. Inspect the Git diff (including diff stat), apply common sense:
539

540
        diff -NaurB \
intrigeri's avatar
intrigeri committed
541
542
            <( cut -d' ' -f1 config/binary_rootfs/squashfs.sort.old | sort ) \
            <( cut -d' ' -f1 config/binary_rootfs/squashfs.sort     | sort ) \
543
            | less
544

545
546
1. `git commit -m 'Updating SquashFS sort file' config/binary_rootfs/squashfs.sort`

547
548
549
Build the final image
---------------------

Bessemer's avatar
Bessemer committed
550
Then all included files should be up-to-date and the versioned APT
551
552
suite should be ready, so it is time to:

553
1. Mark the version as "released" in the changelog:
554

555
        dch --release --no-force-save-on-release --maintmaint && \
556
        git commit -m "Mark Tails ${VERSION:?} as released." debian/changelog
557

558
1. Export `SOURCE_DATE_EPOCH`:
559

560
        export SOURCE_DATE_EPOCH=$(date --utc --date="$(dpkg-parsechangelog --show-field=Date)" '+%s')
561

562
1. tag the release *again*, with all included files in:
563

564
565
        git tag -f -u "${TAILS_SIGNATURE_KEY:?}" \
                -m "tagging version ${VERSION:?}" "${TAG:?}" && \
566
567
        git push --force origin "${TAG:?}" && \
        git push origin "${RELEASE_BRANCH:?}"
anonym's avatar
anonym committed
568

569
570
   Note: for Jenkins to build the release you must push the release
   branch with its tip tagged. I.e. if you deviate from the above
intrigeri's avatar
intrigeri committed
571
   commands by e.g. committing a commit in between `git tag` and the
572
573
   first `git push` then Jenkins won't build from the tag -- please
   avoid that!
anonym's avatar
anonym committed
574

575
1. build the final image!
576

intrigeri's avatar
intrigeri committed
577
578
579
580
581
582
583
584
585
586
1. Compare the new build manifest with the one from the previous,
   almost final build:

        diff -Naur \
           "${PACKAGES_MANIFEST:?}" \
           "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.iso.build-manifest"

   They should be identical, except that the `debian-security` serial might be higher.

1. To ensure we publish the final build's `.build-manifest`, run:
587

588
589
        export PACKAGES_MANIFEST="${ARTIFACTS:?}/tails-amd64-${VERSION:?}.iso.build-manifest"

590

591
592
1. <a id="reproducibility-sanity-check-iso"></a>
   Let's sanity check that Jenkins reproduced your image.
593

anonym's avatar
xxx    
anonym committed
594
595
596
597
598
   Visit the URL printed by this command:

       echo "https://jenkins.tails.boum.org/job/build_Tails_ISO_${RELEASE_BRANCH}/"

   Find the job (probably the last one)
599
   and make sure the image built by Jenkins:
600

601
602
603
   - was built from the correct Git commit
   - has the same file size as the image you built
   - has the same hash (in the `.shasum` file) as the image you built
604

605
   Then:
606

607
   - If all hashes match: yay, we're good to go!
608

609
610
611
612
613
614
615
   - If there is a hash mismatch for the image: ouch! Now we are in a
     tricky situation: on the one hand it seems like a poor idea to
     block users from benefiting from this release's security updates,
     but on the other hand the failure might imply that something
     nefarious is going on. At this stage, no matter what, immediately
     fetch Jenkins' image, compare it with your, and try to rule out
     build system compromise:
616

anonym's avatar
anonym committed
617
618
619
620
621
622
623
624
          sudo diffoscope \
              --text diffoscope.txt \
              --html diffoscope.html \
              --max-report-size 262144000 \
              --max-diff-block-lines 10000 \
              --max-diff-input-lines 10000000 \
                  path/to/your/tails-amd64-${VERSION:?}.iso \
                  path/to/jenkins/tails-amd64-${VERSION:?}.iso
625

626
     Then carefully investigate the `diffoscope` report:
627

628
629
630
631
632
       - If you cannot rule out that the difference is harmful: let's take
         a step back; we might be compromised, so we are in no position to
         release. Halt the release, involve the rest of `tails@`, and then
         try to re-establish trust in all build machines and infra
         involved, etc. Have fun!
633

634
       - Otherwise, if the change is definitely harmless:
635

636
637
638
639
640
         * If the source of non-determinism is identified quickly and
           is easy and fast to fix, *and* the QA of the current image
           has not gone very far (so at least that time is not wasted),
           then you should consider abandoning the current version, and
           immediately start preparing an emergency release with:
641

642
643
644
645
646
           - the reproducibility fix,
           - a new changelog entry,
           - adjustments to the release notes so they are re-purposed for
             this emergency release (the abandoned release gets none, since
             it effectively never will be released publicly).
647

648
649
650
651
652
653
         * Otherwise, if the fix looks time-consuming or difficult,
           let's release anyway. But let's add a known issue about
           "This Tails release does not build reproducibility" to the
           release notes, linking to the ticket where
           the nature of the reproducibility failure is clearly
           described.
654

655
1. check out a new branch:
intrigeri's avatar
intrigeri committed
656

657
658
659
660
661
662
663
664
   If preparing anything but a final release (e.g. an alpha, beta
   or RC):

        git checkout -b "${WEBSITE_RELEASE_BRANCH:?}" origin/master && \
        git push -u origin "${WEBSITE_RELEASE_BRANCH:?}"

   Else, if preparing a final release:

665
666
        git checkout -b "${WEBSITE_RELEASE_BRANCH:?}" "${TAG:?}" && \
        git push -u origin "${WEBSITE_RELEASE_BRANCH:?}"
anonym's avatar
anonym committed
667

anonym's avatar
anonym committed
668
669
670
671
   (as soon as a new commit is created on `$RELEASE_BRANCH`, its ISO
   build will start failing until a new changelog entry is created,
   which we don't want to do on `$RELEASE_BRANCH` before it's merged
   into `master` at release time)
anonym's avatar
anonym committed
672

673
674
675
Generate the OpenPGP signatures and Torrents
============================================

intrigeri's avatar
intrigeri committed
676
677
678
679
680
681
Create a directory with a suitable name, go there, move the built
image to this brand new directory, generate detached OpenPGP
signatures for the image to be published (in the same directory as the
image and with a `.sig` extension), then go up to the parent
directory, create a `.torrent` file and check the generated `.torrent`
files metadata:
682

683
	mkdir "${ISOS:?}/tails-amd64-${VERSION:?}" && \
intrigeri's avatar
intrigeri committed
684
	cd "${ISOS:?}/tails-amd64-${VERSION:?}" && \
685
	mv "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.iso" \
intrigeri's avatar
intrigeri committed
686
687
688
	   "${ISOS:?}/tails-amd64-${VERSION:?}/" && \
	gpg --armor --default-key "${TAILS_SIGNATURE_KEY:?}" --detach-sign *.iso && \
	rename 's,\.asc$,.sig,' *.asc && \
689
	cd .. && \
intrigeri's avatar
intrigeri committed
690
	mktorrent \
intrigeri's avatar
intrigeri committed
691
	  -a 'udp://tracker.torrent.eu.org:451' \
intrigeri's avatar
intrigeri committed
692
	  -a 'udp://tracker.coppersurfer.tk:6969'   \
693
694
	  "tails-amd64-${VERSION:?}" && \
	transmission-show tails-amd64-${VERSION:?}.torrent
695

anonym's avatar
anonym committed
696
697
Lastly, let's set some variables to be used later:

698
    ISO_PATH="${ISOS:?}/tails-amd64-${VERSION:?}/tails-amd64-${VERSION:?}.iso"
699
700
    ISO_SHA256SUM="$(sha256sum "${ISO_PATH:?}" | cut -f 1 -d ' ' | tr -d '\n')"
    ISO_SIZE_IN_BYTES="$(stat -c %s "${ISO_PATH:?}")"
anonym's avatar
anonym committed
701

702
703
<a id="prepare-iuk"></a>

704
705
706
Prepare incremental upgrades
============================

707
708
Build the Incremental Upgrade Kits
----------------------------------
709

710
711
712
713
Incremental upgrades may be skipped if the delta is too big (like when
migrating to a new Debian release) or if there are changes outside of
the scope for IUKs (like partition table changes). Use common sense!

714
715
Use `tails-create-iuk` to build the following IUKs:

716
717
718
719
* From the two previous *planned* releases, and any emergency releases
  in between and after. This should be, more or less, all releases for
  the last 12 weeks (although irregularities in Firefox release
  schedule may add or remove a few weeks).
720
721
722
723
724

* From the last RC for the version being released, e.g. 1.0~rc1 to
  1.0. This should be done even if there was no IUK generated from the
  previous stable release since it is a good way to test the iuk code
  that'll be used for the incremental upgrade paths to the
725
  next version.
726

727
728
729
Include each such version in a white-space separated list called
`IUK_SOURCE_VERSIONS`, (e.g. `IUK_SOURCE_VERSIONS="2.8 2.9 2.9.1 2.10~rc1"`)
and run the following:
730

731
    for source_version in ${IUK_SOURCE_VERSIONS}; do
732
733
734
735
        if [ "$(dpkg-query --showformat '${Version}\n' --show squashfs-tools)" != 1:4.3-3.0tails4 ]; then
            echo 'ERROR! Your squashfs-tools probably does not honor SOURCE_DATE_EPOCH so any generated IUKs will *not* be reproducible!'
            break
        fi
736
        sudo su -c "cd ${IUK_CHECKOUT:?} && \
737
738
          SOURCE_DATE_EPOCH=$SOURCE_DATE_EPOCH \
          LC_ALL=C \
739
740
741
          PERL5LIB=\"${PERL5LIB_CHECKOUT:?}/lib\" \
            ./bin/tails-create-iuk \
               --squashfs-diff-name \"${VERSION:?}.squashfs\"           \
742
743
744
               --old-iso \"${ISOS:?}/tails-amd64-${source_version:?}/tails-amd64-${source_version:?}.iso\" \
               --new-iso \"${ISOS:?}/tails-amd64-${VERSION:?}/tails-amd64-${VERSION:?}.iso\"          \
               --outfile \"${ISOS:?}/Tails_amd64_${source_version:?}_to_${VERSION:?}.iuk\""
745
    done
746
747

Note that developer tools for creating IUK and upgrade-description
Tails developers's avatar
Tails developers committed
748
files were only tested on Debian sid. It should hopefully work well on
749
Debian stable too.
750

751
752
753
754
<a id="reproducibility-sanity-check-iuk"></a>

Note that we do not yet build IUKs on Jenkins, otherwise here would be
a great point to compare its IUKs with yours.
755

Tails developers's avatar
Tails developers committed
756
<a id="prepare-upgrade-description-files"></a>
757

Tails developers's avatar
Tails developers committed
758
759
Prepare upgrade-description files
---------------------------------
760

Tails developers's avatar
Tails developers committed
761
1. Prepare upgrade-description files (see the [[upgrade-description
762
   files
Tails developers's avatar
Tails developers committed
763
   specification|contribute/design/incremental_upgrades#upgrade-description-files]]
764
765
766
767
768
769
   for details). The idea is to:

   * update (create if needed) an upgrade-description file for every
     *previous* supported release (e.g. N~rc1, N-1, N-1~rc2) that replaces
     all existing upgrade paths with the path to the version being
     released;
770
771
772
   * create a new upgrade-description for the version being released
     and for the next one, that expresses that *no* upgrade is
     available for these ones yet.
773

intrigeri's avatar
intrigeri committed
774
   This is what `tails-iuk-generate-upgrade-description-files` tool
775
776
   does:

777
778
779
780
        ( cd ${IUK_CHECKOUT:?} && \
        ./bin/tails-iuk-generate-upgrade-description-files \
            --build-target amd64 \
            --version "${VERSION:?}" \
781
782
783
            --next-version "${NEXT_PLANNED_MAJOR_VERSION:?}" \
            --next-version "${NEXT_PLANNED_MAJOR_VERSION:?}~rc1" \
            --next-version "${NEXT_PLANNED_MINOR_VERSION:?}" \
784
            --next-version "${VERSION:?}.1" \
anonym's avatar
anonym committed
785
            --iso "${ISO_PATH:?}" \
786
787
788
789
790
            --previous-version "${PREVIOUS_VERSION:?}" \
            --previous-version "${VERSION:?}~rc1" \
            --iuks "${ISOS:?}" \
            --release-checkout "${RELEASE_CHECKOUT:?}" \
            --major-release "${MAJOR_RELEASE:?}" \
791
       )
792
793
794
795
796
797
798

   Note:
   * The `--iuks` argument must point to the directory where the IUKs
     generated at the previous step are stored.
   * At least the last stable release and the previous release
     candidates for the version being released must be passed to
     `--previous-version`.
799
800
801
802
803
804
805
806
807
   * Older versions for which there is no incremental upgrade path to
     the new release must be passed with `--previous-version`, so that
     users who skipped a release or two are informed of the new one.
     Note that multi-steps incremental upgrade paths are valid and
     supported: e.g. when releasing 1.1.2, 1.1 users should still be
     able to incrementally upgrade to 1.1.1, and in turn to 1.1.2; to
     make this work, one must _not_ pass `--previous-version 1.1`,
     that would remove the existing incremental upgrade path from 1.1
     to 1.1.1.
808
809
810
811
   * If preparing anything but a final release (e.g. an alpha, beta
     or RC), add `--channel alpha`
   * If preparing anything but a final release (e.g. an alpha, beta
     or RC), drop all `--next-version`
812
     arguments, and instead pass
anonym's avatar
anonym committed
813
     `--next-version $(echo ${VERSION:?} | sed -e 's,~rc.*$,,')`
814
815
816
817
   * Adjust `--next-version "${VERSION:?}.1"` so it matches the next
     potential emergency release. E.g. when releasing 3.7.1,
     pass `--next-version 3.7.2` and when releasing 3.8, pass
     `--next-version 3.8.1`.
818
819
820
821

1. Create an armoured detached signature for each created or modified
   upgrade-description file.

822
823
824
825
        find "${RELEASE_CHECKOUT:?}/wiki/src/upgrade/" \
           -type f -name upgrades.yml | \
           while read udf; do
               if [ -n "$(git status --porcelain "${udf:?}")" ]; then
826
827
828
829
830
                   for x in 1 2 3; do
                       gpg -u "${TAILS_SIGNATURE_KEY:?}" --armor \
                           --detach-sign "${udf:?}" \
                       && break
                   done
831
832
833
834
835
836
837
                   mv --force "${udf:?}.asc" "${udf:?}.pgp"
                   ( \
                     cd ${IUK_CHECKOUT:?} && \
                     ./bin/tails-iuk-check-upgrade-description-file "${udf:?}" \
                   ) || break
               fi
           done
838

Tails developers's avatar
Tails developers committed
839
1. Add and commit the upgrade-description files and their detached
840
841
   signatures to the Git branch used to prepare the release
   (`$WEBSITE_RELEASE_BRANCH`):
Tails developers's avatar
Tails developers committed
842

843
844
845
846
847
        ( \
          cd "${RELEASE_CHECKOUT:?}" && git add wiki/src/upgrade && \
          git commit -m "Update upgrade-description files." && \
          git push origin ${WEBSITE_RELEASE_BRANCH:?} \
        )
Tails developers's avatar
Tails developers committed
848

849
1. If preparing anything but a final release (e.g. an alpha, beta
intrigeri's avatar
intrigeri committed
850
851
852
   or RC), copy the generated UDFs for the previous releases
   to the *test* channel in `$MASTER_CHECKOUT`, modify their content
   accordingly, sign them, commit and push:
Tails developers's avatar
Tails developers committed
853

intrigeri's avatar
intrigeri committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
        ( \
          cd ${MASTER_CHECKOUT:?} && \
          git fetch && \
          for old_version in ${IUK_SOURCE_VERSIONS:?}; do
            alpha_udf="wiki/src/upgrade/v1/Tails/${old_version:?}/amd64/alpha/upgrades.yml" && \
            test_udf="wiki/src/upgrade/v1/Tails/${old_version:?}/amd64/test/upgrades.yml" && \
            mkdir -p "$(dirname "$test_udf")" && \
            git show origin/${WEBSITE_RELEASE_BRANCH:?}:${alpha_udf:?} \
              | sed -e 's/channel: alpha/channel: test/' > ${test_udf:?} && \
            gpg -u "${TAILS_SIGNATURE_KEY:?}" --armor --detach-sign ${test_udf:?} && \
            mv ${test_udf:?}.asc ${test_udf:?}.pgp && \
            git add ${test_udf:?}* ; \
          done && \
          git commit -m "Add incremental upgrades on the test channel for Tails ${VERSION:?}" && \
          git push origin master:master \
        )

1. Else, if preparing a final release, copy the generated UDFs for the previous
   releases to the *test* channel in `$MASTER_CHECKOUT`, modify their content
   accordingly, sign them, commit and push:
874

875
876
877
        ( \
          cd ${MASTER_CHECKOUT:?} && \
          git fetch && \
anonym's avatar
anonym committed
878
          for old_version in ${IUK_SOURCE_VERSIONS:?}; do
879
880
881
882
883
884
885
886
887
888
889
890
            stable_udf="wiki/src/upgrade/v1/Tails/${old_version:?}/amd64/stable/upgrades.yml" && \
            test_udf="wiki/src/upgrade/v1/Tails/${old_version:?}/amd64/test/upgrades.yml" && \
            mkdir -p "$(dirname "$test_udf")" && \
            git show origin/${WEBSITE_RELEASE_BRANCH:?}:${stable_udf:?} \
              | sed -e 's/channel: stable/channel: test/' > ${test_udf:?} && \
            gpg -u "${TAILS_SIGNATURE_KEY:?}" --armor --detach-sign ${test_udf:?} && \
            mv ${test_udf:?}.asc ${test_udf:?}.pgp && \
            git add ${test_udf:?}* ; \
          done && \
          git commit -m "Add incremental upgrades on the test channel for Tails ${VERSION:?}" && \
          git push origin master:master \
        )
891
892


893
894
Prepare the ISO description file for *Tails Verification*
---------------------------------------------------------
895

anonym's avatar
anonym committed
896
897
If preparing a RC, skip this part.

898
899
Update the ISO description file (IDF) used by the browser extension:

900
    cat > "${RELEASE_CHECKOUT:?}"/wiki/src/install/v1/Tails/amd64/stable/latest.yml <<EOF
901
    ---
902
    build-target: amd64
903
904
    channel: stable
    product-name: Tails
905
    version: '${VERSION:?}'
906
907
    target-files:
    - sha256: ${ISO_SHA256SUM}
908
      size: ${ISO_SIZE_IN_BYTES:?}
909
      url: http://dl.amnesia.boum.org/tails/stable/tails-amd64-${VERSION:?}/tails-amd64-${VERSION:?}.iso
910
    EOF
911
    ( cd "${RELEASE_CHECKOUT:?}" && \
anonym's avatar
anonym committed
912
      git add wiki/src/install/v1/Tails/amd64/stable/latest.yml && \
913
      git commit -m "Update IDF file for Tails Verification." )
914

915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
Done with OpenPGP signing
=========================

By now you are done with Tails signing key, so please make sure it is
not usable by your system any more.

<div class="note">

Beware! If your have to plug your OpenPGP smart card or reassemble the
key again after this point it invalidates <i>everything</i> done for
the [[reproduction of this release|test#reproducibility-final-check]]
so it has to be started from the beginning:

* the original text is restored on the pad, and
* some tester follows it from scratch, and
* the Trusted Reproducer follows awaits the new input from said tester
  and then starts from scratch.

So please try to avoid this!

</div>

Tails developers's avatar
Tails developers committed
937
938
939
Upload images
=============

Tails developers's avatar
Tails developers committed
940
941
942
Sanity check
------------

943
Verify once more that the Tor Browser we ship is still the most recent (see
944
above).
Tails developers's avatar
Tails developers committed
945

946
947
<a id="publish-iuk"></a>

intrigeri's avatar
intrigeri committed
948
949
Publish the ISO and IUKs over HTTP
----------------------------------
Tails developers's avatar
Tails developers committed
950

951
Upload the IUKs to our rsync server:
intrigeri's avatar
intrigeri committed
952
953
954
955
956
957
958

    for source_version in ${IUK_SOURCE_VERSIONS}; do
       rsync --partial --inplace --progress -v \
          "${ISOS:?}/Tails_amd64_${source_version:?}_to_${VERSION:?}.iuk" \
          rsync.lizard:
    done

959
Upload the ISO signature to our rsync server:
960

961
    scp "${ISO_PATH:?}.sig" rsync.lizard:
962
963
964
965
966
967

Pick a build from `$RELEASE_BRANCH` that produced an ISO identical to
the one you've built locally (`XXX` must be the job ID, i.e.
an integer):

    MATCHING_JENKINS_BUILD_ID=XXX
968

969
Copy the ISO to our rsync server and verify the signature:
970
971
972
973
974
975
976
977

    cat "${RELEASE_CHECKOUT:?}/wiki/src/tails-signing.key" \
       | ssh rsync.lizard gpg --import
    ssh rsync.lizard << EOF
       wget \
          "https://nightly.tails.boum.org/build_Tails_ISO_${RELEASE_BRANCH:?}/builds/${MATCHING_JENKINS_BUILD_ID:?}/archive/build-artifacts/tails-amd64-${VERSION:?}.iso" && \
       gpg --verify tails-amd64-${VERSION:?}.iso{.sig,}
    EOF
intrigeri's avatar
intrigeri committed
978
979
980

Move files in place with proper ownership and permissions:

981
    ssh rsync.lizard << EOF
982
983
984
985
986
987
988
989
990
991
992
      sudo install -o root -g rsync_tails -m 0755 -d \
         /srv/rsync/tails/tails/${DIST:?}/tails-amd64-${VERSION:?} && \
      sudo chown root:rsync_tails \
         tails-amd64-${VERSION:?}.iso* \
         Tails_amd64_*_to_${VERSION:?}.iuk && \
      sudo chmod u=rwX,go=rX \
         tails-amd64-${VERSION:?}.iso* \
         Tails_amd64_*_to_${VERSION:?}.iuk && \
      sudo mv tails-amd64-${VERSION:?}.iso* \
              /srv/rsync/tails/tails/${DIST:?}/tails-amd64-${VERSION:?} && \
      sudo mv Tails_amd64_*_to_${VERSION:?}.iuk \
993
              /srv/rsync/tails/tails/${DIST:?}/iuk/
994
    EOF
995

996
Update the time in `project/trace` file on our rsync server
997
998
999
and on the live wiki (even for a release candidate):

	TRACE_TIME=$(date +%s) &&
1000
1001
1002
	echo ${TRACE_TIME:?} | ssh rsync.lizard "cat > /srv/rsync/tails/tails/project/trace" && \
	[ -n "${MASTER_CHECKOUT:?}" ] && \
	echo ${TRACE_TIME:?} > "${MASTER_CHECKOUT:?}/wiki/src/inc/trace" &&
1003
	(
1004
	   cd "${MASTER_CHECKOUT:?}" && \
1005
	   git commit wiki/src/inc/trace \
1006
	      -m "Updating trace file after uploading ${VERSION:?}." && \
1007
	   git push origin master
1008
1009
	)

1010
1011
1012
1013
1014
1015
1016

## Announce, seed and test the Torrents

    cat "${RELEASE_CHECKOUT:?}/wiki/src/tails-signing.key" \
       | ssh bittorrent.lizard gpg --import
    scp \
       "${ISOS:?}/tails-amd64-${VERSION:?}.torrent" \
intrigeri's avatar
intrigeri committed
1017
       "${ISO_PATH:?}.sig" \
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
       bittorrent.lizard: && \
    ssh bittorrent.lizard << EOF
       mkdir --mode 0755 "tails-amd64-${VERSION:?}" && \
       mv "tails-amd64-${VERSION:?}.iso.sig" \
          "tails-amd64-${VERSION:?}/" && \
       cd "tails-amd64-${VERSION:?}" && \
       wget \
          "https://nightly.tails.boum.org/build_Tails_ISO_${RELEASE_BRANCH:?}/builds/${MATCHING_JENKINS_BUILD_ID:?}/archive/build-artifacts/tails-amd64-${VERSION:?}.iso" && \
       gpg --verify tails-amd64-${VERSION:?}.iso{.sig,} && \
       cd && \
1028
1029
       chgrp -R debian-transmission "tails-amd64-${VERSION:?}" && \
       chmod -R go+rX,g+w "tails-amd64-${VERSION:?}" && \
anonym's avatar
anonym committed
1030
       mv \
1031
1032
1033
1034
1035
1036
1037
1038
          "tails-amd64-${VERSION:?}" \
          /var/lib/transmission-daemon/downloads/ && \
       transmission-remote --add tails-amd64-${VERSION:?}.torrent \
                           --find /var/lib/transmission-daemon/downloads/
    EOF

Test that you can start downloading the ISO with a BitTorrent client.

1039
1040
1041
1042
ISO history
-----------

Push the released ISO to our Tails ISO history git-annex repo, so that
1043
1044
our isotesters can fetch it from there for their testing. How to do so
is described in our internal Git repo.
1045

1046
1047
1048
1049
1050
1051
1052
Testing
=======

1. Using `check-mirrors`, choose a fast mirror that already has the
   tentative ISO. E.g. <https://mirrors.kernel.org/tails/> or
   <https://mirrors.wikimedia.org/tails/> are reliable and have plenty
   of bandwidth.
anonym's avatar
anonym committed
1053
1054
1055
1056
1057

        ./check-mirrors.rb --allow-multiple --channel ${DIST:?} \
            --ip $(dig +short mirrors.kernel.org | tail -n1) \
            tails-amd64-${VERSION:?}

1058
1059
1060
1061
1062
1. Email <tails-testers@boum.org> to ask them to test the tentative
   ISO, pointing them to the up-to-date mirror you've found previously.
1. Email <tails@boum.org> and potential contributors (see
   `manual_testers.mdwn` in the internal Git repository) that tests
   may start:
1063
   - make sure the Trusted Verifier is in the list of recipients
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
   - point them to the up-to-date mirror you've found previously
   - make it clear what's the deadline
   - make it clear where and how you expect to get feedback
   - attach the Torrent
   - attach the `.packages` file
1. Make sure someone is committed to run the automated test suite.
1. Make sure that enough people are here to run the tests, that they
   report their results in due time, and that they make it clear when
   they're leaving for good.
1. Fill the holes and make sure that the manual test suite is done in
   due time.
1. Triage test results, reproduce bugs as needed, decide what the next
   step is and make sure it happens: add to known issues? file ticket?
1077
   release blocker? improve the test description (steps, expected outcome)?
1078

Tails developers's avatar
Tails developers committed
1079
1080
1081
Update the website and Git repository
=====================================

1082
What follows in this section happens on the `$WEBSITE_RELEASE_BRANCH`
1083
1084
1085
1086
branch in `${RELEASE_CHECKOUT:?}`:

	cd "${RELEASE_CHECKOUT:?}" && \
	   git checkout "${WEBSITE_RELEASE_BRANCH:?}"
1087
1088
1089
1090
1091
1092

If preparing a final release
----------------------------

Skip this part if preparing a RC.

1093
Rename, copy, garbage collect and update various files:
1094

1095
	mv "${ARTIFACTS:?}"/tails-amd64-"${VERSION:?}".iso.packages \
1096
	   "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.packages" && \
1097
	mv "${PACKAGES_MANIFEST:?}" \
1098
	   "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.build-manifest" && \
1099
	cp "${ISO_PATH:?}.sig" \
1100
1101
1102
	   "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.build-manifest" \
	   "${ARTIFACTS:?}/tails-amd64-${VERSION:?}.packages" \
	   "${ISOS:?}/tails-amd64-${VERSION:?}.torrent" \
1103
1104
1105
1106
1107
1108
	   "${RELEASE_CHECKOUT:?}/wiki/src/torrents/files/" && \
	git rm \
	   "${RELEASE_CHECKOUT:?}/wiki/src/torrents/files/tails-amd64-${PREVIOUS_VERSION:?}."{build-manifest,iso.sig,packages,torrent} && \
	LC_NUMERIC=C ls -l -h ${ISO_PATH:?} | \
	   cut -f 5 -d ' ' | sed -r 's/(.+)([MG])/\1 \2B/' \
	   > "${RELEASE_CHECKOUT:?}/wiki/src/inc/stable_amd64_iso_size.html" && \
1109
1110
    gpg --check-trustdb && \
    LANG=C TZ=UTC gpg --no-options --keyid-format 0xlong --verify "${ISO_PATH:?}.sig" "${ISO_PATH:?}" 2>&1 | \
1111
1112
	   sed 's/ /\&nbsp;/g;s/</\&lt;/;s/>/\&gt;/;s/$/<br\/>/g' > \
	   "${RELEASE_CHECKOUT:?}/wiki/src/inc/stable_amd64_gpg_signature_output.html"
1113