英文:
gitlab: How to include build artifacts when adding a package via ci pipeline to the composer package registry
问题
以下是已翻译的内容:
我添加了一个非常基本的流程来将我的软件包导出到私有的GitLab软件包注册表。使用.gitattributes文件来隐藏不应包含在存档中的文件是可行的,但我如何预先构建一些构件(例如将scss文件转换为css文件),并将它们包含在存档中呢?这些构件被.gitignore排除,因为它们是构件。
这是我当前流程的外观:
stages:
- release
stable-release:
stage: release
script:
- apk add curl
- 'curl --header "Job-Token: $CI_JOB_TOKEN" --data tag=$CI_COMMIT_TAG "${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer"'
rules:
- if: '$CI_COMMIT_TAG'
例如,我如何在软件包根目录中创建一个文件(假设是“test.txt”),并将该文件包含在软件包注册表中呢?
我尝试了以下方法,但test.txt文件未包含在软件包中,只能在GitLab界面中找到它:
stable-release:
script:
- ...
- echo "foo" > test.txt
- ...
artifacts:
paths:
- test.txt
请注意,这个问题涉及到如何在GitLab CI/CD流程中将构建产物包含在软件包注册表中,具体的实现可能会根据您的项目和环境而有所不同。
英文:
I added a very basic pipeline to export my packages to a private gitlab package registry. Using the .gitattributes file to mask files, that should not be contained in the archive works fine but how could i prebuild some artifacts (for example scss to css) and have them included in the artifact? Those artifacts are excluded by the gitignore because - well they are artifacts.
This is what my pipeline looks at the moment:
stages:
- release
stable-release:
stage: release
script:
- apk add curl
- 'curl --header "Job-Token: $CI_JOB_TOKEN" --data tag=$CI_COMMIT_TAG "${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer"'
rules:
- if: '$CI_COMMIT_TAG'
How could i for example create a file in the package root (let's say "test.txt") and have that file included in the package registry?
I tried the following but the test.txt file is not included in the package, its only available in the gitlab ui.
stable-release:
script:
- ...
- echo "foo" > test.txt
- ...
artifacts:
paths:
- test.txt
答案1
得分: 1
TLDR:在构建发布修订版后创建软件包版本标签,然后让它触发您的发布阶段,该阶段会触发API HTTP请求,通知您项目的Gitlab Composer软件包注册表有一个新的发布。
工作原理
Composer有两种类型的分发:
- 源码(source)
- 打包文件(dist)
对于每个软件包和版本,都可以有这两种类型。
在Composer软件包注册表中,收集可用软件包的元数据,并且软件包的实际内容由统一资源定位符(URL)引用,以及额外的引用和可选的哈希值(shasum)。
引用通常表示git存储库中的修订版,URL引用了git存储库本身。
当将软件包安装到COMPOSER_VENDOR_DIR时,Composer实际上是克隆了该git存储库并在该修订版上进行了检出。然后,从中的文件被复制到由软件包名称指示的供应商文件夹子目录中。(这是简化的,涉及缓存和一些其他检查,但在这种情况下应该足够了。)
因此,对于您的Gitlab项目的私有Composer软件包注册表,它与Composer之间的接口是git存储库。
如果您希望软件包中包含尚未包含在项目git存储库修订版中的文件,那么它们将不会成为软件包的一部分。正如您已经注意到的,您只能通过_export-ignore_ Git属性来"移除"文件(在技术上,只有_dist_软件包受到影响,而不是_source_)。
如何添加文件
现在,为了添加尚未受版本控制的文件,例如在CI流水线运行时创建的文件,因此您需要将所有这些_额外的_文件添加到存储库并创建一个新的引用。 (请参阅git-add(1)和git-commit(1)。)
然后,使用Composer使用的版本标签对该新引用进行标记。 (请参阅git-tag(1)。)
版本标签非常重要,因为不仅您,而且Composer和Gitlab也会在关联主要.次要.修补版本与您的软件包时出现问题,通常由Composer隐式强制执行的语义版本控制约束引起问题。
由于您正在进行自动化构建,因此我还建议对于该发布提交,您更新//project/composer.json#/version
,将其设置为与标签相同的版本。这不是必需的,仅仅拥有标签就足够了,但它允许在根composer.json中保留版本,以备任何zip或tar.gz包归档内的情况。而且,在进行自动化构建时,您不会忘记更新它(因为它是构建的结果,类似于可能留在归档中的COMMIT
和/或VERSION
文件)。
构建/CI修订版与Composer软件包版本
当我们查看Composer软件包注册表时,与查看作为Composer软件包开发的PHP项目的Git存储库时,情况基本相同但又有所不同。
尽管将后者转变为Composer存储库软件包信息很简单,但如果您需要构建实际软件包(需要在项目中定义了构建过程的情况下,例如,您希望添加文件的情况),就会注意到项目的发布只能在构建之后才能标记适当的修订版。
这是因为我们使用版本控制软件并且有一个中央存储库。
因此,在CI流水线中通常拥有的不是标签,而是构建修订版(通常是CI_COMMIT
),然后运行构建(传统上创建构建工件),并且Composer要求您将构建结果添加到项目存储库中,否则Gitlab将看不到它。
- 检出CI提交
- 运行构建
- 以git修订版(提交)的形式捕获构建结果,其中包含Composer软件包的所有相关文件。
- 对该发布修订版进行标记
然后,对于您拥有的发布阶段,它会"只是工作"™,因为Gitlab将使用该标签正确引用Composer软件包的内容(以及composer.json中的元数据)。
如果您现在保持构建修订版和发布修订版之间的关系(例如,您可以在标签消息中指定构建修订版,还可以在构建运行中指定等等),那么一切都会井然有序,您将永远不需要构建两次修订版。实际上,除非您实践可再现构建,否则不应该构建两次。但这是一个不同的话题。
英文:
TLDR: Create the package version tag after you've build the release revision, then let it trigger your release stage that is firing the API HTTP request to notify the Gitlab Composer package registry of your project that there is a new release.
How it Works
Composer has two kind of distributions:
- source
- dist
That is for each package and version, it can have those two.
In a Composer package registry the metadata of the available packages is collected, and the actual contents of the package is referenced by an Uniform Resource Locator (URL) and additional reference and optionally a hash (shasum).
The reference commonly denotes a revision in a git repository and the url is referencing the git repository itself.
When installing a package into the COMPOSER_VENDOR_DIR, Composer is effectively cloning that git repository and checking it out at that revision. Then the files from therein are copied into the vendor folder subdirectory denoted by the package name. (this is shortened, cache is involved and some more checks are done, but it should suffice in this case.)
So for the private Composer Package Registry for your Gitlab project, the interface between it and Composer is the git repository.
If you want to have files inside the package, that are not yet part of the revision in your projects git repository, they will not become part of the package. As you already noticed, you can only "remove" files with the export-ignore Git Attribute (and technically only dist packages are affected by that, not source).
How to add files
Now to add files not yet under version control, for example those you have created during a build at time of the CI Pipeline run, it is therefore necessary you add all those additional files to the repository and create a new reference out of it. (see git-add(1) and git-commit(1).)
Then tag that new reference with the version tag as Composer is using it. (see git-tag(1).)
The version tag is important, as not only you but also Composer and Gitlab will have a problem to associate a MARJOR . MINOR . PATCH version with your package, which you normally want due to Semantic Versioning constraints implicitly enforced by Composer.
As you're doing automated builds, I'd also suggest for that release-commit, you update //project/composer.json#/version
, setting it to the same version as the tag. This is not a requirement, having the tag alone would suffice, however it allows to keep the version within any zip or tar.gz package archives inside the roots composer.json. And when doing automated builds, you don't risk to forget updating it (as it is a result of the build, similar to a COMMIT
and/or VERSION
file you may leave in archives).
Build/CI Revision vs. Composer Package Version
When we look at a Composer Package Registry this is same same but different as when we look at the Git repository of a PHP project that is developed as a Composer Package.
While it is straight forward to turn the later into Composer Repository Package Information, you may notice if you need to build the actual package (need either in the sense that you can but also do, e.g. you have a defined build process in your project), like the scenario where you want to add files, the releases of a project can only be tagged with the appropriate revision after it has been build.
This is due to the fact that we are using version control software and are having a central repository.
So what you commonly have in a CI Pipeline, like in Gitlab, is not the tag but the build revision (IIRC CI_COMMIT
), then you run the build (traditionally creating the build artifact) and the Composer requires you to add the build result into the projects repository as otherwise Gitlab won't see it.
- checkout the CI Commit
- run the build
- capture the build result in form of a git revision (commit) containing all
the relevant files of the Composer package. - tag that release revision
Then for the release stage you have, it just works<sup>(tm)</sup> as Gitlab with that tag will see the right reference to the Composer packages' contents (and metadata in composer.json).
If you now keep the relation between build revision and release revision (e.g. you can specify the build revision in the tags message, also the build run etc.) everything is nicely arranged und you'll never need to build a revision twice. In fact you shouldn't unless you practice reproducible builds, but that's a different topic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论