Skip to content

Commit 79c0d27

Browse files
authored
Merge pull request #53 from magnusviri/main
Added github actions
2 parents 1f7e396 + e44cae6 commit 79c0d27

File tree

9 files changed

+212
-59
lines changed

9 files changed

+212
-59
lines changed

.github/workflows/build.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build and test python-jamf
2+
on:
3+
push:
4+
branches: [ main ]
5+
pull_request:
6+
branches: [ main ]
7+
jobs:
8+
build:
9+
strategy:
10+
matrix:
11+
os: [ ubuntu-latest, macos-10.15, macos-11 ]
12+
python-version: [ '3.7', '3.8', '3.9', 'pypy-3.7' ]
13+
name: Build on ${{ matrix.os }} using ${{ matrix.python-version }}
14+
runs-on: ${{ matrix.os }}
15+
steps:
16+
- name: Checkout sources
17+
uses: actions/checkout@v2
18+
- name: Initialize Python 3.7
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: ${{ matrix.python-version }}
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install flake8
26+
- name: Lint with flake8
27+
run: |
28+
# stop the build if there are Python syntax errors or undefined names
29+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
30+
# exit-zero treats all errors as warnings.
31+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
32+
- name: Run Unit Tests
33+
run: python -m unittest discover -s tests -p '*_test.py'
34+
codeql:
35+
name: Run CodeQL
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Checkout sources
39+
uses: actions/checkout@v2
40+
- name: Initialize Python 3.7
41+
uses: actions/setup-python@v2
42+
with:
43+
python-version: 3.7
44+
- name: Initialize CodeQL
45+
uses: github/codeql-action/init@v1
46+
with:
47+
languages: python
48+
- name: Perform CodeQL Analysis
49+
uses: github/codeql-action/analyze@v1

.github/workflows/python-package.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Build and publish python-jamf to Github and PyPI
2+
on:
3+
push:
4+
tags:
5+
- '*'
6+
jobs:
7+
build:
8+
name: Build
9+
runs-on: ubuntu-latest
10+
steps:
11+
- name: Checkout sources
12+
uses: actions/checkout@v2
13+
- name: Initialize Python 3.7
14+
uses: actions/setup-python@v2
15+
with:
16+
python-version: ${{ matrix.python-version }}
17+
- name: Install dependencies
18+
run: |
19+
python -m pip install --upgrade pip
20+
pip install flake8
21+
- name: Lint with flake8
22+
run: |
23+
# stop the build if there are Python syntax errors or undefined names
24+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
25+
# exit-zero treats all errors as warnings.
26+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
27+
- name: Run Unit Tests
28+
run: python -m unittest discover -s tests -p '*_test.py'
29+
release:
30+
name: Release
31+
needs: [build]
32+
runs-on: ubuntu-latest
33+
steps:
34+
- uses: actions/checkout@v2
35+
- uses: actions/setup-python@v2
36+
with:
37+
python-version: 3.7
38+
- name: Build binary wheel and a source tarball
39+
run: python setup.py sdist
40+
- name: Publish to PyPI
41+
uses: pypa/gh-action-pypi-publish@master
42+
with:
43+
password: ${{ secrets.PYPI_PASSWORD }}
44+
repository_url: https://upload.pypi.org/legacy/
45+
- name: Create GitHub Release
46+
uses: actions/create-release@v1
47+
id: create_release
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
with:
51+
tag_name: ${{ github.ref }}
52+
release_name: ${{ github.ref }}
53+
draft: true
54+
prerelease: false
55+
- name: Publish to GitHub
56+
uses: xresloader/upload-to-github-release@v1
57+
env:
58+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
59+
with:
60+
file: "dist/*"
61+
release_id: ${{ steps.create_release.outputs.id }}

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515
notes.md
1616
dist
1717
build
18-
archieve
18+
archive
19+
/jamf/VERSION

jamf/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@
1010
from . import package
1111
from . import convert
1212
from .records import *
13-
from .setconfig import setconfig
14-
__version__ = "0.6.5"
13+
from . import version

jamf/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ def package_index(path, cleanup=True):
690690
# process all boms included in package
691691
boms = [x for x in boms.splitlines() if x]
692692
if not boms:
693-
raise RuntimeError(f"no bill of materials found: {pkg}")
693+
raise RuntimeError(f"no bill of materials found: {path}")
694694
# see `man lsbom` for formatting
695695
logger.debug(f"> lsbom -p fMguTsc '%s'", "', '".join(boms))
696696
cmd = ['/usr/bin/lsbom', '-p', 'fMguTsc'] + boms
@@ -702,7 +702,7 @@ def package_index(path, cleanup=True):
702702

703703
if cleanup:
704704
# cleanup all bom files created in /tmp by `pkgutil`
705-
for path in glob.glob(f"/tmp/{pkg}.boms*"):
705+
for path in glob.glob(f"/tmp/{path}.boms*"):
706706
shutil.rmtree(path)
707707

708708
form = []

jamf/package.py

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from xml.etree import ElementTree as ET
2424

2525
from .records import Categories
26+
from . import config
2627

2728
# GLOBALS
2829
TMPDIR = os.environ.get('TMPDIR', '/tmp')
@@ -58,8 +59,8 @@ def find_name(self, name):
5859
:returns Package:
5960
"""
6061
raise NotImplementedError()
61-
if not name and not jssid and not path:
62-
raise ValueError("must specify name, path, or ID")
62+
#if not name and not jssid and not path:
63+
# raise ValueError("must specify name, path, or ID")
6364

6465
def _find(self, key, value):
6566
"""
@@ -617,44 +618,44 @@ def install_package(pkg, target='/'):
617618
"""
618619
logger = logging.getLogger(__name__)
619620
path = pkg.path.absolute() if isinstance(pkg, Package) else pkg
620-
self.log.info(f"installing package: {path}")
621+
logger.info(f"installing package: {path}")
621622
cmd = ['/usr/sbin/installer', '-pkg', path, '-target', target]
622623
logger.debug(f"> sudo -n installer -pkg {path!r} -target {target!r}")
623624
subprocess.check_call(['/usr/bin/sudo', '-n'] + cmd)
624625

625626

626-
def jss_package_details(api, name=None):
627-
"""
628-
:returns: detailed list of all packages in the JSS
629-
"""
630-
# Each dict has the following keys:
631-
# ['allow_uninstalled', # <bool> likely the index value (would be cool if it could be indexed via modification)
632-
# 'boot_volume_required', # <bool> ? (universally: False)
633-
# 'category', # <str> name of category
634-
# 'filename', # <str> name of pkg file
635-
# 'fill_existing_users', # <bool> ? (universally: False)
636-
# 'fill_user_template', # <bool> ? (universally: False)
637-
# 'id', # <int> JSS id
638-
# 'info', # <str> contents of "Info" field
639-
# 'install_if_reported_available', # <str> ? (universally: 'false')
640-
# 'name', # <str> name of package (typically same as filename)
641-
# 'notes', # <str> contents of "Notes" field
642-
# 'os_requirements', # <str> os requirements? (universally: '')
643-
# 'priority', # <int> installation priority? (universally: 10)
644-
# 'reboot_required', # <bool> package requires reboot
645-
# 'reinstall_option', # <str> ? (universally: "Do Not Reinstall")
646-
# 'required_processor', # <str> processor limitation? (universally: 'None')
647-
# 'send_notification', # <bool> ? (universally: False)
648-
# 'switch_with_package', # <str> ? (universally: 'Do Not Install')
649-
# 'triggering_files'] # <dict> ? (universally: {})
650-
651-
# detailed list of every package (takes a long time)
652-
pkgs = []
653-
# isolating packages by name is handled by packages()
654-
for pkg in packages(api, name):
655-
details = api.get(f"packages/id/{pkg['id']}")
656-
pkgs.append(details['package'])
657-
return pkgs
627+
# def jss_package_details(api, name=None):
628+
# """
629+
# :returns: detailed list of all packages in the JSS
630+
# """
631+
# # Each dict has the following keys:
632+
# # ['allow_uninstalled', # <bool> likely the index value (would be cool if it could be indexed via modification)
633+
# # 'boot_volume_required', # <bool> ? (universally: False)
634+
# # 'category', # <str> name of category
635+
# # 'filename', # <str> name of pkg file
636+
# # 'fill_existing_users', # <bool> ? (universally: False)
637+
# # 'fill_user_template', # <bool> ? (universally: False)
638+
# # 'id', # <int> JSS id
639+
# # 'info', # <str> contents of "Info" field
640+
# # 'install_if_reported_available', # <str> ? (universally: 'false')
641+
# # 'name', # <str> name of package (typically same as filename)
642+
# # 'notes', # <str> contents of "Notes" field
643+
# # 'os_requirements', # <str> os requirements? (universally: '')
644+
# # 'priority', # <int> installation priority? (universally: 10)
645+
# # 'reboot_required', # <bool> package requires reboot
646+
# # 'reinstall_option', # <str> ? (universally: "Do Not Reinstall")
647+
# # 'required_processor', # <str> processor limitation? (universally: 'None')
648+
# # 'send_notification', # <bool> ? (universally: False)
649+
# # 'switch_with_package', # <str> ? (universally: 'Do Not Install')
650+
# # 'triggering_files'] # <dict> ? (universally: {})
651+
#
652+
# # detailed list of every package (takes a long time)
653+
# pkgs = []
654+
# # isolating packages by name is handled by packages()
655+
# for pkg in jamf_records(Packages, name):
656+
# details = api.get(f"packages/id/{pkg['id']}")
657+
# pkgs.append(details['package'])
658+
# return pkgs
658659

659660

660661
def jss_packages(jss, name=None):
@@ -696,7 +697,6 @@ def installer_packages():
696697
b_info = plistlib.load(f)
697698
info[name] = {'pkgs': pkgs, 'folder': folder,
698699
'build': b_info, 'name': name}
699-
pprint.pprint(info)
700700

701701

702702
def pkgutil(*args):

jamf/setconfig.py

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,9 @@ def parse(self, argv):
7171
return self.parser.parse_args(argv)
7272

7373
def check_version():
74-
75-
try:
76-
jamf_first, jamf_second, jamf_third = jamf.__version__.split(".")
77-
min_first, min_second, min_third = min_jamf_version.split(".")
78-
79-
if ( int(jamf_first) <= int(min_first) and
80-
int(jamf_second) <= int(min_second) and
81-
int(jamf_third) < int(min_third)):
82-
print(f"Your Version is: {jamf.__version__}, you need at least version {min_jamf_version} to run jctl.")
83-
sys.exit()
84-
85-
except AttributeError:
86-
print(f"Your Version is below 0.4.2, you need at least version {min_jamf_version} to run jctl.")
87-
sys.exit()
74+
if not jamf.version.check_version(min_jamf_version):
75+
print(f"setconfig requires python-jamf {min_jamf_version} or newer.")
76+
sys.exit()
8877

8978
def setconfig(argv):
9079
logger = logging.getLogger(__name__)
@@ -107,7 +96,12 @@ def setconfig(argv):
10796
if args.path:
10897
config_path = args.path
10998
else:
110-
config_path = self.default_pref
99+
myplatform = platform.system()
100+
if myplatform == "Darwin":
101+
default_pref = jamf.config.MACOS_PREFS_TILDA
102+
elif myplatform == "Linux":
103+
default_pref = jamf.config.LINUX_PREFS_TILDA
104+
config_path = default_pref
111105

112106
if config_path[0] == '~':
113107
config_path = path.expanduser(config_path)

jamf/version.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
"""
6+
7+
import os
8+
9+
__all__ = (
10+
'string',
11+
'check_version'
12+
)
13+
14+
def string():
15+
try:
16+
with open(os.path.dirname(__file__) + "/VERSION", "r", encoding="utf-8") as fh:
17+
version = fh.read().strip()
18+
if version:
19+
return version
20+
except:
21+
pass
22+
return "unknown (git checkout)"
23+
24+
25+
def check_version(min_version):
26+
try:
27+
jamf_1, jamf_2, jamf_3 = string().split(".")
28+
min_1, min_2, min_3 = min_version.split(".")
29+
if ( int(jamf_1) <= int(min_1) and
30+
int(jamf_2) <= int(min_2) and
31+
int(jamf_3) < int(min_3)):
32+
return False
33+
except AttributeError:
34+
return False
35+
return True

setup.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,33 @@
11
import setuptools
2+
import subprocess
3+
import os
24

3-
with open("README.md", "r") as fh:
5+
jctl_version = (
6+
subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE)
7+
.stdout.decode("utf-8")
8+
.strip()
9+
)
10+
assert "." in jctl_version
11+
12+
assert os.path.isfile("jamf/version.py")
13+
with open("jamf/VERSION", "w", encoding="utf-8") as fh:
14+
fh.write(f"{jctl_version}\n")
15+
16+
with open("README.md", "r", encoding="utf-8") as fh:
417
long_description = fh.read()
518

619
setuptools.setup(
720
name="python-jamf",
8-
version="0.6.5",
21+
version=jctl_version,
922
author="The University of Utah",
1023
author_email="[email protected]",
1124
description="Python wrapper for Jamf Pro API",
1225
long_description=long_description,
1326
long_description_content_type="text/markdown",
1427
url="https://github.com/univ-of-utah-marriott-library-apple/python-jamf",
1528
packages=setuptools.find_packages(),
16-
package_data={'': ['*.json']},
29+
package_data={'jamf': ['*.json', 'VERSION']},
30+
include_package_data=True,
1731
entry_points={
1832
'console_scripts': ['jamfconfig=jamf.setconfig:main']
1933
},

0 commit comments

Comments
 (0)