Skip to content

Commit

Permalink
safety 1.8.6 now support binary releases
Browse files Browse the repository at this point in the history
  • Loading branch information
jayfk committed Mar 10, 2020
1 parent 955de59 commit 66745db
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 24 deletions.
10 changes: 10 additions & 0 deletions Dockerfilei386
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# this dockerfile is used to build the 32bit linux binary
FROM i386/ubuntu:18.04
RUN apt-get update && apt-get -y install python3 python3-dev python3-pip
COPY requirements_dev.txt /requirements_dev.txt
RUN pip3 install -r /requirements_dev.txt
RUN mkdir /app
WORKDIR /app

ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
History
=======

1.8.6 (2019-03-10)
------------------

* Safety is now available as a binary release for macOS, Windows and Linux.

1.8.5 (2019-02-04)
------------------

Expand Down
14 changes: 14 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Release

Safety is distributed as a binary for Windows 32/64 bit, Linux 32/64 bit and macOS 64 bit.
The binary is built on appveyor (see `appveyor.py` and `appveyor.yml`) and distributed through GitHub.

## Issuing a new release

First, update the version string in `setup.py` and `safety/__init__.py` and push the changes to master.

Make sure the release builds properly on appveyor prior to tagging it.

To issue a new release, tag the release with `git tag 1.x.x` and push the tag with `git push origin --tags`.
Once the build is completed and all artifacts are collected, the binaries are uploaded as a GitHub release.

114 changes: 114 additions & 0 deletions appveyor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
"""
This file is used to build and distribute the safety binary on appveyor, take a look at the corresponding appveyor.yml.
"""
import os
import sys
import subprocess


class environment:

def __init__(self):
os_mapping = {
"Visual Studio 2019": "win",
"Ubuntu": "linux",
"macOS": "macos"
}
self.os = os_mapping[os.getenv("APPVEYOR_BUILD_WORKER_IMAGE")]

@property
def python(self):
for arch, python in self.PYTHON_BINARIES[self.os].items():
yield arch, python

WIN = "win"
LINUX = "linux"
MACOS = "macos"

PYTHON_BINARIES = {
WIN: {
64: "C:\\Python38-x64\\python.exe",
32: "C:\\Python38\\python.exe",

},
LINUX: {
# order is important. if the 32 bit release gets built first,
# you'll run into permission problems due to docker clobbering
# up the current working directory
64: "python",
# 32 bit linux is built using docker
32: f"docker run -t -v {os.getcwd()}:/app 32-bit-linux python3",

},
MACOS: {
# on macOS the binary is built using Python 3.7 (installed via Homebrew), because
# the shipped Python lacks libraries PyInstaller needs.
64: "/usr/local/bin/python3",
}
}

def run(self, command):
"""
Runs the given command via subprocess.check_output, exits with -1 if the command wasn't successfull.
"""
try:
print(f"RUNNING: {command}")
print("-" * 80)
print(subprocess.check_output(command, shell=True))
except subprocess.CalledProcessError as e:
print(f"ERROR calling '{command}'")
print("-" * 20)
print(e.output)
sys.exit(-1)

def install(self):
"""
Install required dependencies
"""
# special case:
# - build the 32 bit binary for linux on docker
# - create dist/ path to circumvent permission errors
if self.os == self.LINUX:
self.run("docker build -t 32-bit-linux -f Dockerfilei386 .")

for arch, python in self.python:
self.run(f"{python} -m pip install -r requirements_dev.txt")

def dist(self):
"""
Runs Pyinstaller producing a single file binary for every available arch for the current platform.
"""
for arch, python in self.python:

# build the binary
build_path = os.path.join("dist", f"safety-{arch}")
self.run(f"{python} -m PyInstaller safety.spec --distpath {build_path}")

# there seems to be no way to tell pyinstaller the name of the actual binary
# this leads to problems with appveyors artifact collector because every binary is named the same
# move them around so they can be picked up correctly
artifact_path = os.path.join(os.getcwd(), "dist", f"safety-{self.os}-{'i686' if arch == 32 else 'x86_64'}")
binary_path = os.path.join(os.getcwd(), build_path, "safety")
if self.os == self.WIN:
self.run(f"move {binary_path}.exe {artifact_path}.exe")
else:
self.run(f"cp {binary_path} {artifact_path}")

def test(self):
"""
Runs tests for every available arch on the current platform.
"""
for arch, python in self.python:
self.run(f"{python} setup.py test")


if __name__ == "__main__":

if len(sys.argv) <= 1 or sys.argv[1] not in ['install', 'test', 'dist']:
print("usage: appveyor.py [install|test|dist]")
sys.exit(-1)

env = environment()
# runs the command in sys.argv[1] (install|test|dist)
getattr(env, sys.argv[1])()
sys.exit(0)
65 changes: 51 additions & 14 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,58 @@
environment:
image:
- Visual Studio 2019
- Ubuntu
- macOS

# note: on macOS the binary is built using Python 3.7 (installed via Homebrew), because
# the shipped Python lacks libraries PyInstaller needs.
stack: python 3.6

# note: 32 bit linux binary is build using docker
for:
-
matrix:
- PYTHON: "C:\\Python27"
- PYTHON: "C:\\Python35"
- PYTHON: "C:\\Python27-x64"
DISTUTILS_USE_SDK: "1"
- PYTHON: "C:\\Python34-x64"
DISTUTILS_USE_SDK: "1"
- PYTHON: "C:\\Python35-x64"
only:
- image: Ubuntu

install:
- "%PYTHON%\\python.exe -m pip install wheel"
- "%PYTHON%\\python.exe -m pip install setuptools --upgrade"

services:
- docker

environment:
PY_DIR: C:\Python36-x64

init:
- cmd: set PATH=%PY_DIR%;%PY_DIR%\Scripts;%PATH%

build: off

artifacts:
- path: "dist\\safety-win-i686.exe"
name: "safety-win-i686.exe"
- path: "dist\\safety-win-x86_64.exe"
name: "safety-win-x86_64.exe"
- path: "dist\\safety-linux-i686"
name: "safety-linux-i686"
- path: "dist\\safety-linux-x86_64"
name: "safety-linux-x86_64"
- path: "dist\\safety-macos-x86_64"
name: "safety-macos-x86_64"

install:
- "python --version"
- "python appveyor.py install"

test_script:
- "%PYTHON%\\python.exe setup.py test"
- "%PYTHON%\\python.exe -m pip freeze"
- "python appveyor.py test"
- "python appveyor.py dist"


deploy:
description: ''
provider: GitHub
auth_token:
secure: dDJgAsevLfBL9BKNuCKpbFhB5rlfbefw696Xe6Na8BhHabwoGYcg8FydNpppnKzX
draft: false
prerelease: false
on:
branch: master
APPVEYOR_REPO_TAG: true
13 changes: 5 additions & 8 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
pip==18.1
wheel==0.32.3
watchdog==0.9.0
flake8==3.6.0
PyYAML==4.2b4
cryptography==2.4.2
coverage==4.5.2
Sphinx==1.8.3
Click==7.0
requests==2.23.0
packaging==20.3
dparse==0.4.1
pyinstaller==3.6
40 changes: 40 additions & 0 deletions safety.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# -*- mode: python ; coding: utf-8 -*-

block_cipher = None

a = Analysis(
['safety/cli.py'],
pathex=['.'],
binaries=[],
datas=[],
hiddenimports=[
'click',
],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False
)
pyz = PYZ(
a.pure, a.zipped_data,
cipher=block_cipher
)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='safety',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True
)
2 changes: 1 addition & 1 deletion safety/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__author__ = """pyup.io"""
__email__ = 'support@pyup.io'
__version__ = '1.8.5'
__version__ = '1.8.6'
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

setup(
name='safety',
version='1.8.5',
version='1.8.6',
description="Safety checks your installed dependencies for known security vulnerabilities.",
long_description=readme + '\n\n' + history,
long_description_content_type="text/markdown",
Expand Down

0 comments on commit 66745db

Please sign in to comment.