使用 GitLab CI 在本地运行测试?

Posted

技术标签:

【中文标题】使用 GitLab CI 在本地运行测试?【英文标题】:Use GitLab CI to run tests locally? 【发布时间】:2016-01-01 04:46:35 【问题描述】:

如果在 GitLab CI 上配置了 GitLab 项目,有没有办法在本地运行构建?

我不想把我的笔记本电脑变成一个构建“运行器”,我只想利用 Docker 和.gitlab-ci.yml 在本地运行测试(即它都是预先配置的)。这样做的另一个好处是我确信我在本地和 CI 上使用相同的环境。

这是how to run Travis builds locally using Docker 的示例,我正在寻找与 GitLab 类似的东西。

【问题讨论】:

应该在最新版本中可用,请参阅gitlab-ci-multi-runner#312 【参考方案1】:

几个月前就可以使用gitlab-runner

gitlab-runner exec docker my-job-name

请注意,您需要在计算机上同时安装 docker 和 gitlab-runner 才能使其正常工作。

您还需要在.gitlab-ci.yml 文件中定义的image 键。否则将无法正常工作。

这是我目前使用gitlab-runner进行本地测试的线路:

gitlab-runner exec docker test --docker-volumes "/home/elboletaire/.ssh/id_rsa:/root/.ssh/id_rsa:ro"

注意:您可以避免添加--docker-volumes,而您的密钥默认设置为/etc/gitlab-runner/config.toml。 See the official documentation for more details。此外,使用gitlab-runner exec docker --help 查看所有基于 docker 的运行器选项(如变量、卷、网络等)。

由于cmets的混乱,我把gitlab-runner --help的结果贴在这里,这样你就可以看到gitlab-runner可以在本地构建:

   gitlab-runner --help
NAME:
   gitlab-runner - a GitLab Runner

USAGE:
   gitlab-runner [global options] command [command options] [arguments...]
   
VERSION:
   1.1.0~beta.135.g24365ee (24365ee)
   
AUTHOR(S):
   Kamil Trzciński <ayufan@ayufan.eu> 
   
COMMANDS:
   exec         execute a build locally
   [...]
   
GLOBAL OPTIONS:
   --debug          debug mode [$DEBUG]
   [...]

如您所见,exec 命令指向execute a build locally

尽管there was an issue to deprecate the current gitlab-runner exec behavior、ended up being reconsidered 和具有更强大功能的新版本将取代当前的 exec 功能。

请注意,此过程是使用您自己的机器使用 docker 容器运行测试。这不是定义自定义跑步者。为此,只需转到您的 repo 的 CI/CD 设置并阅读那里的文档。如果您想确保执行您的跑步者而不是来自 gitlab.com 的跑步者,请为您的跑步者添加一个自定义且唯一的标签,确保它只运行标记的作业并标记您希望跑步者负责的所有作业。

【讨论】:

@elboletaire 如何运行整个构建,而不是单个阶段? 我不确定现在,但我认为没有简单的方法。可能您需要一一指定。 gitlab-runner exec is being deprecated after GitLab 10.0,投票gitlab.com/gitlab-org/gitlab-runner/issues/2797 支持在此之前更换 感谢@Alfageme 指出它,显然在开发替代品之前他们不会弃用它,请参阅gitlab.com/gitlab-org/gitlab-runner/issues/2797#note_42944825 @KongJinJie,你可以做gitlab-runner exec docker --help,你会看到所有的选项。在您的情况下,对于环境变量,就像添加 --env VARIABLE=value 作为 gitlab-runner 的参数一样简单【参考方案2】:

我使用这种基于 docker 的方法。

0。创建一个 git repo 来测试这个答案

mkdir my-git-project
cd my-git-project
git init
git commit --allow-empty -m"Initialize repo to showcase gitlab-runner locally."

1.转到你的 git 目录

cd my-git-project

2。创建一个 .gitlab-ci.yml

例如.gitlab-ci.yml

image: alpine

test:
  script:
    - echo "Hello Gitlab-Runner"

3.创建一个安装了项目目录的 docker 容器

docker run -d \
  --name gitlab-runner \
  --restart always \
  -v $PWD:$PWD \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest

(-d) 在后台运行容器并打印容器ID

(--总是重启)or not?

(-v $PWD:$PWD) 将当前目录挂载到容器的当前目录 - 注意:在 Windows 上,您可以将目录绑定到固定位置,例如-v $PWD:/opt/myapp.

(-v /var/run/docker.sock:/var/run/docker.sock) 这使容器可以访问主机的 docker 套接字,因此它可以启动“同级容器”(例如 Alpine)。

(gitlab/gitlab-runner:latest) 来自 dockerhub 的最新可用镜像。

4.执行与

docker exec -it -w $PWD gitlab-runner gitlab-runner exec docker test
#                ^          ^           ^            ^     ^      ^
#                |          |           |            |     |      |
#               (a)        (b)         (c)          (d)   (e)    (f)

(a) 容器内的工作目录。 注意:在 Windows 上,您可以使用固定位置,例如/opt/myapp.

(b) docker 容器的名称

(c) 在docker容器内执行命令"gitlab-runner"

(d)(e)(f) 使用“docker executer”运行 gitlab-runner 并运行名为“test”的作业

5.打印

...
Executing "step_script" stage of the job script
$ echo "Hello Gitlab-Runner"
Hello Gitlab-Runner
Job succeeded
...

注意:运行器只会在代码库的commited状态下运行。未提交的更改将被忽略。 例外.gitlab-ci.yml 本身并未被承诺考虑在内。

【讨论】:

这里非常有用的例子有助于理解它是如何工作的 注意:确保使用 -v $PWD:$PWD 很重要,因为 docker 在 docker 情况下(否则您将收到错误 fatal: Could not read from remote repository.)。见gitlab.com/gitlab-org/gitlab-runner/-/issues/4574 @vab2048 是的,这是强制性的。此外,它在第 3 点提到。我的回答。 步骤 3 在 windows 终端中不起作用。请改用docker run -d --name gitlab-runner --restart always -v $PWD:/usr/src/app -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest。只有挂载文件参数已更改。 $PWD 已被 $PWD 取代以在 Windows 中工作。此外,您不能在 docker 容器中使用与运行 linux 相同的路径,因此我将其替换为通用路径:/usr/src/app @PassivProgrammer 将此添加到我的答案中。谢谢!【参考方案3】:

我目前正在制作一个可以在本地运行的 gitlab 运行器。 仍处于早期阶段,但最终它将变得非常相关。 gitlab 似乎不想/没有时间来做这个,所以你去吧。 https://github.com/firecow/gitlab-runner-local

【讨论】:

npm install 出现错误,但使用 Linux 库安装就像一个魅力。谢谢!我可以用这个! *Linux Binary - 几个月后我有了一台新笔记本电脑,不得不再次在本地测试管道。我很高兴我再次找到了这个答案:)【参考方案4】:

另一种方法是在您的电脑和服务器上同时安装一个本地构建工具。 所以基本上,你的 .gitlab-ci.yml 基本上会调用你喜欢的构建工具。

这是一个我与 nuke.build 一起使用的示例 .gitlab-ci.yml:

stages:
    - build
    - test
    - pack

variables:
    TERM: "xterm" # Use Unix ASCII color codes on Nuke

before_script:
    - CHCP 65001  # Set correct code page to avoid charset issues

.job_template: &job_definition
  except:
    - tags

build:
    <<: *job_definition
    stage: build
    script:
        - "./build.ps1"

test:
    <<: *job_definition
    stage: test
    script:
        - "./build.ps1 test"
    variables:
        GIT_CHECKOUT: "false"

pack:
    <<: *job_definition
    stage: pack
    script:
        - "./build.ps1 pack"
    variables:
        GIT_CHECKOUT: "false"
    only:
        - master
    artifacts:
        paths:
            - output/

在 nuke.build 中,我定义了 3 个目标,命名为 3 个阶段(构建、测试、打包)

通过这种方式,您可以获得可重现的设置(所有其他内容都使用您的构建工具进行配置),并且您可以直接测试构建工具的不同目标。

(我可以在需要时调用 .\build.ps1 、 .\build.ps1 test 和 .\build.ps1 pack)

【讨论】:

【参考方案5】:

如果您在此处使用 docker 映像运行 Gitlab:https://hub.docker.com/r/gitlab/gitlab-ce,则可以通过使用卷选项:-v /var/run/docker.sock:/var/run/docker.sock 公开本地 docker.sock 来运行管道。将此选项添加到 Gitlab 容器将允许您的工作人员访问主机上的 docker 实例。

【讨论】:

我目前正在尝试在我的项目中的 .gitlab-ci.yml 文件中执行一个任务,该任务是在部署为 Docker 容器的 Runner 上。我是否需要将项目的 src 代码绑定到 Runner 中才能找到/运行任务?或者这是否可能与您在回答中所说的一样,即连接到远程客户端,如 Docker 机器 'eval "$(docker-machine env default)"'? @GregBrown 或者如果其他人想知道,看看这个issue,例如:docker run --rm -v $PWD:$PWD -v /var/run/docker.sock:/var/run/docker.sock -v /opt/gitlab-runner/config:/etc/gitlab-runner --workdir $PWD gitlab/gitlab-runner exec docker deploy。选项--workdir 是关键。【参考方案6】:

GitLab 运行器似乎还不能在 Windows 上运行,并且有 an open issue to resolve this。

因此,与此同时,我正在将我的脚本代码移到一个 bash 脚本中,我可以轻松地在本地运行 map to a docker container 并执行它。

在这种情况下,我想在我的工作中构建一个 docker 容器,所以我创建了一个脚本“build”:

#!/bin/bash

docker build --pull -t myimage:myversion .

在我的 .gitlab-ci.yaml 中执行脚本:

image: docker:latest

services:
- docker:dind

before_script:
- apk add bash

build:
stage: build
script:
- chmod 755 build
- build

要使用 powershell 在本地运行脚本,我可以启动所需的映像并将卷与源文件映射:

$containerId = docker run --privileged -d -v $PWD:/src docker:dind

如果不存在,请安装 bash:

docker exec $containerId apk add bash

在 bash 脚本上设置权限:

docker exec -it $containerId chmod 755 /src/build

执行脚本:

docker exec -it --workdir /src $containerId bash -c 'build'

然后停止容器:

docker stop $containerId

最后清理容器:

docker container rm $containerId

【讨论】:

这需要一个Dockerfile,你没有提到。 @Cerin 需要什么 dockerfile? docker:dind 是官方的 docker 镜像,我没有创建。【参考方案7】:

我在 Windows 上使用 VSCode 和 WSL

我不想将我的工作电脑注册为跑步者,所以我在本地运行我的 yaml 阶段以在上传之前对其进行测试

$ sudo apt-get install gitlab-runner
$ gitlab-runner exec shell build

yaml

image: node:10.19.0 # https://hub.docker.com/_/node/
# image: node:latest

cache:
  # untracked: true
  key: project-name
  # key: $CI_COMMIT_REF_SLUG # per branch
  # key:
  #   files:
  #     - package-lock.json # only update cache when this file changes (not working) @jkr
  paths:
    - .npm/
    - node_modules
    - build

stages:
  - prepare # prepares builds, makes build needed for testing
  - test # uses test:build specifically @jkr
  - build
  - deploy

# before_install:

before_script:
  - npm ci --cache .npm --prefer-offline

prepare:
  stage: prepare
  needs: []
  script:
    - npm install

test:
  stage: test
  needs: [prepare]
  except:
    - schedules
  tags:
    - linux
  script:
    - npm run build:dev
    - npm run test:cicd-deps
    - npm run test:cicd # runs puppeteer tests @jkr
  artifacts:
    reports:
      junit: junit.xml
    paths:
      - coverage/

build-staging:
  stage: build
  needs: [prepare]
  only:
    - schedules
  before_script:
    - apt-get update && apt-get install -y zip
  script:
    - npm run build:stage
    - zip -r build.zip build
  # cache:
  #   paths:
  #     - build
  #   <<: *global_cache
  #   policy: push
  artifacts:
    paths:
      - build.zip

deploy-dev:
  stage: deploy
  needs: [build-staging]
  tags: [linux]
  only:
    - schedules
  #   # - branches@gitlab-org/gitlab
  before_script:
    - apt-get update && apt-get install -y lftp
  script:
    # temporarily using 'verify-certificate no'
    # for more on verify-certificate @jkr: https://www.versatilewebsolutions.com/blog/2014/04/lftp-ftps-and-certificate-verification.html
    # variables do not work with 'single quotes' unless they are "'surrounded by doubles'"
    - lftp -e "set ssl:verify-certificate no; open mediajackagency.com; user $LFTP_USERNAME $LFTP_PASSWORD; mirror --reverse --verbose build/ /var/www/domains/dev/clients/client/project/build/; bye"
  # environment:
  #   name: staging
  #   url: http://dev.mediajackagency.com/clients/client/build
  #   # url: https://stg2.client.co
  when: manual
  allow_failure: true

build-production:
  stage: build
  needs: [prepare]
  only:
    - schedules
  before_script:
    - apt-get update && apt-get install -y zip
  script:
    - npm run build
    - zip -r build.zip build
  # cache:
  #   paths:
  #     - build
  #   <<: *global_cache
  #   policy: push
  artifacts:
    paths:
      - build.zip

deploy-client:
  stage: deploy
  needs: [build-production]
  tags: [linux]
  only:
    - schedules
    # - master
  before_script:
    - apt-get update && apt-get install -y lftp
  script:
    - sh deploy-prod
  environment:
    name: production
    url: http://www.client.co
  when: manual
  allow_failure: true

【讨论】:

码头工人呢?您在 yaml 中指定了“图像” @ShubhamTakode 我最初是走这条路的,但在 WSL 上让一切顺利运行被证明是我想在这个问题上投入更多的努力。【参考方案8】:

这个想法是将检查命令保留在.gitlab-ci.yml 之外。我使用Makefile 运行类似make check 的东西,而我的.gitlab-ci.yml 运行相同的make 命令,我在本地使用这些命令在提交之前检查各种事情。 这样一来,所有/大部分命令 (Makefile) 和.gitlab-ci.yml 将只有与 CI 相关的内容。

【讨论】:

【参考方案9】:

几年前,我使用Makefiledocker-compose 构建了这个简单的解决方案来在docker 中运行gitlab 运行程序,您也可以使用它在本地执行作业,并且应该适用于docker 工作的所有系统:

https://gitlab.com/1oglop1/gitlab-runner-docker

docker-compose.override.yaml 中的更改很少

version: "3"
services:
    runner:
      working_dir: <your project dir>
      environment:
        - REGISTRATION_TOKEN=<token if you want to register>
      volumes:
        - "<your project dir>:<your project dir>"

然后在您的项目中,您可以按照其他答案中提到的相同方式执行它:

docker exec -it -w $PWD runner gitlab-runner exec &lt;commands&gt;..

【讨论】:

【参考方案10】:

我编写了一个工具来在本地运行所有 GitLab-CI 作业,而无需提交或推送,只需使用命令 ci-toolbox my_job_name

项目网址:https://gitlab.com/mbedsys/citbx4gitlab

【讨论】:

以上是关于使用 GitLab CI 在本地运行测试?的主要内容,如果未能解决你的问题,请参考以下文章

在项目上运行Gitlab-CI以获取两个不同的Docker镜像

无法在GitLab CI docker-in-docker中对neo4j数据库运行测试

Gitlab Ci使用docker和mysql服务进行缓慢构建

在 gitlab ci 中查找在 docker-compose 中运行的容器的 url/ip

无法使用 Gitlab CI 运行 Cypress 测试

在 Gitlab CI 上更改 Xdebug 模式 PHP Docker