From 1bb935477ac8b791f55ea2d7ec105777f02c7e92 Mon Sep 17 00:00:00 2001 From: Doug Hellmann Date: Thu, 8 Feb 2018 14:57:46 -0500 Subject: [PATCH] add validation step for pypi permissions Projects that are going to try to upload releases to PyPI need to have given openstackci permission to do that. Change-Id: I8e5e60ea6bf2842e834d2352134a11b1f9fe02b9 Signed-off-by: Doug Hellmann --- openstack_releases/cmds/validate.py | 49 +++++++++++++++++++++++++++++ openstack_releases/pythonutils.py | 12 +++++++ 2 files changed, 61 insertions(+) diff --git a/openstack_releases/cmds/validate.py b/openstack_releases/cmds/validate.py index 8fb5ea09b1..75376d99b7 100644 --- a/openstack_releases/cmds/validate.py +++ b/openstack_releases/cmds/validate.py @@ -524,6 +524,48 @@ def validate_tarball_base(deliverable_info, action, expected, sdist)) +def validate_pypi_permissions(deliverable_info, zuul_projects, workdir, + mk_warning, mk_error): + + header('Validate PyPI Permissions') + + for repo in deliverable_info['repository-settings'].keys(): + + job_templates = zuul_projects.get(repo, {}).get('templates', []) + + # Look for jobs that appear to be talking about publishing to + # PyPI. There are variations. + pypi_jobs = [ + j + for j in job_templates + if 'pypi' in j + ] + + if not pypi_jobs: + print('rule does not apply to repos not publishing to PyPI') + continue + + print('{} publishes to PyPI via {}'.format(repo, pypi_jobs)) + + try: + sdist = pythonutils.get_sdist_name(workdir, repo) + except Exception as err: + mk_warning( + 'Could not determine the sdist name ' + 'for {} to check PyPI permissions: {}'.format( + repo, err) + ) + continue + + uploaders = pythonutils.get_pypi_uploaders(sdist) + if 'openstackci' not in uploaders: + mk_error( + 'openstackci does not have permission to upload packages ' + 'for {}. Current owners include: {}'.format( + sdist, ', '.join(sorted(uploaders))) + ) + + def validate_releases(deliverable_info, zuul_projects, series_name, workdir, @@ -1260,6 +1302,13 @@ def main(): mk_warning, mk_error, ) + validate_pypi_permissions( + deliverable_info, + zuul_projects, + workdir, + mk_warning, + mk_error, + ) validate_gitreview(deliverable_info, workdir, mk_warning, mk_error) validate_releases( deliverable_info, diff --git a/openstack_releases/pythonutils.py b/openstack_releases/pythonutils.py index 7badfb096d..c6eb01d28f 100644 --- a/openstack_releases/pythonutils.py +++ b/openstack_releases/pythonutils.py @@ -16,6 +16,7 @@ import json import logging import os import os.path +import xmlrpc.client import requests @@ -71,3 +72,14 @@ def get_pypi_info(dist_name): return requests.get(url).json() except json.decoder.JSONDecodeError: return {} + + +def get_pypi_uploaders(dist_name): + client = xmlrpc.client.ServerProxy('https://pypi.python.org/pypi') + roles = client.package_roles(dist_name) + uploaders = set( + acct + for role, acct in roles + if role in ('Owner', 'Maintainer') + ) + return uploaders