Repository: bokeh/bokeh

Issue:
All release notes on one webpage
Would it be possible to have a version of the release notes in the same style as e.g. the pandas package ? http://pandas.pydata.org/pandas-docs/version/0.21/release.html

Everything in one page with one long scrollbar. This makes the navigation easier with ctrl+f, especially to find breaking changes and deprecated features.

The Releases page on the bokeh website is well structured, but hard to use when you don't know which version to look up.



Discussion:
I'll work on this after the current release in progess. 

Resolving patch:
diff --git a/bokeh/sphinxext/bokeh_index_toctree.py b/bokeh/sphinxext/bokeh_index_toctree.py
deleted file mode 100644
--- a/bokeh/sphinxext/bokeh_index_toctree.py
+++ /dev/null
@@ -1,57 +0,0 @@
-''' This specialized toctree subclass sorts toctree entries for releases.
-
-it is convenient to add a glob for release notes in the top level
-``index.rst`` file, so that the list does not have to be constantly
-updated and maintained:
-
-.. code-block:: rst
-
-    .. bokeh-index-toctree::
-        :hidden:
-        :glob:
-
-        docs/installation
-        docs/user_guide
-        docs/user_guide/quickstart
-        docs/releases/*
-
-But the release files are named ``0.1.0.rst``, ``0.12.2.rst``, etc, and
-and default alphabetic sort will not produce good results. This directive
-will re-order any release documents according to semantic version.
-
-'''
-from __future__ import absolute_import
-from packaging.version import Version as V
-from sphinx.directives import TocTree
-
-def _ver_sort(x):
-    # x is an "entries" tuple
-    return V(x[1].split("docs/releases/")[1])
-
-class BokehIndexTocTree(TocTree):
-    def run(self):
-        rst = super(BokehIndexTocTree, self).run()
-
-        # entries are tuples something like: (None, 'docs/dev_guide/env_vars')
-        entries = rst[0][0]['entries']
-
-        # find the slice i:j of the entries that has the releases docs
-        i = -1
-        j = None
-        for ind, item in enumerate(entries):
-            if i < 0:
-                if item[1].startswith("docs/releases"):
-                    i = ind
-            else:
-                if not item[1].startswith("docs/releases"):
-                    j = ind
-                    break
-
-        if i >= 0:
-            # have to modfy in-place for changes to have effect
-            entries[i:j] = sorted(entries[i:j], key=_ver_sort, reverse=True)
-
-        return rst
-
-def setup(app):
-    app.add_directive('bokeh-index-toctree', BokehIndexTocTree)
diff --git a/bokeh/sphinxext/bokeh_releases.py b/bokeh/sphinxext/bokeh_releases.py
new file mode 100644
--- /dev/null
+++ b/bokeh/sphinxext/bokeh_releases.py
@@ -0,0 +1,49 @@
+''' Publish all Bokeh release notes on to a single page.
+
+This directive collect all the release notes files in the ``docs/releases``
+subdirectory, and includes them in *reverse version order*. Typical usage:
+
+.. code-block:: rst
+
+    :tocdepth: 1
+
+    .. toctree::
+
+    .. bokeh-releases::
+
+To avoid warnings about orphaned files, add the following to the Sphinx
+``conf.py`` file:
+
+.. code-block:: python
+
+    exclude_patterns = ['docs/releases/*']
+
+'''
+from __future__ import absolute_import
+
+from os import listdir
+from os.path import join
+
+from packaging.version import Version as V
+
+from .bokeh_directive import BokehDirective
+
+class BokehReleases(BokehDirective):
+
+    def run(self):
+        env = self.state.document.settings.env
+        app = env.app
+
+        rst = []
+
+        versions = [x.rstrip(".rst") for x in listdir(join(app.srcdir, 'docs', 'releases'))]
+        versions.sort(key=V, reverse=True)
+
+        for v in versions:
+            entry = self._parse(".. include:: releases/%s.rst" % v, "<bokeh-releases>")
+            rst.extend(entry)
+
+        return rst
+
+def setup(app):
+    app.add_directive('bokeh-releases', BokehReleases)
diff --git a/sphinx/source/conf.py b/sphinx/source/conf.py
--- a/sphinx/source/conf.py
+++ b/sphinx/source/conf.py
@@ -23,7 +23,7 @@
 # -- General configuration -----------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.4'
+needs_sphinx = '1.7'
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
@@ -40,13 +40,13 @@
     'bokeh.sphinxext.bokeh_gallery',
     'bokeh.sphinxext.bokeh_github',
     'bokeh.sphinxext.bokeh_jinja',
-    'bokeh.sphinxext.bokeh_index_toctree',
     'bokeh.sphinxext.bokeh_model',
     'bokeh.sphinxext.bokeh_options',
     'bokeh.sphinxext.bokeh_palette',
     'bokeh.sphinxext.bokeh_palette_group',
     'bokeh.sphinxext.bokeh_plot',
     'bokeh.sphinxext.bokeh_prop',
+    'bokeh.sphinxext.bokeh_releases',
     'bokeh.sphinxext.bokeh_sitemap',
     'bokeh.sphinxext.collapsible_code_block',
 ]
@@ -129,6 +129,9 @@
 # Sort members by type
 autodoc_member_order = 'groupwise'
 
+# patterns to exclude
+exclude_patterns = ['docs/releases/*']
+
 # This would more properly be done with rst_epilog but something about
 # the combination of this with the bokeh-gallery directive breaks the build
 rst_prolog = """
@@ -194,7 +197,7 @@
         ('Gallery', 'gallery'),
         ('Tutorial', 'https://mybinder.org/v2/gh/bokeh/bokeh-notebooks/master?filepath=tutorial%2F00%20-%20Introduction%20and%20Setup.ipynb'),
         ('Reference', 'reference'),
-        ('Releases', 'releases/%s' % version),
+        ('Releases', 'releases'),
         ('Developer Guide', 'dev_guide'),
     ),
     'ALL_VERSIONS': all_versions,


Test patch: