跳转到主要内容

Camptocamp CI通用工具

项目描述

C2C CI utils

发布

C2C CI utils的主要目标是提供命令和工作流程,以拥有以下项目结构:

默认情况下,将稳定分支命名为 <major>.<minor>。默认情况下,将发布版本命名为 <major>.<minor>.<patch>

使用C2C CI utils,您可以从同一存储库发布Python包和Docker镜像。

默认发布选项

  • <major>.<minor> 分支上推送将发布Docker镜像。
  • 创建标签 <major>.<minor>.<patch> 将发布Docker镜像和Python包。
  • 在功能分支(无论其他名称如何)上推送将发布Docker镜像。
  • 删除功能分支将删除Docker镜像。
  • master分支上推送将会发布带有master标签的Docker镜像(发布Python包也是可能的)。
  • master分支的SECURITY.md文件最后一行的版本也会使用latest标签发布,这将尊重配置中的tags
  • master分支的SECURITY.md文件中,我们还可以添加一个Alternate Tag列来使用其他标签发布Docker镜像,这将尊重配置中的tags(仅限Docker)。

Docker镜像发布在Docker Hub和GitHub容器注册库。

您可以在本地以dry-run模式运行发布。

GITHUB_REF=... c2cciutils-publish --dry-run ...

变更日志

默认情况下,通过changelog工作流创建标签时,会在GitHub上创建一个发布,生成变更日志并添加到发布中。

安全

安全由c2cciutils-audit命令与Snyk管理,它将在每个稳定分支上审计项目的依赖项,如果可能,会自动创建一个拉取请求来更新依赖项。

当我们发布Docker镜像时,生成的镜像将由Snyk监控,这意味着Snyk将搜索所有依赖项并将列表发送到Snyk网站进行监控。我们还对镜像进行测试并记录结果(这永远不会导致构建失败)。

检查

C2C CI工具将不再提供检查项目的工具,这已被pre-commit替代,示例项目中提供了一个基本配置。

拉取请求检查

提供了一个工作流来在拉取请求上运行检查,它将运行c2cciutils-pr-checks命令。

  • 检查提交信息和拉取请求标题是否以大写字母开头。
  • 检查提交信息和拉取请求标题中是否存在拼写错误。
  • 如果拉取请求分支名称以[a-zA-Z]+-[0-9]+-开头或以-[a-zA-Z]+-[0-9]+结尾,则在拉取请求中添加一条消息,其中包含JIRA问题的链接。

依赖项

在示例项目中有一个基本的Renovate配置,它将更新项目的依赖项。还有一个工作流来在Renovate拉取请求上添加审阅,以便在需要审阅的仓库上启用自动合并。

回滚

提供了一个工作流来在稳定分支上回滚拉取请求,它将在拉取请求上添加名为backport <destination_branch>的标签时触发。

旧工作流

GitHub将保留所有旧工作流,因此我们需要删除它们,delete-old-workflows-run工作流将删除500天以上的工作流。

工作流

C2cciutils使在项目中拥有这些工作流变得更加容易

  • audit.yaml:检查应用稳定分支中Python和Node依赖项的漏洞
  • auto-review.yaml:自动审阅Renovate拉取请求
  • backport.yaml:触发回滚(与标签一起工作)
  • clean.yaml:清理与已删除功能分支相关的Docker镜像
  • main.yaml:主要工作流,特别是使用c2cciutils-checks命令
  • changelog.yaml:生成变更日志并在GitHub上创建发布
  • delete-old-workflows-run.yaml:删除旧工作流
  • pr-checks.yaml:在拉取请求上运行检查

工作流中使用的所有提供的命令

  • c2cciutils:一些通用工具。
  • c2cciutils-version:创建项目的新的版本。
  • c2cciutils-checks:在代码上运行检查(这些检查不需要任何项目依赖项)。
  • c2cciutils-audit:执行审计,与检查的主要区别在于它可以在同一代码的运行之间更改。
  • c2cciutils-publish:发布项目。
  • c2cciutils-clean:删除Docker Hub上对应的分支被删除后的Docker镜像。

工具

以下工具提供

  • c2cciutils:一些通用工具。
  • c2cciutils-download-applications:下载由Renovate管理的版本的程序,见下文。
  • c2cciutils-docker-logs:显示Docker(compose)中应用程序的日志。
  • c2cciutils-k8s-install:安装k3d/k3s集群,见下文。
  • c2cciutils-k8s-logs:显示k8s集群中应用程序的日志,见下文。
  • c2cciutils-k8s-db:在k8s集群中创建数据库,见下文。
  • c2cciutils-k8s-wait:等待应用程序在集群中正确启动,见下文。
  • c2cciutils-docker-versions-gen:生成Docker包版本文件(ci/dpkg-versions.yaml),见下文。
  • c2cciutils-pin-pipenv:显示存在于Pipenv.lock但不在Pipenv中的所有依赖项,以便能够固定它们。
  • c2cciutils-trigger-image-update:在CI中触发关于图像更新的ArgoCD存储库(在发布时自动完成)。
  • c2cciutils-google-calendar:用于测试日历API的Google凭证并在需要时刷新它们的工具。有关更多信息,请参阅c2cciutils-google-calendar -h

新项目

example-project的内容可以作为一个新项目的良好基础。

新版本

要求:应使用带有version扩展的c2cciutils的正确版本(>=1.6)进行安装。

要创建一个新的小版本,只需运行c2cciutils-version --version=<version>

欢迎运行c2cciutils-version --help以查看其功能。

请注意,它没有创建标签,您应手动完成。

要创建一个补丁版本,您只需创建标签。

机密

在CI中,我们需要以下机密:

  • HAS_SECRETS应设置为'HAS_SECRETS',以避免来自外部拉取请求的错误,Camptocamp组织已全局设置。
  • 需要GOPASS_CI_GITHUB_TOKENCI_GPG_PRIVATE_KEY来初始化gopass密码存储,这些机密存在于Camptocamp组织中,但未在所有项目中共享,因此您应将您的项目添加到共享列表中。

在本地使用,在使用c2cciutils的项目中

安装它:python3 -m pip install --user --requirement ci/requirements.txt 干运行发布:GITHUB_REF=... c2cciutils-publish --dry-run ...

配置

您可以使用c2cciutils --get-config获取当前配置,默认配置取决于您的项目。请注意,它不包含在生成的文档中定义的默认架构和可见性。

您可以使用ci/config.yaml文件覆盖配置。

配置的基础部分包括

  • version:包含一些正则表达式,用于查找版本分支和标签,并将它们转换为应用程序版本。
  • audit:审计配置,见c2cciutils/audit.py获取更多信息。
  • publish:发布配置,见c2cciutils/publish.py获取更多信息。

可以通过将相应的配置部分设置为False来禁用许多操作。

SECURITY.md

SECURITY.md文件应包含存储库的安全策略,特别是支持结束日期。

为了与c2cciutils兼容,它应包含一个包含至少VersionSupported Until列的数组。将包含相关版本的Version列。将包含支持结束日期的Supported Until列,格式为dd/mm/yyyy。它还可以包含以下句子

  • Unsupported:不再受支持 => 无审计,无重建。
  • 尽力而为:支持已结束,它仍然会重建和审查,但可以随时停止而无需任何通知。
  • 待定义:尚未发布或日期将与另一个项目的发布日期相关联(如GeoMapFish)。

参见GitHub 文档

集成开发环境

集成开发环境应该配置为

  • 使用blackisort不带任何参数,
  • 使用editorconfig配置。

VScode

选择一个格式化器

  • CTRL+MAJ+P
  • 使用...格式化文档
  • 配置默认格式化器...
  • 选择格式化器

发布

到pypi

配置如下

versions:
  # List of kinds of versions you want to publish, that can be:
  # rebuild (specified with --type),
  # version_tag, version_branch, feature_branch, feature_tag (for pull request)

如果我们有一个setup.py文件,我们将处于旧模式:当发布时,从参数或GITHUB_REF计算出的版本将放入环境变量VERSION中,因此您应在setup.py中使用它,例如

VERSION = os.environ.get("VERSION", "1.0.0")

我们还考虑使用poetrypoetry-dynamic-versioning来管理版本,并使用poetry-plugin-tweak-dependencies-version来管理依赖项版本。

配置示例

[tool.poetry-dynamic-versioning]
enable = true
vcs = "git"
pattern = "^(?P<base>\\d+(\\.\\d+)*)"
format-jinja = """
{%- if env.get("VERSION_TYPE") == "version_branch" -%}
{{serialize_pep440(bump_version(base, 1 if env.get("IS_MASTER") == "TRUE" else 2), dev=distance)}}
{%- elif distance == 0 -%}
{{serialize_pep440(base)}}
{%- else -%}
{{serialize_pep440(bump_version(base), dev=distance)}}
{%- endif -%}
"""

注意,我们可以访问环境变量VERSIONVERSION_TYPEIS_MASTER

然后默认情况下

  • 标记为1.2.3 => 发布1.2.3
  • 在功能分支上提交仅进行验证
  • 在标记1.3.0后的master分支上提交 => 发布1.4.0.dev1
  • 在标记1.3.0后的1.3分支上提交 => 发布1.3.1.dev1

为了使其在Dockerfile中工作,您应该在poetry阶段具有以下内容

ENV POETRY_DYNAMIC_VERSIONING_BYPASS=dev
RUN poetry export --extras=checks --extras=publish --extras=audit --output=requirements.txt \
    && poetry export --with=dev --output=requirements-dev.txt

并且在run阶段

ARG VERSION=dev
RUN --mount=type=cache,target=/root/.cache \
    POETRY_DYNAMIC_VERSIONING_BYPASS=${VERSION} python3 -m pip install --disable-pip-version-check --no-deps --editable=.

并且在Makefile

VERSION = $(strip $(shell poetry version --short))

.PHONY: build
build: ## Build the Docker images
    docker build --build-arg=VERSION=$(VERSION) --tag=$(GITHUB_REPOSITORY) .

到Docker注册表

配置如下

latest: True
images:
  - # The base name of the image we want to publish
    name:
repository:
  <internal_name>:
    # The fqdn name of the server if not Docker hub
    server:
    # List of kinds of versions you want to publish, that can be: rebuild (specified using --type),
    # version_tag, version_branch, feature_branch, feature_tag (for pull request)
    version:
    # List of tags we want to publish interpreted with `template(version=version)`
    # e.g. if you use `{version}-lite` when you publish the version `1.2.3` the source tag
    # (that should be built by the application build) is `latest-lite`, and it will be published
    # with the tag `1.2.3-lite`.
    tags:
    # If your images are published by different jobs you can separate them in different groups
    # and publish them with `c2cciutils-publish --group=<group>`
    group:

默认情况下,SECURITY.md文件的最后一行将以latest标签发布(docker)。将latest设置为False以禁用它。

使用c2cciutils-clean,在分支删除时将从Docker Hub上移除feature_branch的镜像。

下载应用程序

如果CI主机需要来自GitHub发布或其他URL的某些可执行文件或应用程序,并且它们不由任何依赖项管理器处理,我们提供了一组工具来安装它们,并通过Renovate管理升级。

创建一个应用程序文件(例如,applications.yaml):

# yaml-language-server: $schema=https://raw.githubusercontent.com/camptocamp/c2cciutils/master/c2cciutils/schema-applications.json

# Application from GitHub release
<organization>/<project>:
  get-file-name: <file name present in the release>
  to-file-name: <The file name you want to create in ~/.local/bin>
  finish-command: # The command you want to run after the file is downloaded
    - - chmod # To be executable (usually required)
      - +x
      - <to-file-name>
    - - <to-file-name> # Print the version of the application
      - --version
# Application from GitHub release in a tar file (or tar.gz)
<organization>/<project>:
  get-file-name: <file name present in the release>
  type: tar
  tar-file-name: <The file name available in the tar file>
  to-file-name: <The file name you want to create in ~/.local/bin>
  finish-command: [...] # The command you want to run after the file is downloaded
# Application from an URL
<application reference name>:
  url-pattern: <The URL used to download the application>
  to-file-name: <The file name you want to create in ~/.local/bin>
  finish-command: [...] # The command you want to run after the file is downloaded

在属性url-patternget-file-name中,您可以使用以下变量:

  • {version}:版本文件中存在的应用程序版本。
  • {version_quote}:URL编码的版本。
  • {short_version}:不带v前缀的版本。

applications-versions.yaml文件是应用程序及其版本的映射。

将它们添加到您的Renovate配置中:

  regexManagers: [
    {
      fileMatch: ['^applications-versions.yaml$'],
      matchStrings: [
        '(?<depName>[^\\s]+): (?<currentValue>[^\\s]+) # (?<datasource>[^\\s]+)',
      ],
    },
  ],

现在您需要调用c2cciutils-download-applications --applications-file=applications.yaml --versions-file=applications-version.yaml来在CI主机上安装所需的应用程序,然后再使用它们(已安装的应用程序仅在需要时才重新安装)。

使用Renovate触发新构建而不是旧构建

运行命令c2cciutils-docker-versions-gen camptocamp/image[:tag]以生成一个文件,该文件是ci/dpkg-versions.yaml文件中Debian软件包的包锁定文件。

将其添加到您的renovate配置中

  regexManagers: [
    {
      fileMatch: ['^ci/dpkg-versions.yaml$'],
      matchStrings: [" *(?<depName>[^'\\s]+): '?(?<currentValue>[^'\\s/]*[0-9][^'\\s/]*)'?"],
      datasourceTemplate: 'repology',
      versioningTemplate: 'loose',
    },
  ],

当Debian软件包的新版本可用时

  • Renovate将自动打开一个pull request以更新文件ci/dpkg-versions.yaml
  • 并且持续集成将构建一个包含所有Debian包最新版本的全新Docker镜像。

Kubernetes

c2cciutils为Kubernetes提供了一些命令。

您可以定义如下工作流程

- name: Install k3s/k3d (Kubernetes cluster)
  run: c2cciutils-k8s-install

- name: Create a database to do the tests
  run: c2cciutils-k8s-db --script=<my_script>.sql

- name: Install the application in the Kubernetes cluster
  run: kubectl apply -f <my_application>.yaml

- name: Wait that the application is ready
  run: c2cciutils-k8s-wait
- name: Print the application status and logs
  run: c2cciutils-k8s-logs
  if: always()

- name: Uninstall the application
  run: kubectl delete -f <my_application>.yaml || true

- name: Cleanup the database
  run: c2cciutils-k8s-db --cleanup

c2cciutils-k8s-install可以在ci/config.yaml文件中进行配置,在k8s/k3d/install-commands部分,默认为

- - k3d
    cluster
    create
    test-cluster
    --no-lb
    --no-rollback

另请参阅:K3d集群创建文档

c2cciutils-k8s-db可以在ci/config.yaml文件中进行配置,在k8s/db/chart-options部分,默认为

persistence.enabled: 'false'
tls.enabled: 'true'
tls.autoGenerated: 'true'
postgresqlPassword: mySuperTestingPassword
volumePermissions.enabled: 'true'

另请参阅:参数文档

贡献

安装pre-commit钩子

pip install pre-commit
pre-commit install --allow-missing-config

支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面