在管道中跨作业保留 Gitlab CI 服务数据(或者:如何在一项作业中播种数据并在另一项作业中访问它)

Gar*_*ner 2 gitlab-ci

我试图弄清楚如何在 CI 管道中正确使用服务。我想要一个像这样的管道:

variables:
  MYSQL_DATABASE: test
  MYSQL_ROOT_PASSWORD: root_password
  MYSQL_USER: mysqluser
  MYSQL_PASSWORD: user_password

services:
  - mysql

stages:
  - setup
  - test

seed data:
  stage: setup
  image: mysql
  script:
    - >-
      cat database_setup/*.sql | mysql 
      -hmysql
      -u${MYSQL_USER}
      -p${MYSQL_PASSWORD} 
      ${MYSQL_DATABASE}
test:
  script:
    - ./connect_to_sql_or_something

Run Code Online (Sandbox Code Playgroud)

我希望它能起作用,它与典型的例子没有太大不同,它只是有第二阶段和工作。然而,当运行这个时,似乎每个作业都在使用不同的服务。测试作业无法访问种子作业的结果。我查看了文档,找不到任何有关服务生命周期的信息,以及它与作业和阶段的对应关系。而且我找不到任何使用mysql的多阶段示例。有办法让这项工作发挥作用吗?这是否与缓存或在阶段之间传递工件有关?我缺少什么?因为看起来这样的事情应该是可能的......

Sam*_*Bob 5

Gitlab 在全新的环境中运行每个作业(通常在不同网络的不同计算机上)。因此,为了简化安全需求,services在作业的生命周期内为作业运行器上的每个作业创建,然后销毁。您可以在管道日志中看到这一点:

Starting service mysql:latest ...
Run Code Online (Sandbox Code Playgroud)

它出现在每个作业的开始处。然后,它们仅在该本地主机上可用(因为出于安全和复杂性原因,没有防火墙管理来进一步公开该服务)

因此,如果我们希望在这些服务之间共享状态,我们必须在它们之间手动传递信息。gitlab 允许我们将数据从一项工作传递到另一项工作的唯一方法是通过工件。

简而言之,我们需要:

  1. 在作业结束时将数据库转储到文件
  2. 将该文件保存为工件
  3. 在下一个作业中加载该工件
  4. 将加载的工件恢复到数据库。

例如,下面是一个管道,它在一个作业中创建一个包含单个表的数据库,然后在下一个作业中列出该表。

services:
  - mysql

variables:
  # Configure mysql service (https://hub.docker.com/_/mysql/)
  MYSQL_DATABASE: hello_world_test
  MYSQL_ROOT_PASSWORD: mysql

stages:
  - create
  - read

create_table:
  image: mysql
  stage: create
  script:
    - echo "CREATE TABLE table1(id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY);" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" 
    - mysqldump --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" > db_backup.sql # 1) Dump the database to a file
  artifacts:
    paths:
      - db_backup.sql # 2) Save that file as an artifact

show_tables:
  image: mysql
  stage: read # 3) following stages receive artifacts from previous stages
  script:
    - mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" < db_backup.sql # 4) Restore the backup
    - echo "SHOW TABLES;" | mysql --user=root --password="$MYSQL_ROOT_PASSWORD" --host=mysql "$MYSQL_DATABASE" 
Run Code Online (Sandbox Code Playgroud)

如果您想要进一步的阶段,请确保在修改数据库的每个作业中进行备份。如果您有很多阶段,请考虑使用before_script/after_script来简化。