<divid="unreleased-message"> You are reading an old version of the documentation (v3.3.3). For the latest version see <ahref="https://matplotlib.org/stable/devel/release_guide.html">https://matplotlib.org/stable/devel/release_guide.html</a></div>
<pclass="first admonition-title">This document is only relevant for Matplotlib release managers.</p>
<pclass="last">A guide for developers who are doing a Matplotlib release.</p>
</div>
<divclass="admonition note">
<pclass="first admonition-title">Note</p>
<pclass="last">This assumes that a read-only remote for the canonical repository is
<codeclass="docutils literal notranslate"><spanclass="pre">remote</span></code> and a read/write remote is <codeclass="docutils literal notranslate"><spanclass="pre">DANGER</span></code></p>
</div>
<divclass="section" id="all-releases">
<h2>All Releases<aclass="headerlink" href="#all-releases" title="Permalink to this headline">¶</a></h2>
<divclass="section" id="testing">
<spanid="release-testing"></span><h3>Testing<aclass="headerlink" href="#testing" title="Permalink to this headline">¶</a></h3>
<p>We use <aclass="reference external" href="https://travis-ci.org/matplotlib/matplotlib">Travis CI</a> for
continuous integration. When preparing for a release, the final
tagged commit should be tested locally before it is uploaded:</p>
<p>Review and commit changes. Some issue/PR titles may not be valid reST (the
most common issue is <codeclass="docutils literal notranslate"><spanclass="pre">*</span></code> which is interpreted as unclosed markup).</p>
<divclass="admonition note">
<pclass="first admonition-title">Note</p>
<p>Make sure you authenticate against the GitHub API. If you
do not you will get blocked by GitHub for going over the API rate
limits. You can authenticate in one of two ways:</p>
<ulclass="last simple">
<li>using the <codeclass="docutils literal notranslate"><spanclass="pre">keyring</span></code> package; <codeclass="docutils literal notranslate"><spanclass="pre">pip</span><spanclass="pre">install</span><spanclass="pre">keyring</span></code> and then when
running the stats script, you will be prompted for user name and password,
that will be stored in your system keyring, or,</li>
<li>using a personal access token; generate a new token <aclass="reference external" href="https://github.com/settings/tokens">on this GitHub page</a> with the <codeclass="docutils literal notranslate"><spanclass="pre">repo:public_repo</span></code>
scope and place the token in <codeclass="file docutils literal notranslate"><spanclass="pre">~/.ghoauth</span></code>.</li>
<spanid="release-chkdocs"></span><h3>Update and Validate the Docs<aclass="headerlink" href="#update-and-validate-the-docs" title="Permalink to this headline">¶</a></h3>
<divclass="section" id="merge-doc-branch">
<h4>Merge <codeclass="docutils literal notranslate"><spanclass="pre">*-doc</span></code> branch<aclass="headerlink" href="#merge-doc-branch" title="Permalink to this headline">¶</a></h4>
<p>Merge the most recent 'doc' branch (e.g., <codeclass="docutils literal notranslate"><spanclass="pre">v3.2.0-doc</span></code>) into the branch you
are going to tag on and delete the doc branch on GitHub.</p>
<h4>Update "What's New" and "API changes"<aclass="headerlink" href="#update-what-s-new-and-api-changes" title="Permalink to this headline">¶</a></h4>
<p>Before tagging major and minor releases, the "what's new" and "API changes"
listings should be updated. This is not needed for micro releases.</p>
<p>For the "what's new",</p>
<blockquote>
<div><olclass="arabic simple">
<li>copy the current content to a file in <codeclass="file docutils literal notranslate"><spanclass="pre">doc/users/prev_whats_new</span></code></li>
<li>merge all of the files in <codeclass="file docutils literal notranslate"><spanclass="pre">doc/users/next_whats_new/</span></code> into
<codeclass="file docutils literal notranslate"><spanclass="pre">doc/users/whats_new.rst</span></code> and delete the individual files</li>
<li>comment out the next what's new glob at the top</li>
</ol>
</div></blockquote>
<p>Similarly for the "API changes",</p>
<blockquote>
<div><olclass="arabic simple">
<li>copy the current api changes to a file is <codeclass="file docutils literal notranslate"><spanclass="pre">doc/api/prev_api_changes</span></code></li>
<li>merge all of the files in the most recent <codeclass="file docutils literal notranslate"><spanclass="pre">doc/api/api_changes_X.Y</span></code>
into <codeclass="file docutils literal notranslate"><spanclass="pre">doc/api/api_changes.rst</span></code></li>
<li>comment out the most recent API changes at the top.</li>
</ol>
</div></blockquote>
<p>In both cases step 3 will have to be un-done right after the release.</p>
</div>
<divclass="section" id="verify-that-docs-build">
<h4>Verify that docs build<aclass="headerlink" href="#verify-that-docs-build" title="Permalink to this headline">¶</a></h4>
<p>Finally, make sure that the docs build cleanly</p>
<divclass="highlight-bash notranslate"><divclass="highlight"><pre><span></span>make -Cdoc <spanclass="nv">O</span><spanclass="o">=</span>-j<spanclass="k">$(</span>nproc<spanclass="k">)</span> html latexpdf
</pre></div>
</div>
<p>After the docs are built, check that all of the links, internal and external,
are still valid. We use <codeclass="docutils literal notranslate"><spanclass="pre">linkchecker</span></code> for this, which has not been ported to
Python3 yet. You will need to create a Python2 environment with
<codeclass="docutils literal notranslate"><spanclass="pre">requests==2.9.0</span></code> and linkchecker</p>
<spanid="release-tag"></span><h3>Create release commit and tag<aclass="headerlink" href="#create-release-commit-and-tag" title="Permalink to this headline">¶</a></h3>
<p>To create the tag, first create an empty commit with a very terse set of the release notes
<p>and then create a signed, annotated tag with the same text in the body
message</p>
<divclass="highlight-bash notranslate"><divclass="highlight"><pre><span></span>git tag -a -s v2.0.0
</pre></div>
</div>
<p>which will prompt you for your GPG key password and an annotation. For pre
releases it is important to follow <spanclass="target" id="index-0"></span><aclass="pep reference external" href="https://www.python.org/dev/peps/pep-0440"><strong>PEP 440</strong></a> so that the build artifacts will
sort correctly in PyPI.</p>
<p>To prevent issues with any down-stream builders which download the
tarball from GitHub it is important to move all branches away from the commit
with the tag <aclass="footnote-reference" href="#id3" id="id2">[1]</a>:</p>
<tr><tdclass="label"><aclass="fn-backref" href="#id2">[1]</a></td><td><pclass="first">The tarball that is provided by GitHub is produced using <aclass="reference external" href="https://git-scm.com/docs/git-archive">git
<codeclass="file docutils literal notranslate"><spanclass="pre">lib/matplotlib/_version.py</span></code> to have <codeclass="docutils literal notranslate"><spanclass="pre">git</span></code> insert a
list of references to exported commit (see
<codeclass="file docutils literal notranslate"><spanclass="pre">.gitattributes</span></code> for the configuration). This string is
then used by <codeclass="docutils literal notranslate"><spanclass="pre">versioneer</span></code> to produce the correct version,
based on the git tag, when users install from the tarball.
However, if there is a branch pointed at the tagged commit,
then the branch name will also be included in the tarball.
When the branch eventually moves, anyone how checked the hash
of the tarball before the branch moved will have an incorrect
<p>On this branch un-comment the globs from <aclass="reference internal" href="#release-chkdocs"><spanclass="std std-ref">Update and Validate the Docs</span></a>. And then</p>
<spanid="release-doi"></span><h3>Release Management / DOI<aclass="headerlink" href="#release-management-doi" title="Permalink to this headline">¶</a></h3>
<p>Via the <aclass="reference external" href="https://github.com/matplotlib/matplotlib/releases">GitHub UI</a>, turn the newly
pushed tag into a release. If this is a pre-release remember to mark
it as such.</p>
<p>For final releases, also get the DOI from <aclass="reference external" href="https://zenodo.org/">zenodo</a> (which will automatically produce one once
the tag is pushed). Add the doi post-fix and version to the dictionary in
<codeclass="file docutils literal notranslate"><spanclass="pre">tools/cache_zenodo_svg.py</span></code> and run the script.</p>
<p>This will download the new svg to the <codeclass="file docutils literal notranslate"><spanclass="pre">_static</span></code> directory in the
docs and edit <codeclass="file docutils literal notranslate"><spanclass="pre">doc/citing.rst</span></code>. Commit the new svg, the change
to <codeclass="file docutils literal notranslate"><spanclass="pre">tools/cache_zenodo_svg.py</span></code>, and the changes to
<codeclass="file docutils literal notranslate"><spanclass="pre">doc/citing.rst</span></code> to the VER-doc branch and push to GitHub.</p>
<spanid="release-bld-bin"></span><h3>Building binaries<aclass="headerlink" href="#building-binaries" title="Permalink to this headline">¶</a></h3>
<p>We distribute macOS, Windows, and many Linux wheels as well as a source tarball
via PyPI. Most builders should trigger automatically once the tag is pushed to
GitHub:</p>
<ulclass="simple">
<li>Mac and manylinux wheels are built on Travis CI. Builds are triggered by the
GitHub Action defined in <codeclass="file docutils literal notranslate"><spanclass="pre">.github/workflows/wheels.yml</span></code>, and wheels
will be available at the site defined in the <aclass="reference external" href="https://github.com/MacPython/matplotlib-wheels">matplotlib-wheels repo</a>.</li>
<li>Windows wheels are built by Christoph Gohlke automatically and will be
<aclass="reference external" href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#matplotlib">available at his site</a> once built.</li>
<li>The auto-tick bot should open a pull request into the <aclass="reference external" href="https://github.com/conda-forge/matplotlib-feedstock">conda-forge feedstock</a>. Review and merge
(if you have the power to).</li>
</ul>
<divclass="admonition warning">
<pclass="first admonition-title">Warning</p>
<pclass="last">Because this is automated, it is extremely important to bump all branches
away from the tag as discussed in <aclass="reference internal" href="#release-tag"><spanclass="std std-ref">Create release commit and tag</span></a>.</p>
</div>
<p>If this is a final release the following downstream packagers should be contacted:</p>
<ulclass="simple">
<li>Debian</li>
<li>Fedora</li>
<li>Arch</li>
<li>Gentoo</li>
<li>Macports</li>
<li>Homebrew</li>
<li>Continuum</li>
<li>Enthought</li>
</ul>
<p>This can be done ahead of collecting all of the binaries and uploading to pypi.</p>
<spanid="release-upload-bin"></span><h3>Make distribution and upload to PyPI<aclass="headerlink" href="#make-distribution-and-upload-to-pypi" title="Permalink to this headline">¶</a></h3>
<p>Once you have collected all of the wheels (expect this to take about a
<spanid="release-docs"></span><h3>Build and Deploy Documentation<aclass="headerlink" href="#build-and-deploy-documentation" title="Permalink to this headline">¶</a></h3>
<p>To build the documentation you must have the tagged version installed, but
build the docs from the <codeclass="docutils literal notranslate"><spanclass="pre">ver-doc</span></code> branch. An easy way to arrange this is:</p>
make -Cdoc <spanclass="nv">O</span><spanclass="o">=</span>-j<spanclass="k">$(</span>nproc<spanclass="k">)</span> html latexpdf <spanclass="nv">LATEXMKOPTS</span><spanclass="o">=</span><spanclass="s2">"-silent -f"</span>
</pre></div>
</div>
<p>which will build both the html and pdf version of the documentation.</p>
<p>The built documentation exists in the <aclass="reference external" href="https://github.com/matplotlib/matplotlib.github.com/">matplotlib.github.com</a> repository.
Pushing changes to master automatically updates the website.</p>
<p>The documentation is organized by version. At the root of the tree is always
the documentation for the latest stable release. Under that, there are
directories containing the documentation for older versions. The documentation
for current master is built on Circle CI and pushed to the <aclass="reference external" href="https://github.com/matplotlib/devdocs/">devdocs</a> repository. These are available at