如何在不重新构建项目的情况下部署已经存在的 Gitlab 版本?

How to Deploy an already existing Gitlab release without building the project again?

我有一个整洁的 Gitlab 管道,它由 5 个阶段和 >10 个作业组成,用于在多个环境中测试、构建、发布和部署结果。

有时,我们需要将一个环境回滚到旧版本。使用 Jenkins,这可以通过额外的工作轻松完成,只需从存储库部署现有版本,而无需再次构建项目。

在 Gitlab 上,我似乎要么必须创建一个新项目,它自己的构建管道仅用于部署,要么向每个作业添加一个 rule,上面写着 不要 运行 构建和测试作业,但在设置环境变量 DEPLOY_OLD_RELEASE 时仅部署作业

我不喜欢任何一种方式,因为仅为构建管道创建项目似乎开销很大,修改所有作业是一项巨大的工作并且不容易维护。

一旦 Gitlab 作业通过,您可以重新运行它任意次。因此,例如,如果您有一个部署作业,其中 scp 是一个 tar 文件到远程服务器,ssh 用于提取、移动到特定目录、更改符号链接等。您可以重新 运行 那个特定的工作。

但是,由于听起来您有一个定义明确的管道,因此 tar 文件可能不是在您的部署作业中构建的,而是一个类似于“打包应用程序”的作业。在此作业中,您可能会上传最终的 tar 文件作为工件,以便您的部署作业可以部署它。

如果是这种情况,只要您的 'Package' 作业的工件仍然存在(因为它们根据服务器的默认值或您在作业定义中指定的时间过期),您可以简单地重新-运行 部署作业。但是,如果这些工件已过期,您将必须重新运行 打包作业,然后是部署作业。

但是,也许您的 'Package' 作业依赖于一些未构建在该作业中的依赖项,例如 运行ning npm cicomposer install(对于 PHP 项目)。如果这些活动发生在先前阶段的其他作业中,并作为 'Package' 作业使用的工件上传,您可能还需要重新运行 这些。

这听起来好像需要重新运行大量作业,但如果您根据自己的目的准确设置了过期时间,那也不错。例如,我的“构建”作业(那些安装 npm 依赖项等)在 30 分钟后到期,因为“打包”作业将在完成后立即 运行,我再也不需要它们了。相反,我将 'package' 工作工件保留 2 周,这样我就可以相对快速地重新部署而无需重建依赖项。

根据我使用应用程序的经验,我几乎从不重新部署超过 2 周的构建,因为通常会有更新的构建来替换它。但是,您应该调整每个项目的过期时间。

这里有一个管道定义,类似于我在项目中使用的定义作为示例。这是一个带有 JS/Vue 前端的 PHP 后端项目,因此大多数作业都不适用,但会让您了解如何继续。

stages:
  - build
  - package
  - deploy

Run Composer Install:
  stage: build
  image: composer:latest
  only:
    - tags
  needs: []
  before_script:
    - echo ${COMPOSER_AUTH_JSON} > auth.json
  script:
    - composer clearcache; composer self-update --2
    - php -d memory_limit=-1 /bin/composer install --ignore-platform-reqs --no-dev
  artifacts:
    paths:
      - vendor
    when: on_success
    expire_in: 30 minutes

Npm Install:
  stage: build
  image: hub.comcast.net/code_common/spa_site_7.4:5
  only:
    - branches
    - tags
  needs: []
  script:
    - /usr/bin/npm ci
  artifacts:
    paths:
      - node_modules
    when: on_success
    expire_in: 30 minutes

Package Application:
  stage: package
  image: ... #same situation as the Package job for int environment
  dependencies:
    - Run Composer Install
    - Npm Install
  needs: ["Npm Install", "Run Composer Install"]
  only:
    - tags
  script:
    - npm run build
    - rm -rf .git* Vagrantfile vagrant_files .env.example .env.local CONTRIBUTING.md build.xml
    - mkdir -p bootstrap/cache
    - chmod -R go+r ./*
    - find ./ -type d -exec chmod ugo+x {} \;
    - php artisan package:discover
    - php artisan optimize
    - tar -C ../ --exclude "$CI_PIPELINE_ID.tar.gz" -zcpf $CI_PIPELINE_ID.tar.gz --warning=no-file-changed $(basename $CI_PROJECT_DIR) || [[ $? -eq 1 ]]
  artifacts:
    paths:
    - $CI_PIPELINE_ID.tar.gz
    when: on_success
    expire_in: 30 days

Deploy:
  stage: deploy
  image: my_image
  needs: ["Package Application"]
  dependencies: ["Package Application"]
  script:
    - ./deploy_placeholder.sh

前三个作业 运行 为多个环境构建步骤。接下来我获取在之前的作业中上传的工件,运行 之类的东西 npm run build,并最终创建 .tar.gz 文件作为工件上传。最后,部署作业拉下 .tar.gz 文件并部署。

使用此层次结构,根据初始部署和重新部署之间经过的时间长短,您只需重新运行一些作业,只需按一下按钮即可完成每个作业工作。