Add nox role and some simple jobs
This is an alternative to tox. Change-Id: Ib4920acec09c2c980af909e8f9d1eabd1c6d253a
This commit is contained in:
parent
77b1b24911
commit
50fd134646
@ -17,6 +17,17 @@ Python Jobs
|
||||
.. zuul:autojob:: tox-cover
|
||||
.. zuul:autojob:: tox-bashate
|
||||
.. zuul:autojob:: tox-nodejs-npm
|
||||
.. zuul:autojob:: nox
|
||||
.. zuul:autojob:: nox-py27
|
||||
.. zuul:autojob:: nox-py36
|
||||
.. zuul:autojob:: nox-py37
|
||||
.. zuul:autojob:: nox-py38
|
||||
.. zuul:autojob:: nox-py39
|
||||
.. zuul:autojob:: nox-py310
|
||||
.. zuul:autojob:: nox-py311
|
||||
.. zuul:autojob:: nox-docs
|
||||
.. zuul:autojob:: nox-linters
|
||||
.. zuul:autojob:: nox-cover
|
||||
.. zuul:autojob:: build-python-release
|
||||
.. zuul:autojob:: python-upload-pypi
|
||||
.. zuul:autojob:: build-sphinx-docs
|
||||
|
@ -21,4 +21,5 @@ Python Roles
|
||||
.. zuul:autorole:: find-constraints
|
||||
.. zuul:autorole:: sphinx
|
||||
.. zuul:autorole:: tox
|
||||
.. zuul:autorole:: nox
|
||||
.. zuul:autorole:: upload-pypi
|
||||
|
3
playbooks/nox/cover-post.yaml
Normal file
3
playbooks/nox/cover-post.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: fetch-coverage-output
|
3
playbooks/nox/docs-post.yaml
Normal file
3
playbooks/nox/docs-post.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- fetch-sphinx-tarball
|
4
playbooks/nox/docs-pre.yaml
Normal file
4
playbooks/nox/docs-pre.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: bindep
|
||||
bindep_dir: "{{ zuul_work_dir }}"
|
4
playbooks/nox/pre.yaml
Normal file
4
playbooks/nox/pre.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- ensure-python
|
||||
- ensure-nox
|
4
playbooks/nox/run.yaml
Normal file
4
playbooks/nox/run.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- hosts: all
|
||||
roles:
|
||||
- revoke-sudo
|
||||
- nox
|
@ -5,7 +5,8 @@
|
||||
name: bindep
|
||||
vars:
|
||||
bindep_dir: "{{ zuul_work_dir }}"
|
||||
when: tox_install_bindep | default(true)
|
||||
# TODO don't make this runtime specific
|
||||
when: (tox_install_bindep | default(true)) and (nox_install_bindep | default(true))
|
||||
- name: Run test-setup role
|
||||
include_role:
|
||||
name: test-setup
|
||||
|
84
roles/nox/README.rst
Normal file
84
roles/nox/README.rst
Normal file
@ -0,0 +1,84 @@
|
||||
Runs nox for a project
|
||||
|
||||
This role overrides Python packages installed into nox environments with
|
||||
corresponding Zuul sibling projects and runs nox tests as follows:
|
||||
|
||||
#. Create nox environments. Note this role currently relies on using
|
||||
the default .nox/session name environment paths.
|
||||
#. Get Python sibling package names for sibling projects created by
|
||||
Zuul (using ``required-projects`` job variable). Package names are
|
||||
searched in following sources:
|
||||
|
||||
* ``setup.cfg`` of *pbr* projects,
|
||||
* ``setup.py``,
|
||||
* ``nox_package_name`` role variable.
|
||||
|
||||
#. Remove sibling packages from nox environments.
|
||||
#. Create temporary constraints file, lines for sibling packages are
|
||||
removed.
|
||||
#. Install sibling packages from Zuul projects into nox environments
|
||||
with temporary constraints file.
|
||||
#. Run nox tests.
|
||||
|
||||
**Role Variables**
|
||||
|
||||
.. zuul:rolevar:: nox_environment
|
||||
:type: dict
|
||||
:default: { "CI": "1" }
|
||||
|
||||
Environment variables to pass in to the nox run. Nox behaves differently
|
||||
when the CI env var is set. We set that by default but allow you to
|
||||
override it if the CI behaviors are not desireable.
|
||||
|
||||
.. zuul:rolevar:: nox_session
|
||||
|
||||
Space separated string listing nox sessions to run.
|
||||
|
||||
.. zuul:rolevar:: nox_keyword
|
||||
|
||||
String to select nox sessions via keyword rather than session name.
|
||||
|
||||
.. zuul:rolevar:: nox_tag
|
||||
|
||||
String to select nox sessions via tag rather than session name.
|
||||
|
||||
.. zuul:rolevar:: nox_force_python
|
||||
|
||||
String to force a specific python version to be used in the session.
|
||||
This allows you to request session `tests` be run against python `3.11`.
|
||||
|
||||
.. zuul:rolevar:: nox_executable
|
||||
:default: nox
|
||||
|
||||
Location of the nox executable.
|
||||
|
||||
.. zuul:rolevar:: nox_config_file
|
||||
|
||||
Path to a nox configuration file. If not specified the nox will look
|
||||
for noxfile.py by default.
|
||||
|
||||
.. zuul:rolevar:: nox_extra_args
|
||||
:default: -v
|
||||
|
||||
String of extra command line options to pass to nox.
|
||||
|
||||
.. zuul:rolevar:: nox_constraints_file
|
||||
|
||||
Path to a pip constraints file. Will be provided to nox via
|
||||
``NOX_CONSTRAINTS_FILE``.
|
||||
|
||||
.. zuul:rolevar:: nox_install_siblings
|
||||
:default: true
|
||||
|
||||
Flag controlling whether to attempt to install python packages from any
|
||||
other source code repos zuul has checked out. Defaults to True.
|
||||
|
||||
.. zuul:rolevar:: nox_package_name
|
||||
|
||||
Allows a user to setup the package name to be used by nox, over reading
|
||||
a setup.cfg file in the project.
|
||||
|
||||
.. zuul:rolevar:: zuul_work_dir
|
||||
:default: {{ zuul.project.src_dir }}
|
||||
|
||||
Directory to run nox in.
|
0
roles/nox/__init__.py
Normal file
0
roles/nox/__init__.py
Normal file
10
roles/nox/defaults/main.yaml
Normal file
10
roles/nox/defaults/main.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
nox_environment:
|
||||
# nox will fail with missing session with this flag set.
|
||||
CI: "1"
|
||||
nox_executable: nox
|
||||
nox_extra_args: '-v'
|
||||
nox_install_siblings: true
|
||||
nox_inline_comments: true
|
||||
|
||||
zuul_work_dir: "{{ zuul.project.src_dir }}"
|
0
roles/nox/library/__init__.py
Normal file
0
roles/nox/library/__init__.py
Normal file
347
roles/nox/library/nox_install_sibling_packages.py
Normal file
347
roles/nox/library/nox_install_sibling_packages.py
Normal file
@ -0,0 +1,347 @@
|
||||
# Copyright (c) 2017 Red Hat
|
||||
#
|
||||
# This module is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This software is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This was adapted from the tox siblings role.
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: nox_install_sibling_packages
|
||||
short_description: Install packages needed by nox that have local git versions
|
||||
author: Monty Taylor (@mordred) and Clark Boylan
|
||||
description:
|
||||
- Looks for git repositories that zuul has placed on the system that provide
|
||||
python packages needed by package nox is testing. If if finds any, it will
|
||||
install them into the nox virtualenv so that subsequent runs of nox will
|
||||
use the provided git versions.
|
||||
requirements:
|
||||
- "python >= 3.6"
|
||||
options:
|
||||
nox_sessions:
|
||||
description:
|
||||
- output of `nox --list` showing which sessions are selected
|
||||
required: true
|
||||
type: path
|
||||
project_dir:
|
||||
description:
|
||||
- The directory in which the project we care about is in.
|
||||
required: true
|
||||
type: str
|
||||
projects:
|
||||
description:
|
||||
- A list of project dicts that zuul knows about
|
||||
required: true
|
||||
type: list
|
||||
'''
|
||||
|
||||
try:
|
||||
import configparser
|
||||
except ImportError:
|
||||
import ConfigParser as configparser
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
import tempfile
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
log = list()
|
||||
|
||||
|
||||
def to_filename(name):
|
||||
"""Convert a project or version name to its filename-escaped form
|
||||
Any '-' characters are currently replaced with '_'.
|
||||
|
||||
Implementation vendored from pkg_resources.to_filename in order to avoid
|
||||
adding an extra runtime dependency.
|
||||
"""
|
||||
return name.replace('-', '_')
|
||||
|
||||
|
||||
def get_sibling_python_packages(projects, nox_python):
|
||||
'''Finds all python packages that zuul has cloned.
|
||||
|
||||
If someone does a require_project: and then runs a nox job, it can be
|
||||
assumed that what they want to do is to test the two together.
|
||||
'''
|
||||
packages = {}
|
||||
|
||||
for project in projects:
|
||||
root = project['src_dir']
|
||||
package_name = None
|
||||
setup_cfg = os.path.join(root, 'setup.cfg')
|
||||
found_python = False
|
||||
if os.path.exists(setup_cfg):
|
||||
found_python = True
|
||||
c = configparser.ConfigParser()
|
||||
c.read(setup_cfg)
|
||||
try:
|
||||
package_name = c.get('metadata', 'name')
|
||||
packages[package_name] = root
|
||||
except Exception:
|
||||
# Some things have a setup.cfg, but don't keep
|
||||
# metadata in it; fall back to setup.py below
|
||||
log.append(
|
||||
"[metadata] name not found in %s, skipping" % setup_cfg)
|
||||
if not package_name and os.path.exists(os.path.join(root, 'setup.py')):
|
||||
found_python = True
|
||||
# It's a python package but doesn't use pbr, so we need to run
|
||||
# python setup.py --name to get setup.py to tell us what the
|
||||
# package name is.
|
||||
package_name = subprocess.check_output(
|
||||
[os.path.abspath(nox_python), 'setup.py', '--name'],
|
||||
cwd=os.path.abspath(root),
|
||||
stderr=subprocess.STDOUT).decode('utf-8')
|
||||
if package_name:
|
||||
package_name = package_name.strip()
|
||||
packages[package_name] = root
|
||||
if found_python and not package_name:
|
||||
log.append(
|
||||
"Could not find package name for {root}".format(
|
||||
root=root))
|
||||
return packages
|
||||
|
||||
|
||||
def get_installed_packages(nox_python):
|
||||
# We use the output of pip freeze here as that is pip's stable public
|
||||
# interface.
|
||||
frozen_pkgs = subprocess.check_output(
|
||||
[nox_python, '-m', 'pip', '-qqq', 'freeze'],
|
||||
stderr=subprocess.STDOUT
|
||||
).decode('utf-8')
|
||||
# Matches strings of the form:
|
||||
# 1. '<package_name>==<version>'
|
||||
# 2. '# Editable Git install with no remote (<package_name>==<version>)'
|
||||
# 3. '<package_name> @ <URI_reference>' # PEP440, PEP508, PEP610
|
||||
# results <package_name>
|
||||
installed_packages = []
|
||||
for x in frozen_pkgs.split('\n'):
|
||||
if '==' in x:
|
||||
installed_packages.append(x[x.find('(') + 1:].split('==')[0])
|
||||
elif '@' in x:
|
||||
installed_packages.append(x.split('@')[0].rstrip(' \t'))
|
||||
return installed_packages
|
||||
|
||||
|
||||
def write_new_constraints_file(constraints, packages):
|
||||
with tempfile.NamedTemporaryFile(mode='w', delete=False) \
|
||||
as constraints_file:
|
||||
constraints_lines = open(constraints, 'r').read().split('\n')
|
||||
for line in constraints_lines:
|
||||
package_name = line.split('===')[0]
|
||||
if package_name in packages:
|
||||
continue
|
||||
constraints_file.write(line)
|
||||
constraints_file.write('\n')
|
||||
return constraints_file.name
|
||||
|
||||
|
||||
def _get_package_root(name, sibling_packages):
|
||||
'''
|
||||
Returns a package root from the sibling packages dict.
|
||||
|
||||
If name is not found in sibling_packages, tries again using the 'filename'
|
||||
form of the name returned by the setuptools package resource API.
|
||||
|
||||
:param name: package name
|
||||
:param sibling_packages: dict of python packages that zuul has cloned
|
||||
:returns: the package root (str)
|
||||
:raises: KeyError
|
||||
'''
|
||||
try:
|
||||
pkg_root = sibling_packages[name]
|
||||
except KeyError:
|
||||
pkg_root = sibling_packages[to_filename(name)]
|
||||
|
||||
return pkg_root
|
||||
|
||||
|
||||
def find_installed_siblings(nox_python, package_name, sibling_python_packages):
|
||||
installed_sibling_packages = []
|
||||
for dep_name in get_installed_packages(nox_python):
|
||||
log.append(
|
||||
"Found {name} python package installed".format(
|
||||
name=dep_name))
|
||||
if (dep_name == package_name or
|
||||
to_filename(dep_name) == package_name):
|
||||
# We don't need to re-process ourself.
|
||||
# We've filtered ourselves from the source dir list,
|
||||
# but let's be sure nothing is weird.
|
||||
log.append(
|
||||
"Skipping {name} because it's us".format(
|
||||
name=dep_name))
|
||||
continue
|
||||
if dep_name in sibling_python_packages:
|
||||
log.append(
|
||||
"Package {name} on system in {root}".format(
|
||||
name=dep_name,
|
||||
root=sibling_python_packages[dep_name]))
|
||||
installed_sibling_packages.append(dep_name)
|
||||
elif to_filename(dep_name) in sibling_python_packages:
|
||||
real_name = to_filename(dep_name)
|
||||
log.append(
|
||||
"Package {name} ({pkg_name}) on system in {root}".format(
|
||||
name=dep_name,
|
||||
pkg_name=real_name,
|
||||
root=sibling_python_packages[real_name]))
|
||||
# need to use dep_name here for later constraint file rewrite
|
||||
installed_sibling_packages.append(dep_name)
|
||||
return installed_sibling_packages
|
||||
|
||||
|
||||
def install_siblings(envdir, projects, package_name, constraints):
|
||||
changed = False
|
||||
nox_python = '{envdir}/bin/python'.format(envdir=envdir)
|
||||
|
||||
sibling_python_packages = get_sibling_python_packages(
|
||||
projects, nox_python)
|
||||
for name, root in sibling_python_packages.items():
|
||||
log.append("Sibling {name} at {root}".format(name=name,
|
||||
root=root))
|
||||
|
||||
installed_sibling_packages = find_installed_siblings(
|
||||
nox_python,
|
||||
package_name,
|
||||
sibling_python_packages)
|
||||
|
||||
if constraints:
|
||||
constraints_file = write_new_constraints_file(
|
||||
constraints, installed_sibling_packages)
|
||||
|
||||
for sibling_package in installed_sibling_packages:
|
||||
changed = True
|
||||
log.append("Uninstalling {name}".format(name=sibling_package))
|
||||
uninstall_output = subprocess.check_output(
|
||||
[nox_python, '-m',
|
||||
'pip', 'uninstall', '-y', sibling_package],
|
||||
stderr=subprocess.STDOUT)
|
||||
log.extend(uninstall_output.decode('utf-8').split('\n'))
|
||||
|
||||
args = [nox_python, '-m', 'pip', 'install']
|
||||
if constraints:
|
||||
args.extend(['-c', constraints_file])
|
||||
|
||||
pkg_root = _get_package_root(sibling_package,
|
||||
sibling_python_packages)
|
||||
log.append(
|
||||
"Installing {name} from {root} for deps".format(
|
||||
name=sibling_package,
|
||||
root=pkg_root))
|
||||
args.append(pkg_root)
|
||||
|
||||
install_output = subprocess.check_output(args)
|
||||
log.extend(install_output.decode('utf-8').split('\n'))
|
||||
|
||||
for sibling_package in installed_sibling_packages:
|
||||
changed = True
|
||||
pkg_root = _get_package_root(sibling_package,
|
||||
sibling_python_packages)
|
||||
log.append(
|
||||
"Installing {name} from {root}".format(
|
||||
name=sibling_package,
|
||||
root=pkg_root))
|
||||
|
||||
install_output = subprocess.check_output(
|
||||
[nox_python, '-m', 'pip', 'install', '--no-deps',
|
||||
pkg_root])
|
||||
log.extend(install_output.decode('utf-8').split('\n'))
|
||||
return changed
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
nox_sessions=dict(required=True, type='str'),
|
||||
nox_constraints_file=dict(type='str'),
|
||||
nox_package_name=dict(type='str'),
|
||||
project_dir=dict(required=True, type='str'),
|
||||
projects=dict(required=True, type='list'),
|
||||
)
|
||||
)
|
||||
constraints = module.params.get('nox_constraints_file')
|
||||
nox_package_name = module.params.get('nox_package_name')
|
||||
project_dir = module.params['project_dir']
|
||||
projects = module.params['projects']
|
||||
nox_sessions = module.params.get('nox_sessions')
|
||||
|
||||
sessions = []
|
||||
for line in nox_sessions.split('\n'):
|
||||
if line.startswith('*'):
|
||||
sessions.append(line[1:].strip())
|
||||
|
||||
if not sessions:
|
||||
module.exit_json(
|
||||
changed=False,
|
||||
msg='No sessions to run, no action needed.')
|
||||
|
||||
log.append('Using sessions: {}'.format(sessions))
|
||||
|
||||
if (not nox_package_name
|
||||
and not os.path.exists(os.path.join(project_dir, 'setup.cfg'))
|
||||
):
|
||||
module.exit_json(changed=False, msg="No setup.cfg, no action needed")
|
||||
if constraints and not os.path.exists(constraints):
|
||||
module.fail_json(msg="Constraints file {constraints} was not found")
|
||||
|
||||
# Who are we?
|
||||
package_name = nox_package_name
|
||||
if not package_name:
|
||||
try:
|
||||
c = configparser.ConfigParser()
|
||||
c.read(os.path.join(project_dir, 'setup.cfg'))
|
||||
package_name = c.get('metadata', 'name')
|
||||
except Exception:
|
||||
module.exit_json(
|
||||
changed=False, msg="No name in setup.cfg, skipping siblings")
|
||||
|
||||
log.append(
|
||||
"Processing siblings for {name} from {project_dir}".format(
|
||||
name=package_name,
|
||||
project_dir=project_dir))
|
||||
|
||||
changed = False
|
||||
for session in sessions:
|
||||
# Nox replaces dots in the session name with dashes when creating
|
||||
# venvs.
|
||||
envdir = os.path.join(project_dir, '.nox', session.replace('.', '-'))
|
||||
if not os.path.exists(envdir):
|
||||
# Nox doesn't appear to allow us to lookup the env dir that was
|
||||
# created in a previous step. We look for it where we expect it
|
||||
# to be and fail otherwise.
|
||||
module.fail_json(msg="Nox session env not found: {envdir}")
|
||||
try:
|
||||
siblings_changed = install_siblings(envdir,
|
||||
projects,
|
||||
package_name,
|
||||
constraints)
|
||||
changed = changed or siblings_changed
|
||||
except subprocess.CalledProcessError as e:
|
||||
tb = traceback.format_exc()
|
||||
log.append(str(e))
|
||||
log.append(tb)
|
||||
log.append("Output:")
|
||||
log.extend(e.output.decode('utf-8').split('\n'))
|
||||
module.fail_json(msg=str(e), log="\n".join(log))
|
||||
except Exception as e:
|
||||
tb = traceback.format_exc()
|
||||
log.append(str(e))
|
||||
log.append(tb)
|
||||
module.fail_json(msg=str(e), log="\n".join(log))
|
||||
module.exit_json(changed=changed, msg="\n".join(log))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
2
roles/nox/library/test-constraints.txt
Normal file
2
roles/nox/library/test-constraints.txt
Normal file
@ -0,0 +1,2 @@
|
||||
requests===2.18.4
|
||||
doesnotexistonpypi===0.0.1
|
61
roles/nox/library/test_nox_install_sibling_packages.py
Normal file
61
roles/nox/library/test_nox_install_sibling_packages.py
Normal file
@ -0,0 +1,61 @@
|
||||
# Copyright (C) 2019 VEXXHOST, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
#
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This was adapted from the tox siblings role.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import testtools
|
||||
|
||||
from .nox_install_sibling_packages import get_installed_packages
|
||||
from .nox_install_sibling_packages import write_new_constraints_file
|
||||
|
||||
|
||||
class TestNoxInstallSiblingPackages(testtools.TestCase):
|
||||
def test_get_installed_packages(self):
|
||||
# NOTE(mnaser): Given that we run our tests inside a venv, we can
|
||||
# leverage the virtual environment we use in
|
||||
# unit tests instead of mocking up everything.
|
||||
pkgs = get_installed_packages(sys.executable)
|
||||
|
||||
# NOTE(mnaser): requests should be installed in this virtualenv
|
||||
# but this might fail later if we stop adding requests
|
||||
# in the unit tests.
|
||||
self.assertIn("requests", pkgs)
|
||||
|
||||
def test_write_new_constraints_file(self):
|
||||
# NOTE(mnaser): Given that we run our tests inside a venv, we can
|
||||
# leverage the virtual environment we use in
|
||||
# unit tests instead of mocking up everything.
|
||||
pkgs = get_installed_packages(sys.executable)
|
||||
|
||||
# NOTE(mnaser): requests should be installed in this virtualenv
|
||||
# but this might fail later if we stop adding requests
|
||||
# in the unit tests.
|
||||
test_constraints = os.path.join(os.path.dirname(__file__),
|
||||
'test-constraints.txt')
|
||||
constraints = write_new_constraints_file(test_constraints, pkgs)
|
||||
|
||||
def cleanup_constraints_file():
|
||||
if os.path.exists(constraints):
|
||||
os.unlink(constraints)
|
||||
self.addCleanup(cleanup_constraints_file)
|
||||
|
||||
self.assertTrue(os.path.exists(constraints))
|
||||
with open(constraints) as f:
|
||||
s = f.read()
|
||||
self.assertNotIn("requests", s)
|
||||
self.assertIn("doesnotexistonpypi", s)
|
83
roles/nox/tasks/main.yaml
Normal file
83
roles/nox/tasks/main.yaml
Normal file
@ -0,0 +1,83 @@
|
||||
- name: Check to see if the constraints file exists
|
||||
stat:
|
||||
path: "{{ nox_constraints_file }}"
|
||||
get_checksum: false
|
||||
get_mime: false
|
||||
get_md5: false
|
||||
register: stat_results
|
||||
when: nox_constraints_file is defined
|
||||
|
||||
- name: Fail if constraints file is missing
|
||||
when: nox_constraints_file is defined and not stat_results.stat.exists
|
||||
fail:
|
||||
msg: nox_constraints_file is defined but was not found
|
||||
|
||||
- name: Record constraints file location
|
||||
set_fact:
|
||||
nox_constraints_env:
|
||||
NOX_CONSTRAINTS_FILE: "{{ nox_constraints_file }}"
|
||||
when: nox_constraints_file is defined
|
||||
|
||||
- name: Install nox siblings
|
||||
include_tasks: siblings.yaml
|
||||
when: nox_install_siblings
|
||||
|
||||
- name: Emit nox command
|
||||
debug:
|
||||
msg: >-
|
||||
{{ nox_executable }}
|
||||
{% if nox_config_file is defined and nox_config_file %}
|
||||
-f {{ nox_config_file }}
|
||||
{% endif %}
|
||||
{% if nox_session is defined and nox_session %}
|
||||
-s {{ nox_session }}
|
||||
{% endif %}
|
||||
{% if nox_keyword is defined and nox_keyword %}
|
||||
-k {{ nox_keyword }}
|
||||
{% endif %}
|
||||
{% if nox_tag is defined and nox_tag %}
|
||||
-t {{ nox_tag }}
|
||||
{% endif %}
|
||||
{% if nox_force_python is defined and nox_force_python %}
|
||||
--force-python {{ nox_force_python }}
|
||||
{% endif %}
|
||||
{% if nox_install_siblings %}
|
||||
--reuse-existing-virtualenvs --no-install
|
||||
{% endif %}
|
||||
{{ nox_extra_args }}
|
||||
|
||||
- name: Run nox
|
||||
block:
|
||||
- name: Run nox
|
||||
args:
|
||||
chdir: "{{ zuul_work_dir }}"
|
||||
environment: "{{ nox_environment | combine(nox_constraints_env | default({})) }}"
|
||||
command: >-
|
||||
{{ nox_executable }}
|
||||
{% if nox_config_file is defined and nox_config_file %}
|
||||
-f {{ nox_config_file }}
|
||||
{% endif %}
|
||||
{% if nox_session is defined and nox_session %}
|
||||
-s {{ nox_session }}
|
||||
{% endif %}
|
||||
{% if nox_keyword is defined and nox_keyword %}
|
||||
-k {{ nox_keyword }}
|
||||
{% endif %}
|
||||
{% if nox_tag is defined and nox_tag %}
|
||||
-t {{ nox_tag }}
|
||||
{% endif %}
|
||||
{% if nox_force_python is defined and nox_force_python %}
|
||||
--force-python {{ nox_force_python }}
|
||||
{% endif %}
|
||||
{% if nox_install_siblings %}
|
||||
--reuse-existing-virtualenvs --no-install
|
||||
{% endif %}
|
||||
{{ nox_extra_args }}
|
||||
register: nox_output
|
||||
|
||||
# Even though any test environment in nox failed we want to
|
||||
# return file comments produced so always run this.
|
||||
always:
|
||||
- name: TODO
|
||||
debug:
|
||||
msg: TODO
|
56
roles/nox/tasks/siblings.yaml
Normal file
56
roles/nox/tasks/siblings.yaml
Normal file
@ -0,0 +1,56 @@
|
||||
# Install sibling with nox so we can replace them later
|
||||
- name: Run nox without tests
|
||||
command: >-
|
||||
{{ nox_executable }}
|
||||
{% if nox_config_file is defined and nox_config_file %}
|
||||
-f {{ nox_config_file }}
|
||||
{% endif %}
|
||||
{% if nox_session is defined and nox_session %}
|
||||
-s {{ nox_session }}
|
||||
{% endif %}
|
||||
{% if nox_keyword is defined and nox_keyword %}
|
||||
-k {{ nox_keyword }}
|
||||
{% endif %}
|
||||
{% if nox_tag is defined and nox_tag %}
|
||||
-t {{ nox_tag }}
|
||||
{% endif %}
|
||||
{% if nox_force_python is defined and nox_force_python %}
|
||||
--force-python {{ nox_force_python }}
|
||||
{% endif %}
|
||||
--install-only
|
||||
{{ nox_extra_args }}
|
||||
args:
|
||||
chdir: "{{ zuul_work_dir }}"
|
||||
environment: "{{ nox_environment | combine(nox_constraints_env | default({})) }}"
|
||||
|
||||
- name: Get nox session list
|
||||
command: >-
|
||||
{{ nox_executable }}
|
||||
{% if nox_config_file is defined and nox_config_file %}
|
||||
-f {{ nox_config_file }}
|
||||
{% endif %}
|
||||
{% if nox_session is defined and nox_session %}
|
||||
-s {{ nox_session }}
|
||||
{% endif %}
|
||||
{% if nox_keyword is defined and nox_keyword %}
|
||||
-k {{ nox_keyword }}
|
||||
{% endif %}
|
||||
{% if nox_tag is defined and nox_tag %}
|
||||
-t {{ nox_tag }}
|
||||
{% endif %}
|
||||
{% if nox_force_python is defined and nox_force_python %}
|
||||
--force-python {{ nox_force_python }}
|
||||
{% endif %}
|
||||
--list
|
||||
args:
|
||||
chdir: "{{ zuul_work_dir }}"
|
||||
environment: "{{ nox_environment | combine(nox_constraints_env | default({})) }}"
|
||||
register: _nox_session_listing
|
||||
|
||||
- name: Install any sibling python packages
|
||||
nox_install_sibling_packages:
|
||||
nox_sessions: "{{ _nox_session_listing.stdout }}"
|
||||
nox_constraints_file: "{{ nox_constraints_file | default(omit) }}"
|
||||
nox_package_name: "{{ nox_package_name | default(omit) }}"
|
||||
project_dir: "{{ zuul_work_dir }}"
|
||||
projects: "{{ zuul.projects.values() | selectattr('required') | list }}"
|
@ -335,6 +335,191 @@
|
||||
vars:
|
||||
npm_command: build
|
||||
|
||||
- job:
|
||||
name: nox
|
||||
parent: unittests
|
||||
description: |
|
||||
Base job containing setup and teardown for nox-based test jobs.
|
||||
|
||||
This performs basic host and general project setup tasks common
|
||||
to all nox unit test jobs.
|
||||
|
||||
Responds to these variables:
|
||||
|
||||
.. zuul:jobvar:: nox_session
|
||||
|
||||
Use the specified nox sessions
|
||||
|
||||
.. zuul:jobvar:: nox_keyword
|
||||
|
||||
Use the specified nox keyword
|
||||
|
||||
.. zuul:jobvar:: nox_tag
|
||||
|
||||
Use the specified nox tag
|
||||
|
||||
.. zuul:jobvar:: nox_force_python
|
||||
|
||||
Force nox to run the selected sessions under this version of python.
|
||||
|
||||
.. zuul:jobvar:: nox_config_file
|
||||
|
||||
Override the default noxfile.py configuration path.
|
||||
|
||||
.. zuul:jobvar:: nox_environment
|
||||
:type: dict
|
||||
|
||||
Environment variables to pass in to the nox run.
|
||||
Nox behaves differently when CI=1 is set. Consider setting this
|
||||
if you override the role defaults.
|
||||
|
||||
.. zuul:jobvar:: nox_extra_args
|
||||
|
||||
String containing extra arguments to append to the nox command line.
|
||||
|
||||
.. zuul:jobvar:: nox_constraints_file
|
||||
|
||||
Path to a pip constraints file. Will be provided to nox in the
|
||||
NOX_CONSTRAINTS_FILE environment variable if it exists.
|
||||
|
||||
.. zuul:jobvar:: nox_install_siblings
|
||||
:default: true
|
||||
|
||||
Override nox requirements that have corresponding zuul git repos
|
||||
on the node by installing the git versions into the nox virtualenv.
|
||||
|
||||
.. zuul:jobvar:: nox_install_bindep
|
||||
:default: true
|
||||
|
||||
Whether or not to run the binary dependencies detection and
|
||||
installation with bindep.
|
||||
run: playbooks/nox/run.yaml
|
||||
pre-run: playbooks/nox/pre.yaml
|
||||
|
||||
- job:
|
||||
name: nox-py27
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 2.7.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 2.7.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "2.7"
|
||||
python_version: "2.7"
|
||||
|
||||
- job:
|
||||
name: nox-py36
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.6.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.6.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.6"
|
||||
python_version: "3.6"
|
||||
|
||||
- job:
|
||||
name: nox-py37
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.7.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.7.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.7"
|
||||
python_version: "3.7"
|
||||
|
||||
- job:
|
||||
name: nox-py38
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.8.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.8.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.8"
|
||||
python_version: "3.8"
|
||||
|
||||
- job:
|
||||
name: nox-py39
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.9.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.9.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.9"
|
||||
python_version: "3.9"
|
||||
|
||||
- job:
|
||||
name: nox-py310
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.10.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.10.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.10"
|
||||
python_version: "3.10"
|
||||
|
||||
- job:
|
||||
name: nox-py311
|
||||
parent: nox
|
||||
description: |
|
||||
Run unit tests for a Python project under cPython version 3.11.
|
||||
|
||||
Uses nox with the ``test`` keyword forcing python 3.11.
|
||||
vars:
|
||||
nox_keyword: tests
|
||||
nox_force_python: "3.11"
|
||||
python_version: "3.11"
|
||||
|
||||
- job:
|
||||
name: nox-cover
|
||||
parent: nox
|
||||
description: |
|
||||
Run code coverage tests.
|
||||
|
||||
Uses nox with the ``cover`` keyword.
|
||||
post-run: playbooks/nox/cover-post.yaml
|
||||
vars:
|
||||
nox_keyword: cover
|
||||
|
||||
- job:
|
||||
name: nox-linters
|
||||
parent: nox
|
||||
description: |
|
||||
Runs code linting tests.
|
||||
|
||||
Uses nox with the ``linters`` keyword.
|
||||
vars:
|
||||
nox_keyword: linters
|
||||
test_setup_skip: true
|
||||
|
||||
- job:
|
||||
name: nox-docs
|
||||
# This is not parented to nox since we do not need
|
||||
# the roles from its parent unittests.
|
||||
description: |
|
||||
Run documentation unit tests.
|
||||
|
||||
Uses nox with the ``docs`` keyword.
|
||||
vars:
|
||||
nox_keyword: docs
|
||||
bindep_profile: compile doc
|
||||
run: playbooks/nox/run.yaml
|
||||
pre-run:
|
||||
- playbooks/nox/docs-pre.yaml
|
||||
- playbooks/nox/pre.yaml
|
||||
post-run:
|
||||
- playbooks/nox/docs-post.yaml
|
||||
|
||||
- job:
|
||||
name: build-python-release
|
||||
description: |
|
||||
|
Loading…
Reference in New Issue
Block a user