diff --git a/doc/source/conf.py b/doc/source/conf.py index 71c7697bb2..80cde65c60 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -29,7 +29,7 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinxcontrib.blockdiag', 'sphinxcontrib.programoutput', - 'oslosphinx' + 'zuul.sphinx.zuul', ] #extensions = ['sphinx.ext.intersphinx'] #intersphinx_mapping = {'python': ('http://docs.python.org/2.7', None)} @@ -89,7 +89,7 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +#html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/doc/source/user/config.rst b/doc/source/user/config.rst index 6b63e496ca..0e9d6cf5b8 100644 --- a/doc/source/user/config.rst +++ b/doc/source/user/config.rst @@ -75,6 +75,8 @@ after the main entries, for example using number prefixes in file's names:: .. _pipeline: +.. zuul:configobject:: Pipeline + Pipeline ~~~~~~~~ @@ -125,53 +127,60 @@ success, the pipeline reports back to Gerrit with a *Verified* vote of The attributes available on a pipeline are as follows (all are optional unless otherwise specified): -**name** (required) - This is used later in the project definition to indicate what jobs - should be run for events in the pipeline. +.. zuul:attr:: name + :required: -**manager** (required) - There are currently two schemes for managing pipelines: + This is used later in the project definition to indicate what jobs + should be run for events in the pipeline. - .. _independent_pipeline_manager: +.. zuul:attr:: manager + :required: - *independent* - Every event in this pipeline should be treated as independent of - other events in the pipeline. This is appropriate when the order of - events in the pipeline doesn't matter because the results of the - actions this pipeline performs can not affect other events in the - pipeline. For example, when a change is first uploaded for review, - you may want to run tests on that change to provide early feedback - to reviewers. At the end of the tests, the change is not going to - be merged, so it is safe to run these tests in parallel without - regard to any other changes in the pipeline. They are independent. + There are currently two schemes for managing pipelines: - Another type of pipeline that is independent is a post-merge - pipeline. In that case, the changes have already merged, so the - results can not affect any other events in the pipeline. + .. _independent_pipeline_manager: - .. _dependent_pipeline_manager: + .. zuul:attr:: independent - *dependent* - The dependent pipeline manager is designed for gating. It ensures - that every change is tested exactly as it is going to be merged - into the repository. An ideal gating system would test one change - at a time, applied to the tip of the repository, and only if that - change passed tests would it be merged. Then the next change in - line would be tested the same way. In order to achieve parallel - testing of changes, the dependent pipeline manager performs - speculative execution on changes. It orders changes based on - their entry into the pipeline. It begins testing all changes in - parallel, assuming that each change ahead in the pipeline will pass - its tests. If they all succeed, all the changes can be tested and - merged in parallel. If a change near the front of the pipeline - fails its tests, each change behind it ignores whatever tests have - been completed and are tested again without the change in front. - This way gate tests may run in parallel but still be tested - correctly, exactly as they will appear in the repository when - merged. + Every event in this pipeline should be treated as independent of + other events in the pipeline. This is appropriate when the order + of events in the pipeline doesn't matter because the results of + the actions this pipeline performs can not affect other events in + the pipeline. For example, when a change is first uploaded for + review, you may want to run tests on that change to provide early + feedback to reviewers. At the end of the tests, the change is + not going to be merged, so it is safe to run these tests in + parallel without regard to any other changes in the pipeline. + They are independent. - For more detail on the theory and operation of Zuul's dependent - pipeline manager, see: :doc:`gating`. + Another type of pipeline that is independent is a post-merge + pipeline. In that case, the changes have already merged, so the + results can not affect any other events in the pipeline. + + .. _dependent_pipeline_manager: + + .. zuul:attr:: dependent + + The dependent pipeline manager is designed for gating. It + ensures that every change is tested exactly as it is going to be + merged into the repository. An ideal gating system would test + one change at a time, applied to the tip of the repository, and + only if that change passed tests would it be merged. Then the + next change in line would be tested the same way. In order to + achieve parallel testing of changes, the dependent pipeline + manager performs speculative execution on changes. It orders + changes based on their entry into the pipeline. It begins + testing all changes in parallel, assuming that each change ahead + in the pipeline will pass its tests. If they all succeed, all + the changes can be tested and merged in parallel. If a change + near the front of the pipeline fails its tests, each change + behind it ignores whatever tests have been completed and are + tested again without the change in front. This way gate tests + may run in parallel but still be tested correctly, exactly as + they will appear in the repository when merged. + + For more detail on the theory and operation of Zuul's dependent + pipeline manager, see: :doc:`gating`. **allow-secrets** This is a boolean which can be used to prevent jobs which require diff --git a/test-requirements.txt b/test-requirements.txt index 914dcf0198..dcc67e250f 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -11,7 +11,6 @@ python-subunit testrepository>=0.0.17 testtools>=0.9.32 sphinxcontrib-programoutput -oslosphinx mock PyMySQL mypy diff --git a/zuul/sphinx/__init__.py b/zuul/sphinx/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/zuul/sphinx/zuul.py b/zuul/sphinx/zuul.py new file mode 100644 index 0000000000..4561a70675 --- /dev/null +++ b/zuul/sphinx/zuul.py @@ -0,0 +1,94 @@ +# Copyright 2017 Red Hat, 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. + +from sphinx import addnodes +from sphinx.domains import Domain, ObjType +from sphinx.directives import ObjectDescription + + +class ZuulConfigObject(ObjectDescription): + pass + + +class ZuulConfigobjectDirective(ZuulConfigObject): + has_content = False + + def before_content(self): + self.env.ref_context['zuul:configobject'] = self.names[-1].lower() + + def handle_signature(self, sig, signode): + return sig + + +class ZuulAttrDirective(ZuulConfigObject): + has_content = True + + option_spec = { + 'required': lambda x: x, + } + + def before_content(self): + path = self.env.ref_context.setdefault('zuul:attr_path', []) + path.append(self.names[-1]) + + def after_content(self): + path = self.env.ref_context.get('zuul:attr_path') + if path: + path.pop() + + def handle_signature(self, sig, signode): + obj = self.env.ref_context.get('zuul:configobject') + attr_path = self.env.ref_context.get('zuul:attr_path', []) + path = [] + if obj: + path.append(obj) + if attr_path: + path.extend(attr_path) + for x in path: + signode += addnodes.desc_addname(x + '.', x + '.') + signode += addnodes.desc_name(sig, sig) + if 'required' in self.options: + signode += addnodes.desc_annotation(' (required)', ' (required)') + return sig + + def add_target_and_index(self, name, sig, signode): + targetname = self.objtype + '-' + name + if targetname not in self.state.document.ids: + signode['names'].append(targetname) + signode['ids'].append(targetname) + signode['first'] = (not self.names) + self.state.document.note_explicit_target(signode) + + indextext = '%s (%s)' % (name, self.objtype) + self.indexnode['entries'].append(('single', indextext, + targetname, '', None)) + + +class ZuulDomain(Domain): + name = 'zuul' + label = 'Zuul' + + object_types = { + 'configobject': ObjType('configobject'), + 'attr': ObjType('attr'), + } + + directives = { + 'configobject': ZuulConfigobjectDirective, + 'attr': ZuulAttrDirective, + } + + +def setup(app): + app.add_domain(ZuulDomain)