如何在执行composer update后自动获取私有Composer包的版本更新提交信息?
解决方案:自动获取Composer包更新的Commit变更日志
完全可以实现!核心思路是利用Composer的脚本钩子,结合Git命令来对比更新前后的版本,自动提取并展示这段区间的Commit信息,包括你标记的[action required]提示。下面是具体的实现步骤:
1. 利用Composer钩子记录版本变化
Composer提供了pre-update-cmd和post-update-cmd两个钩子,分别在更新前和更新后执行脚本。我们可以用前者记录更新前的bundle版本,后者用来对比新版本并提取变更日志。
方法一:PHP脚本实现(跨平台通用)
第一步:创建版本对比脚本
在你的项目根目录下新建scripts/post-update-mybundle-changelog.php文件,内容如下:
<?php // 读取更新前保存的旧版本 $oldVersion = getenv('MYBUNDLE_OLD_VERSION'); if (!$oldVersion) { echo "⚠️ 无法获取me/mybundle的历史版本\n"; exit(0); } // 获取更新后的新版本 exec('composer show me/mybundle --format=json', $output); $packageInfo = json_decode(implode("\n", $output), true); $newVersion = $packageInfo['versions'][0]['version']; // 统一版本的v前缀(如果你的Git Tag是v开头的话) if (!str_starts_with($oldVersion, 'v')) { $oldVersion = "v{$oldVersion}"; } if (!str_starts_with($newVersion, 'v')) { $newVersion = "v{$newVersion}"; } // 提取两个版本之间的Commit信息 $bundlePath = __DIR__ . '/../vendor/me/mybundle'; exec("git -C {$bundlePath} log --oneline {$oldVersion}..{$newVersion}", $commits); if (empty($commits)) { echo "\n✅ me/mybundle从{$oldVersion}到{$newVersion}无变更\n"; exit(0); } // 格式化输出变更日志 echo "\n📋 me/mybundle版本变更({$oldVersion} → {$newVersion}):\n"; foreach ($commits as $commit) { echo "- {$commit}\n"; // 高亮显示需要手动操作的提示 if (str_contains($commit, '[action required]')) { echo " ⚠️ *重要操作提示*: {$commit}\n"; } } echo "\n"; ?>
第二步:配置Composer钩子
在项目根目录的composer.json中添加脚本配置:
{ "scripts": { "pre-update-cmd": [ "@php -r '$version = shell_exec(\"composer show me/mybundle --format=json\"); $info = json_decode($version, true); putenv(\"MYBUNDLE_OLD_VERSION=\" . $info[\"versions\"][0][\"version\"]);'" ], "post-update-cmd": [ "@php scripts/post-update-mybundle-changelog.php" ] } }
方法二:Shell脚本实现(适合Linux/macOS环境)
如果你习惯用Shell脚本,也可以这样做:
第一步:创建Shell脚本
新建scripts/post-update-mybundle-changelog.sh,添加执行权限(chmod +x scripts/post-update-mybundle-changelog.sh):
#!/bin/bash # 读取更新前的旧版本 OLD_VERSION=$(cat .mybundle_old_version) rm .mybundle_old_version # 获取更新后的新版本 NEW_VERSION=$(composer show me/mybundle --format=json | jq -r '.versions[0].version') # 统一v前缀 [[ ! $OLD_VERSION == v* ]] && OLD_VERSION="v$OLD_VERSION" [[ ! $NEW_VERSION == v* ]] && NEW_VERSION="v$NEW_VERSION" # 输出变更日志 echo -e "\n📋 me/mybundle版本变更($OLD_VERSION → $NEW_VERSION):" git -C vendor/me/mybundle log --oneline "$OLD_VERSION..$NEW_VERSION" | while read -r commit; do echo "- $commit" if [[ $commit == *"[action required]"* ]]; then echo " ⚠️ *重要操作提示*: $commit" fi done echo -e "\n"
第二步:配置Composer钩子
{ "scripts": { "pre-update-cmd": [ "composer show me/mybundle --format=json | jq -r '.versions[0].version' > .mybundle_old_version" ], "post-update-cmd": [ "./scripts/post-update-mybundle-changelog.sh" ] } }
2. 关键注意事项
- 确保你的私有包是通过Git仓库安装的(Composer默认会克隆Git仓库,而不是下载压缩包),否则无法在
vendor目录下使用Git命令。 - 如果你的Git Tag没有
v前缀,记得删除脚本中添加v的逻辑。 - 若使用Shell脚本,需要确保系统安装了
jq工具(用来解析JSON),可以通过包管理器安装。 - 如果你希望所有使用该bundle的项目都自动生效,可以把脚本和钩子配置放到bundle自己的
composer.json中(注意脚本路径要相对于bundle目录)。
现在,当你执行composer update me/mybundle后,终端会自动输出从旧版本到新版本的所有Commit信息,并且高亮显示需要手动操作的提示,完全符合你的需求!
内容的提问来源于stack exchange,提问作者ptmr.io
相关产品推荐
相关产品推荐

