summaryrefslogtreecommitdiff
path: root/release-info/howto.md
blob: 0022e67d230134a456f7d9a4abdce3fc84b95270 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
These are informal notes on how to do an OCaml release.

Following these steps requires commit right in the OCaml repository,
as well as SSH access to the inria.fr file servers hosting the
distribution archives and manual.

We are not fully confident that those steps are correct, feel free to
check with other release managers in case of doubt.

Note: we say that a new release is a "testing release" if it is a Beta
version or Release Candidate. Otherwise, we call it a "production
release".


## A few days in advance

Send a mail on caml-devel to warn Gabriel (to make a pass on Changes;
see the "Changes curation" appendix for more details) and the
OCamlLabs folks (for OPAM testing).

## 0: release environment setup

```
rm -f /tmp/env-$USER.sh
cat >/tmp/env-$USER.sh <<EOF
# Update the data below
export MAJOR=4
export MINOR=12
export BUGFIX=0
export PLUSEXT=

# names for the release announce
export HUMAN=

# do we need to use tar or gtar?
export TAR=tar

export WORKTREE=~/o/\$MAJOR.\$MINOR
  # must be the git worktree for the branch you are releasing

export BRANCH=\$MAJOR.\$MINOR
export VERSION=\$MAJOR.\$MINOR.\$BUGFIX\$PLUSEXT
export TAGVERSION=\`echo \$VERSION | sed s/\~/-/g\`

export REPO=https://github.com/ocaml/ocaml

# these values are specific to caml.inria's host setup
# they are defined in the release manager's .bashrc file
export ARCHIVE_HOST="$OCAML_RELEASE_ARCHIVE_HOST"
export ARCHIVE_PATH="$OCAML_RELEASE_ARCHIVE_PATH"
export WEB_HOST="$OCAML_RELEASE_WEB_HOST"
export WEB_PATH="$OCAML_RELEASE_WEB_PATH"

export DIST="\$ARCHIVE_PATH/ocaml/ocaml-\$MAJOR.\$MINOR"
export INSTDIR="/tmp/ocaml-\$VERSION"


EOF
source /tmp/env-$USER.sh
echo $VERSION
```


## 1: check repository state

```
cd $WORKTREE
git checkout $MAJOR.$MINOR
git status  # check that the local repo is in a clean state
git pull
```

## 2: magic numbers

If you are about to do a major release, you should check that the
magic numbers have been updated since the last major release. It is
preferable to do this just before the first testing release for this
major version, typically the first beta.

See the `utils/HACKING.adoc` file for documentation on how to bump the
magic numbers.

## 3: build, refresh dependencies, sanity checks

```
make distclean
git clean -n -d -f -x  # Check that "make distclean" removed everything

rm -rf ${INSTDIR}
./configure --prefix=${INSTDIR}

make -j5

# Check that dependencies are up-to-date
make alldepend

git diff
# should have empty output

# check that .depend files have no absolute path in them
find . -name .depend | xargs grep ' /'
  # must have empty output

# Run the check-typo script
./tools/check-typo


make install
./tools/check-symbol-names runtime/*.a
  # must have empty output and return 0
```


## 4: tests

```
make tests
```


## 5: build, tag and push the new release

```
# at this point, the VERSION file contains N+devD
# increment it into N+dev(D+1); for example,
#   4.07.0+dev8-2018-06-19 => 4.07.0+dev9-2018-06-26
# for production releases: check and change the Changes header
#  (remove "next version" and add a date)
make -B configure
git commit -a -m "last commit before tagging $VERSION"

# update VERSION with the new release; for example,
#   4.07.0+dev9-2018-06-26 => 4.07.0+rc2
# Update ocaml-variants.opam with new version.
# Update \year in manual/src/macros.hva
make -B configure
# For a production release
make coreboot -j5
make coreboot -j5 # must say "Fixpoint reached, bootstrap succeeded."
git commit -m "release $VERSION" -a
git tag -m "release $VERSION" $TAGVERSION

# for production releases, change the VERSION file into (N+1)+dev0; for example,
#   4.08.0 => 4.08.1+dev0
# for testing candidates, use N+dev(D+2) instead; for example,
#   4.07.0+rc2 => 4.07.0+dev10-2018-06-26
# Revert ocaml-variants.opam to its "trunk" version.
make -B configure
git commit -m "increment version number after tagging $VERSION" VERSION configure ocaml-variants.opam
git push
git push --tags
```

## 5-bis: Alternative for branching

This needs to be more tested, tread with care.
```
# at this point, the VERSION file contains N+devD
# increment it into N+dev(D+1); for example,
#   4.07.0+dev0-2018-06-19 => 4.07.0+dev1-2018-06-26
# Rename the "Working version" header in Changes
# to "OCaml $BRANCH"
make -B configure
git commit -a -m "last commit before branching $BRANCH"
git branch $BRANCH

# update VERSION with the new future branch,
#   4.07.0+dev1-2018-06-26 => 4.08.0+dev0-2018-06-30
# Update ocaml-variants.opam with new version.
make -B configure
# Add a "Working version" section" to Changes
# Add common subsections in Changes, see Changelog.
git commit -m "first commit after branching $BRANCH" -a
git push

# Switch to the new branch
git checkout $BRANCH
# increment VERSION, for instance
#   4.07.0+dev1-2018-06-26 => 4.07.0+dev2-2018-06-30
make -B configure
git commit -m "first commit on branch $BRANCH" -a
git push --set-upstream origin $BRANCH
```

Adjust github branch settings:

Go to
  https://github.com/ocaml/ocaml/settings/branches
and add a rule for protecting the new branch
(copy the rights from the previous version)

## 5.1: create the release on github (only for a production release)

open https://github.com/ocaml/ocaml/releases
# and click "Draft a new release"
# for a minor release, the description is:
 Bug fixes. See [detailed list of changes](https://github.com/ocaml/ocaml/blob/$MAJOR.$MINOR/Changes).

## 5.3: Inria CI (for a new release branch)

Add the new release branch to the Inria CI list.
Remove the oldest branch from this list.

## 5.4 new badge in README.adoc (for a new release branch)

Add a badge for the new branch in README.adoc.
Remove the oldest badge.

## 6: create OPAM packages

Clone the opam-repository
```
git clone https://github.com/ocaml/opam-repository
```

Create a branch for the new release
```
git checkout -b OCaml_$VERSION
```

The following opam packages are needed for all releases:

- `ocaml-base-compiler.$VERSION`
- `ocaml-variants.$VERSION+options`

For production release, the following packages need to be updated:

- `ocaml-system.$VERSION`
- `ocaml-src.$VERSION`
- `ocaml-src.$MAJOR.$MINOR.dev`
- `ocaml-manual.$VERSION`
- `ocaml.$NEXTVERSION`
- `ocaml-variants.$NEXTVERSION+trunk` should be moved to
   `ocaml-variants.$NEXTNEXTVERSION+trunk`

Note that the `ocaml` virtual package needs to be updated to the next version.

Similarly, the `ocurrent/ocaml-version` library should be updated.

Do not forget to add/update the checksum field for the tarballs in the
"url" section of the opam files. Use opam-lint before sending the pull
request.

You can test the new opam package before sending a PR to the
main opam-repository by using the local repository:

```
opam repo add local /path/to/your/opam-repository
opam switch create --repo=local,beta=git+https://github.com/ocaml/ocaml-beta-repository.git ocaml-variants.$VERSION
```
The switch should build.

For a production release, you also need to create new opam files for the ocaml-manual and
ocaml-src packages.

## 6.1 Update OPAM dev packages after branching

Create a new ocaml/ocaml.$NEXT/opam file.
Copy the opam dev files from ocaml-variants/ocaml-variants.$VERSION+trunk*
into ocaml-variants/ocaml-variants.$NEXT+trunk+* .
Update the version in those opam files.

Update the synopsis and "src" field in the opam $VERSION packages.
The "src" field should point to
 src: "https://github.com/ocaml/ocaml/archive/$VERSION.tar.gz"
The synopsis should be "latest $VERSION development(,...)".


## 7: build the release archives

```
cd $WORKTREE
TMPDIR=/tmp/ocaml-release
git checkout $TAGVERSION
git checkout-index -a -f --prefix=$TMPDIR/ocaml-$VERSION/
cd $TMPDIR
$TAR -c --owner 0 --group 0 -f ocaml-$VERSION.tar ocaml-$VERSION
gzip -9 <ocaml-$VERSION.tar >ocaml-$VERSION.tar.gz
xz <ocaml-$VERSION.tar >ocaml-$VERSION.tar.xz
```

## 8: upload the archives and compute checksums

For the first beta of a major version, create the distribution directory on
the server:
```
ssh $ARCHIVE_HOST "mkdir -p $DIST"
```

Upload the archives:
```
scp ocaml-$VERSION.tar.{xz,gz} $ARCHIVE_HOST:$DIST
```

To update the checksum files on the remote host, we first upload the
release environment.
(note: this assumes the user name is the same on the two machines)

```
scp /tmp/env-$USER.sh $ARCHIVE_HOST:/tmp/env-$USER.sh
```

and then login there to update the checksums (MD5SUM, SHA512SUM)

```
ssh $ARCHIVE_HOST
source /tmp/env-$USER.sh
cd $DIST

cp MD5SUM MD5SUM.old
md5sum ocaml-$VERSION.tar.{xz,gz} > new-md5s
# check new-md5s to ensure that they look right, and then
cat new-md5s >> MD5SUM
# if everything worked well,
rm MD5SUM.old new-md5s

# same thing for SHA512
cp SHA512SUM SHA512SUM.old
sha512sum ocaml-$VERSION.tar.{xz,gz} > new-sha512s
cat new-sha512s >> SHA512SUM
rm SHA512SUM.old new-sha512s

# clean up
rm /tmp/env-$USER.sh
exit
```


## 9: update note files (technical documentation)

```
ssh $ARCHIVE_HOST "mkdir -p $DIST/notes"
cd ocaml-$VERSION
scp INSTALL.adoc LICENSE README.adoc README.win32.adoc Changes \
   $ARCHIVE_HOST:$DIST/notes/
```


## 10: upload the reference manual

You don't need to do this if the previous release had the same
$MAJOR.$MINOR ($BRANCH) value and the exact same manual -- this is frequent if
it was a release candidate.

```
cd $WORKTREE
make
make install
export PATH="$INSTDIR/bin:$PATH"
cd manual
make clean
make
rm -rf /tmp/release
mkdir -p /tmp/release
RELEASENAME="ocaml-$BRANCH-"
make -C manual release RELEASE=/tmp/release/$RELEASENAME
scp /tmp/release/* $ARCHIVE_HOST:$DIST/


# upload manual checksums
ssh $ARCHIVE_HOST "cd $DIST; md5sum ocaml-$BRANCH-refman* >>MD5SUM"
ssh $ARCHIVE_HOST "cd $DIST; sha512sum ocaml-$BRANCH-refman* >>SHA512SUM"
```

Releasing the manual online happens on another machine:
Do this ONLY FOR A PRODUCTION RELEASE

```
scp /tmp/env-$USER.sh $ARCHIVE_HOST:/tmp/env-$USER.sh
ssh $ARCHIVE_HOST
source /tmp/env-$USER.sh
scp /tmp/env-$USER.sh $WEB_HOST:/tmp
ssh $WEB_HOST
source /tmp/env-$USER.sh

cd $WEB_PATH/caml/pub/docs
mkdir -p manual-ocaml-$BRANCH
cd manual-ocaml-$BRANCH
rm -fR htmlman ocaml-$BRANCH-refman-html.tar.gz
wget http://caml.inria.fr/pub/distrib/ocaml-$BRANCH/ocaml-$BRANCH-refman-html.tar.gz
tar -xzvf ocaml-$BRANCH-refman-html.tar.gz # this extracts into htmlman/
/bin/cp -r htmlman/* . # move HTML content to docs/manual-caml-$BRANCH
rm -fR htmlman ocaml-$BRANCH-refman-html.tar.gz

cd $WEB_PATH/caml/pub/docs
rm manual-ocaml
ln -sf manual-ocaml-$BRANCH manual-ocaml
```


## 11: prepare web announce for the release

For production releases, you should get in touch with ocaml.org to
organize the webpage for the new release. See

  <https://github.com/ocaml/ocaml.org/issues/819>


## 13: announce the release on caml-list, caml-announce, and discuss.ocaml.org

See the email announce templates in the `templates/` directory.



# Appendix

## Announce templates

See

- templates/beta.md for alpha and beta releases
- templates/rc.md for release candidate
- templates/production.md for the production release


## Changelog template for a new version

A list of common subsection for the "Changes" file:

```
### Language features:

### Runtime system:

### Code generation and optimizations:

### Standard library:

### Other libraries:

### Tools:

### Manual and documentation:

### Compiler user-interface and warnings:

### Internal/compiler-libs changes:

### Build system:

### Bug fixes:
```


## Changes curation

Here is the process that Gabriel uses to curate the Changes entries of
a release in preparation. Feel free to take care of it if you wish.

(In theory it would be possible to maintain the Changes in excellent
 shape so that no curation would be necessary. In practice it is less
 work and less friction to tolerate imperfect Changes entries, and
 curate them before the release.)

### Synchronizing the trunk Changes with release branches

The Changes entries of a release branch or past release should be
exactly included in the trunk Changes, in the section of this release
(or release branch). Use an interactive diffing tool (for example
"meld") to compare and synchronize the Changes files of trunk and
release branches.

Here are typical forms of divergence and their usual solutions:

- A change entry is present in a different section in two branches.
  (Typically: in the XX.YY section of the XX.YY release branch,
  but in the trunk section of the trunk branch.)

  This usually happens when the PR is written for a given branch
  first, and then cherry-picked in an older maintenance branch, but
  the cherry-picker forgets to move the Change entry in the first
  branch.

  Fix: ensure that the entry is in the same section on all branches,
  by putting it in the "smallest" version -- assuming that all bigger
  versions also contain this change.

- A change entry is present in a given section, but the change is not
  present in the corresponding release branch.

  There are two common causes for this with radically different solutions:

  + If a PR is merged a long time after they were submitted, the merge
    may put their Changes entry in the section of an older release,
    while it should go in trunk.

    Fix: in trunk, move the entry to the trunk section.

  + Sometimes the author of a PR against trunk intends it to be
    cherry-picked in an older release branch, and places it in the
    corresponding Changes entry, but we forget to cherry-pick.

    Fix: cherry-pick the PR in the appropriate branch.

  Reading the PR discussion is often enough to distinguish between the
  two cases, but one should be careful before cherry-picking in
  a branch (for an active release branch, check with the release
  manager(s)).

Figuring out the status of a given Changes entry often requires
checking the git log for trunk and branches. Grepping for the PR
number often suffices (note: when you cherry-pick a PR in a release
branch, please target the merge commit to ensure the PR number is
present in the log), or parts of the commit message text.

### Ensure each entry is in the appropriate section

(of course)

### Fill more details in unclear Changes entries

Expert users want to learn about the changes in the new release. We
want to avoid forcing them to read the tortuous PR discussion, by
giving enough details in the Changes entry.

In particular, for language changes, showing a small example of
concrete syntax of the new feature is very useful, and giving a few
words of explanations helps.

Compare for example

    - #8820: quoted string extensions
      (Gabriel Radanne, Leo White and Gabriel Scherer,
       request by Bikal Lem)

with

    - #8820: quoted extensions: {%foo|...|} is lighter syntax for
      [%foo {||}], and {%foo bar|...|bar} for [%foo {bar|...|bar}].
      (Gabriel Radanne, Leo White and Gabriel Scherer,
       request by Bikal Lem)

This is also important for changes that break compatibility; users
will scrutinize them with more care, so please give clear information on
what breaks and, possibly, recommended update methods.

Having enough details is also useful when you will grep the Changes
later to know when a given change was introduced (knowing what to grep
can be difficult).

### Ordering of Changes entries

In the past, we would order Changes entries numerically (this would
also correspond to a chronological order). Since 4.09 Gabriel is
trying to order them by importance (being an exciting/notable feature
for a large number of users). What is the best ordering of sections,
and the best entry ordering within a section, to put the most
important changes first? This is guesswork of course, and we commonly
have a long tail of "not so important PRs" in each section which don't
need to be ordered with respect to each other -- one may break two
lines just before this long tail.

The ordering of sections depends on the nature of the changes within
the release; some releases have an exciting "Runtime" section, many
release don't. Usually "Language features" is among the first, and
"Bug fixes" is the very last (who cares about bugs, right?).

If some entries feel very anecdotal, consider moving them to the Bug
Fixes section.

### Extract release highlights to News

From time to time, synchronize the `News` file with the release highlights
of each version.