README(659 行 → 176 行):只保留「这是什么」与「怎么部署/维护」——快速开始、首次安装、 升级(注明不需要 --force-recreate)、回滚(给真实存在的 sha-<commit> 标签)、备份与恢复 (整目录 tar,并说明 SQLite 开了 WAL 会短暂出现 -wal/-shm)、常见配置(端口/证书路径/ APACHE_* 六个变量与实际默认值)、许可与致谢。不再记录任何修复史或差异逐条。 所有具体值(镜像名、容器名、端口、卷路径、WEB_PORT/HTTPS_PORT、MPM 默认值、PHP/Laravel 版本、回滚标签)都对着源码与实机逐条核过。 构建与 CI: - .dockerignore 补 src/storage/logs/*(+ 保留 .gitignore 占位):本机开发日志会被 COPY src/ 带进镜像(含本机绝对路径与错误栈)。用一份 moby 语义 matcher 验过排除生效、 且不影响 fontawesome 字体等构建必需品。 - update-composer-lock.yaml:两处 curl … | php 改成与 Dockerfile 同款「先落盘 → 官方 installer.sig → 校验 96 位 hex → sha384sum -c - → 再执行 → 删临时文件」(哈希不写死); 注释里的 9.52.17 与「5 条公告」校正为 9.52.22 / 4 条(OSV 实查)。 - build-image.yaml:扩展自证那段的结论文案改成与实际一致(硬断言只有 pdo_sqlite, 其余仅打印供人工比对)——sqlite3 对本站不是必需,钉死它会在无害变动时误红。 - tools/vendor-upstream.sh:去掉不存在的 test/run.sh,改为 cd test && npm test。
132 lines
7.5 KiB
YAML
132 lines
7.5 KiB
YAML
name: Update composer.lock (targeted)
|
||
|
||
# 用途:本机/CI 里没有 php,composer.lock 只能在容器里重算。
|
||
# 这个 workflow 只做一件事:在指定 PHP 版本里对**指定包**跑 composer update,
|
||
# 把新的 composer.lock 作为 artifact 上传(**不自动提交**,人工看过再 commit)。
|
||
# 这样"升依赖"这件事不会意外改动我们没打算动的包。
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
packages:
|
||
description: '要升级的包(空格分隔,传给 composer update)'
|
||
required: true
|
||
default: 'laravel/framework symfony/* league/commonmark guzzlehttp/guzzle guzzlehttp/psr7 phpseclib/phpseclib aws/aws-sdk-php'
|
||
php_version:
|
||
description: 'PHP 版本(用于解析平台约束)'
|
||
required: true
|
||
default: '8.3'
|
||
ignore_advisory_policy:
|
||
description: '是否显式关闭 Composer 的「拒绝带未修公告的版本」策略(Laravel 9 整线被公告覆盖,不关无法解析)'
|
||
required: true
|
||
default: 'true'
|
||
type: choice
|
||
options:
|
||
- 'true'
|
||
- 'false'
|
||
|
||
permissions:
|
||
contents: read
|
||
|
||
concurrency:
|
||
group: update-lock-${{ github.ref }}
|
||
cancel-in-progress: false
|
||
|
||
jobs:
|
||
lock:
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 30
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
|
||
|
||
- name: composer update(结果只上传,不自动提交)
|
||
env:
|
||
PACKAGES: ${{ inputs.packages }}
|
||
PHPVER: ${{ inputs.php_version }}
|
||
run: |
|
||
set -euo pipefail
|
||
echo "目标包:$PACKAGES"
|
||
echo "解析用 PHP:$PHPVER"
|
||
docker run --rm -v "$PWD/src:/app" -w /app \
|
||
-e PACKAGES="$PACKAGES" \
|
||
-e PHPVER="$PHPVER" \
|
||
-e ADVPOL="${{ inputs.ignore_advisory_policy }}" \
|
||
"php:${PHPVER}-cli" bash -lc '
|
||
set -euo pipefail
|
||
apt-get update -qq >/dev/null
|
||
apt-get install -yqq git unzip >/dev/null
|
||
# F16:composer 安装器**先校验、再执行**(与仓库 Dockerfile 同一套做法)——
|
||
# 不能 curl | php 直接把网上的字节喂给解释器。预期 sha384 取自
|
||
# https://composer.github.io/installer.sig,与 https://getcomposer.org/installer
|
||
# 分属两个域名,单点被投毒时另一侧能拦住;哈希故意不写死(installer 随每个
|
||
# composer 版本重新生成,写死会让 composer 一发新版 CI 就红)。验不过即失败。
|
||
curl -fsSL -o /tmp/composer-setup.php https://getcomposer.org/installer
|
||
curl -fsSL -o /tmp/composer-setup.sig https://composer.github.io/installer.sig
|
||
grep -Eq "^[0-9a-f]{96}$" /tmp/composer-setup.sig
|
||
printf "%s %s\n" "$(cat /tmp/composer-setup.sig)" /tmp/composer-setup.php | sha384sum -c -
|
||
php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||
rm -f /tmp/composer-setup.php /tmp/composer-setup.sig
|
||
composer --version
|
||
if [ "${ADVPOL:-true}" = "true" ]; then
|
||
echo "==================== 注意 ===================="
|
||
echo "显式关闭 Composer 的「拒绝带未修公告版本」策略。"
|
||
echo "原因:整条 laravel/framework 9.x 线被 4 条公告覆盖(PKSA-*),不关掉就无法重新解析任何依赖。"
|
||
echo "这**不新增风险**:线上本来就跑在这条线上(9.52.22),只是把既有事实写明。"
|
||
echo "根治之道是升级 Laravel 大版本(另立项)。"
|
||
echo "=============================================="
|
||
# 必须用 --global:写进容器内的 ~/.composer/config.json,不碰仓库里的 composer.json
|
||
# (否则 lock 的 content-hash 会与 composer.json 不一致,镜像构建期的 composer install 会失败)
|
||
composer config --global policy.advisories.block false
|
||
fi
|
||
# 诊断:先说清楚"为什么当前依赖集上不了这个 PHP 版本"
|
||
echo "=== composer why-not php $PHPVER(谁把版本卡住了) ==="
|
||
composer why-not "php" "$PHPVER" --no-interaction || true
|
||
echo "=== 当前 lock 的平台要求 ==="
|
||
composer check-platform-reqs --no-interaction || true
|
||
# ext-ftp 只是这个裸容器里没有(生产镜像有),不影响求解
|
||
# --with-all-dependencies:允许连带升级这些包的下级依赖(否则常被旧约束卡住)
|
||
# --prefer-stable 必须加:Lsky 的 composer.json 是 minimum-stability: dev,
|
||
# 不钉版本时求解器会把 laravel/framework 选成 9.x-dev(开发分支!),
|
||
# 而那个分支把 symfony 约束放宽到 ^7.0,会拖进一堆 Symfony 7 组件。
|
||
composer update --with-all-dependencies --no-interaction --no-progress --prefer-stable \
|
||
--ignore-platform-req=ext-ftp $PACKAGES
|
||
|
||
# 升级后的这套依赖,还能不能在更低的 PHP 上装?(能 → 回退 PHP 版本只需改一个 ARG)
|
||
echo "=== 这套新依赖在 PHP 8.2 上还装得动吗(无输出=可以) ==="
|
||
composer why-not php 8.2.0 --no-interaction 2>/dev/null || true
|
||
composer prohibits php 8.2.0 --no-interaction 2>/dev/null || true
|
||
composer validate --no-check-publish
|
||
echo "=== composer audit(升级后的已知漏洞,仅供参考) ==="
|
||
composer audit --no-interaction || true
|
||
'
|
||
echo "=== 锁与 composer.json 是否一致(必须 OK,否则镜像构建会报 lock file is not up to date)==="
|
||
git status --short -- src/composer.json
|
||
docker run --rm -v "$PWD/src:/app" -w /app "php:${PHPVER}-cli" bash -lc '
|
||
set -e
|
||
# 同样先校验再执行(F16,与上面那步、以及仓库 Dockerfile 保持一致)
|
||
curl -fsSL -o /tmp/composer-setup.php https://getcomposer.org/installer
|
||
curl -fsSL -o /tmp/composer-setup.sig https://composer.github.io/installer.sig
|
||
grep -Eq "^[0-9a-f]{96}$" /tmp/composer-setup.sig
|
||
printf "%s %s\n" "$(cat /tmp/composer-setup.sig)" /tmp/composer-setup.php | sha384sum -c -
|
||
php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||
rm -f /tmp/composer-setup.php /tmp/composer-setup.sig
|
||
composer validate --no-check-publish --no-interaction 2>&1 | tail -4
|
||
'
|
||
|
||
echo "=== composer.lock 的改动规模 ==="
|
||
git diff --stat -- src/composer.lock
|
||
echo "=== 版本变化(升级前后对照) ==="
|
||
git diff -U0 -- src/composer.lock | grep -E '^[+-]\s+"version"' | head -60 || true
|
||
|
||
- name: Upload composer.lock
|
||
# 钉到 actions/upload-artifact v7.0.1 的 commit SHA(不是可移动的 tag)。
|
||
# 旧 pin ea165f8d…(v4)的 action.yml 是 runs.using: node20 → 会打 Node 20 弃用警告;
|
||
# v7.0.1 是 node24。name / path / if-no-files-found 三个输入在 v7 里都存在且语义不变
|
||
# (已核该 SHA 的 action.yml),with: 段无需改动。
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: composer-lock-php${{ inputs.php_version }}
|
||
path: src/composer.lock
|
||
if-no-files-found: error
|