xref: /php-src/docs/release-process.md (revision bca94e34)
1# PHP Release Process
2
3A release manager's role includes making packaged source code from the canonical
4repository available according to the release schedule.
5
6The release schedule for each version is published on the
7[PHP wiki](https://wiki.php.net):
8
9- [PHP 8.3](https://wiki.php.net/todo/php83)
10- [PHP 8.2](https://wiki.php.net/todo/php82)
11- [PHP 8.1](https://wiki.php.net/todo/php81)
12
13The PHP project publishes builds every two weeks.
14
15We publish [general availability][] (GA) releases for major and minor versions of
16PHP on the fourth Thursday of November each year. Following the GA release, we
17publish patch-level releases every four weeks, with at least one release
18candidate (RC) published two weeks before each patch-level release.
19
20Each major and minor version undergoes a 24-week pre-release cycle before GA
21release. The pre-release cycle begins on the second Thursday of June with the
22first alpha release of the new major/minor version. The pre-release cycle
23consists of at least:
24
25- 3 alpha releases
26- 3 beta releases
27- 6 release candidates
28
29Feature freeze for the next major/minor occurs with the first beta release.
30
31We refer to alpha, beta, and RC as *non-stable releases*, while GA are *stable*.
32
33The process of making packaged source available and announcing availability is
34explained in detail below. The process differs slightly for non-stable and
35stable releases.
36
37New release managers should review [New release manager
38checklist](#new-release-manager-checklist) at the end of this document. This
39section  explains the procedures for getting ready to begin work on managing PHP
40releases.
41
42
43## General notes and tips
44
451. Do not release on Fridays, Saturdays, or Sundays as this gives poor lead
46   time for downstream consumers adhering to a typical work week.
47
48   Our general procedure is to release on Thursdays, whenever possible.
49
502. Package two days before a release.
51
52   If the release is to be on Thursday, package on Tuesday. Think about
53   timezones as well.
54
553. Ensure that the relevant tests on CI are green.
56
57   - https://travis-ci.com/github/php/php-src
58   - https://cirrus-ci.com/github/php/php-src
59   - https://github.com/php/php-src/actions
60
61   > �� **Tip** \
62   > We recommend checking the build status a couple of days before packaging day
63   > to allow enough time to investigate failures, communicate with the authors,
64   > and commit any fixes.
65   >
66   > Check the CI status for your branch periodically and resolve the failures
67   > ASAP.
68   >
69   > See more in https://wiki.php.net/rfc/travis_ci.
70
714. Follow all steps to the letter.
72
73   > �� **Tip** \
74   > When you are unsure about anything, ask a previous RM before proceeding.
75   > Ideally, make sure a previous RM is available to answer questions during
76   > the first few releases of your version. For the steps related to the
77   > `web-php`, `web-qa`, and `web-php-distributions` repositories, try to have
78   > someone from the webmaster team on hand.
79
805. Verify the tags to be extra sure everything was tagged properly.
81
826. There is a PHP release Docker image https://github.com/sgolemon/php-release
83   with forks available to help with releases.
84
857. Communicate with release managers via release-managers@php.net.
86
878. References to repositories in this document refer to the canonical source
88   located at https://github.com/php.
89
909. It might be helpful to name your remote repositories something other than
91   "origin" to avoid accidentally pushing changes to "origin" with [muscle
92   memory][].
93
9410. It might also be helpful to set up conditional includes in your global
95    `~/.gitconfig` to set the proper `user.name`, `user.email`, and
96    `user.signingKey` values to use with your local PHP repositories. See
97    [Conditional Includes For Git Config][] for more information.
98
99
100## Packaging a non-stable release (alpha/beta/RC)
101
102All releases during the pre-release cycle (alpha/beta/RC) leading up to the GA
103release for a version are *non-stable* releases. Following the GA release, all
104RCs are *non-stable* releases.
105
106All non-stable releases follow a similar pattern, though pre-GA releases have
107slightly different steps. We'll call attention where the steps differ.
108
1091. Check that CI is passing (see above).
110
1112. Run `./scripts/dev/credits` in php-src and commit the changes to the credits
112   files in `ext/standard`.
113
114   > �� **Hint** \
115   > It's rare this script will make any changes, so if you run `git diff`
116   > and do not see anything, there's no need to panic. That means there are no
117   > changes to the credits files.
118
1193. Check out the *release branch* for this release from the *version branch*.
120
121   > �� **Non-stable version branches: pre-GA** \
122   > There is no *version branch* for alpha or beta releases. Instead, treat the
123   > main branch as the version branch. You will create a local-only release
124   > branch from the main branch. Do not push it!
125   >
126   > ```shell
127   > git checkout -b php-X.Y.0alpha1-local-release-branch upstream/master
128   > ```
129   >
130   > During the first RC release, you will create (and push!) the version
131   > branch for the pre-GA release, e.g., `PHP-8.2`. See
132   > "[Forking a new version branch](#forking-a-new-version-branch)" below.
133   > From this point forward, all pre-GA release branches will be created from
134   > this version branch. Again, these release branches are local-only. Do not
135   > push them!
136   >
137   > ```shell
138   > git checkout -b php-X.Y.0beta2-local-release-branch upstream/PHP-X.Y
139   > ```
140
141   > �� **Non-stable version branches: post-GA** \
142   > After GA, you will create (and push) a new *patch-level version branch*
143   > along with each non-stable release. For example, if you are building a
144   > release for PHP 8.2.8 RC1, you will create the `PHP-8.2.8` patch-level
145   > version branch from the `PHP-8.2` version branch.
146   >
147   > ```shell
148   > git checkout -b PHP-X.Y.Z upstream/PHP-X.Y
149   > git push upstream PHP-X.Y.Z
150   > ```
151   >
152   > We will use the patch-level version branch to commit any critical bug or
153   > security fixes before this version's GA.
154   >
155   > Then, from the patch-level version branch, you will create another
156   > local-only release branch. Do not push this one!
157   >
158   > ```shell
159   > git checkout -b php-X.Y.ZRC1-local-release-branch upstream/PHP-X.Y.Z
160   > ```
161
1624. Using your local-only release branch, bump the version numbers in
163   `main/php_version.h`, `Zend/zend.h`, `configure.ac`, and possibly
164   `NEWS`.
165
166   For examples, see [Update versions for PHP 8.1.0beta3][] (for a pre-GA
167   example) or [Update versions for PHP 8.1.6RC1][] along with
168   [Update NEWS for PHP 8.1.6RC1][] (for a post-GA example).
169
170   > ⚠️ **Important** \
171   > Do not use abbreviations for alpha or beta. Do not use dashes as
172   > separators.
173   >
174   > Do this:
175   >
176   > ```c
177   > #define PHP_VERSION "7.4.22RC1"
178   > ```
179   >
180   > Not this:
181   >
182   > ```c
183   > #define PHP_VERSION "7.4.22-RC1"
184   > ```
185
186   > �� **Note** \
187   > We update `Zend/zend.h` only when preparing RC and GA releases. We do not
188   > update `ZEND_VERSION` for alpha or beta releases.
189
190   > �� **API version bump for pre-GA** \
191   > When releasing the *first release candidate* of a pre-GA release, you must
192   > also bump the API version numbers in `Zend/zend_extensions.h`,
193   > `Zend/zend_modules.h`, and `main/php.h`. See [Prepare for PHP 8.1.0RC1][],
194   > for example.
195   >
196   > The API versions between the alpha, beta, and X.Y.0RCn releases may remain
197   > the same, or be bumped as little as possible because PHP extensions need to
198   > be rebuilt with each bump.
199   >
200   > Do *not* bump the API versions after RC1.
201
2025. Compile and run `make test`, with and without ZTS (Zend Thread Safety), using
203   the correct Bison and re2c versions, e.g., for PHP 7.4, Bison 3.0.0 and re2c
204   0.13.4 are required, as a minimum.
205
206   For example:
207
208   ```shell
209   # With ZTS
210   make distclean || \
211   ./buildconf --force \
212       && ./configure --enable-zts --disable-all --enable-debug --enable-opcache --enable-opcache-jit \
213       && make -j$(nproc) \
214       && make test TEST_PHP_ARGS="-q -j$(nproc)" \
215       || ./sapi/cli/php -v
216
217   # Without ZTS
218   make distclean || \
219   ./buildconf --force \
220       && ./configure --disable-all --enable-debug --enable-opcache --enable-opcache-jit \
221       && make -j$(nproc) \
222       && make test TEST_PHP_ARGS="-q -j$(nproc)" \
223       || ./sapi/cli/php -v
224   ```
225
2266. After each build, check the output of `./sapi/cli/php -v` to ensure the
227   versions match the release.
228
2297. If all is correct, commit the changes to your local-only release branch.
230
231   ```shell
232   git add -p
233   git commit --gpg-sign=YOURKEYID -m "Update versions for PHP X.Y.ZRCn"
234   ```
235
2368. Tag your local-only release branch with the release version.
237
238   ```shell
239   git tag -s -u YOURKEYID php-X.Y.ZRCn -m "Tag for php-X.Y.ZRCn"
240   ```
241
2429. �� **For post-GA releases only,** switch back to the *version branch* for
243   your release (e.g., `PHP-8.2`) and bump the version numbers in
244   `main/php_version.h`, `Zend/zend.h`, `configure.ac` and `NEWS`. This prepares
245   the version branch for the next version.
246
247   For example, if the RC is `8.2.1RC1` then the version numbers in the version
248   branch should be bumped to `8.2.2-dev`. We do this regardless of whether we
249   build a new RC to make sure `version_compare()` works correctly. See
250   [Bump for 8.1.8-dev][] for a real example.
251
252   Commit the changes to the version branch.
253
254   ```shell
255   git add -p
256   git commit --gpg-sign=YOURKEYID -m "PHP-X.Y is now for PHP X.Y.Z-dev"
257   ```
258
259   > �� **Tip** \
260   > Version branches (e.g. `PHP-8.1`) will *always* have version numbers in
261   > `main/php_version.h`, `Zend/zend.h`, and `configure.ac` that end in `-dev`.
262   > Patch-level version branches (e.g. `PHP-8.1.7`) will also *always* have
263   > version numbers that end in `-dev` in these files. The main branch (i.e.
264   > `master`) will *always* have version numbers that end in `-dev` in these
265   > files.
266   >
267   > Only release tags should have version numbers in these files that do not
268   > end in `-dev` (e.g., `8.1.7`, `8.1.7RC1`, `8.2.0alpha1`, etc.).
269
27010. Push the changes to the `php-src`.
271
272    ```shell
273    git push upstream php-X.Y.ZRCn # tag name
274    git push upstream PHP-X.Y.Z    # patch-level version branch (post-GA only)
275    git push upstream PHP-X.Y      # version branch
276    ```
277
278    > �� **Attention** \
279    > Do not push with `--tags`, as this will push all local tags, including
280    > tags you might not wish to push.
281    >
282    > Local-only release branches should not be pushed!
283
28411. Run the following using the release tag to export the tree, create the
285    `configure` script, and build and compress three tarballs (`.tar.gz`,
286    `.tar.bz2` and `.tar.xz`).
287
288    ```shell
289    ./scripts/dev/makedist php-X.Y.ZRCn
290    ```
291
29212. Run the following using the release tag and your GPG key ID to sign the
293    tarballs and save the signatures to `php-X.Y.ZRCn.manifest`, which you can
294    upload to GitHub and include in the announcement emails.
295
296    ```shell
297    ./scripts/dev/gen_verify_stub X.Y.ZRCn YOURKEYID > php-X.Y.ZRCn.manifest
298    ```
299
30013. If you have the [GitHub command line tool][] installed, run the following to
301    create a public Gist for the manifest file:
302
303    ```shell
304    gh gist create --public php-X.Y.ZRCn.manifest
305    ```
306
307    Or you may go to https://gist.github.com to create it manually.
308
30914. Copy the tarballs (using scp, rsync, etc.) to your `public_html/` folder on
310    downloads.php.net.
311
312    ```shell
313    scp php-X.Y.ZRCn.tar.* downloads.php.net:~/public_html/
314    ```
315
316    > �� **Hint** \
317    > If you do not have a `public_html` directory, create it and set its
318    > permissions to `0755`.
319
32015. Now the tarballs and signatures may be found at
321    `https://downloads.php.net/~yourname/`, e.g. https://downloads.php.net/~derick/.
322
32316. Once the release is tagged, contact the release-managers@php.net distribution
324    list so that Windows binaries can be created. Once those are made, they may
325    be found at https://windows.php.net/qa/.
326
327    Here is an example "ready for builds" message to release-managers@php.net:
328
329    ```text
330    Subject: PHP 8.1.6RC1 ready for builds
331
332    Hi, all!
333
334    Tag: php-8.1.6RC1
335    Tarballs: https://downloads.php.net/~ramsey/
336    Manifest: https://gist.github.com/ramsey/5d73f0717effb6d8d17699381361e4b1
337
338    Cheers,
339    Ben
340
341    << PASTE FULL MANIFEST CONTENTS HERE >>
342    ```
343
344
345## Announcing a non-stable release (alpha/beta/RC)
346
3471. Switch to your local clone of the `web-qa` repository and update the
348   information in the `$QA_RELEASES` array in `include/release-qa.php`.
349
350   Follow the documentation in the file for editing the QA release information.
351   See also [Announce 8.1.0RC3][] and [8.1.6RC1][] for examples.
352
353   Add, commit, and push your changes, when finished.
354
355   ```shell
356   git add -p
357   git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.ZRCn"
358   git push upstream master
359   ```
360
3612. �� **For pre-GA releases only,** add a short notice to `web-php` stating
362   there is a new release, and highlight the major changes (e.g., security
363   fixes).
364
365   To help produce the files for this, use the `bin/createNewsEntry` tool. When
366   you run it, it will ask several questions (see below). For pre-GA non-stable
367   releases, use only the "frontpage" category.
368
369   ```shell
370   cd /path/to/repos/php/web-php
371   ./bin/createNewsEntry
372   # Please type in the title: PHP X.Y.0 Alpha n available for testing
373   # Categories:
374   #     0: PHP.net frontpage news   [frontpage]
375   #     1: New PHP release          [releases]
376   #     2: Conference announcement  [conferences]
377   #     3: Call for Papers          [cfp]
378   # Please select appropriate categories, separated with space: 0
379   # Will a picture be accompanying this entry? no
380   # And at last; paste/write your news item here.
381   # To end it, hit <enter>.<enter>
382   #
383   #   [[ Here you will paste the full HTML of the post. ]]
384   # .
385   #
386   git add -p
387   git add archive/entries/*.xml
388   git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.0RCn"
389   git push upstream master
390   ```
391
392   Each news entry for pre-GA releases will be similar, though we change the
393   text slightly to indicate progression through the pre-release cycle. For
394   example, here are all the news posts for the pre-GA releases of PHP 8.1.0:
395
396   * [Announce 8.1.0alpha1](https://github.com/php/web-php/commit/57b9675c8d8550493289fa1fba77427c93cdd472)
397   * [Announce 8.1.0alpha2](https://github.com/php/web-php/commit/cec044fc0763f5cfa77d0e79479f8b6279023570)
398   * [Announce 8.1.0alpha3](https://github.com/php/web-php/commit/5c480765f444a3fddfd575e01fe0be3fcfdde05b)
399   * [Announce 8.1.0beta1](https://github.com/php/web-php/commit/40840e3c3f89d6dd95baa4b8cdf22d6f206f86c2)
400   * [Announce 8.1.0beta2](https://github.com/php/web-php/commit/7bf6acdadd4940bd9db711bf3f9d5a4054dc0722)
401   * [Announce 8.1.0beta3](https://github.com/php/web-php/commit/38c8a872700fb0c2ebde49e2eae3374257ba6d08)
402   * [Announce 8.1.0RC1](https://github.com/php/web-php/commit/6e4bf3d0228ce113728d5f1a769ed42e0d63ca10)
403   * [Announce 8.1.0RC2](https://github.com/php/web-php/commit/1ae95f4b686a5d614a94a664a7466ee0e5cd21eb)
404   * [Announce 8.1.0RC3](https://github.com/php/web-php/commit/3091246d77a3f445fcc593587597d0abcab8c373)
405   * [Announce 8.1.0RC4](https://github.com/php/web-php/commit/fbaeb9403f4e2856115889946d3f63751e183c7b)
406   * [Announce 8.1.0RC5](https://github.com/php/web-php/commit/46473ccccfb5f7fedc3f169c55fb7c22a596b55d)
407   * [Announce 8.1.0RC6](https://github.com/php/web-php/commit/cacaef9c41352b5dbf3fbbf44702cc6c0cbfb478)
408
409   > ⚠️ **Important** \
410   > In your announcement news entry, be sure to include the following text or
411   > text similar to the following:
412   >
413   > > Please DO NOT use this version in production, it is an early test version.
414
415   > �� **Note** \
416   > When a version is in its post-GA phase, we do not post news entries for
417   > non-stable releases.
418
4193. Wait for the web and qa sites to update with the new information before
420   sending announcements. This could take up to an hour.
421
4224. Send *separate* announcement emails to:
423
424   * `internals@lists.php.net`
425   * `php-general@lists.php.net`
426   * `php-qa@lists.php.net`
427
428   In the announcement message, point out the location of the release and the
429   possible release date of either the next RC or the final release. Also
430   include the manifest generated by `gen_verify_stub` when you packaged the
431   build.
432
433   Here are a few examples of non-stable release announcement emails:
434
435   * [PHP 8.1.0alpha1 is available for testing](https://news-web.php.net/php.qa/69043)
436   * [PHP 8.1.0beta3 available for testing](https://news-web.php.net/php.qa/69079)
437   * [PHP 8.1.0RC6 available for testing](https://news-web.php.net/php.qa/69117)
438   * [PHP 8.1.7RC1 Ready for testing](https://news-web.php.net/php.qa/69163)
439
440   > �� **Send separate emails!** \
441   > Do *not* send a single email message with all addresses in the `To`, `Cc`,
442   > or `Bcc` headers. If a user replies to one of these messages, we do not
443   > want their email client to automatically send the reply to each list, as
444   > often occurs.
445
446   > �� **Hint** \
447   > We send emails to the followers of these mailing lists to notify them of
448   > new releases, so they can make sure their projects keep working and can
449   > report any potential bugs that should be fixed before the upcoming GA
450   > release.
451
4525. �� **For pre-GA *RCs* only,** coordinate with the social media team (i.e.,
453   Derick) to post a tweet with the RC release announcement and link to the news
454   entry on php.net. ([@official_php](https://twitter.com/official_php))
455
456
457## Packaging a stable release
458
4591. Check out the *patch-level version branch* for the release
460   (e.g., `PHP-8.1.7`).
461
462   > �� **Hint** \
463   > You should have created this branch when packaging the non-stable release
464   > candidate for this version. If it is for a PHP-X.Y.0 version, then just
465   > create and push this branch.
466
4672. If a CVE commit needs to be merged to the release, have it committed to
468   the base branches and [merged upwards as usual][] (e.g. commit the CVE fix
469   to 7.2, merge to 7.3, 7.4, etc.). Then, you can cherry-pick it into the
470   patch-level version branch for this release.
471
472   Commit these changes and push the patch-level version branch. Ensure
473   that CI is still passing (see above).
474
475   > �� **Tip** \
476   > Don't forget to update `NEWS` manually in an extra commit to the
477   > patch-level version branch.
478
4793. Run the `./scripts/dev/credits` script in the patch-level version branch,
480   and commit the changes in the credits files in `ext/standard`.
481
482   > �� **Note** \
483   > It's very rare this will make changes at this point, but we run it here
484   > in case the credits changed as a result of a bug fix that was
485   > cherry-picked into this branch.
486
4874. Create a local-only release branch for this release from the *patch-level
488   version branch*.
489
490   ```shell
491   git checkout -b php-X.Y.Z-local-release-branch upstream/PHP-X.Y.Z
492   ```
493
4945. Using your local-only release branch, bump the version numbers in
495   `main/php_version.h`, `Zend/zend.h`, `configure.ac`, and possibly
496   `NEWS`.
497
498   For example, if you're releasing a stable version for PHP 8.1.8, then all
499   the version numbers in the patch-level version branch should be
500   `8.1.8-dev`. In your local-only release branch, you will change them all to
501   `8.1.8`.
502
503   See [Update versions for PHP 8.1.7][] and [Update NEWS for PHP 8.1.7][] for
504   an example.
505
5066. Compile and run `make test`, with and without ZTS (Zend Thread Safety), using
507   the correct Bison and re2c versions, e.g., for PHP 7.4, Bison 3.0.0 and re2c
508   0.13.4 are required, as a minimum.
509
510   For example:
511
512   ```shell
513   # With ZTS
514   make distclean || \
515   ./buildconf --force \
516       && ./configure --enable-zts --disable-all --enable-debug --enable-opcache --enable-opcache-jit \
517       && make -j$(nproc) \
518       && make test TEST_PHP_ARGS="-q -j$(nproc)" \
519       || ./sapi/cli/php -v
520
521   # Without ZTS
522   make distclean || \
523   ./buildconf --force \
524       && ./configure --disable-all --enable-debug --enable-opcache --enable-opcache-jit \
525       && make -j$(nproc) \
526       && make test TEST_PHP_ARGS="-q -j$(nproc)" \
527       || ./sapi/cli/php -v
528   ```
529
5307. After each build, check the output of `./sapi/cli/php -v` to ensure the
531   versions match the release.
532
5338. If all is correct, commit the changes to your local-only release branch.
534
535   ```shell
536   git add -p
537   git commit --gpg-sign=YOURKEYID -m "Update versions for PHP X.Y.Z"
538   ```
539
5409. Tag your local-only release branch with the release version and push the tag.
541
542   ```shell
543   git tag -s -u YOURKEYID php-X.Y.Z -m "Tag for php-X.Y.Z"
544   git push upstream php-X.Y.Z
545   ```
546
54710. Run the following using the release tag to export the tree, create the
548    `configure` script, and build and compress three tarballs (`.tar.gz`,
549    `.tar.bz2` and `.tar.xz`).
550
551    ```shell
552    ./scripts/dev/makedist php-X.Y.Z
553    ```
554
555    > �� **Hint** \
556    > Check if the PEAR files are updated (Phar).
557
558    > �� **Tip** \
559    > On some systems the behavior of GNU tar can default to produce POSIX
560    > compliant archives with PAX headers. As not every application is
561    > compatible with that format, creation of archives with PAX headers should
562    > be avoided. When packaging on such a system, the GNU tar can be influenced
563    > by defining the environment variable `TAR_OPTIONS='--format=gnu'`.
564
56511. Run the following using the release tag and your GPG key ID to sign the
566    tarballs and save the signatures to `php-X.Y.Z.manifest`, which you can
567    upload to GitHub and include in the announcement emails.
568
569    ```shell
570    ./scripts/dev/gen_verify_stub X.Y.Z YOURKEYID > php-X.Y.Z.manifest
571    ```
572
57312. If you have the [GitHub command line tool][] installed, run the following to
574    create a public Gist for the manifest file:
575
576    ```shell
577    gh gist create --public php-X.Y.Z.manifest
578    ```
579
580    Or you may go to https://gist.github.com to create it manually.
581
58213. Switch to your local clone of the `web-php-distributions` repository and
583    copy the tarballs and signature files into the repository. Add, commit, and
584    push them.
585
586    ```shell
587    cd /path/to/repos/php/web-php-distributions
588    mv /path/to/repos/php/php-src/php-X.Y.Z.tar.* .
589    git add php-X.Y.Z.tar.*
590    git commit --gpg-sign=YOURKEYID -m "Add tarballs for php-X.Y.Z"
591    git push upstream master
592    ```
593
59414. Switch to your local clone of the `web-php` repository and update the
595    `web-php-distributions` submodule.
596
597    ```shell
598    cd /path/to/repos/php/web-php
599    git pull --rebase upstream master
600    git submodule init
601    git submodule update
602    cd distributions
603    git fetch --all
604    git pull --rebase upstream master
605    cd ..
606    git commit distributions -m "X.Y.Z tarballs"
607    git push upstream master
608    ```
609
610    > �� **Hint** \
611    > This fetches the last commit ID from `web-php-distributions` and pins the
612    > "distributions" submodule in `web-php` to this commit ID.
613    >
614    > When the website syncs, which should happen within an hour, the tarballs
615    > will be available from `https://www.php.net/distributions/php-X.Y.Z.tar.gz`,
616    > etc.
617
61815. Once the release is tagged, contact the release-managers@php.net distribution
619    list so that Windows binaries can be created. Once those are made, they may
620    be found at https://windows.php.net/qa/.
621
622    > ⚠️ **Important** \
623    > Do *not* send this announcement to any public lists.
624
625    Here is an example "ready for builds" message to release-managers@php.net:
626
627    ```text
628    Subject: PHP 8.1.6 ready for builds
629
630    Hi, all!
631
632    Tag: php-8.1.6
633    Tarballs: web-php-distributions
634    Manifest: https://gist.github.com/ramsey/432fcf8afcbfb1f1de6c3ab47d82e366
635
636    Cheers,
637    Ben
638
639    << PASTE FULL MANIFEST CONTENTS HERE >>
640    ```
641
642
643## Announcing a stable release
644
6451. This steps applies only for releases after PHP-X.Y.0.
646
647   Switch to your local clone of `web-php` and add the information for the
648   previous release to `include/releases.inc`.
649
650   For example, if you are preparing to announce version 8.2.2, then the
651   previous release is 8.2.1, so you will add the information for 8.2.1 to this
652   file. Most of the time, you can do this using the `bin/bumpRelease` tool.
653
654   ```shell
655   ./bin/bumpRelease 8 2
656   ```
657
658   The first number is the major version, and the second number is the minor
659   version. In this example, we're bumping the release information for version
660   8.2. There is no need to provide the patch level.
661
662   > �� **Tip** \
663   > If this fails for any reason, you can manually copy the information
664   > for the previous release from `include/version.inc` into
665   > `include/releases.inc`.
666
6673. Update the version information for the new release in `include/version.inc`.
668
669   Find the part of the `$data` array that is related to your version (e.g.,
670   `$data['8.2']` for 8.2.x releases) or create a new section if releasing
671   PHP-X.Y.0 version, and make the following edits / additions:
672
673   * Set `version` to the full version number (e.g. '8.2.1')
674   * Set `date` to the release date in `j M Y` format (e.g. '5 Jan 2021')
675   * Update the `tags` array to include `'security'` if this is a security release
676   * Set the `sha256` array with the hashes for each of the release tarballs
677
6785. Create the release file and news entry for the new version.
679
680   ```shell
681   ./bin/createReleaseEntry -v X.Y.Z -r # --security for security releases
682   ```
683
684   This will create a release file (i.e., `releases/X_Y_Z.php`) and a news entry
685   file (i.e., `archive/entries/YYYY-MM-DD-n.xml`), while also updating
686   `archive/archive.xml`.
687
688   Within these files, it will generate standard messages for the new version.
689   You may edit the generated files to expand on the base message, if needed.
690
691   The edits are necessary for PHP-X.Y.0 version where the format is different.
692   See for example [PHP-8.2 announcement](https://github.com/php/web-php/commit/c966868202caafa880213055f4e3e97c0483119b)
693
6947. Update the ChangeLog file for the given major version (e.g., `ChangeLog-8.php`).
695
696   If PHP-X.Y.0 is released, modify the `ChangeLog-X.php` (where `X` is the major
697   version) file manually first. The `$MINOR_VERSIONS` field needs to be extended
698   with the new version and initial anchor (e.g. `<a id="PHP_8_4"></a>` if added
699   for PHP 8.4) added above the first anchor of the previous version.
700
701   ```shell
702   ./bin/news2html 'https://github.com/php/php-src/raw/php-X.Y.Z/NEWS' 'X.Y.Z' 'ChangeLog-X.php'
703   ```
704
7059. Review all the changes in `web-php`, commit, and push them.
706
707   ```shell
708   git add -p
709   git add archive/entries/*.xml releases/*.php
710   git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.Z"
711   git push upstream master
712   ```
713
714   See [Announce PHP 8.1.6][] for an example commit.
715
71610. Switch to your local clone of the `web-qa` repository and update the
717   information in the `$QA_RELEASES` array in `include/release-qa.php`.
718
719   The array probably contains information about the RC released two weeks ago
720   in preparation for the current release. Since the current release is now GA,
721   it's time to remove the RC build from the QA website.
722
723   It is sufficient to set the `number` property for the release to `0` to
724   stop displaying the RC build on the QA website. You may also remove the
725   sha256 hashes for the RC tarballs, but it's not necessary. For an example,
726   see [PHP 8.1.6 released][].
727
728   Add, commit, and push your changes, when finished.
729
730   ```shell
731   git add -p
732   git commit --gpg-sign=YOURKEYID -m "PHP X.Y.Z released"
733   git push upstream master
734   ```
735
73611. �� **Before sending announcement emails, check to make sure the websites have
737   synced.**
738
739   * Make sure the tarballs are available from, e.g.,
740     `https://www.php.net/distributions/php-X.Y.Z.tar.gz`
741   * Check the "downloads" page to make sure the new version appears:
742     https://www.php.net/downloads
743   * Does the news entry show up on the home page? https://www.php.net
744   * Do the updates to the ChangeLog appear?
745     e.g., https://www.php.net/ChangeLog-8.php
746   * Is there a release page for the new version?
747     e.g., `https://www.php.net/releases/X_Y_Z.php`
748   * Does the RC for this version still appear on the QA home page?
749     https://qa.php.net
750
751   Keep in mind it may take up to an hour for the websites to sync.
752
75311. Please note down the sha256 and the PGP signature (.asc). These *must* be
754   included in the release mail.
755
75612. Send *separate* announcement emails to:
757
758   * `php-announce@lists.php.net`
759   * `php-general@lists.php.net`
760   * `internals@lists.php.net`
761
762   Release announcement emails must include the manifest generated when
763   packaging the build, along with links to the sources, Windows binaries, and
764   changelog. Here are a few examples of stable release announcement emails:
765
766   * [PHP 8.1.0 Released](https://news-web.php.net/php.announce/321)
767   * [PHP 8.1.3 Released](https://news-web.php.net/php.announce/325)
768   * [PHP 8.1.6 Released](https://news-web.php.net/php.announce/331)
769
770   > ⚠️ **Important** \
771   > For standard patch-level releases, we will note "This is a bugfix release."
772   > If it is a security release, we must note "This is a security release."
773
774   > �� **Send separate emails!** \
775   > Do *not* send a single email message with all addresses in the `To`, `Cc`,
776   > or `Bcc` headers. If a user replies to one of these messages, we do not
777   > want their email client to automatically send the reply to each list, as
778   > often occurs.
779
78013. Coordinate with the social media team (i.e., Derick) to
781    [create a PR request](https://github.com/derickr/toot-together/blob/main/toots/README.md)
782    for posting the release announcement to Mastodon. Posts need to be
783    approved.
784
785## Re-releasing the same version or a patch-level (i.e., `-plN`)
786
787While unlikely, there may be times we need to re-release the same version. This
788might happen if the tarballs have a corrupted file, for example.
789
790Should this occur *before* announcing the release, you may choose to delete the
791tag and go through the full packaging process again, as described above.
792
793> �� **Hint** \
794> This is one of the reasons we package releases two days before announcing
795> them.
796
797If this happens *after* announcing the release, you may choose to tag, package,
798and release a patch-level (i.e., *pl*) release. If it is not critical and/or
799affects a very limited subset of users, then you may choose to wait until the
800next release.
801
802If you choose to create a patch-level release, follow these steps:
803
8041. Commit the new binaries to `web-php-distributions`
805
8062. Update $data['X.Y'] in `web-php:/include/version.inc`
807   (X.Y=major.minor release, e.g. '8.0'):
808
809    * `version` to the full version number (e.g. '8.0.1-pl1')
810    * `date` to the release date in `j M Y` format (e.g. '9 Jan 2021')
811    * `tags` array should include `security` if this is a security release
812    * `sha256` array and sub-elements for all SHA256 sums
813
8143. Add a short notice to `web-php` stating that there is a new release, and
815   highlight the major important things (security fixes) and when it is
816   important to upgrade.
817
818    * Call `php bin/createReleaseEntry -v <version> [ --security ]` in your
819      local web-php checkout.
820
8214. Commit all the changes (`include/version.inc`, `archive/archive.xml`,
822   `archive/entries/YYYY-MM-DD-N.xml`).
823
8245. Wait an hour or two, then send a mail to php-announce@lists.php.net,
825   php-general@lists.php.net and internals@lists.php.net with a text similar to
826   the news entry.
827
828   Please make sure that the mail to php-announce@ is its own completely
829   separate email. This is to make sure that replies to the announcement on
830   php-general@ or internals@ will not accidentally hit the php-announce@
831   mailinglist.
832
833
834## Feature freeze
835
836A major/minor version [feature freeze][] occurs with the first beta release.
837Specifically, it occurs when the first beta release is packaged, which means the
838feature freeze occurs two days before the first beta release.
839
840The feature freeze for `php-src` means that we will not accept any new features
841after the date of the feature freeze. For any RFCs to be included in the new
842version, they should be discussed and have the voting polls closed no later than
843the feature freeze date. However, this does not mean the new feature must have a
844complete implementation by this date.
845
846Following the feature freeze, the focus of work for the new version will be on
847fixing bugs, writing tests, and completing/polishing all accepted features.
848
849As a courtesy to the community, the release managers should remind others about
850the upcoming feature freeze by posting reminders to internals@lists.php.net at
8514-weeks, 3-weeks, 2-weeks, and 1-week prior to the feature freeze. This is a
852recommendation and the intervals may vary based on work load.
853
854
855## Forking a new version branch
856
857When the new version has reached the first RC, it is time to create a new
858version branch. This frees up the main branch (i.e., `master`) for any new
859feature development that cannot go into the new version.
860
8611. One week prior to tagging `X.Y.0RC1`, warn internals@ that your version's
862   branch is about to be created. Be specific about when the branch creation
863   will occur. For example: https://news-web.php.net/php.internals/99864
864
8652. Just prior to tagging `X.Y.0RC1`, create the new version branch locally,
866   i.e. `PHP-X.Y`.
867
8683. Add a commit on the main branch (i.e., `master`) after the branch point.
869
870   This commit should:
871
872   * clear the `NEWS`, `UPGRADING`, and `UPGRADING.INTERNALS` files;
873   * update the version numbers in `configure.ac`, `main/php_version.h`,
874     `Zend/zend.h`, and `win32/build/confutils.js`;
875   * update the API version numbers in `Zend/zend_extensions.h`,
876     `Zend/zend_modules.h`, and `main/php.h`; and
877   * add the new branch to the list in `CONTRIBUTING.md`.
878
879   See [Prepare for PHP 8.2][] and [Prepare for PHP 8.2 (bis)][] for an example
880   of what this commit should include.
881
8824. Push the new version branch and the changes to the `master` branch, with an
883   appropriate commit message (e.g., "master is now for PHP 8.3.0-dev").
884
8855. Immediately notify internals@ of the new branch and advise on the new merging
886   order. For example: https://news-web.php.net/php.internals/99903
887
8886. Update `web-php:git.php` and https://wiki.php.net/vcs/gitworkflow to reflect
889   the new branch.
890
891   For example:
892
893   * [Add PHP-8.1 to the Git steps page][]
894   * [Changes to the wiki][]
895
896> �� **Hint** \
897> We create the new version branch at the first release candidate rather than at
898> feature freeze to allow a period of time where the focus is on making the new
899> version ready for RC and GA. During this time, the main branch is *only* for
900> minor improvements and bug fixes. All major improvements and new features must
901> wait.
902
903
904## Preparing for the initial stable version (PHP X.Y.0)
905
9061. When you release the first pre-GA RC, remind the documentation team
907   (phpdoc@lists.php.net) to write the [migration guide][]. Make sure the guide
908   is available before releasing the initial stable version, since you should
909   link to it in the release announcements.
910
9112. Timely get used to the differences in preparing and announcing a stable
912   release.
913
9143. Before releasing X.Y.0, merge the `NEWS` entries of the pre-releases, so that
915   there is only a single section about PHP X.Y.0, instead of individual
916   sections for each pre-release.
917
918   All the changes that are already present in the previous version NEWS should be
919   removed. It means all bug fixes that went to the previous version as well should
920   have their entries removed. It is possible to use `grep` to compare the changes.
921   For exampe if `82/NEWS` is NEWS for PHP 8.2 and `83/NEWS` is NEWS file for PHP 8.3,
922   then following command will show changes present in both files:
923
924   ```sh
925   grep -Fxf 82/NEWS 83/NEWS
926   ```
927
928
9295. On the announcement day for the initial stable version (or shortly before),
930   update the `Expires` field in the <https://www.php.net/.well-known/security.txt>
931   file. The `Expires` field should be set to the expected date of the next X.Y.0
932   release (following the one currently being prepared), which is usually the
933   fourth Thursday of November in the next year.
934
935   Following the recommendation of [RFC 9116](https://www.rfc-editor.org/rfc/rfc9116),
936   we maintain an `Expires` time of about a year for our security policies. This
937   provides security researchers with confidence they are using our most
938   up-to-date reporting policies.
939
940   The `security.txt` file is located in the [web-php repository](https://github.com/php/web-php)
941   under the `.well-known/` directory. We may make changes to this file at other
942   times, as needed, but we will always advance the `Expires` timestamp on a
943   yearly cadence, coinciding with our X.Y.0 releases.
944
945   Please see the instructions for
946   [making changes to security.txt][security-txt].
947
948
949## Prime the selection of release managers for the next version
950
951About three months prior to the scheduled release of the first alpha release of
952the next  minor or major version (around March 1st or shortly thereafter), the
953release managers for the latest version branch should issue a call for
954volunteers to begin the selection process for the next release managers.
955
9561. Issue the call for volunteers on internals@lists.php.net on or around March
957   1st. See, for example: https://news-web.php.net/php.internals/113334
958
959   There is no rule for how long the call for volunteers must remain open. We
960   should aim to select the release managers by early April, so announcing the
961   call in early March gives people about a month to decide whether they wish to
962   volunteer.
963
9642. There should be two or more volunteers. Typically, one should be a veteran
965   release manager (having previously served as a `php-src` release manager),
966   while the other one (or two) should be rookies. Hold a vote if necessary (see
967   https://wiki.php.net/rfc/releaseprocess#release_managers_selection).
968
9693. Help the new release managers with their first steps.
970
971
972## New release manager checklist
973
9741. Request membership to the
975   [release managers group](https://github.com/orgs/php/teams/release-managers) on GitHub.
976
9772. Subscribe to the php-announce@lists.php.net mailing list by emailing
978   php-announce+subscribe@lists.php.net
979
9803. Email systems@php.net to get setup for access to downloads.php.net, to be
981   added to the release-managers@php.net distribution list, and to be added to
982   the moderators for php-announce@lists.php.net so you are able to moderate
983   your release announcements.
984
985   Provide the following information in a single email:
986
987   - Prefered Unix username (will also become part of location to download RCs,
988     such as `https://downloads.php.net/~derick/`).
989   - An SSH public key, preferably a new unique one for PHP systems and
990     projects.
991   - Read [Machine Access](https://wiki.php.net/systems#machine_access) to set
992     up access to downloads.php.net through jump hosts, and provide a
993     `.google_authenticator` file for 2FA.
994   - Your @php.net email address to use for the release-managers@php.net
995     distribution list and php-announce@lists.php.net moderator address. This
996     should preferably not forward to a Gmail address.
997   - Your GitHub account name, so that your membership to the release managers
998     group may be approved.
999
1000   A system admin will then contact you to go through with steps 5 through 8 of
1001   [2FA setup instructions](https://wiki.php.net/systems#fa_setup_instructions).
1002
1003   > �� **Hint** \
1004   > To send email from your @php.net address, you will need to use a custom
1005   > SMTP server. If you use Gmail, you may
1006   > "[Send emails from a different address or alias][]."
1007
1008
10094. Create a [GPG key][] for your @php.net address.
1010
1011   > �� **Tip** \
1012   > If you're new to GPG, follow GitHub's instructions for
1013   > [Generating a new GPG key][].
1014
1015   Publish your key by editing `include/gpg-keys.inc` in the `web-php`
1016   repository. Add a `case` for your username to the `gpg_key_get()` function,
1017   and paste the output from `gpg --fingerprint`. You may also need to update
1018   the `$branches` array in the `gpg_key_get_branches()` function to include
1019   your username alongside your branch.
1020
1021   ```console
1022   ❯ gpg --fingerprint ramsey@php.net
1023   pub   rsa4096 2021-04-26 [SC] [expires: 2025-11-24]
1024   39B6 4134 3D8C 104B 2B14  6DC3 F9C3 9DC0 B969 8544
1025   uid           [ultimate] Ben Ramsey <ramsey@php.net>
1026   sub   rsa4096 2021-04-26 [E] [expires: 2025-11-24]
1027   ```
1028
1029   Have one or more of the other RMs [sign your GPG key][], and publish your
1030   public key to a keyserver:
1031
1032   ```shell
1033   gpg --keyserver keys.openpgp.org --send-keys YOURKEYID
1034   gpg --keyserver keyserver.ubuntu.com --send-keys YOURKEYID
1035   ```
1036
1037   Add your public key to `php-keyring.gpg` in `web-php-distributions`. To do
1038   this, you will need to import all keys from the current PHP keyring file to
1039   your local GPG keyring. You will need to take note of the key IDs for each of
1040   the release managers listed in `php-keyring.gpg`. Then, you will export,
1041   specifying your key ID in addition to the key IDs of every other release
1042   manager. Save this export back to `php-keyring.gpg`, commit the changes,
1043   and push.
1044
1045   ```shell
1046   cd /path/to/repos/php/web-php-distributions
1047   gpg php-keyring.gpg            # lists all keys in the keyring
1048   gpg --import php-keyring.gpg   # imports all keys to your local keyring
1049   gpg --export \
1050       --export-options export-minimal \
1051       --armor \
1052       YOURKEYID F9C39DC0B9698544 DBDB397470D12172 MORE RM KEY IDS ... \
1053       > php-keyring.gpg
1054   gpg php-keyring.gpg  # verify all the keys are present, including yours
1055   git add -p
1056   git commit --gpg-sign=YOURKEYID -m "Update PHP release manager keyring"
1057   git push
1058   ```
1059
1060   `web-php-distributions` is a submodule of `web-php`. You'll now have to update
1061   the commit reference to reflect the change made in web-php-distributions.
1062
1063   ```shell
1064   cd /path/to/repos/php/web-php
1065   git submodule update
1066   cd distributions           # This is the submodule referring to web-php-distributions
1067   git pull origin master
1068   cd ..
1069   git add distributions
1070   git commit --gpg-sign=YOURKEYID -m "Update php-keyring.gpg in distributions"
1071   git push
1072   ```
1073
10745. Make sure you have the following repositories cloned locally:
1075
1076   * https://github.com/php/php-src
1077   * https://github.com/php/web-php
1078   * https://github.com/php/web-qa
1079   * https://github.com/php/web-php-distributions
1080
1081
1082[general availability]: https://en.wikipedia.org/wiki/Software_release_life_cycle#General_availability_(GA)
1083[muscle memory]: https://en.wikipedia.org/wiki/Muscle_memory
1084[Conditional Includes For Git Config]: https://motowilliams.com/2017-05-11-conditional-includes-for-git-config/
1085[Update versions for PHP 8.1.0beta3]: https://github.com/php/php-src/commit/3edd1087c70bee2ec21f0fbec1a575d78a500f15
1086[Update versions for PHP 8.1.6RC1]: https://github.com/php/php-src/commit/40e8ced23898e3069340ca03ea5febc5361015ad
1087[Update NEWS for PHP 8.1.6RC1]: https://github.com/php/php-src/commit/a4fdeaebe419b88e3b4a1f5aba845c2d4e81fd4e
1088[Prepare for PHP 8.1.0RC1]: https://github.com/php/php-src/commit/5764414eb8900ae98020a3c20693f4fb793efa99
1089[Bump for 8.1.8-dev]: https://github.com/php/php-src/commit/3b6ee1eb19c14c3339ebfcf5c967065a9f828971
1090[GitHub command line tool]: https://cli.github.com
1091[Announce 8.1.0RC3]: https://github.com/php/web-qa/commit/f264b711fd3827803b79bbb342959eae57ea502b
1092[8.1.6RC1]: https://github.com/php/web-qa/commit/e6d61ad7a9d8be0b1cd159af29f3b9cbdde33384
1093[merged upwards as usual]: https://wiki.php.net/vcs/gitworkflow
1094[Update versions for PHP 8.1.7]: https://github.com/php/php-src/commit/d35e577a1bd0b35b9386cea97cddc73fd98eed6d
1095[Update NEWS for PHP 8.1.7]: https://github.com/php/php-src/commit/b241f07f52ca9f87bf52be81817f475e6e727439
1096[Announce PHP 8.1.6]: https://github.com/php/web-php/commit/9f796a96c65f07e45845ec248933bfb0010b94a9
1097[PHP 8.1.6 released]: https://github.com/php/web-qa/commit/bff725f8373cf6fd9d97ba62a8517b19721a4c2e
1098[feature freeze]: https://en.wikipedia.org/wiki/Freeze_(software_engineering)
1099[Prepare for PHP 8.2]: https://github.com/php/php-src/commit/1c33ddb5e5598c5385c4c965992c6e031fd00dd6
1100[Prepare for PHP 8.2 (bis)]: https://github.com/php/php-src/commit/a93e12f8a6dfc23e334339317c97aa35356db821
1101[Add PHP-8.1 to the Git steps page]: https://github.com/php/web-php/commit/1fcd78c2817cf1fbf1a1de2ddec1350be4e26491
1102[Changes to the wiki]: https://wiki.php.net/vcs/gitworkflow?do=diff&rev2%5B0%5D=1617123194&rev2%5B1%5D=1654728193&difftype=sidebyside
1103[migration guide]: https://www.php.net/manual/en/migration81.php
1104[GPG key]: https://en.wikipedia.org/wiki/GNU_Privacy_Guard
1105[Generating a new GPG key]: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key
1106[sign your GPG key]: https://carouth.com/articles/signing-pgp-keys/
1107[Send emails from a different address or alias]: https://support.google.com/mail/answer/22370?hl=en
1108[security-txt]: https://github.com/php/policies/blob/main/security-policies.rst#making-changes-to-securitytxt
1109