使用Appveyor支持Windows

页面状态

已废弃

上次审核时间

2015-12-03

本节介绍如何使用免费的Appveyor持续集成服务为您的项目提供Windows支持。这包括在Windows上测试代码,以及为使用C扩展的项目构建面向Windows的二进制文件。

背景

许多项目默认在Unix上开发,提供Windows支持可能是一个挑战,因为建立一个合适的Windows测试环境并非易事,并且可能需要购买软件许可证。

Appveyor服务是一个持续集成服务,很像更著名的Travis服务,通常用于GitHub上托管的项目进行测试。然而,与Travis不同的是,Appveyor上的构建工作器是Windows主机,并且安装了必要的编译器来构建Python扩展。

Windows用户通常无法访问C编译器,因此,对于使用C扩展的项目,他们依赖于在PyPI上分发二进制轮子,以便通过python -m pip install <dist>进行安装。通过使用Appveyor作为构建服务(即使不用于测试),没有专用Windows环境的项目也可以提供面向Windows的二进制文件。

设置

为了使用Appveyor为您的项目构建Windows轮子,您必须在该服务上拥有一个帐户。设置帐户的说明在Appveyor文档中给出。免费层帐户完全适用于开源项目。

Appveyor提供与GitHubBitbucket的集成,因此只要您的项目托管在这两个服务中的一个上,设置Appveyor集成就很简单。

设置好Appveyor帐户并添加项目后,Appveyor将在每次提交发生时自动构建您的项目。这种行为对于Travis的用户来说是熟悉的。

为您的项目添加Appveyor支持

为了定义Appveyor应如何构建您的项目,您需要向项目中添加一个appveyor.yml文件。文件中可以包含的完整详细信息在Appveyor文档中有所介绍。本指南将提供设置轮子构建所需的详细信息。

Appveyor默认包含构建Python扩展所需的所有编译器工具链。对于Python 2.7、3.5+以及3.3和3.4的32位版本,这些工具开箱即用。但对于Python 3.3和3.4的64位版本,需要少量额外配置,以告知distutils在哪里找到64位编译器。(从3.5开始,所使用的Visual Studio版本包含64位编译器,无需额外设置)。

appveyor.yml

 1environment:
 2
 3  matrix:
 4
 5    # For Python versions available on Appveyor, see
 6    # https://www.appveyor.com/docs/windows-images-software/#python
 7    # The list here is complete (excluding Python 2.6, which
 8    # isn't covered by this document) at the time of writing.
 9
10    - PYTHON: "C:\\Python27"
11    - PYTHON: "C:\\Python33"
12    - PYTHON: "C:\\Python34"
13    - PYTHON: "C:\\Python35"
14    - PYTHON: "C:\\Python27-x64"
15    - PYTHON: "C:\\Python33-x64"
16      DISTUTILS_USE_SDK: "1"
17    - PYTHON: "C:\\Python34-x64"
18      DISTUTILS_USE_SDK: "1"
19    - PYTHON: "C:\\Python35-x64"
20    - PYTHON: "C:\\Python36-x64"
21
22install:
23  # We need wheel installed to build wheels
24  - "%PYTHON%\\python.exe -m pip install wheel"
25
26build: off
27
28test_script:
29  # Put your test command here.
30  # If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,
31  # you can remove "build.cmd" from the front of the command, as it's
32  # only needed to support those cases.
33  # Note that you must use the environment variable %PYTHON% to refer to
34  # the interpreter you're using - Appveyor does not do anything special
35  # to put the Python version you want to use on PATH.
36  - "build.cmd %PYTHON%\\python.exe setup.py test"
37
38after_test:
39  # This step builds your wheels.
40  # Again, you only need build.cmd if you're building C extensions for
41  # 64-bit Python 3.3/3.4. And you need to use %PYTHON% to get the correct
42  # interpreter
43  - "build.cmd %PYTHON%\\python.exe setup.py bdist_wheel"
44
45artifacts:
46  # bdist_wheel puts your built wheel in the dist directory
47  - path: dist\*
48
49#on_success:
50#  You can use this step to upload your artifacts to a public website.
51#  See Appveyor's documentation for more details. Or you can simply
52#  access your wheels from the Appveyor "artifacts" tab for your build.

此文件可从此处下载。

appveyor.yml文件必须位于项目的根目录中。它采用YAML格式,由多个部分组成。

environment部分是定义将为哪个Python版本创建轮子的关键。Appveyor预装了Python 2.6、2.7、3.3、3.4和3.5,包括32位和64位版本。示例文件为除Python 2.6之外的所有这些环境构建。为Python 2.6安装更复杂,因为它不包含pip。本文档不支持2.6(因为仍然使用Python 2的Windows用户通常可以毫不费力地迁移到Python 2.7)。

install部分使用pip安装项目可能需要的任何额外软件。构建轮子所需的唯一要求是wheel项目,但在某些情况下,项目可能希望自定义此代码(例如,安装额外的构建包,如Cython,或测试工具,如tox)。

build部分只是关闭构建——对于Python,不需要构建步骤,不像C#等语言。

需要根据您的项目进行调整的主要部分是test_scriptafter_test

test_script部分是您运行项目测试的地方。提供的文件使用setup.py test运行您的测试套件。如果您只对构建轮子感兴趣,而不对在Windows上运行测试感兴趣,您可以将此部分替换为虚拟命令,例如echo Skipped Tests。您可能希望使用其他测试工具,例如nosepy.test。或者您可能希望使用像tox这样的测试驱动程序——但是如果您使用tox,您需要考虑一些额外的配置更改,这些更改将在下面描述。

after_test在测试完成后运行,因此是应该构建轮子的地方。假设您的项目使用推荐的工具(特别是setuptools),那么setup.py bdist_wheel命令将构建您的轮子。

请注意,只有在测试成功时才会构建轮子。如果您预计测试在Windows上会失败,您可以如上所述跳过它们。

支持脚本

appveyor.yml文件依赖于一个支持脚本,该脚本设置环境以在Python 3.3和3.4上进行64位构建时使用SDK编译器。对于不需要编译器,或者在64位Windows上不支持3.3或3.4的项目,只需要appveyor.yml文件。

build.cmd是一个Windows批处理脚本,它在具有所选Python版本相应编译器的环境中运行单个命令。您需要做的就是将单个环境变量DISTUTILS_USE_SDK设置为1,脚本将完成其余工作。它设置了Python 3.3或3.4的64位构建所需的SDK,因此不要为任何其他构建设置环境变量。

您可以简单地下载批处理文件并将其包含在您的项目中,无需更改。

访问已构建的轮子

构建完成后,已构建的轮子将从您项目的Appveyor控制面板中可用。可以通过依次转到每个构建的构建状态页面来找到它们。在构建输出的顶部有一系列链接,其中一个是“Artifacts”。该页面将包含指向该Python版本/架构轮子的链接列表。您可以下载这些轮子并将其作为发布过程的一部分上传到PyPI。

补充说明

使用tox进行测试

许多项目使用Tox工具来运行他们的测试。它确保测试在隔离环境中运行,使用项目将分发的精确文件。

为了在Appveyor上使用tox,还需要考虑一些额外的问题(实际上,这些问题并非Appveyor特有,很可能影响其他CI系统)。

  1. 默认情况下,tox只将所选的环境变量子集传递给测试进程。由于distutils使用环境变量来控制编译器,这个“测试隔离”功能将导致测试默认使用错误的编译器。

    为了强制tox将必要的环境变量传递给子进程,您需要设置tox配置选项passenv以列出要传递给子进程的额外环境变量。对于SDK编译器,您需要

    • DISTUTILS_USE_SDK

    • MSSdk

    • INCLUDE

    • LIB

    passenv选项可以在您的tox.ini中设置,或者如果您更喜欢避免将Windows特定的设置添加到您的通用项目文件中,可以通过设置TOX_TESTENV_PASSENV环境变量来设置。提供的build.cmd脚本在设置DISTUTILS_USE_SDK时默认执行此操作。

  2. 在交互使用时,tox允许您针对多个环境(通常意味着多个Python版本)运行测试。此功能在Travis或Appveyor等CI环境中不太有用,因为所有测试都在每个配置的隔离环境中运行。因此,项目通常向tox提供参数-e ENVNAME来指定要使用的环境(大多数Python版本都有默认环境)。

    然而,这在像Appveyor这样的Windows CI系统上太适用,因为那里有(例如)两个Python 3.4安装(32位和64位),但tox中只有一个py34环境。

    因此,为了使用tox运行测试,项目可能应该使用tox中的默认py环境,该环境使用用于运行tox的Python解释器。这将确保当Appveyor运行测试时,它们将使用配置的解释器运行。

    为了支持在py环境下运行,具有复杂tox配置的项目可能需要修改其tox.ini文件。然而,这样做超出了本文档的范围。

自动上传轮子

可以请求Appveyor自动上传轮子。appveyor.yml中有一个可用的deployment步骤,可以用于(例如)将构建的工件复制到FTP站点或Amazon S3实例。有关如何执行此操作的文档包含在Appveyor指南中。

或者,可以将twine upload步骤添加到构建中。提供的appveyor.yml没有这样做,因为尚不清楚在每次提交后上传新轮子是否可取(尽管有些项目可能希望这样做)。

外部依赖

提供的脚本将成功构建任何不依赖于第三方外部库进行构建的分发。

可以在appveyor.yml配置中添加步骤(通常在“安装”部分)以下载和/或构建分发所需的外部库。如果需要,可以为构建添加额外的配置,以向编译器提供这些库的位置。然而,这种级别的配置超出了本文档的范围。

支持脚本

供参考,SDK设置支持脚本在此处列出

appveyor-sample/build.cmd

 1@echo off
 2:: To build extensions for 64 bit Python 3, we need to configure environment
 3:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
 4:: MS Windows SDK for Windows 7 and .NET Framework 4
 5::
 6:: More details at:
 7:: https://github.com/cython/cython/wiki/CythonExtensionsOnWindows
 8
 9IF "%DISTUTILS_USE_SDK%"=="1" (
10    ECHO Configuring environment to build with MSVC on a 64bit architecture
11    ECHO Using Windows SDK 7.1
12    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Setup\WindowsSdkVer.exe" -q -version:v7.1
13    CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release
14    SET MSSdk=1
15    REM Need the following to allow tox to see the SDK compiler
16    SET TOX_TESTENV_PASSENV=DISTUTILS_USE_SDK MSSdk INCLUDE LIB
17) ELSE (
18    ECHO Using default MSVC build environment
19)
20
21CALL %*