Merge "Remove team diversity tags"

This commit is contained in:
Zuul 2018-07-10 17:05:27 +00:00 committed by Gerrit Code Review
commit 0a90d65df3
7 changed files with 0 additions and 624 deletions

View File

@ -16,8 +16,6 @@ astara:
load balancing, vpn) for connecting and security multi-tenant OpenStack
environments.
url: https://wiki.openstack.org/wiki/Astara
tags:
- team:single-vendor
deliverables:
astara:
repos:
@ -55,8 +53,6 @@ Chef OpenStack:
and consumption of OpenStack cloud deployments.
url: https://wiki.openstack.org/wiki/Chef
partial: yes
tags:
- team:diverse-affiliation
deliverables:
cookbook-openstack-bare-metal:
repos:
@ -112,8 +108,6 @@ cue:
To provide a multi-tenant service that offers scalable and reliable
provisioning and management capabilities for off-the-shelf message brokers.
url: https://wiki.openstack.org/wiki/Cue
tags:
- team:single-vendor
deliverables:
cue:
repos:
@ -359,8 +353,6 @@ OpenStackSalt:
based IT automation for installing and operating
OpenStack deployments.
url: https://wiki.openstack.org/wiki/OpenStackSalt
tags:
- team:single-vendor
deliverables:
openstack-salt:
repos:
@ -474,8 +466,6 @@ Packaging-deb:
mission: >
Maintain packages for Debian (and other deb based distributions) as a
community.
tags:
- team:single-vendor
deliverables:
deb-alembic:
repos:

View File

@ -10,8 +10,6 @@ barbican:
To produce a secret storage and generation system capable of providing key
management for services wishing to enable encryption features.
url: https://wiki.openstack.org/wiki/Barbican
tags:
- team:diverse-affiliation
deliverables:
barbican:
repos:
@ -146,8 +144,6 @@ cinder:
access to Block Storage resources via abstraction and automation on top of
other block storage devices.
url: https://wiki.openstack.org/wiki/Cinder
tags:
- team:diverse-affiliation
deliverables:
cinder:
repos:
@ -286,8 +282,6 @@ designate:
To provide scalable, on demand, self service access to authoritative DNS
services, in technology-agnostic manner.
url: https://wiki.openstack.org/wiki/Designate
tags:
- team:diverse-affiliation
deliverables:
designate:
repos:
@ -326,8 +320,6 @@ Documentation:
guides enabling OpenStack project teams to produce consistent, accurate,
and high-quality documentation.
url: https://wiki.openstack.org/wiki/Documentation
tags:
- team:diverse-affiliation
deliverables:
constellations:
repos:
@ -376,8 +368,6 @@ dragonflow:
It's designed to support containers networking and large scale
production loads.
url: https://wiki.openstack.org/wiki/Dragonflow
tags:
- team:single-vendor
deliverables:
dragonflow:
repos:
@ -538,8 +528,6 @@ horizon:
To provide an extensible unified web based user interface for all
OpenStack services.
url: https://wiki.openstack.org/wiki/Horizon
tags:
- team:diverse-affiliation
deliverables:
django_openstack_auth:
repos:
@ -665,8 +653,6 @@ I18n:
To make OpenStack ubiquitously accessible to people of
all language backgrounds.
url: https://wiki.openstack.org/wiki/I18nTeam
tags:
- team:diverse-affiliation
deliverables:
i18n:
repos:
@ -1026,8 +1012,6 @@ Infrastructure:
Develop and maintain the tooling and infrastructure needed to support the
development process and general operation of the OpenStack project.
url: https://docs.openstack.org/infra/system-config/
tags:
- team:diverse-affiliation
deliverables:
activity-board:
repos:
@ -1516,8 +1500,6 @@ ironic:
managing and provisioning physical machines, and to do this in a
security-aware and fault-tolerant manner.
url: https://wiki.openstack.org/wiki/Ironic
tags:
- team:diverse-affiliation
deliverables:
bifrost:
repos:
@ -1636,8 +1618,6 @@ keystone:
To facilitate API client authentication, service discovery, distributed
multi-tenant authorization, and auditing.
url: https://wiki.openstack.org/wiki/Keystone
tags:
- team:diverse-affiliation
deliverables:
keystone:
repos:
@ -1692,8 +1672,6 @@ kolla:
To provide production-ready containers and deployment tools for operating
OpenStack clouds.
url: https://wiki.openstack.org/wiki/Kolla
tags:
- team:diverse-affiliation
deliverables:
kolla:
repos:
@ -1764,8 +1742,6 @@ magnum:
To provide a set of services for provisioning, scaling, and managing
container orchestration engines.
url: https://wiki.openstack.org/wiki/Magnum
tags:
- team:diverse-affiliation
deliverables:
magnum:
repos:
@ -1795,8 +1771,6 @@ manila:
in a multitenant cloud environment, similar to how OpenStack provides
for block-based storage management through the Cinder project.
url: https://wiki.openstack.org/wiki/Manila
tags:
- team:diverse-affiliation
deliverables:
manila:
repos:
@ -1839,8 +1813,6 @@ masakari:
Provide instances high availability service for OpenStack
clouds by automatically recovering the instances from failures.
url: https://wiki.openstack.org/wiki/Masakari
tags:
- team:single-vendor
deliverables:
masakari:
repos:
@ -1906,8 +1878,6 @@ monasca:
services that can be used by both operators and tenants to gain
operational insight and visibility, ensuring availability and stability.
url: https://wiki.openstack.org/wiki/Monasca
tags:
- team:diverse-affiliation
deliverables:
monasca-api:
repos:
@ -2027,8 +1997,6 @@ neutron:
To implement services and associated libraries to provide on-demand,
scalable, and technology-agnostic network abstraction.
url: https://wiki.openstack.org/wiki/Neutron
tags:
- team:diverse-affiliation
deliverables:
networking-bagpipe:
repos:
@ -2116,8 +2084,6 @@ nova:
scalable, on demand, self service access to compute resources, including
bare metal, virtual machines, and containers.
url: https://wiki.openstack.org/wiki/Nova
tags:
- team:diverse-affiliation
deliverables:
nova:
repos:
@ -2206,8 +2172,6 @@ OpenStack Charms:
Develop and maintain Juju Charms for deploying and managing
OpenStack services.
url: https://docs.openstack.org/charm-guide/latest/
tags:
- team:single-vendor
deliverables:
charms.ceph:
repos:
@ -2461,8 +2425,6 @@ OpenStack-Helm:
To provide a collection of Helm charts that simply, resiliently,
and flexibly deploy OpenStack and related services on Kubernetes.
url: https://wiki.openstack.org/wiki/Openstack-helm
tags:
- team:single-vendor
deliverables:
openstack-helm:
repos:
@ -2615,8 +2577,6 @@ OpenStackClient:
Provide a single command-line interface for OpenStack services with a
uniform command set and format.
url: https://wiki.openstack.org/wiki/OpenStackClient
tags:
- team:diverse-affiliation
deliverables:
cliff:
repos:
@ -2643,8 +2603,6 @@ OpenStackSDK:
exposing both the full set of low-level APIs as well as curated higher
level business logic.
url: https://docs.openstack.org/openstacksdk/latest/
tags:
- team:diverse-affiliation
deliverables:
openstacksdk:
repos:
@ -2682,8 +2640,6 @@ oslo:
projects. The APIs provided by these libraries should be high quality,
stable, consistent, documented and generally applicable.
url: https://wiki.openstack.org/wiki/Oslo
tags:
- team:diverse-affiliation
deliverables:
automaton:
repos:
@ -2902,8 +2858,6 @@ PowerVMStackers:
To provide OpenStack support for the POWER CPU architecture on the PowerVM
hypervisor.
url: https://wiki.openstack.org/wiki/PowerVM
tags:
- team:single-vendor
deliverables:
ceilometer-powervm:
repos:
@ -3085,8 +3039,6 @@ qinling:
Provide a serverless platform for managing functions that can be executed
in a scalable, highly-available manner.
url: https://wiki.openstack.org/wiki/Qinling
tags:
- team:single-vendor
deliverables:
qinling:
repos:
@ -3106,8 +3058,6 @@ Quality Assurance:
stability and quality of OpenStack, and its release readiness at any point
during the release cycle.
url: https://wiki.openstack.org/wiki/QA
tags:
- team:diverse-affiliation
deliverables:
bashate:
repos:
@ -3233,8 +3183,6 @@ Release Management:
versioning rules and tools, then enabling project teams to produce
their own releases.
url: https://wiki.openstack.org/wiki/Release_Management
tags:
- team:diverse-affiliation
deliverables:
release-schedule-generator:
repos:
@ -3263,8 +3211,6 @@ requirements:
while ensuring that all libraries are compatible both technically and
from a licensing standpoint.
url: https://wiki.openstack.org/wiki/Requirements
tags:
- team:diverse-affiliation
deliverables:
requirements:
repos:
@ -3333,7 +3279,6 @@ searchlight:
cloud resources.
url: https://wiki.openstack.org/wiki/Searchlight
tags:
- team:diverse-affiliation
- status:maintenance-mode
deliverables:
searchlight:
@ -3361,8 +3306,6 @@ Security:
for reported vulnerabilities and to foster new security initiatives to the
benefit of the OpenStack community as a whole.
url: https://wiki.openstack.org/wiki/Security
tags:
- team:diverse-affiliation
deliverables:
anchor:
repos:
@ -3400,8 +3343,6 @@ senlin:
To implement clustering services and libraries for the management of groups
of homogeneous objects exposed by other OpenStack services.
url: https://wiki.openstack.org/wiki/Senlin
tags:
- team:diverse-affiliation
deliverables:
senlin:
repos:
@ -3428,8 +3369,6 @@ solum:
application development process by automating the source-to-image
process, and simplifying app-centric deployment.
url: https://wiki.openstack.org/wiki/Solum
tags:
- team:single-vendor
deliverables:
python-solumclient:
repos:
@ -3458,8 +3397,6 @@ Stable branch maintenance:
of a common stable branch policy. Keeping CI working on stable branches.
Creating and improving related tooling and automation.
url: https://wiki.openstack.org/wiki/StableBranch
tags:
- team:diverse-affiliation
deliverables: {}
storlets:
@ -3474,8 +3411,6 @@ storlets:
executing storage centric user defined functions near the data within
OpenStack Swift
url: https://wiki.openstack.org/wiki/Storlets
tags:
- team:single-vendor
deliverables:
storlets:
repos:
@ -3597,8 +3532,6 @@ tricircle:
To provide networking automation across Neutron in multi-region OpenStack
clouds deployment.
url: https://wiki.openstack.org/wiki/Tricircle
tags:
- team:single-vendor
deliverables:
tricircle:
repos:
@ -3618,8 +3551,6 @@ tripleo:
Develop and maintain tooling and infrastructure able to deploy OpenStack in
production, using OpenStack itself wherever possible.
url: https://wiki.openstack.org/wiki/TripleO
tags:
- team:single-vendor
deliverables:
ansible-role-container-registry:
repos:
@ -3818,8 +3749,6 @@ watcher:
Watcher's goal is to provide a flexible and scalable resource optimization
service for multi-tenant OpenStack-based clouds.
url: https://wiki.openstack.org/wiki/Watcher
tags:
- team:diverse-affiliation
deliverables:
watcher:
repos:
@ -3848,8 +3777,6 @@ winstackers:
into OpenStack. This includes producing projects containing Hyper-V /
Windows related code, commonly used in OpenStack scenarios.
url: https://wiki.openstack.org/wiki/Os-win
tags:
- team:single-vendor
deliverables:
os-win:
repos:
@ -3895,8 +3822,6 @@ zaqar:
scalable and highly-available manner, and to create and maintain
associated Python libraries and documentation.
url: https://wiki.openstack.org/wiki/Zaqar
tags:
- team:diverse-affiliation
deliverables:
python-zaqarclient:
repos:
@ -3928,8 +3853,6 @@ zun:
To provide an OpenStack containers service that integrates with various
container technologies for managing application containers on OpenStack.
url: https://wiki.openstack.org/wiki/Zun
tags:
- team:diverse-affiliation
deliverables:
python-zunclient:
repos:

View File

@ -38,8 +38,6 @@ Team Description Tags
:maxdepth: 1
status_maintenance-mode
team_diverse-affiliation
team_single-vendor
Project Assertion Tags
======================

View File

@ -1,77 +0,0 @@
::
This work is licensed under a Creative Commons Attribution 3.0
Unported License.
http://creativecommons.org/licenses/by/3.0/legalcode
.. _`tag-team:diverse-affiliation`:
========================
team:diverse-affiliation
========================
A project with this tag has achieved a level of diversity in the affiliation of
contributors that is indicative of a healthy collaborative project. This tag
exists in the 'team' category, which as the name implies, covers information
about the team itself. Another example of a tag that could exist in this
category is one that conveys the size of the team that is actively contributing.
Application to current teams
============================
It's worth pointing out that the criteria used for this tag is applied across
all git repositories managed by a team.
.. tagged-projects:: team:diverse-affiliation
Script used to apply this tag:
http://git.openstack.org/cgit/openstack/governance/tree/tools/validate_tags.py
Rationale
=========
We value having a broad base of contributors to a project for several reasons.
One such reason is that it's more risky to rely on a project controlled by a
single organization as the project will immediately come to a halt if that one
organization chooses to stop working on it. We also value a project where
priorities must be set and agreed upon in a community fashion instead of purely
controlled by a single organization.
Requirements
============
No one organization should represent a majority (>50%) and no two organizations
should represent >80% of any of the following:
* the sum of all commits merged into any of the git repositories managed by the
team
* the sum of all reviews done against patches submitted to any of the git
repositories managed by the team
* the sum of all reviews done by active core reviewers against patches submitted
to any of the git repositories managed by the team
* the union of the active memberships of the core review teams associated with
the git repositories managed by the team
This tag is applied based on the `tools/teamstats.py` script. The output of this
script is then reviewed by the TC to verify it matches the reality.
The timeline used for evaluation is based on the past 6 months, and should be
updated around the same time as the 6 month release.
Based on how requirements are defined, this tag is only applicable for projects
where their primary deliverables are represented by commits and reviews in git.
An example of where this doesn't make sense is the release management team.
Deprecation
===========
There is no deprecation period required for this tag. It can be added or
removed at any time.

View File

@ -1,78 +0,0 @@
::
This work is licensed under a Creative Commons Attribution 3.0
Unported License.
http://creativecommons.org/licenses/by/3.0/legalcode
.. _`tag-team:single-vendor`:
==================
team:single-vendor
==================
This tag communicates that a given project team is currently driven by a
single organization.
This tag exists in the 'team' category, which as the name implies,
covers information about the team itself.
Application to current teams
============================
It's worth pointing out that the criteria used for this tag is applied across
all git repositories managed by a team.
.. tagged-projects:: team:single-vendor
Script used to apply this tag:
http://git.openstack.org/cgit/openstack/governance/tree/tools/validate_tags.py
Rationale
=========
Knowing that a given project is produced by a team essentially from a single
organization is a critical factor in the decision to deploy a project, as it
changes the dynamics of who you trust to continue to deliver this project.
In particular, such a project could be abandoned due to the budgeting
decisions of a single party. Additional steps (like engaging early on with
that single party) could be taken before investing significantly on such a
project.
Requirements
============
The tag applies to any project team where one organization represents >=90% of
any of the following over the prior six months:
* the sum of all commits merged into any of the git repositories managed by the
team
* the sum of all reviews done against patches submitted to any of the git
repositories managed by the team
* the sum of all reviews done by active core reviewers against patches submitted
to any of the git repositories managed by the team
* the union of the active members of the core review teams associated with the
git repositories managed by the team
This tag is applied based on the `tools/teamstats.py` script. The output of this
script is then reviewed by the TC to verify it matches the reality.
The application of this tag to new projects should be updated around the same
time as the 6 month release. But the removal of this tag should happen shortly
after it does not apply to a given project.
Based on how requirements are defined, this tag is only applicable for projects
where their primary deliverables are represented by commits and reviews in git.
Deprecation
===========
There is no deprecation period required for this tag. It can be added or
removed at any time.

View File

@ -1,280 +0,0 @@
#!/usr/bin/env python
# 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.
import functools
import os
import sys
import time
import uuid
import requests
import requests_cache
import yaml
import base
# Since the stackalytics is slow and we can call it twice, cache the results
requests_cache.install_cache(backend='memory', expire_after=60)
s = requests.session()
six_months = int(time.time() - 30*6*24*60*60) # 6 months ago
# NOTE(flaper87): This value affects both, single-vendor and diverse-affiliation
# tags and it's been tuned to a reasonable enough threshold to measure reviews
# activeness. Changes to this value must be discussed separately.
MIN_PERCENTAGE_REVIEWS = 0.02 # 2%
MIN_REVIEWS = 30
MIN_COMMITS = 6
def _memoize(func):
cache = {}
@functools.wraps(func)
def memoized(*args, **kwargs):
key = (args, tuple(kwargs.items()))
try:
return cache[key]
except KeyError:
cache[key] = func(*args, **kwargs)
return cache[key]
return memoized
@_memoize
def _get_number_of_commits(group, start_date=six_months):
commits = s.get('http://stackalytics.com/api/'
'1.0/stats/companies?metric=commits&release=all'
'&project_type=all&module=%s&start_date=%s'
% (group, start_date)).json()
return sum([company['metric'] for company in commits['stats']])
@_memoize
def get_team_size_stats(team):
team_stats = {}
group = "%s-group" % team.lower()
commits_total = _get_number_of_commits(group)
min_percent = int(commits_total * MIN_PERCENTAGE_REVIEWS)
reviews = s.get('http://stackalytics.com/api/'
'1.0/stats/engineers?metric=marks&release=all'
'&start_date=%s&project_type=all'
'&module=%s' % (six_months, group)).json()
team_stats['active_reviewers'] = 0
for eng in reviews['stats']:
if eng['metric'] >= MIN_REVIEWS or eng['metric'] >= min_percent:
team_stats['active_reviewers'] += 1
team_stats['active_committers'] = 0
commits = s.get('http://stackalytics.com/api/'
'1.0/stats/engineers?metric=commits&release=all'
'&project_type=all&module=%s&start_date=%s'
% (group, six_months)).json()
for eng in commits['stats']:
if eng['metric'] >= MIN_COMMITS:
team_stats['active_committers'] += 1
return team_stats
@_memoize
def get_core_reviews_by_company(group):
# reviews by individual
commits_total = _get_number_of_commits(group)
min_percent = int(commits_total * MIN_PERCENTAGE_REVIEWS)
reviews = s.get('http://stackalytics.com/api/'
'1.0/stats/engineers?metric=marks&release=all'
'&start_date=%s&project_type=all'
'&module=%s' % (six_months, group)).json()
companies = {}
for eng in reviews['stats']:
if eng['core'] != 'master':
continue
for stat in s.get('http://stackalytics.com/api/1.0/stats/'
'companies?metric=marks&module=%s&user_id=%s&'
'project_type=all&release=all&start_date=%s' %
(group, eng['id'], six_months)).json()['stats']:
company = stat['id']
if company == '*independent':
# several independent reviewers are not working in one company
company = 'independent-%s' % uuid.uuid4()
companies.setdefault(company, {'reviewers': 0, 'reviews': 0})
if eng['metric'] >= MIN_REVIEWS or eng['metric'] >= min_percent:
companies[company]['reviews'] += stat['metric']
companies[company]['reviewers'] += 1
return companies
@_memoize
def get_diversity_stats(project):
team_stats = {}
# commits by company
group = "%s-group" % project.lower()
commit_resp = s.get('http://stackalytics.com/api/'
'1.0/stats/companies?metric=commits&release=all'
'&project_type=all&module=%s&start_date=%s'
% (group, six_months))
if commit_resp.status_code == 404:
# The project in question doesn't have a group in stackalytics because
# it's part of a different group. Just look for it without the group
# suffix (e.g. during shade transition, there is no shade-group because
# the shade repo was in infra-group)
group = project.lower()
commit_resp = s.get('http://stackalytics.com/api/'
'1.0/stats/companies?metric=commits&release=all'
'&project_type=all&module=%s&start_date=%s'
% (group, six_months))
commits = commit_resp.json()
# reviews by company
reviews = s.get('http://stackalytics.com/api/'
'1.0/stats/companies?metric=marks&release=all'
'&project_type=all&module=%s&start_date=%s'
% (group, six_months)).json()
core_reviews_by_company = get_core_reviews_by_company(group)
commits_total = sum([company['metric'] for company in commits['stats']])
top2 = [
commits['stats'][0]['metric'] if len(commits['stats']) > 0 else 0,
commits['stats'][1]['metric'] if len(commits['stats']) > 1 else 0,
]
team_stats['commits_top'] = (
(float(top2[0]) / commits_total * 100) if commits_total else 0)
team_stats['commits_top2'] = (
(float(sum(top2)) / commits_total * 100) if commits_total else 0)
reviews_total = sum([company['metric'] for company in reviews['stats']])
top2 = [
reviews['stats'][0]['metric'] if len(reviews['stats']) > 0 else 0,
reviews['stats'][1]['metric'] if len(reviews['stats']) > 1 else 0,
]
team_stats['reviews_top'] = (
(float(top2[0]) / reviews_total * 100) if reviews_total else 0)
team_stats['reviews_top2'] = (
(float(sum(top2)) / reviews_total * 100) if reviews_total else 0)
core_review_values = [company['reviews'] for company in
core_reviews_by_company.values()]
if len(core_review_values) == 1:
core_review_values = [core_review_values[0], 0]
core_review_values.sort(reverse=True)
core_reviews_total = sum(core_review_values)
team_stats['core_reviews_top'] = (
(float(core_review_values[0]) / core_reviews_total * 100)
if core_reviews_total else 0)
team_stats['core_reviews_top2'] = (
((float(core_review_values[0]) + float(core_review_values[1])) /
core_reviews_total * 100) if core_reviews_total else 0)
core_reviewers_values = [company['reviewers'] for company in
core_reviews_by_company.values()]
if len(core_reviewers_values) == 1:
core_reviewers_values = [core_reviewers_values[0], 0]
core_reviewers_values.sort(reverse=True)
core_reviewers_total = sum(core_reviewers_values)
team_stats['core_reviewers_top'] = (
(float(core_reviewers_values[0]) / core_reviewers_total * 100)
if core_reviewers_total else 0)
team_stats['core_reviewers_top2'] = (
((float(core_reviewers_values[0]) + float(core_reviewers_values[1])) /
core_reviewers_total * 100) if core_reviewers_total else 0)
return team_stats
def is_diverse(team):
team_stats = get_diversity_stats(team)
diversity = all((
(team_stats['commits_top'] <= 50),
(team_stats['reviews_top'] <= 50),
(team_stats['core_reviews_top'] <= 50),
(team_stats['core_reviewers_top'] <= 50),
(team_stats['commits_top2'] <= 80),
(team_stats['reviews_top2'] <= 80),
(team_stats['core_reviews_top2'] <= 80),
(team_stats['core_reviewers_top2'] <= 80),
))
return diversity
def is_single_vendor(team):
team_stats = get_diversity_stats(team)
multi_vendor = all((
(team_stats['commits_top'] < 90),
(team_stats['reviews_top'] < 90),
(team_stats['core_reviews_top'] < 90),
(team_stats['core_reviewers_top'] < 90),
))
return not multi_vendor
def print_diversity(team):
team_stats = get_diversity_stats(team)
print('%-18s (%.2f%% | %.2f%% | %.2f%% | %.2f%%)' % (
team, team_stats['commits_top'], team_stats['reviews_top'],
team_stats['core_reviews_top'], team_stats['core_reviewers_top']))
print('%-18s (%.2f%% | %.2f%% | %.2f%% | %.2f%%)' % (
'', team_stats['commits_top2'], team_stats['reviews_top2'],
team_stats['core_reviews_top2'], team_stats['core_reviewers_top2']))
def print_team_size(team):
team_stats = get_team_size_stats(team)
print('%-18s (%6s | %6s)' % (
'', team_stats['active_committers'],
team_stats['active_reviewers']))
class ValidateDiversity(base.ValidatorBase):
@staticmethod
def validate(team):
"""Return True of team should have 'team:diverse-affiliation'"""
return is_diverse(team)
@staticmethod
def get_tag_name():
return "team:diverse-affiliation"
class ValidateSingleVendor(base.ValidatorBase):
@staticmethod
def validate(team):
"""Return True of team should have 'team:single-vendor'"""
return is_single_vendor(team)
@staticmethod
def get_tag_name():
return "team:single-vendor"
def main():
filename = os.path.abspath('reference/projects.yaml')
with open(filename, 'r') as f:
projects = [k for k in yaml.safe_load(f.read())]
projects.sort()
print('<Team> (top commit % | top review % | top core review % | '
'top core reviewer %)')
print(' (top 2 commit % | top 2 review % | top 2 core review % | '
'top 2 core reviewer %)')
print(' (active committers | active reviewers)')
for project in projects:
print_diversity(project)
print_team_size(project)
if __name__ == '__main__':
sys.exit(main())

View File

@ -1,100 +0,0 @@
#!/usr/bin/env python
# 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.
""" validate tag applications in projects.yaml
Validate the application of tags that can be pragmatically applied.
Note: Does not automatically update projects.yaml since doing so can reformat
and reorder projects.yaml
"""
import teamstats
import requests
import yaml
import os
import sys
from six.moves.urllib import parse
# List of modules to validate team based tags
team_validators = [
teamstats.ValidateDiversity,
teamstats.ValidateSingleVendor,
]
# List of modules to validate repository based tags
repo_validators = []
def main():
script_path = os.path.abspath(os.path.dirname(__file__))
filename = os.path.abspath(os.path.join(script_path,
'../reference/projects.yaml'))
if not os.path.isfile(filename):
sys.exit("Projects.yaml was not found at %s" % (filename))
with open(filename, 'r') as f:
teams = yaml.safe_load(f.read())
for team in teams:
# Check team based tags
for validator in team_validators:
validate(team, teams[team], validator)
# Check deliverable based tags
for name, deliverable in teams[team]['deliverables'].items():
for repo in deliverable['repos']:
if not repo_exists(repo):
continue
for validator in repo_validators:
validate(repo, deliverable, validator)
def validate(name, data, validator):
tag_name = validator.get_tag_name()
contains_tag = any([tag_name == tag for tag in
data.get('tags', [])])
if validator.validate(name):
# should contain tag
if not contains_tag:
print_tag_missing(name, tag_name)
else:
# should not contain tag
if contains_tag:
print_bad_tag(name, tag_name)
def repo_exists(repo):
"""Sometimes the governance docs can get out of sync with repo names."""
response = requests.get(
'https://review.openstack.org:443/projects/%s/' %
parse.quote_plus(repo))
# strip off first few chars because 'the JSON response body starts with
# a magic prefix line that must be stripped before feeding the rest of
# the response body to a JSON parser'
# https://review.openstack.org/Documentation/rest-api.html
if response.status_code == 404:
return False
return True
def print_tag_missing(name, tag):
print("* %s should have the tag '%s'" % (name, tag))
def print_bad_tag(name, tag):
print("* %s should not have the tag '%s'" % (name, tag))
if __name__ == '__main__':
sys.exit(main())