Skip to content

[MRG] Add Windows continuous integration with AppVeyor CI #3363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# AppVeyor.com is a Continuous Integration service to build and run tests under
# Windows

environment:
global:
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
# /E:ON and /V:ON options are not enabled in the batch script intepreter
# See: http://stackoverflow.com/a/13751649/163740
CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\continuous_integration\\appveyor\\run_with_env.cmd"

matrix:
- PYTHON: "C:\\Python27_32"
PYTHON_VERSION: "2.7.8"
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python27"
PYTHON_VERSION: "2.7.8"
PYTHON_ARCH: "64"

- PYTHON: "C:\\Python34_32"
PYTHON_VERSION: "3.4.1"
PYTHON_ARCH: "32"

- PYTHON: "C:\\Python34"
PYTHON_VERSION: "3.4.1"
PYTHON_ARCH: "64"

install:
# Install Python (from the official .msi of http://python.org) and pip when
# not already installed.
- "powershell ./continuous_integration/appveyor/install.ps1"
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"

# Check that we have the expected version and architecture for Python
- "python --version"
- "python -c \"import struct; print(struct.calcsize('P') * 8)\""

# Install the build and runtime dependencies of the project.
- "%CMD_IN_ENV% pip install -r continuous_integration/appveyor/requirements.txt"
- "%CMD_IN_ENV% python setup.py bdist_wheel bdist_wininst -b doc/logos/scikit-learn-logo.bmp"
- ps: "ls dist"

# Install the genreated wheel package to test it
- "pip install --pre --no-index --find-links dist/ scikit-learn"

# Not a .NET project, we build scikit-learn in the install step instead
build: false

test_script:
# Change to a non-source folder to make sure we run the tests on the
# installed library.
- "SET PROJECT_DIR=%CD%"
- "cd C:\\"

# Skip joblib tests that require multiprocessing as they are prone to random
# slow down
- "python -c \"import nose; nose.main()\" -v -s --with-noseexclude --exclude-test-file=%PROJECT_DIR%/continuous_integration/exclude_joblib_mp.txt sklearn"

artifacts:
# Archive the generated wheel package in the ci.appveyor.com build report.
- path: dist\*

#on_success:
# - TODO: upload the content of dist/*.whl to a public wheelhouse
90 changes: 90 additions & 0 deletions continuous_integration/appveyor/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel and Kyle Kastner
# License: BSD 3 clause

$BASE_URL = "https://www.python.org/ftp/python/"
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"


function DownloadPython ($python_version, $platform_suffix) {
$webclient = New-Object System.Net.WebClient
$filename = "python-" + $python_version + $platform_suffix + ".msi"
$url = $BASE_URL + $python_version + "/" + $filename

$basedir = $pwd.Path + "\"
$filepath = $basedir + $filename
if (Test-Path $filename) {
Write-Host "Reusing" $filepath
return $filepath
}

# Download and retry up to 3 times in case of network transient errors.
Write-Host "Downloading" $filename "from" $url
$retry_attempts = 2
for($i=0; $i -lt $retry_attempts; $i++){
try {
$webclient.DownloadFile($url, $filepath)
break
}
Catch [Exception]{
Start-Sleep 1
}
}
if (Test-Path $filepath) {
Write-Host "File saved at" $filepath
} else {
# Retry once to get the error message if any at the last try
$webclient.DownloadFile($url, $filepath)
}
return $filepath
}


function InstallPython ($python_version, $architecture, $python_home) {
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home
if (Test-Path $python_home) {
Write-Host $python_home "already exists, skipping."
return $false
}
if ($architecture -eq "32") {
$platform_suffix = ""
} else {
$platform_suffix = ".amd64"
}
$filepath = DownloadPython $python_version $platform_suffix
Write-Host "Installing" $filepath "to" $python_home
$install_log = $python_home + ".log"
$args = "/qn /log $install_log /i $filepath TARGETDIR=$python_home"
Write-Host "msiexec.exe" $args
Start-Process -FilePath "msiexec.exe" -ArgumentList $args -Wait -Passthru
if (Test-Path $python_home) {
Write-Host "Python $python_version ($architecture) installation complete"
} else {
Write-Host "Failed to install Python in $python_home"
Get-Content -Path $install_log
Exit 1
}
}


function InstallPip ($python_home) {
$pip_path = $python_home + "\Scripts\pip.exe"
$python_path = $python_home + "\python.exe"
if (-not(Test-Path $pip_path)) {
Write-Host "Installing pip..."
$webclient = New-Object System.Net.WebClient
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
Write-Host "Executing:" $python_path $GET_PIP_PATH
Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru
} else {
Write-Host "pip already installed."
}
}

function main () {
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
InstallPip $env:PYTHON
}

main
11 changes: 11 additions & 0 deletions continuous_integration/appveyor/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Fetch numpy and scipy wheels from the sklearn rackspace wheelhouse.
# Those wheels were generated by @ogrisel by calling `wheel convert` on
# the binaries from http://www.lfd.uci.edu/~gohlke/pythonlibs/
# This is a temporary solution. As soon as numpy and scipy provide official
# wheel for windows we ca delete this --find-links line.
--find-links http://28daf2247a33ed269873-7b1aad3fab3cc330e1fd9d109892382a.r6.cf2.rackcdn.com/index.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this scary-looking url?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a temporary wheelhouse we host on the rackspace cloud account of the sklearn project to host numpy and scipy wheels built from Christoph Gohlke's installers. I will add an inline comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/we ca delete/we can delete
Thanks for the clarification. The note about how they're obtained is definitely useful.

numpy
scipy
nose
nose-exclude
wheel
47 changes: 47 additions & 0 deletions continuous_integration/appveyor/run_with_env.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
::
:: To build extensions for 64 bit Python 2, we need to configure environment
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
::
:: 32 bit builds do not require specific environment configurations.
::
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
:: cmd interpreter, at least for (SDK v7.0)
::
:: More details at:
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
:: http://stackoverflow.com/a/13751649/163740
::
:: Author: Olivier Grisel
:: License: BSD 3 clause
@ECHO OFF

SET COMMAND_TO_RUN=%*
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows

SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%"
IF %MAJOR_PYTHON_VERSION% == "2" (
SET WINDOWS_SDK_VERSION="v7.0"
) ELSE IF %MAJOR_PYTHON_VERSION% == "3" (
SET WINDOWS_SDK_VERSION="v7.1"
) ELSE (
ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
EXIT 1
)

IF "%PYTHON_ARCH%"=="64" (
ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
SET DISTUTILS_USE_SDK=1
SET MSSdk=1
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
) ELSE (
ECHO Using default MSVC build environment for 32 bit architecture
ECHO Executing: %COMMAND_TO_RUN%
call %COMMAND_TO_RUN% || EXIT 1
)
16 changes: 16 additions & 0 deletions sklearn/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import inspect
import pickle
import pkgutil
import struct

import numpy as np
from scipy import sparse
Expand Down Expand Up @@ -198,7 +199,22 @@ def test_transformers():
yield check_transformer, name, Transformer, X, y


def _is_32bit_windows():
"""Detect if process is 32bit Python running on Windows."""
return sys.platform == 'win32' and struct.calcsize('P') * 8 == 32


def check_transformer(name, Transformer, X, y):
if (name in ('CCA', 'LocallyLinearEmbedding', 'KernelPCA')
and _is_32bit_windows()):
# Those transformers yield non-deterministic output on Windows
# with a 32bit Python. The same transformers are stable with 32bit
# Python on other platforms or 64bit Python under Windows.
# FIXME: try to isolate a minimalistic reproduction case only depending
# on numpy & scipy
msg = name + ' is non deterministic on 32bit Python for Windows'
raise SkipTest(msg)

n_samples, n_features = X.shape
# catch deprecation warnings
with warnings.catch_warnings(record=True):
Expand Down