tox 中的条件命令? (tox、travis-ci 和工作服)

Conditional Commands in tox? (tox, travis-ci, and coveralls)

tl;博士:

我正在为我的一个项目设置 CI,托管在 github,使用 toxtravis-ci。在构建结束时,我 运行 converalls 将覆盖率报告推送到 coveralls.io。我想使这个命令 'conditional' - 仅当测试在 travis 上 运行 时才执行;不是当它们在我的本地机器上 运行 时。有办法实现吗?

详情:

我要测试的包是 python 包。我正在使用/计划使用以下 'infrastructure' 来设置测试:

相关测试脚本如下所示:

.travis.yml

language: python
python: 2.7
env:
  - TOX_ENV=py27
install:
  - pip install tox
script:
  - tox -e $TOX_ENV

tox.ini

[tox]
envlist = py27

[testenv]
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
deps =
    pytest
    coverage
    pytest-cov
    coveralls
commands =
    py.test --cov={envsitepackagesdir}/mypackage --cov-report=term --basetemp={envtmpdir}
    coveralls

这个文件让我 运行 在本地进行测试。但是,由于最后的 coveralls 调用,原则上测试失败,并显示:

py27 runtests: commands[1] | coveralls
You have to provide either repo_token in .coveralls.yml, or launch via Travis
ERROR: InvocationError: ...coveralls'

这是预期的错误。 passenv 位从 travis 发送必要的信息以便能够写入 coveralls,如果没有 travis 提供此信息,命令应该会失败。我也不希望这将结果推送到 coveralls.io。只有在 travis-ci 上进行测试时,我才希望有 coveralls 运行。有什么方法可以让我有条件地使用这个命令 运行,或者设置一个构建配置来达到同样的效果?

我已经尝试将工作服部分移动到 .travis.yml,但是执行时 coveralls 似乎无法找到合适的 .coverage 文件来发送。我朝这个方向做了各种尝试,其中 none 成功提交给 coveralls.io 除了上面列出的组合。以下是我希望能起作用的,因为当我在本地 运行 tox 时,我确实在我期望的地方得到了一个 .coverage 文件 - 在根文件夹中我的源代码树。

没有提交给coveralls.io

language: python
python: 2.7
env:
  - TOX_ENV=py27
install:
  - pip install tox
  - pip install python-coveralls
script:
  - tox -e $TOX_ENV
after_success:
  - coveralls

我对 Travis、tox 和工作服有类似的设置。我的想法是仅在设置了 TRAVIS 环境变量时才执行 coveralls 。然而,这似乎并不容易,因为 tox 无法解析带有引号和符号的命令。此外,这个 confused Travis me a lot.

最后我写了一个简单的python脚本run_coveralls.py:

#!/bin/env/python

import os

from subprocess import call


if __name__ == '__main__':
    if 'TRAVIS' in os.environ:
        rc = call('coveralls')
        raise SystemExit(rc)

tox.ini 中,将 coveralls 命令替换为 python {toxinidir}/run_coveralls.py

另一种解决方案是在 coveralls 命令前加上破折号 (-),以告诉 tox 忽略其退出代码,如 in the documentation 所述。这样即使来自 coveralls 的失败也将被忽略,并且 tox 将在本地执行时认为测试执行成功。

使用上面的示例配置,将如下所示:

[tox]
envlist = py27

[testenv]
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
deps =
    pytest
    coverage
    pytest-cov
    coveralls
commands =
    py.test --cov={envsitepackagesdir}/mypackage --cov-report=term --basetemp={envtmpdir}
    - coveralls

我正在使用环境变量来 运行 其他命令。

tox.ini

commands =
    coverage run runtests.py
    {env:POST_COMMAND:python --version}

.travis.yml

language: python
python:
  - "3.6"
install: pip install tox-travis
script: tox
env:
  - POST_COMMAND=codecov -e TOX_ENV

现在在我的本地设置中,它打印 python 版本。当来自 Travis 的 运行 它 运行s codecov.

如果您使用 Makefile 并且不想要新的 py 文件的替代解决方案:

define COVERALL_PYSCRIPT
import os
from subprocess import call

if __name__ == '__main__':
    if 'TRAVIS' in os.environ:
        rc = call('coveralls')
        raise SystemExit(rc)
    print("Not in Travis CI, skipping coveralls")
endef
export COVERALL_PYSCRIPT

coveralls: ## runs coveralls if TRAVIS in env
    @python -c "$$COVERALL_PYSCRIPT"

tox.ini 中添加 make coverallscommands