symfony github actions流水线需分离测试与翻译任务:测试用php bin/console test+phpunit配置校验,翻译用translation:pull/push配合secrets注入token、显式指定provider,并启用intl扩展;缓存仅限composer和vendor,禁用var/cache。

直接上手就能跑通的 Symfony GitHub Actions 流水线,核心是分清「测试」和「翻译管理」两类任务——它们用的命令、触发时机、失败容忍度都不同,混在一起配置反而容易出错。
php bin/console test 命令不生效?先确认 PHPUnit 配置路径
Symfony 项目默认不自带 phpunit.xml.dist,但 symfony/test-pack 安装后会生成。如果运行 ./vendor/bin/phpunit 报错 “No tests found”,大概率是 tests/ 目录没被扫描到,或配置里 <testsuites></testsuites> 指向了错误路径。
- 检查
phpunit.xml.dist中的<testsuites></testsuites>是否包含<directory>tests</directory> - 确保
tests/下有至少一个以Test.php结尾的类,且继承TestCase - 若用 Symfony 6.4+,
bin/phpunit是推荐入口,它会自动加载phpunit.xml.dist;别硬写vendor/bin/phpunit - CI 中建议显式加
--configuration=phpunit.xml.dist,避免因工作目录切换导致配置未加载
translation:pull/push 失败常见于环境变量缺失
translation:pull 和 translation:push 命令依赖外部服务(如 Lokalise、Crowdin),它们不会在本地报错,而是静默跳过或返回空结果——除非你打开 --verbose 或检查退出码。
- 必须通过
secrets注入服务 Token:LOKALISE_API_TOKEN或CROWDIN_PROJECT_ID,不能写死在 YAML 里 - 命令需配合
--provider=lokalise显式指定,否则默认用file提供商,什么都不会拉 - 执行前加一步验证:
php bin/console translation:lint --format=json translations/,能提前发现 XLIFF 格式错误,避免 push 后被服务端拒收 - 注意:push 前务必
git checkout main && git pull,否则可能覆盖他人刚提交的翻译
PHP 版本与扩展不是“装了就行”,intl 必须启用
symfony/translation 在解析 XLIFF 或处理复数规则时强依赖 intl 扩展。GitHub Actions 默认 PHP 环境常漏掉它,导致 translation:extract 报错 “Class IntlRuleBasedBreakIterator not found”。
- 用
shivammathur/setup-php@v2时,extensions参数必须显式列出:intl, mbstring, xml - PHP 8.3+ 的
intl在 Alpine 镜像中需额外安装icu-dev,但 GitHub Actions 的 Ubuntu runner 不需要 - 别信 “PHP >= 8.2” 就够了——
intl在 PHP 8.2 Ubuntu 包里默认关闭,必须手动启用 - 快速验证:
php -m | grep intl,没输出就说明没启
缓存 composer install 但别缓存 var/cache
CI 中反复 composer install 很慢,加缓存能省 40 秒以上;但缓存 var/cache 可能导致测试用旧容器、翻译提取漏字符串,属于典型“省小钱丢大功能”。
- 用
actions/cache@v3缓存~/.composer/cache和vendor/,key 建议含composer.lockhash - 每次测试前加
rm -rf var/cache/*,强制重建容器,避免 DI 编译器读取过期定义 - 翻译提取命令(
translation:extract)必须在cache restore之后、composer install之前执行,否则新字符串进不了 catalogue - 如果用了
symfony/framework-bundle,APP_ENV=test必须设在所有步骤之前,否则 cache 清理逻辑不生效
最易被忽略的是:translation:pull 和 translation:push 的权限边界。它们不该放在同一个 job 里自动提交——pull 应该只读,push 才该有写权限;否则某次 CI 失败后误推脏数据,整个翻译库就乱了。











