Skip to content

Commit 66745db

Browse files
committed
safety 1.8.6 now support binary releases
1 parent 955de59 commit 66745db

File tree

9 files changed

+241
-24
lines changed

9 files changed

+241
-24
lines changed

Dockerfilei386

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# this dockerfile is used to build the 32bit linux binary
2+
FROM i386/ubuntu:18.04
3+
RUN apt-get update && apt-get -y install python3 python3-dev python3-pip
4+
COPY requirements_dev.txt /requirements_dev.txt
5+
RUN pip3 install -r /requirements_dev.txt
6+
RUN mkdir /app
7+
WORKDIR /app
8+
9+
ENV LC_ALL=C.UTF-8
10+
ENV LANG=C.UTF-8

HISTORY.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
History
33
=======
44

5+
1.8.6 (2019-03-10)
6+
------------------
7+
8+
* Safety is now available as a binary release for macOS, Windows and Linux.
9+
510
1.8.5 (2019-02-04)
611
------------------
712

RELEASE.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Release
2+
3+
Safety is distributed as a binary for Windows 32/64 bit, Linux 32/64 bit and macOS 64 bit.
4+
The binary is built on appveyor (see `appveyor.py` and `appveyor.yml`) and distributed through GitHub.
5+
6+
## Issuing a new release
7+
8+
First, update the version string in `setup.py` and `safety/__init__.py` and push the changes to master.
9+
10+
Make sure the release builds properly on appveyor prior to tagging it.
11+
12+
To issue a new release, tag the release with `git tag 1.x.x` and push the tag with `git push origin --tags`.
13+
Once the build is completed and all artifacts are collected, the binaries are uploaded as a GitHub release.
14+

appveyor.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""
2+
This file is used to build and distribute the safety binary on appveyor, take a look at the corresponding appveyor.yml.
3+
"""
4+
import os
5+
import sys
6+
import subprocess
7+
8+
9+
class environment:
10+
11+
def __init__(self):
12+
os_mapping = {
13+
"Visual Studio 2019": "win",
14+
"Ubuntu": "linux",
15+
"macOS": "macos"
16+
}
17+
self.os = os_mapping[os.getenv("APPVEYOR_BUILD_WORKER_IMAGE")]
18+
19+
@property
20+
def python(self):
21+
for arch, python in self.PYTHON_BINARIES[self.os].items():
22+
yield arch, python
23+
24+
WIN = "win"
25+
LINUX = "linux"
26+
MACOS = "macos"
27+
28+
PYTHON_BINARIES = {
29+
WIN: {
30+
64: "C:\\Python38-x64\\python.exe",
31+
32: "C:\\Python38\\python.exe",
32+
33+
},
34+
LINUX: {
35+
# order is important. if the 32 bit release gets built first,
36+
# you'll run into permission problems due to docker clobbering
37+
# up the current working directory
38+
64: "python",
39+
# 32 bit linux is built using docker
40+
32: f"docker run -t -v {os.getcwd()}:/app 32-bit-linux python3",
41+
42+
},
43+
MACOS: {
44+
# on macOS the binary is built using Python 3.7 (installed via Homebrew), because
45+
# the shipped Python lacks libraries PyInstaller needs.
46+
64: "/usr/local/bin/python3",
47+
}
48+
}
49+
50+
def run(self, command):
51+
"""
52+
Runs the given command via subprocess.check_output, exits with -1 if the command wasn't successfull.
53+
"""
54+
try:
55+
print(f"RUNNING: {command}")
56+
print("-" * 80)
57+
print(subprocess.check_output(command, shell=True))
58+
except subprocess.CalledProcessError as e:
59+
print(f"ERROR calling '{command}'")
60+
print("-" * 20)
61+
print(e.output)
62+
sys.exit(-1)
63+
64+
def install(self):
65+
"""
66+
Install required dependencies
67+
"""
68+
# special case:
69+
# - build the 32 bit binary for linux on docker
70+
# - create dist/ path to circumvent permission errors
71+
if self.os == self.LINUX:
72+
self.run("docker build -t 32-bit-linux -f Dockerfilei386 .")
73+
74+
for arch, python in self.python:
75+
self.run(f"{python} -m pip install -r requirements_dev.txt")
76+
77+
def dist(self):
78+
"""
79+
Runs Pyinstaller producing a single file binary for every available arch for the current platform.
80+
"""
81+
for arch, python in self.python:
82+
83+
# build the binary
84+
build_path = os.path.join("dist", f"safety-{arch}")
85+
self.run(f"{python} -m PyInstaller safety.spec --distpath {build_path}")
86+
87+
# there seems to be no way to tell pyinstaller the name of the actual binary
88+
# this leads to problems with appveyors artifact collector because every binary is named the same
89+
# move them around so they can be picked up correctly
90+
artifact_path = os.path.join(os.getcwd(), "dist", f"safety-{self.os}-{'i686' if arch == 32 else 'x86_64'}")
91+
binary_path = os.path.join(os.getcwd(), build_path, "safety")
92+
if self.os == self.WIN:
93+
self.run(f"move {binary_path}.exe {artifact_path}.exe")
94+
else:
95+
self.run(f"cp {binary_path} {artifact_path}")
96+
97+
def test(self):
98+
"""
99+
Runs tests for every available arch on the current platform.
100+
"""
101+
for arch, python in self.python:
102+
self.run(f"{python} setup.py test")
103+
104+
105+
if __name__ == "__main__":
106+
107+
if len(sys.argv) <= 1 or sys.argv[1] not in ['install', 'test', 'dist']:
108+
print("usage: appveyor.py [install|test|dist]")
109+
sys.exit(-1)
110+
111+
env = environment()
112+
# runs the command in sys.argv[1] (install|test|dist)
113+
getattr(env, sys.argv[1])()
114+
sys.exit(0)

appveyor.yml

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,58 @@
1-
environment:
1+
image:
2+
- Visual Studio 2019
3+
- Ubuntu
4+
- macOS
5+
6+
# note: on macOS the binary is built using Python 3.7 (installed via Homebrew), because
7+
# the shipped Python lacks libraries PyInstaller needs.
8+
stack: python 3.6
29

10+
# note: 32 bit linux binary is build using docker
11+
for:
12+
-
313
matrix:
4-
- PYTHON: "C:\\Python27"
5-
- PYTHON: "C:\\Python35"
6-
- PYTHON: "C:\\Python27-x64"
7-
DISTUTILS_USE_SDK: "1"
8-
- PYTHON: "C:\\Python34-x64"
9-
DISTUTILS_USE_SDK: "1"
10-
- PYTHON: "C:\\Python35-x64"
14+
only:
15+
- image: Ubuntu
1116

12-
install:
13-
- "%PYTHON%\\python.exe -m pip install wheel"
14-
- "%PYTHON%\\python.exe -m pip install setuptools --upgrade"
15-
17+
services:
18+
- docker
19+
20+
environment:
21+
PY_DIR: C:\Python36-x64
22+
23+
init:
24+
- cmd: set PATH=%PY_DIR%;%PY_DIR%\Scripts;%PATH%
1625

1726
build: off
1827

28+
artifacts:
29+
- path: "dist\\safety-win-i686.exe"
30+
name: "safety-win-i686.exe"
31+
- path: "dist\\safety-win-x86_64.exe"
32+
name: "safety-win-x86_64.exe"
33+
- path: "dist\\safety-linux-i686"
34+
name: "safety-linux-i686"
35+
- path: "dist\\safety-linux-x86_64"
36+
name: "safety-linux-x86_64"
37+
- path: "dist\\safety-macos-x86_64"
38+
name: "safety-macos-x86_64"
39+
40+
install:
41+
- "python --version"
42+
- "python appveyor.py install"
43+
1944
test_script:
20-
- "%PYTHON%\\python.exe setup.py test"
21-
- "%PYTHON%\\python.exe -m pip freeze"
45+
- "python appveyor.py test"
46+
- "python appveyor.py dist"
47+
48+
49+
deploy:
50+
description: ''
51+
provider: GitHub
52+
auth_token:
53+
secure: dDJgAsevLfBL9BKNuCKpbFhB5rlfbefw696Xe6Na8BhHabwoGYcg8FydNpppnKzX
54+
draft: false
55+
prerelease: false
56+
on:
57+
branch: master
58+
APPVEYOR_REPO_TAG: true

requirements_dev.txt

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
pip==18.1
2-
wheel==0.32.3
3-
watchdog==0.9.0
4-
flake8==3.6.0
5-
PyYAML==4.2b4
6-
cryptography==2.4.2
7-
coverage==4.5.2
8-
Sphinx==1.8.3
1+
Click==7.0
2+
requests==2.23.0
3+
packaging==20.3
4+
dparse==0.4.1
5+
pyinstaller==3.6

safety.spec

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
3+
block_cipher = None
4+
5+
a = Analysis(
6+
['safety/cli.py'],
7+
pathex=['.'],
8+
binaries=[],
9+
datas=[],
10+
hiddenimports=[
11+
'click',
12+
],
13+
hookspath=[],
14+
runtime_hooks=[],
15+
excludes=[],
16+
win_no_prefer_redirects=False,
17+
win_private_assemblies=False,
18+
cipher=block_cipher,
19+
noarchive=False
20+
)
21+
pyz = PYZ(
22+
a.pure, a.zipped_data,
23+
cipher=block_cipher
24+
)
25+
exe = EXE(
26+
pyz,
27+
a.scripts,
28+
a.binaries,
29+
a.zipfiles,
30+
a.datas,
31+
[],
32+
name='safety',
33+
debug=False,
34+
bootloader_ignore_signals=False,
35+
strip=False,
36+
upx=True,
37+
upx_exclude=[],
38+
runtime_tmpdir=None,
39+
console=True
40+
)

safety/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
__author__ = """pyup.io"""
44
__email__ = '[email protected]'
5-
__version__ = '1.8.5'
5+
__version__ = '1.8.6'

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
setup(
3333
name='safety',
34-
version='1.8.5',
34+
version='1.8.6',
3535
description="Safety checks your installed dependencies for known security vulnerabilities.",
3636
long_description=readme + '\n\n' + history,
3737
long_description_content_type="text/markdown",

0 commit comments

Comments
 (0)