PHP 源码发行完整流程解析:分支模型、版本号文件、makedist 打包签名与发布公告
本文基于 PHP 源码仓库(php-src)中官方维护的发行流程文档 docs/release-process.md 撰写,系统讲解发布经理(Release Manager, RM)如何将规范仓库中的代码按节奏打包成可分发的发布版本:从发布日历与分支模型,到修改版本号、GPG 签名、生成三格式 tarball,再到更新官网仓库与邮件公告的完整操作链。读完本文,你将理解 PHP 每次 alpha/beta/RC/GA 版本背后完整的工程化流程,并能对照仓库中的 打包脚本 与 校验脚本 验证其中每一步的实际行为。
一、发布节奏:GA 日、20 周预发布周期与 RC 制度
PHP 项目的版本发布遵循固定日历:
- GA(General Availability,正式发布):每个主/次版本(major/minor)的 GA 版本在每年 11 月第四个星期四 发布。
- 补丁版本:GA 之后每 4 周 发布一个补丁级别版本,且每个补丁版本发布前 两周 至少发布一个 RC(Release Candidate)。
- 预发布周期:每个主/次版本在 GA 前经历 20 周 的预发布周期,通常从 7 月第二个星期四的第一个 alpha 开始(从 GA 日期倒推)。该周期至少包含:
- 3 个 alpha 版本
- 3 个 beta 版本
- 4 个 release candidate(自 PHP 8.4 起,X.Y.0 的 RC 固定为 4 个,不再是最初文档时代的 6 个)
术语约定:alpha、beta、RC 统称 non-stable(非稳定版) 发布,GA 为 stable(稳定版) 发布。两个非稳定阶段(GA 前的预发布阶段,与 GA 后的补丁 RC)的打包步骤略有差异,流程文档在各步骤中明确标注了差异点。
二、Git 分支模型:四级分支与 -dev 版本号铁律
理解 PHP 发布流程的关键是分支层级。从流程文档可以归纳出四级分支结构:
| 分支 | 示例 | 生命周期 | 是否推送到远端 |
|---|---|---|---|
| 主干分支 | master |
永远指向下一个主/次版本 | 是 |
| 版本分支(version branch) | PHP-8.2 |
该主/次版本的整个维护期 | 是 |
| 补丁级版本分支(patch-level) | PHP-8.2.8 |
从版本分支切出,承载该补丁版本 RC/GA 前的关键修复 | 是 |
| 本地发布分支(release branch) | php-8.2.8RC1-local-release-branch |
仅用于打 tag 与改版本号 | 仅本地,严禁推送 |
版本号规则是这套模型的核心不变式:只有发布 tag 上的版本号不带 -dev 后缀;master、所有版本分支与补丁级分支上的版本号永远以 -dev 结尾。在当前仓库中可以直接验证这一规则:
- main/php_version.h:
#define PHP_VERSION "8.6.0-dev"(当前主干正在开发 8.6.0) - Zend/zend.h:
#define ZEND_VERSION "4.6.0-dev" - configure.ac:
AC_INIT([PHP],[8.6.0-dev],...)
三个文件必须保持一致,这也正是发布流程中"bump 版本号"步骤要同时修改这三个文件的原因。
三、发布纪律:文档总结的 12 条通用守则
流程文档在开头给出了 12 条贯穿所有发布的通用守则,这些是踩过坑之后的经验结晶,值得逐条保留:
- 不要在周五、周六、周日发布——这会让遵循标准工作周的下游用户没有处理时间。惯例是尽量在星期四发布。
- 提前两天打包:如果星期四发布,就星期二打包(打包日)。同时要留意时区。
- 确认 CI 全绿。建议在打包日前几天检查构建状态,为排查失败、与作者沟通、提交修复留出时间。
- 严格逐步执行。拿不准时先问上一任 RM;涉及官网仓库(
web-php、web-php-distributions)的步骤时,最好有 webmaster 团队成员在场。 - 核验 tag,确保所有 tag 正确打上。
- 存在专门的 PHP release Docker 镜像可辅助发布工作(流程文档指向了 sgolemon 的 php-release 镜像及其 fork)。
- 发布经理之间通过 release-managers@php.net 邮件组沟通。
- 文档中提到的"仓库"均指规范源仓库(php 组织下的 php-src 等)。
- 把远端命名为
origin以外的名字,避免凭肌肉记忆误推送。 - 建议在全局
~/.gitconfig中配置 conditional includes,为本地 PHP 仓库单独设置正确的user.name、user.email与user.signingKey。 - 占位符
php-X.Y.ZRCn中的RCn不一定是 RC 编号,也可能是php-8.4.0alpha1、php-8.4.0beta2、php-8.4.0(首个 GA)、php-8.4.9(周期性 bugfix 或安全版本)等任意发布形态。 - 熟悉并遵守"向上合并(merging upwards)"规程:修复先进入最低分支,再逐级合并到
master。
四、打包一个非稳定版发布(alpha/beta/RC)
4.1 完整操作步骤
非稳定版发布的打包流程共 17 步(原文档步骤编号有跳跃,此处按顺序整理):
-
确认 CI 通过(见上文守则 3)。
-
运行 credits 脚本:在 php-src 中执行
./scripts/dev/credits,并提交对ext/standard下 credits 文件的改动。该脚本从各ext/*/CREDITS与sapi/*/CREDITS文件重新生成 ext/standard/credits_ext.h 与 ext/standard/credits_sapi.h(见 scripts/dev/credits)。很少产生实际改动,git diff为空时无需担心。 -
从版本分支切出本地发布分支,这里预发布前后做法不同:
-
GA 前(pre-GA):alpha/beta 阶段没有版本分支,以
master充当版本分支,仅本地建分支、不推送:git checkout -b php-X.Y.0alpha1-local-release-branch upstream/master首个 RC 时要创建(并推送)正式版本分支(如
PHP-8.2,见下文"分支切分"一节)。最后一个 RC 及 GA 走 GA 后流程;在那之前,RC 的本地发布分支都从该版本分支切出,同样不推送:git checkout -b php-X.Y.0RC3-local-release-branch upstream/PHP-X.Y注意:GA(PHP X.Y.0)的补丁级版本分支是在最后一个计划内 RC(当前为 RC4)发布时创建的。GA 后若 PHP X.Y 分支再收到修复,不会进入已定型的 X.Y.0;若回归问题值得纳入 X.Y.0,则按普通补丁流程先合并到 PHP X.Y,再 cherry-pick 到 X.Y.0 分支。
-
GA 后(post-GA):随每个非稳定 RC 创建(并推送)新的补丁级版本分支。例如构建 PHP 8.2.8RC1 时,从
PHP-8.2切出PHP-8.2.8并推送,该分支用于在 GA 前提交关键 bug/安全修复:git checkout -b PHP-X.Y.Z upstream/PHP-X.Y git push upstream PHP-X.Y.Z再从中切出仅本地的发布分支(不推送):
git checkout -b php-X.Y.ZRC1-local-release-branch upstream/PHP-X.Y.Z
-
-
修改版本号。在本地发布分支中更新
main/php_version.h、Zend/zend.h、configure.ac,可能还有NEWS。NEWS 的日期写公告日(周四),而不是打标日(周二)。版本字符串禁止缩写、禁止用连字符分隔:#define PHP_VERSION "7.4.22RC1" /* 正确 */ #define PHP_VERSION "7.4.22-RC1" /* 错误 */两条特殊规则:
Zend/zend.h中的ZEND_VERSION只在准备 RC 与 GA 时更新,alpha/beta 不动它;- pre-GA 的第一个 RC 还必须提升
Zend/zend_extensions.h、Zend/zend_modules.h、main/php.h中的 API 版本号(因为每次 API 提升都会迫使所有扩展重编译,alpha→beta→RCn 之间可以保持不变或少量提升);RC1 之后不得再提升 API 版本。
-
编译并跑
make test,ZTS(Zend Thread Safety)与 non-ZTS 各一遍,且使用正确版本的 Bison 与 re2c(例如 PHP 8.5 至少要求 Bison 3.0.0、re2c 1.0.3):# With ZTS make distclean || \ ./buildconf --force \ && ./configure --enable-zts --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v # Without ZTS make distclean || \ ./buildconf --force \ && ./configure --disable-all --enable-debug --enable-opcache-jit \ && make -j$(nproc) \ && make test TEST_PHP_ARGS="-q -j$(nproc)" \ || ./sapi/cli/php -v -
每次构建后检查
./sapi/cli/php -v输出,确认版本号与目标发布一致。 -
一切正确后提交到本地发布分支:
git add -p git commit --gpg-sign=YOURKEYID -m "Update versions for PHP X.Y.ZRCn" -
打 GPG 签名 tag:
git tag -s -u YOURKEYID php-X.Y.ZRCn -m "Tag for php-X.Y.ZRCn" -
pre-GA 专属:切回
master(alpha/beta)或PHP-X.Y(RC),为新版本更新NEWS并提交,例如:git add -p git commit --gpg-sign=YOURKEYID -m "[ci skip] Update NEWS for PHP X.Y.0 alpha2"NEWS 是在下一轮 tag 周期开始时更新的——例如"Update NEWS for PHP 8.2.0 alpha2" 这笔提交是在打 alpha1 tag 时随附发出的。
-
GA 后的补丁 RC 与最后一个 pre-GA RC:切回版本分支(如
PHP-8.2),把main/php_version.h、Zend/zend.h、configure.ac、NEWS中的版本号 bump 到下一个-dev(如 8.2.1RC1 发布后应改为8.2.2-dev)。无论是否真的会发新 RC 都要做,这保证version_compare()行为正确。提交信息形如"PHP-X.Y is now for PHP X.Y.Z-dev"。版本分支与master上这三个文件的版本号永远以-dev结尾,只有 tag 例外。 -
向上合并:把
PHP-X.Y一路合并到master:git switch PHP-X.Y+1 # 从发布分支开始 git merge PHP-X.Y # repeat # 逐级向上合并 git switch master git merge PHP-X.Y+n # 最新的发布分支解决冲突时,在
PHP-X.Y+1或master上采用--ours(忽略来自 PHP-X.Y 的版本号改动):git checkout --ours main/php_version.h Zend/zend.h configure.ac git add main/php_version.h Zend/zend.h configure.ac git merge --continue同时要按照 PHP wiki 的 Git FAQ 为
NEWS文件配置专用 merge driver。 -
推送到 php-src:
git push upstream php-X.Y.ZRCn # tag git push upstream PHP-X.Y.Z # 补丁级版本分支(自 GA 前最后一个 RC 开始) git push upstream PHP-X.Y # 版本分支(分支切出之后) git push upstream master # 主干(分支切出之前)严禁使用
--tags推送(会带上所有本地 tag);本地发布分支绝不推送。 -
生成发行包:用发布 tag 导出源码树、生成
configure脚本、构建并压缩三个 tarball(.tar.gz、.tar.bz2、.tar.xz):./scripts/dev/makedist php-X.Y.ZRCn -
签名并生成 manifest:
./scripts/dev/gen_verify_stub X.Y.ZRCn YOURKEYID > php-X.Y.ZRCn.manifest -
若安装了 GitHub 命令行工具,创建公开 Gist 托管 manifest:
gh gist create --public php-X.Y.ZRCn.manifest -
用 scp/rsync 等方式把 tarball 拷到 downloads.php.net 上的
public_html/(目录不存在则创建并设为0755):scp php-X.Y.ZRCn.tar.* downloads.internal.php.net:~/public_html/完成后文件可通过 downloads.php.net 上
~yourname/路径访问。 -
打 tag 后联系 release-managers@php.net 邮件组以制作 Windows 二进制;完成后在 windows.php.net/qa/ 可获取。示例的"ready for builds"通知邮件:
Subject: PHP 8.1.6RC1 ready for builds Hi, all! Tag: php-8.1.6RC1 Tarballs: https://downloads.php.net/~ramsey/ Manifest: <gist 链接> Cheers, Ben << PASTE FULL MANIFEST CONTENTS HERE >>
4.2 源码印证:makedist 与 gen_verify_stub 到底做了什么
scripts/dev/makedist 是发行包生成的核心脚本,从源码可以确认其完整行为链:
- 要求 GNU tar——若检测到 bsdtar 直接报错退出(scripts/dev/makedist)。tag 命名必须符合
php-X.Y.Z[alpha|beta|RC]或分支PHP-X.Y[.Z]约定; - 用
git archive把指定 tag/分支导出为纯净源码树(scripts/dev/makedist); - 在导出树中执行
./buildconf --force生成configure脚本,使安装包无需 autoconf;再执行 scripts/dev/genfiles 预生成词法/语法分析器文件,使安装不再依赖 bison 与 re2c(scripts/dev/makedist); - 下载 PEAR 的 phar 归档放入包内(scripts/dev/makedist);
- 将包内所有文件的修改/访问时间重置为该 tag 对应提交的日期,保证 tarball 可复现构建(scripts/dev/makedist);
- 依次生成
.tar→tar.gz(gzip -9)→tar.bz2(bzip2 -9)→tar.xz(xz -9),每种都计算 md5 并做完整性校验(scripts/dev/makedist)。
scripts/dev/gen_verify_stub 则负责生成公告所需的校验信息:对三个 tarball 逐一执行 gpg --armor --detach-sign(可用第二个参数指定 -u <GPG_USER> 身份),随后输出每个 tarball 的文件名、SHA256 hash 与完整的 PGP 签名块(scripts/dev/gen_verify_stub)。输出重定向到 php-X.Y.ZRCn.manifest 后,即成为 Gist 与公告邮件的附件内容。
另外,文档在稳定版打包处特别提醒:某些系统的 GNU tar 默认产出带 PAX 头的 POSIX 归档,并非所有应用兼容,打包时应通过环境变量 TAR_OPTIONS='--format=gnu' 强制 GNU 格式。
五、公告非稳定版发布(alpha/beta/RC)
-
切换到
web-php仓库本地克隆,更新include/release-qa.php中$QA_RELEASES数组(文件内有编辑说明)。pre-GA 阶段先不要提交,因为还要附加公告新闻条目,改完跳到第 2 步;post-GA 的 RC 则直接提交推送:git add -p git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.ZRCn" git push upstream master -
仅 pre-GA:用
bin/createNewsEntry工具在web-php中创建简短新闻条目,突出主要变化(如安全修复)。pre-GA 非稳定版只使用 "frontpage" 分类(编号 0,PHP.net 首页新闻):./bin/createNewsEntry # Please type in the title: PHP X.Y.0 Alpha n available for testing # Categories: 0: PHP.net frontpage news [frontpage] ... # Will a picture be accompanying this entry? no提交时把生成的
archive/entries/*.xml一并纳入。撰写文案时的更新提示:qa.php.net已由 php.net 的 release-candidates 页面取代;bugs.php.net已迁至 GitHub issues 表单;自 8.4 起 X.Y.0 只有 4 个 RC。新闻条目必须包含类似 "Please DO NOT use this version in production, it is an early test version." 的警示。post-GA 阶段的非稳定版则不再发新闻条目。 -
等待官网同步(最长约一小时)后再发公告邮件。
-
向以下三个邮件组分别发送独立公告邮件:
- internals@lists.php.net
- php-general@lists.php.net
- php-qa@lists.php.net
邮件中要说明发布物位置、下一个 RC 或最终版的预计日期,并附上打包时
gen_verify_stub生成的 manifest。严禁把三个地址放进同一封邮件的 To/Cc/Bcc——否则用户回复时客户端会把回复群发给所有列表。这些列表的订阅者会在发布后验证自己项目在新版本下的表现,并在 GA 前反馈 bug。 -
alpha、beta 与 pre-GA RC:与社交媒体团队协调,向 Mastodon 上的 PHP 官方账号发布带新闻链接的 toot;也可以自行向 toot-together 仓库提交含 NEWS 摘要的 PR。
六、打包稳定版发布(GA 与补丁版)
-
切换到该发布的补丁级版本分支:
git switch PHP-X.Y.Z该分支应在打包对应 RC 时已创建;若是 PHP-X.Y.0,则分支在最后一个计划内 RC(RC4)时创建。
-
安全发布:若即将到来的发布是安全版本,安全发布经理(SRM)会在周二 UTC 12 点前通知。若尚未配置安全仓库远端:
git remote add security git@github.com:php/php-src-security.gitSRM 会给出一个需要合入补丁级版本分支的安全分支:
git fetch security git merge security/PHP-X.Y.Z-security git push upstream PHP-X.Y.Z无需合并回
PHP-X.Y,SRM 会处理。 -
在补丁级版本分支中运行
./scripts/dev/credits,提交ext/standard下 credits 文件改动(很少触发,只为覆盖 cherry-pick 进来的修复)。 -
从补丁级版本分支切出仅本地发布分支:
git checkout -b php-X.Y.Z-local-release-branch upstream/PHP-X.Y.Z -
在本地发布分支中把
main/php_version.h、Zend/zend.h、configure.ac(可能还有NEWS)里的版本号从X.Y.Z-dev改为X.Y.Z。例如发布 PHP 8.1.8 时,补丁级分支上全部是8.1.8-dev,本地发布分支上全部改为8.1.8。 -
与 4.5 步相同:ZTS/non-ZTS 两种配置编译并
make test,使用正确版本的 Bison 与 re2c。 -
每次构建后核对
./sapi/cli/php -v输出。 -
提交到本地发布分支:
git add -p git commit --gpg-sign=YOURKEYID -m "Update versions for PHP X.Y.Z" -
打签名 tag 并立即推送 tag(稳定版比非稳定版多一步推送):
git tag -s -u YOURKEYID php-X.Y.Z -m "Tag for php-X.Y.Z" git push upstream php-X.Y.Z -
打包:
./scripts/dev/makedist php-X.Y.Z顺带确认 PEAR 文件(Phar)已更新;注意前文提到的
TAR_OPTIONS='--format=gnu'提示。 -
签名生成 manifest:
./scripts/dev/gen_verify_stub X.Y.Z YOURKEYID > php-X.Y.Z.manifest -
用
gh gist create --public php-X.Y.Z.manifest创建公开 Gist(或手动创建)。 -
稳定版 tarball 走 git 仓库分发:切到
web-php-distributions仓库,把 tarball 与签名文件拷入、提交、推送:cd /path/to/repos/php/web-php-distributions mv /path/to/repos/php/php-src/php-X.Y.Z.tar.* . git add php-X.Y.Z.tar.* git commit --gpg-sign=YOURKEYID -m "Add tarballs for php-X.Y.Z" git push upstream master -
打 tag 后联系 release-managers@php.net 制作 Windows 二进制。此通知只发内部邮件组,不发任何公开列表。示例"ready for builds"邮件(tarball 位置写作 web-php-distributions):
Subject: PHP 8.1.6 ready for builds Hi, all! Tag: php-8.1.6 Tarballs: web-php-distributions Manifest: <gist 链接> Cheers, Ben << PASTE FULL MANIFEST CONTENTS HERE >>
七、公告稳定版发布
-
(仅适用于 PHP-X.Y.0 之后的版本)在
web-php中把上一个发布的信息归档进include/releases.inc。例:准备公告 8.2.2 时,为 8.2.1 归档,通常用bin/bumpRelease:./bin/bumpRelease 8 2第一个数是主版本、第二个是次版本,不需要补丁号。若工具失败,可手动把
include/version.inc中上一版本信息拷入include/releases.inc。 -
在
include/version.inc中更新新版本的$data段(X.Y.0 需新建段):version设为完整版本号(如'8.2.1')date设为j M Y格式的发布日(如'5 Jan 2021')- 安全版本在
tags数组中加入'security' sha256数组填入各 tarball 的哈希
-
生成发布页与新闻条目:
./bin/createReleaseEntry -v X.Y.Z -r # 安全发布追加 --security该工具会生成发布文件(如
releases/X_Y_Z.php)与新闻条目(如archive/entries/YYYY-MM-DD-n.xml),同时更新archive/archive.xml。生成的消息是标准模板,可以在此基础上编辑扩充;X.Y.0 的版本公告格式不同,需要参照历史 PHP-8.2 公告提交手工调整。 -
更新对应主版本的 ChangeLog(如
ChangeLog-8.php):若发布的是 X.Y.0,先手工修改ChangeLog-X.php,在$MINOR_VERSIONS中补上新版本及其初始锚点(如 PHP 8.4 加<a id="PHP_8_4"></a>,置于上一版本第一个锚点之前);然后执行:./bin/news2html 'https://github.com/php/php-src/raw/php-X.Y.Z/NEWS' 'X.Y.Z' 'ChangeLog-X.php' -
更新
include/release-qa.php的$QA_RELEASES:其中通常还挂着两周前发布的 RC。当前版本既已 GA,把该 RC 的number属性设为0即可让 RC 从 Release Candidate Builds 页面消失(可顺带删掉 RC tarball 的 sha256,非必需)。 -
审读
web-php全部改动,提交并推送:git add -p git add archive/entries/*.xml releases/*.php git commit --gpg-sign=YOURKEYID -m "Announce PHP X.Y.Z" git push upstream master -
发公告邮件前,先确认网站已同步(最长一小时),逐项核对:
- tarball 可从
www.php.net/distributions/php-X.Y.Z.tar.gz下载 - downloads 页面出现新版本
- 首页显示新闻条目
www.php.net/ChangeLog-8.php等 ChangeLog 页面出现新条目- 存在新版本的发布页(如
www.php.net/releases/X_Y_Z.php) - 对应 RC 是否已从 Release Candidate Builds 页面撤下
- tarball 可从
-
记录 sha256 与 PGP 签名(.asc)——必须写进发布公告邮件。
-
向下列邮件组分别发送独立公告邮件:
- php-announce@lists.php.net
- php-general@lists.php.net
- internals@lists.php.net
公告必须包含打包时生成的 manifest,以及源码、Windows 二进制、ChangeLog 的链接。普通补丁版本要写明 "This is a bugfix release.";安全版本则必须写 "This is a security release."。同样严禁把三个地址塞进同一封邮件的 To/Cc/Bcc。
-
与社交媒体团队协调,为 Mastodon 发布创建待审批的 toot 请求。
八、重发同一版本与 -plN 补丁级发布
极端情况下(如 tarball 损坏)需要重发同一版本:
- 公告之前发现:可以删除 tag,按前述完整打包流程重来。"提前两天打包"的守则正是为这种补救留出的时间窗口。
- 公告之后发现:可以打 tag、打包并发布一个 patch-level(
pl)版本,如8.0.1-pl1;若不紧急或影响面极小,也可以等到下一个发布。
pl 发布步骤:提交新二进制到 web-php-distributions;更新 web-php:/include/version.inc 中 $data['X.Y'](version 如 '8.0.1-pl1'、date、安全版本的 tags、sha256);在 web-php 加一条简短新闻,说明重要修复(安全修复)与升级紧迫性(调用 php bin/createReleaseEntry -v <version> [--security]);提交全部改动(include/version.inc、archive/archive.xml、archive/entries/YYYY-MM-DD-N.xml);等一两小时后向 php-announce@lists.php.net、php-general@lists.php.net、internals@lists.php.net 分别发送与新闻条目内容相近的邮件,且 php-announce@ 必须是完全独立的邮件,避免其他列表的回复误入 php-announce@。
九、软冻结与硬冻结
- 软特性冻结(soft feature freeze):随第一个 beta 发布生效。之所以叫"软",是因为特性仍可在 RM 批准后合入。要在某版本中收录的 RFC,其投票应在第一个 beta 发布前讨论完毕并关票;但实现不必在此前完成——实现可在 RM 批准下于硬冻结前合入。作为对社区的礼貌,RM 应在冻结前 5、4、3、2、1 周向 internals@lists.php.net 发布提醒(间隔可按工作量调整),提醒中附上"最晚可开始投票的 RFC 日期"。
- 硬特性冻结(hard feature freeze):随第一个 RC 生效,准确地说发生在第一个 RC 被打包之时——即第一个 RC 发布日前两天。此后 php-src 不再接受任何新特性;工作重心转向修 bug、补测试与为已收录特性撰写文档。
十、切分新版本分支(branch cut)
当新版本到达第一个 RC 时,从 master 切出 PHP-X.Y 版本分支,让主干重新自由承载不能进入该版本的新特性开发。步骤:
-
在打
X.Y.0RC1tag 前一周,向 internals@ 预告分支即将创建,明确时间点。 -
打
X.Y.0RC1tag 前,在本地创建PHP-X.Y。 -
在
master的分支点上追加一个提交,内容应包含:- 清空
NEWS、UPGRADING、UPGRADING.INTERNALS文件; - 更新 configure.ac、main/php_version.h、Zend/zend.h 与 win32/build/confutils.js 中的版本号;
- 更新
Zend/zend_extensions.h、Zend/zend_modules.h、main/php.h中的 API 版本号; - 在 CONTRIBUTING.md 的分支列表中登记新分支。
- 清空
-
API 版本号约定:
master上的 API 号必须大于新PHP-X.Y分支中的。惯例是取发布星期四的YYYYMMDD作为版本分支的 API 号,星期五的日期作为master的 API 号,从而保证master永远被视为更新。 -
推送新分支与
master改动,提交信息形如 "master is now for PHP 8.3.0-dev"。 -
立即向 internals@ 通报新分支与新的合并顺序。
-
更新
web-php的git.php页面与 wiki 上的 git 工作流文档。为何在第一个 RC 而非特性冻结时切分支?这样有一段"专注让新版本达到 RC/GA 就绪"的窗口期,期间主干只接受小幅改进与 bug 修复,重大改进与新特性一律等待。
-
CI 配置维护在最低支持分支上:在该分支更新相关文件反映切分,再把该提交向上合并 5 次到达
master。当前仓库中确认存在的 CI 相关文件包括 .github/matrix.php(加入新分支、更新 master 的版本)与 .github/scripts/windows/find-target-branch.bat(更新 master 版本)。 -
更新
pushworkflow 的触发分支列表:该文件不需要更新最低支持分支,只需更新新切出的分支以加入新分支、再向上合并一次到master。 -
更新
php/php-sdk-binary-tools在master上nightly与push作业所使用的版本以适配新版本;若切分时新版本 SDK 工具尚不可用,应提交 issue 上报。
十一、准备首个稳定版(PHP X.Y.0)
-
发布第一个 pre-GA RC 时,提醒文档团队(phpdoc@lists.php.net)撰写该版本的迁移指南(migration guide);X.Y.0 公告中要链接它,因此必须在首发稳定版前就位。
-
尽早熟悉稳定版与非稳定版在准备和公告流程上的差异。
-
发布 X.Y.0 前,把各预发布版本的
NEWS条目合并为 X.Y.0 的单一章节,并删除上一版本 NEWS 中已有的条目(即已随上一版本发布的 bug 修复)。可用grep对比找出重复项,例如82/NEWS与83/NEWS分别是 8.2 与 8.3 的 NEWS 时:grep -Fxf 82/NEWS 83/NEWS -
在 X.Y.0 公告日(或稍早),更新 web-php 仓库
.well-known/目录下security.txt的Expires字段,设为下一个 X.Y.0 的预计日期(通常是一年后的 11 月第四个星期四)。依据 RFC 9116 的建议,PHP 以约一年的周期推进该时间戳,让安全研究人员确信他们看到的是最新报告政策。
十二、发布经理的选拔与上任清单
选拔:在下一主/次版本首个 alpha 计划发布日前约三个月(3 月 1 日前后),当前版本分支的 RM 应在 internals@lists.php.net 发起志愿者招募,目标 4 月初确定人选;志愿者应不少于两人,通常由一位资深 RM 与一两位新手组成,必要时投票决定;随后要手把手带新人起步。
新 RM 上任清单(流程文档末尾的完整清单):
-
填写 php.net 的 Git 权限表单获取 PHP 账号(若尚无)。
-
申请加入 GitHub 上 php 组织的 release-managers 团队。
-
订阅全部将用于公告的邮件组(否则无法向列表投递):internals@、php-announce@、php-general@、php-qa@(均位于 lists.php.net)。
-
在 php/infrastructure 项目提交 release manager access 工单,提供 SSH 公钥、@php.net 邮箱、GitHub 账号与首选系统账户名(最好全部一致)。
-
按 infrastructure 仓库的 ServerAccess 文档配置经跳板机加 2FA 访问 downloads.php.net;用 Google Authenticator 生成
.google_authenticator文件,连同上一步工单链接一并发给 systems@php.net。提示:从 @php.net 地址发信需配置自定义 SMTP 服务器(Gmail 可用"其他别名发信")。 -
为 @php.net 地址创建 GPG 密钥并发布:
-
编辑
web-php的include/gpg-keys.inc,在gpg_key_get()函数中为自己的用户名添加case,粘贴gpg --fingerprint的输出;必要时更新gpg_key_get_branches()中$branches数组把自己与所负责分支关联; -
请一位或多位现有 RM 为自己的密钥签名,并上传公钥到密钥服务器:
gpg --keyserver keys.openpgp.org --send-keys YOURKEYID gpg --keyserver keyserver.ubuntu.com --send-keys YOURKEYID -
把自己的公钥加入
web-php-distributions的php-keyring.gpg:先导入现有 keyring 中所有密钥,记录各 RM 的 key ID,再连同自己的 ID 一起导出覆写:cd /path/to/repos/php/web-php-distributions gpg php-keyring.gpg # 列出 keyring 内所有密钥 gpg --import php-keyring.gpg # 导入到本地 keyring gpg --export \ --export-options export-minimal \ --armor \ YOURKEYID <其他 RM 的 KEY IDs>... \ > php-keyring.gpg gpg php-keyring.gpg # 确认所有密钥(含自己)都在 git add -p git commit --gpg-sign=YOURKEYID -m "Update PHP release manager keyring" git push -
web-php-distributions是web-php的子模块,还需更新子模块引用:cd /path/to/repos/php/web-php git submodule update cd distributions # 即 web-php-distributions 子模块 git pull origin master cd .. git add distributions git commit --gpg-sign=YOURKEYID -m "Update php-keyring.gpg in distributions" git push
-
-
本地克隆齐三个仓库:php-src、web-php、web-php-distributions。
十三、关键脚本与文件速查
| 仓库内路径 | 在发布流程中的角色 |
|---|---|
| scripts/dev/makedist | 从 tag/分支导出源码树、生成 configure 与词法语法文件、下载 PEAR、产出 tar.gz/tar.bz2/tar.xz 三种发行包 |
| scripts/dev/gen_verify_stub | 对三个 tarball 做 GPG 分离签名,输出 SHA256 与签名构成的 manifest |
| scripts/dev/credits | 由各扩展 CREDITS 文件重新生成 ext/standard 下的 credits 头文件 |
| scripts/dev/genfiles | 预生成 bison/re2c 产物,被 makedist 调用,使安装包免装 bison 与 re2c |
| main/php_version.h | PHP 版本号单一事实源之一(当前为 8.6.0-dev) |
| Zend/zend.h | ZEND_VERSION(当前为 4.6.0-dev),仅 RC/GA 时随发布更新 |
| configure.ac | AC_INIT 中的版本字符串,须与 php_version.h 一致 |
| win32/build/confutils.js | Windows 构建的版本号来源,分支切分时一并更新 |
| NEWS | 发布变更记录;打包日更新、向上合并时需专用 merge driver |
| .github/matrix.php | CI 分支矩阵,切分版本分支后登记新分支 |
| .github/scripts/windows/find-target-branch.bat | Windows CI 的目标分支判定,切分支后更新 master 版本 |
以上流程均以 docs/release-process.md 为准,其中涉及的 web-php、web-php-distributions、security 仓库与 downloads.php.net 服务器属于 php 组织的基础设施,本文仅按该文档描述其职责与操作步骤。对读者而言,理解这套流程的价值在于:它展示了如何用一个可复现的打包脚本(GNU tar + 时间戳归一化 + 三格式压缩)、一套签名校验链(GPG tag、分离签名、SHA256 manifest、keyring 公钥环)和严格的分支不变式(-dev 版本号、仅 tag 落定),把一个大型解释器项目的版本发布从"手工仪式"变成可审计、可交接的工程流水线。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00