故事很长:将这样一个多图像gitlab-CI文件翻译成travis-CI的正确方法是什么?特别是一种允许脚本比裸命令更复杂的方法。
使用gitlab CI,可以在不同的docker映像中运行不同的CI作业,而不知道docker CLI和docker文件,如下所示:
build_jessie-gcc48:
image: debian:jessie
before_script:
- apt-get update
- apt-get install -y git cmake g\+\+-4.8 ninja-build
script:
- BUILDDIR=$(mktemp -d)
- cd ${BUILDDIR}
- SOMEVAR=somevalue cmake -G Ninja -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 ${CI_PROJECT_DIR}
- cmake --build builddir
build_stretch-gcc63:
image: debian:stretch
before_script:
- apt-get update
- apt-get install -y git cmake g\+\+-6 ninja-build
script:
- BUILDDIR=$(mktemp -d)
- cd ${BUILDDIR}
- cmake -G Ninja -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ${CI_PROJECT_DIR}
- cmake --build .
即。我的脚本大多是普通的shell代码,我可以cd
并分配/使用变量。我想知道如何用travis做同样的事情。 This帖子建议使用docker CLI,但有一些我觉得这种方法不方便的事情:
docker exec IMAGENAME
会使yml cd
更改目录不会"只是工作" (它是内置的shell而不是可执行文件,对吧?所以我目前的方法看起来像这样:
language: c++
services:
- docker
jobs:
include:
- script:
- docker pull debian:jessie
- docker run -itd --name JESSIE -v ${TRAVIS_BUILD_DIR}:/repo.git debian:jessie
- docker exec JESSIE apt-get update
- docker exec JESSIE apt-get install -y git cmake g\+\+-4.8 ninja-build
- docker exec JESSIE bash -c 'cd $(mktemp -d) && \
SOMEVAR=somevalue cmake -G Ninja -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 /repo.git && \
cmake --build .'
- script:
- docker pull debian:stretch
- docker run -itd --name STRETCH -v ${TRAVIS_BUILD_DIR}:/repo.git debian:stretch
- docker exec STRETCH apt-get update
- docker exec STRETCH apt-get install -y git cmake g\+\+-6 ninja-build
- docker exec STRETCH bash -c 'cd $(mktemp -d) && \
cmake -G Ninja -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 /repo.git && \
cmake --build .'
这涉及一些尝试和错误,因为bash -c apt-get
没有成功,因为bash(?)不知道apt-get
。 (而且这项工作甚至失败了,因为变量赋值会导致bash SOMEVAR=somevalue command not found
出错,并且cmake
虽然刚刚安装,但未找到logouttime = mm.fetchone()
。所以我通常不会觉得这就是使用它的方式。
答案 0 :(得分:3)
我不知道为什么SOMEVAR=somevalue
不起作用,因为语法看起来很好并且应与docker exec CONTAINER bash -c '…'
无论如何,我有一个建议来写你的.travis.yml
,它不那么冗长,更接近于GitLab CI conf文件的措辞:它依赖于所谓的block style YAML。< / p>
所有步骤都在同一个bash命令中运行,因此您可以分配变量并重复使用它们。
以下是我建议的相应.travis.yml
:
sudo: required
language: cpp
services:
- docker
jobs:
include:
- script: |
docker run --name JESSIE -it -v ${TRAVIS_BUILD_DIR}:/repo.git debian:jessie /bin/bash -c '
export PS4='\''+ \e[33;1m($0 @ line $LINENO) \$\e[0m '\'' # quotes must be escaped
set -e # exit on failure
set -x # trace for debug
apt-get update
apt-get install -y git cmake g\+\+-4.8 ninja-build
cd $(mktemp -d)
SOMEVAR=somevalue cmake -G Ninja -DCMAKE_C_COMPILER=gcc-4.8 -DCMAKE_CXX_COMPILER=g++-4.8 /repo.git
cmake --build .'
- script: |
docker run --name STRETCH -it -v ${TRAVIS_BUILD_DIR}:/repo.git debian:stretch /bin/bash -c '
export PS4='\''+ \e[33;1m($0 @ line $LINENO) \$\e[0m '\'' # quotes must be escaped
TRAVIS_EVENT_TYPE="$1"
set -e # exit on failure
set -x # trace for debug
echo "Build triggered by ${TRAVIS_EVENT_TYPE}"
apt-get update
apt-get install -y git cmake g\+\+-6 ninja-build
cd $(mktemp -d)
cmake -G Ninja -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 /repo.git
cmake --build .' bash "${TRAVIS_EVENT_TYPE}"
一些相关的评论:
sudo: required
(并用cpp替换了c ++)。'
在脚本的第一行和最后一行的末尾是必需的。docker pull debian:jessie
命令,因为它应该由docker run […] debian:jessie […]
-v ${TRAVIS_BUILD_DIR}:/repo.git
)是个好主意!--rm
标记传递给docker run
(除非您想在后续的Travis CI命令中检查或重新使用容器)。如果您传递--rm
标记,则当然应删除--name JESSIE
选项。-d
标记,因为现在不需要在后台运行容器,因为只有一个docker run
而没有docker exec
。此外,它确保传递给docker run
的Bash命令的输出将显示在Travis CI日志中(因为它们不在后台运行)。set -e
,而选项set -x
则不那么重要(可以用set -v
替换为类似目的而不是详细程度),并且重新定义PS4
的行有助于使用set -x
获得改进的黄色提示。另请注意,如果您愿意,可以将-e
和-x
选项直接传递给bash(即,您可以将bash -c 'set -e; […]'
替换为bash -e -c '[…]'
)。最后,我修改了第二个脚本,以举例说明如何将其他变量(此处为Travis CI env变量TRAVIS_EVENT_TYPE
)从Travis传递到Docker / Bash上下文。
实际上,实现这一目标的一种更简单的方法是使用选项-e
:
docker run […] -e TRAVIS_EVENT_TYPE="${TRAVIS_EVENT_TYPE}" debian:jessie /bin/bash […]
注意:我自己没有测试过这个解决方案,因为手动没有cmake
项目;但是如果你有一些反馈意见或者看到这个主题的问题,请随时告诉我。