如何通过GitLab CI安装Composer依赖并将vendor目录纳入发布包
问题场景
需要在GitLab CI流水线中自动生成PHP项目的/vendor/目录,无需在代码仓库中提交维护该目录。实际执行Pipeline时,依赖安装作业显示成功,vendor/目录也作为作业工件正常上传,但最终生成的Release ZIP发布包中不包含/vendor/目录,压缩包内容和仓库源码完全一致。
流水线执行日志
Running with gitlab-runner 14.8.2 (c6e7e194) on k8s-gitlab-runner hfVw4xNF Preparing the "kubernetes" executor 00:00 Using Kubernetes namespace: gitlab-runner Using Kubernetes executor with image composer:2 ... Using attach strategy to execute scripts... Preparing environment 00:09 Waiting for pod gitlab-runner/runner-hfvw4xnf-project-520-concurrent-0sn79m to be running, status is Pending Waiting for pod gitlab-runner/runner-hfvw4xnf-project-520-concurrent-0sn79m to be running, status is Pending ContainersNotInitialized: "containers with incomplete status: [init-permissions]" ContainersNotReady: "containers with unready status: [build helper]" ContainersNotReady: "containers with unready status: [build helper]" Waiting for pod gitlab-runner/runner-hfvw4xnf-project-520-concurrent-0sn79m to be running, status is Pending ContainersNotReady: "containers with unready status: [build helper]" ContainersNotReady: "containers with unready status: [build helper]" Running on runner-hfvw4xnf-project-520-concurrent-0sn79m via gitlab-runner-gitlab-runner-6cd96486f4-s62w7... Getting source from Git repository 00:00 Fetching changes with git depth set to 20... Initialized empty Git repository in /builds/saligzhanov.i/admin-changelog-md/.git/ Created fresh repository. Checking out b5018ce4 as make-vendor-on-ci... Skipping Git submodules setup Executing "step_script" stage of the job script 00:02 $ composer config -g cache-dir "$(pwd)/.composer-cache" $ composer install --ignore-platform-reqs --no-dev --optimize-autoloader --no-ansi --no-interaction --no-progress Installing dependencies from lock file Verifying lock file contents can be installed on current platform. Package operations: 1 install, 0 updates, 0 removals - Downloading erusev/parsedown (1.7.4) - Installing erusev/parsedown (1.7.4): Extracting archive Generating optimized autoload files Uploading artifacts for successful job 00:00 Uploading artifacts... vendor/: found 19 matching files and directories Uploading artifacts as "archive" to coordinator... 201 Created id=910700 responseStatus=201 Created token=2nEedKzr Cleaning up project directory and file based variables 00:01 Job succeeded
当前使用的.gitlab-ci.yml配置
image: composer:2 composer_install: stage: deploy before_script: - composer config -g cache-dir "$(pwd)/.composer-cache" script: - composer install --ignore-platform-reqs --no-dev --optimize-autoloader --no-ansi --no-interaction --no-progress artifacts: paths: - vendor/
问题原因
GitLab默认附带在Release下的源码ZIP包,是直接基于Git仓库对应标签的提交快照生成的,只会包含提交到仓库内的文件,不会自动合并CI过程中生成的工件(包括安装生成的vendor/目录)。当前配置仅将vendor/作为普通作业工件上传,没有关联到Release资产的构建流程,自然不会出现在默认源码包中。
解决方案
核心逻辑是放弃使用GitLab自动生成的源码包,在CI流程中手动打包包含vendor/目录的完整发布压缩包,再将这个手动生成的压缩包作为Release资产上传。
- 拆分流水线阶段,分离构建和发布流程
- 在构建阶段完成Composer依赖安装后,手动执行压缩命令打包包含
vendor/的完整项目文件 - 在发布阶段将手动生成的压缩包作为Release关联资产上传
可用配置参考
image: composer:2 # 定义流水线阶段 stages: - build - release # 构建阶段:安装依赖+打包完整发布包 build_package: stage: build # 配置composer缓存加速后续构建 cache: paths: - .composer-cache/ before_script: - composer config -g cache-dir "$(pwd)/.composer-cache" # 打包需要zip依赖,composer镜像默认不带,先安装 - apt-get update && apt-get install -y zip script: # 安装生产环境依赖 - composer install --ignore-platform-reqs --no-dev --optimize-autoloader --no-ansi --no-interaction --no-progress # 手动打包,排除git目录、缓存、CI配置等不需要纳入发布包的文件 - zip -r release-${CI_COMMIT_TAG}.zip . -x "*.git/*" ".composer-cache/*" ".gitlab-ci.yml" artifacts: paths: - vendor/ - release-${CI_COMMIT_TAG}.zip # 发布阶段:上传发布包到Release资产 create_release: stage: release image: registry.gitlab.com/gitlab-org/release-cli:latest # 仅在打标签触发流水线时执行发布 rules: - if: $CI_COMMIT_TAG script: - echo "开始发布版本 ${CI_COMMIT_TAG}" release: tag_name: ${CI_COMMIT_TAG} name: "Release ${CI_COMMIT_TAG}" assets: links: - name: 完整发布包(含vendor依赖) url: "${CI_PROJECT_URL}/-/jobs/${CI_JOB_ID}/artifacts/file/release-${CI_COMMIT_TAG}.zip"
配置说明
- 构建阶段提前安装
zip工具,官方composer镜像默认没有携带zip命令,会导致打包失败 - 打包时的排除规则可以根据项目实际情况调整,避免把测试文件、本地配置、CI相关文件打进发布包
- 发布作业使用GitLab官方提供的release-cli镜像,不需要额外配置认证,流水线默认自带的CI_TOKEN即可完成上传
- 只有给项目打Git标签触发的流水线,才会执行发布作业生成带依赖的正式发布包
内容的提问来源于stack exchange,提问作者LeTraceurSnork
相关产品推荐
相关产品推荐

