properties([ parameters([ string(defaultValue: '', description: 'The version from PyPI to build', name: 'BUILD_VERSION') ]), pipelineTriggers([]) ]) def configs = [ [ label: 'windows', versions: ['py27', 'py34', 'py35', 'py36'], ], [ label: 'windows64', versions: ['py27', 'py34', 'py35', 'py36'], ], [ label: 'sierra', // The py3x version listed here corresponds to the minimum ABI version // the wheels will support. e.g. py34 supports py34+ versions: ['py27', 'py34'], ], [ label: 'docker', imageName: 'pyca/cryptography-manylinux1:i686', // The py3x version listed here corresponds to the minimum ABI version // the wheels will support. e.g. cp34-cp34m supports py34+ versions: [ 'cp27-cp27m', 'cp27-cp27mu', 'cp34-cp34m', ], ], [ label: 'docker', imageName: 'pyca/cryptography-manylinux1:x86_64', // The py3x version listed here corresponds to the minimum ABI version // the wheels will support. e.g. cp34-cp34m supports py34+ versions: [ 'cp27-cp27m', 'cp27-cp27mu', 'cp34-cp34m', ], ], ] def build(version, label, imageName) { try { timeout(time: 30, unit: 'MINUTES') { if (label.contains("windows")) { def pythonPath = [ py27: "C:\\Python27\\python.exe", py34: "C:\\Python34\\python.exe", py35: "C:\\Python35\\python.exe", py36: "C:\\Python36\\python.exe" ] if (version == "py35" || version == "py36") { opensslPaths = [ "windows": [ "include": "C:\\OpenSSL-Win32-2015\\include", "lib": "C:\\OpenSSL-Win32-2015\\lib" ], "windows64": [ "include": "C:\\OpenSSL-Win64-2015\\include", "lib": "C:\\OpenSSL-Win64-2015\\lib" ] ] } else { opensslPaths = [ "windows": [ "include": "C:\\OpenSSL-Win32-2010\\include", "lib": "C:\\OpenSSL-Win32-2010\\lib" ], "windows64": [ "include": "C:\\OpenSSL-Win64-2010\\include", "lib": "C:\\OpenSSL-Win64-2010\\lib" ] ] } bat """ wmic qfe @set PATH="C:\\Python27";"C:\\Python27\\Scripts";%PATH% @set PYTHON="${pythonPath[version]}" @set INCLUDE="${opensslPaths[label]['include']}";%INCLUDE% @set LIB="${opensslPaths[label]['lib']}";%LIB% virtualenv -p %PYTHON% .release call .release\\Scripts\\activate pip install wheel virtualenv pip wheel cryptography==$BUILD_VERSION --wheel-dir=wheelhouse --no-binary cryptography pip install -f wheelhouse cryptography --no-index python -c "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" """ } else if (label.contains("sierra")) { def pythonPath = [ py27: "/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7", py34: "/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4", ] ansiColor { sh """#!/usr/bin/env bash set -xe # output the list of things we've installed as a point in time check of how up # to date the builder is /usr/sbin/system_profiler SPInstallHistoryDataType # Jenkins logs in as a non-interactive shell, so we don't even have /usr/local/bin in PATH export PATH="/usr/local/bin:\${PATH}" export PATH="/Users/jenkins/.pyenv/shims:\${PATH}" printenv virtualenv .venv -p ${pythonPath[version]} source .venv/bin/activate pip install -U wheel # upgrade wheel to latest before we use it to build the wheel pip install cffi six idna asn1crypto ipaddress enum34 pip download cryptography==$BUILD_VERSION --no-binary cryptography --no-deps tar zxf cryptography* pushd cryptography* REGEX="py3([0-9])*" if [[ "${version}" =~ \$REGEX ]]; then PY_LIMITED_API="--py-limited-api=cp3\${BASH_REMATCH[1]}" fi CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS="1" \ LDFLAGS="/usr/local/opt/openssl@1.1/lib/libcrypto.a /usr/local/opt/openssl@1.1/lib/libssl.a" \ CFLAGS="-I/usr/local/opt/openssl@1.1/include -mmacosx-version-min=10.9" \ python setup.py bdist_wheel --dist-dir=../wheelhouse \$PY_LIMITED_API popd pip install -f wheelhouse cryptography --no-index python -c "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" otool -L `find .venv -name '_openssl*.so'` lipo -info `find .venv -name '*.so'` otool -L `find .venv -name '_openssl*.so'` | grep -vG "libcrypto\\|libssl" """ } } else if (label.contains("docker")) { linux32 = "" if (imageName.contains("i686")) { linux32 = "linux32" } sh """#!/usr/bin/env bash set -x -e $linux32 /opt/python/$version/bin/pip install cffi six idna asn1crypto ipaddress enum34 $linux32 /opt/python/$version/bin/pip download cryptography==$BUILD_VERSION --no-binary cryptography --no-deps tar zxf cryptography* # Because we are doing this as root in the container, but we write to a mounted dir that is outside the container # we need to make sure we set these files writable such that the jenkins user can delete them afterwards mkdir -p tmpwheelhouse mkdir -p wheelhouse chmod -R 777 tmpwheelhouse chmod -R 777 wheelhouse pushd cryptography* REGEX="cp3([0-9])*" if [[ "${version}" =~ \$REGEX ]]; then PY_LIMITED_API="--py-limited-api=cp3\${BASH_REMATCH[1]}" fi LDFLAGS="-L/opt/pyca/cryptography/openssl/lib" \ CFLAGS="-I/opt/pyca/cryptography/openssl/include -Wl,--exclude-libs,ALL" \ $linux32 /opt/python/$version/bin/python setup.py bdist_wheel --dist-dir=../tmpwheelhouse \$PY_LIMITED_API popd chmod -R 777 cryptography* $linux32 auditwheel repair tmpwheelhouse/cryptography*.whl -w wheelhouse/ unzip wheelhouse/*.whl -d execstack.check chmod -R 777 execstack.check (execstack execstack.check/cryptography/hazmat/bindings/*.so | grep '^X') && exit 1 $linux32 /opt/python/$version/bin/pip install cryptography==$BUILD_VERSION --no-index -f wheelhouse/ $linux32 /opt/python/$version/bin/python -c "from cryptography.hazmat.backends.openssl.backend import backend;print('Loaded: ' + backend.openssl_version_text());print('Linked Against: ' + backend._ffi.string(backend._lib.OPENSSL_VERSION_TEXT).decode('ascii'))" """ } archiveArtifacts artifacts: "wheelhouse/cryptography*.whl" } } finally { deleteDir() } } def builders = [:] for (config in configs) { def label = config["label"] def versions = config["versions"] for (_version in versions) { def version = _version if (label.contains("docker")) { def imageName = config["imageName"] def combinedName = "${imageName}-${version}" builders[combinedName] = { node(label) { stage(combinedName) { def buildImage = docker.image(imageName) buildImage.pull() buildImage.inside("-u root") { build(version, label, imageName) } } } } } else { def combinedName = "${label}-${version}" builders[combinedName] = { node(label) { stage(combinedName) { build(version, label, "") } } } } } } parallel builders