generate the series status table from data
Move the information about the series status into a data file and use that to generate the table on the main page. This is the first step toward adding deliverable-specific series status information to the output, since we need a place to put the default values. Because we're adding a yaml file under the deliverables directory that is not actually a deliverable file, we have to update the validation tool to ignore it. Story: #2001852 Task: #14347 Change-Id: I99bd94a323b53c0dfc2cb648268e51a30321cd46 Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
78
deliverables/series_status.yaml
Normal file
78
deliverables/series_status.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
- name: rocky
|
||||
status: development
|
||||
initial-release: 2018-08-30
|
||||
next-phase:
|
||||
status: maintained
|
||||
date: 2018-08-30
|
||||
- name: queens
|
||||
status: maintained
|
||||
initial-release: 2018-02-28
|
||||
next-phase:
|
||||
status: extended maintenance
|
||||
date: 2019-08-25
|
||||
- name: pike
|
||||
status: maintained
|
||||
initial-release: 2017-08-30
|
||||
next-phase:
|
||||
status: extended maintenance
|
||||
date: 2019-03-03
|
||||
- name: ocata
|
||||
status: maintained
|
||||
initial-release: 2017-02-22
|
||||
next-phase:
|
||||
status: extended maintenance
|
||||
date: 2018-08-27
|
||||
- name: newton
|
||||
status: end of life
|
||||
initial-release: 2016-10-06
|
||||
eol-date: 2017-10-25
|
||||
- name: mitaka
|
||||
status: end of life
|
||||
initial-release: 2016-04-07
|
||||
eol-date: 2017-04-10
|
||||
- name: liberty
|
||||
status: end of life
|
||||
initial-release: 2015-10-15
|
||||
eol-date: 2016-11-17
|
||||
- name: kilo
|
||||
status: end of life
|
||||
initial-release: 2015-04-30
|
||||
eol-date: 2016-05-02
|
||||
- name: juno
|
||||
status: end of life
|
||||
initial-release: 2014-10-16
|
||||
eol-date: 2015-12-07
|
||||
- name: icehouse
|
||||
status: end of life
|
||||
initial-release: 2014-04-17
|
||||
eol-date: 2015-07-02
|
||||
- name: havana
|
||||
status: end of life
|
||||
initial-release: 2013-10-17
|
||||
eol-date: 2014-09-30
|
||||
- name: grizzly
|
||||
status: end of life
|
||||
initial-release: 2013-04-04
|
||||
eol-date: 2014-03-29
|
||||
- name: folsom
|
||||
status: end of life
|
||||
initial-release: 2012-09-27
|
||||
eol-date: 2013-11-19
|
||||
- name: essex
|
||||
status: end of life
|
||||
initial-release: 2012-04-05
|
||||
eol-date: 2013-05-06
|
||||
- name: diablo
|
||||
status: end of life
|
||||
initial-release: 2011-09-22
|
||||
eol-date: 2013-05-06
|
||||
- name: cactus
|
||||
status: end of life
|
||||
initial-release: 2011-04-15
|
||||
- name: bexar
|
||||
status: end of life
|
||||
initial-release: 2011-02-03
|
||||
- name: austin
|
||||
status: end of life
|
||||
initial-release: 2010-10-21
|
||||
24
doc/source/_themes/releases/series_status_table.tmpl
Normal file
24
doc/source/_themes/releases/series_status_table.tmpl
Normal file
@@ -0,0 +1,24 @@
|
||||
.. -*- mode: rst -*-
|
||||
|
||||
.. This template renders a table showing the default status of each
|
||||
series using the list-table directive.
|
||||
|
||||
{% macro phase_link(phase) -%}
|
||||
`{{ phase|title }} <https://docs.openstack.org/project-team-guide/stable-branches.html#maintenance-phases>`__
|
||||
{%- endmacro %}
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
- * Series
|
||||
* Status
|
||||
* Initial Release Date
|
||||
* Next Phase
|
||||
* EOL Date
|
||||
{%- for series in data %}
|
||||
- * :doc:`{{ series['name'] }}/index`
|
||||
* {{ phase_link(series['status']) }}
|
||||
* {{ series['initial-release'] }} {%- if series['status'] == 'development' %} *estimated* :doc:`(schedule) <{{ series['name'] }}/schedule>`{%- endif %}
|
||||
* {% if series['next-phase'] %}{{ phase_link(series['next-phase']['status']) }} *estimated {{ series['next-phase']['date'] }}*{% endif %}
|
||||
* {{ series.get('eol-date', '') }}
|
||||
{%- endfor %}
|
||||
@@ -77,7 +77,10 @@ latex_documents = [
|
||||
|
||||
def format_date(s, fmt='%b %d'):
|
||||
# This function is used in schedule_table.tmpl
|
||||
d = datetime.datetime.strptime(s, '%Y-%m-%d')
|
||||
if isinstance(s, (datetime.date, datetime.datetime)):
|
||||
d = s
|
||||
else:
|
||||
d = datetime.datetime.strptime(s, '%Y-%m-%d')
|
||||
return d.strftime(fmt)
|
||||
|
||||
|
||||
|
||||
@@ -13,107 +13,9 @@ updates.
|
||||
|
||||
.. _combined release calendar: schedule.ics
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
- * Series
|
||||
* Status
|
||||
* Initial Release Date
|
||||
* Next Phase
|
||||
* EOL Date
|
||||
- * :doc:`rocky/index`
|
||||
* :doc:`Under Development <rocky/schedule>`
|
||||
* :ref:`scheduled <r-release>`
|
||||
*
|
||||
* TBD
|
||||
- * :doc:`queens/index`
|
||||
* `Maintained`_
|
||||
* 2018-02-28
|
||||
* `Extended Maintenance`_ approximately on 2019-08-25
|
||||
* TBD
|
||||
- * :doc:`pike/index`
|
||||
* `Maintained`_
|
||||
* 2017-08-30
|
||||
* `Extended Maintenance`_ approximately on 2019-03-03
|
||||
* TBD
|
||||
- * :doc:`ocata/index`
|
||||
* `Maintained`_
|
||||
* 2017-02-22
|
||||
* `Extended Maintenance`_ approximately on 2018-08-27
|
||||
* TBD
|
||||
- * :doc:`newton/index`
|
||||
* EOL
|
||||
* 2016-10-06
|
||||
*
|
||||
* 2017-10-25
|
||||
- * :doc:`mitaka/index`
|
||||
* EOL
|
||||
* 2016-04-07
|
||||
*
|
||||
* 2017-04-10
|
||||
- * :doc:`liberty/index`
|
||||
* EOL
|
||||
* 2015-10-15
|
||||
*
|
||||
* 2016-11-17
|
||||
- * :doc:`kilo/index`
|
||||
* EOL
|
||||
* 2015-04-30
|
||||
*
|
||||
* 2016-05-02
|
||||
- * :doc:`juno/index`
|
||||
* EOL
|
||||
* 2014-10-16
|
||||
*
|
||||
* 2015-12-07
|
||||
- * :doc:`icehouse/index`
|
||||
* EOL
|
||||
* 2014-04-17
|
||||
*
|
||||
* 2015-07-02
|
||||
- * :doc:`havana/index`
|
||||
* EOL
|
||||
* 2013-10-17
|
||||
*
|
||||
* 2014-09-30
|
||||
- * :doc:`grizzly/index`
|
||||
* EOL
|
||||
* 2013-04-04
|
||||
*
|
||||
* 2014-03-29
|
||||
- * :doc:`folsom/index`
|
||||
* EOL
|
||||
* 2012-09-27
|
||||
*
|
||||
* 2013-11-19
|
||||
- * :doc:`essex/index`
|
||||
* EOL
|
||||
* 2012-04-05
|
||||
*
|
||||
* 2013-05-06
|
||||
- * :doc:`diablo/index`
|
||||
* EOL
|
||||
* 2011-09-22
|
||||
*
|
||||
* 2013-05-06
|
||||
- * :doc:`cactus/index`
|
||||
* Deprecated
|
||||
* 2011-04-15
|
||||
*
|
||||
*
|
||||
- * :doc:`bexar/index`
|
||||
* Deprecated
|
||||
* 2011-02-03
|
||||
*
|
||||
*
|
||||
- * :doc:`austin/index`
|
||||
* Deprecated
|
||||
* 2010-10-21
|
||||
*
|
||||
*
|
||||
|
||||
.. _Maintained: https://docs.openstack.org/project-team-guide/stable-branches.html#maintenance-phases
|
||||
.. _Extended Maintenance: https://docs.openstack.org/project-team-guide/stable-branches.html#maintenance-phases
|
||||
.. datatemplate::
|
||||
:source: ../../deliverables/series_status.yaml
|
||||
:template: series_status_table.tmpl
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
@@ -27,14 +28,50 @@ import pkgutil
|
||||
import sys
|
||||
|
||||
import jsonschema
|
||||
import jsonschema.validators
|
||||
|
||||
from openstack_releases import yamlutils
|
||||
|
||||
_SCHEMA = yamlutils.loads(
|
||||
LOG = logging.getLogger('')
|
||||
|
||||
_SERIES_SCHEMA = yamlutils.loads(
|
||||
pkgutil.get_data('openstack_releases',
|
||||
'series_status_schema.yaml').decode('utf-8')
|
||||
)
|
||||
|
||||
_DELIVERABLE_SCHEMA = yamlutils.loads(
|
||||
pkgutil.get_data('openstack_releases', 'schema.yaml').decode('utf-8')
|
||||
)
|
||||
|
||||
|
||||
def is_date(validator, value, instance, schema):
|
||||
if not isinstance(instance, str):
|
||||
return
|
||||
try:
|
||||
return datetime.datetime.strptime(instance, "%Y-%m-%d")
|
||||
except Exception:
|
||||
yield jsonschema.ValidationError('Invalid date {!r}'.format(instance))
|
||||
|
||||
|
||||
def make_validator_with_date(schema_data):
|
||||
return jsonschema.validators.extend(
|
||||
validator=jsonschema.Draft4Validator(schema_data),
|
||||
validators={'date': is_date},
|
||||
)(schema_data, types={'date': datetime.date})
|
||||
|
||||
|
||||
def validate_one_file(filename, schema_data, debug):
|
||||
LOG.info('Checking %s', filename)
|
||||
validator = make_validator_with_date(schema_data)
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
info = yamlutils.loads(f.read())
|
||||
for error in validator.iter_errors(info):
|
||||
LOG.error(error)
|
||||
yield '{}: {}'.format(filename, error)
|
||||
if debug:
|
||||
raise RuntimeError(error)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
@@ -58,38 +95,23 @@ def main():
|
||||
level=logging.DEBUG,
|
||||
)
|
||||
logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
|
||||
log = logging.getLogger('')
|
||||
|
||||
errors = []
|
||||
|
||||
errors.extend(
|
||||
validate_one_file('deliverables/series_status.yaml',
|
||||
_SERIES_SCHEMA, args.debug)
|
||||
)
|
||||
|
||||
filenames = args.input or sorted(glob.glob('deliverables/*/*.yaml'))
|
||||
|
||||
errors = []
|
||||
warnings = []
|
||||
|
||||
for filename in filenames:
|
||||
log.info('Checking %s', filename)
|
||||
if not os.path.isfile(filename):
|
||||
log.info("File was deleted, skipping.")
|
||||
LOG.info("%s was deleted, skipping.", filename)
|
||||
continue
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
deliverable_info = yamlutils.loads(f.read())
|
||||
|
||||
def mk_warning(msg):
|
||||
log.warning(msg)
|
||||
warnings.append('{}: {}'.format(filename, msg))
|
||||
|
||||
def mk_error(msg):
|
||||
log.error(msg)
|
||||
errors.append('{}: {}'.format(filename, msg))
|
||||
if args.debug:
|
||||
raise RuntimeError(msg)
|
||||
|
||||
validator = jsonschema.Draft4Validator(_SCHEMA)
|
||||
for error in validator.iter_errors(deliverable_info):
|
||||
mk_error(str(error))
|
||||
|
||||
print('\n\n%s warnings found' % len(warnings))
|
||||
for w in warnings:
|
||||
print(w)
|
||||
errors.extend(
|
||||
validate_one_file(filename, _DELIVERABLE_SCHEMA, args.debug)
|
||||
)
|
||||
|
||||
print('\n\n%s errors found' % len(errors))
|
||||
for e in errors:
|
||||
|
||||
@@ -38,7 +38,8 @@ def find_modified_deliverable_files():
|
||||
filenames = [
|
||||
l.strip()
|
||||
for l in results.splitlines()
|
||||
if l.startswith('deliverables/')
|
||||
if (l.startswith('deliverables/') and
|
||||
not l.endswith('series_status.yaml'))
|
||||
]
|
||||
return filenames
|
||||
|
||||
|
||||
47
openstack_releases/series_status_schema.yaml
Normal file
47
openstack_releases/series_status_schema.yaml
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
$schema: "http://json-schema.org/schema#"
|
||||
$id: "http://git.openstack.org/cgit/openstack/releases/tree/README.rst"
|
||||
|
||||
# Do not allow any properties not defined here. This lets us catch
|
||||
# typos.
|
||||
additionalProperties: false
|
||||
|
||||
type: "array"
|
||||
items:
|
||||
type: "object"
|
||||
additionalProperties: false
|
||||
required:
|
||||
- name
|
||||
- status
|
||||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
status:
|
||||
type: "string"
|
||||
enum:
|
||||
- development
|
||||
- maintained
|
||||
- extended maintenance
|
||||
- unmaintained
|
||||
- end of life
|
||||
initial-release:
|
||||
type: "date"
|
||||
eol-date:
|
||||
type: "date"
|
||||
next-phase:
|
||||
type: "object"
|
||||
additionalProperties: false
|
||||
properties:
|
||||
required:
|
||||
- status
|
||||
- date
|
||||
status:
|
||||
type: "string"
|
||||
enum:
|
||||
- development
|
||||
- maintained
|
||||
- extended maintenance
|
||||
- unmaintained
|
||||
- end of life
|
||||
date:
|
||||
type: "date"
|
||||
Reference in New Issue
Block a user