<pclass="admonition-title">This document is only relevant for Matplotlib release managers.</p>
<p>A guide for developers who are doing a Matplotlib release.</p>
</div>
<divclass="admonition note">
<pclass="admonition-title">Note</p>
<p>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>
<sectionid="testing">
<spanid="release-testing"></span><h2>Testing<aclass="headerlink" href="#testing" title="Permalink to this headline">¶</a></h2>
<p>We use <aclass="reference external" href="https://github.com/matplotlib/matplotlib/actions">GitHub Actions</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="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="simple">
<li><p>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,</p></li>
<li><p>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>.</p></li>
</ul>
</div>
</section>
<sectionid="update-and-validate-the-docs">
<spanid="release-chkdocs"></span><h2>Update and validate the docs<aclass="headerlink" href="#update-and-validate-the-docs" title="Permalink to this headline">¶</a></h2>
<sectionid="merge-doc-branch">
<h3>Merge <codeclass="docutils literal notranslate"><spanclass="pre">*-doc</span></code> branch<aclass="headerlink" href="#merge-doc-branch" title="Permalink to this headline">¶</a></h3>
<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>
<h3>Update supported versions in Security Policy<aclass="headerlink" href="#update-supported-versions-in-security-policy" title="Permalink to this headline">¶</a></h3>
<p>When making major or minor releases, update the supported versions in the
Security Policy in <codeclass="file docutils literal notranslate"><spanclass="pre">SECURITY.md</span></code>. Commonly, this may be one or two
previous minor releases, but is dependent on release managers.</p>
</section>
<sectionid="update-release-notes">
<h3>Update release notes<aclass="headerlink" href="#update-release-notes" title="Permalink to this headline">¶</a></h3>
<sectionid="what-s-new">
<h4>What's new<aclass="headerlink" href="#what-s-new" title="Permalink to this headline">¶</a></h4>
<p><em>Only needed for major and minor releases. Bugfix releases should not have new
features.</em></p>
<p>Merge the contents of all the files in <codeclass="file docutils literal notranslate"><spanclass="pre">doc/users/next_whats_new/</span></code>
into a single file <codeclass="file docutils literal notranslate"><spanclass="pre">doc/users/prev_whats_new/whats_new_X.Y.0.rst</span></code>
and delete the individual files.</p>
</section>
<sectionid="api-changes">
<h4>API changes<aclass="headerlink" href="#api-changes" title="Permalink to this headline">¶</a></h4>
<p><em>Primarily needed for major and minor releases. We may sometimes have API
changes in bugfix releases.</em></p>
<p>Merge the contents of all the files in <codeclass="file docutils literal notranslate"><spanclass="pre">doc/api/next_api_changes/</span></code>
into a single file <codeclass="file docutils literal notranslate"><spanclass="pre">doc/api/prev_api_changes/api_changes_X.Y.Z.rst</span></code>
and delete the individual files.</p>
</section>
<sectionid="release-notes-toc">
<h4>Release notes TOC<aclass="headerlink" href="#release-notes-toc" title="Permalink to this headline">¶</a></h4>
<h3>Update supported versions in SECURITY.md<aclass="headerlink" href="#update-supported-versions-in-security-md" title="Permalink to this headline">¶</a></h3>
<p>For minor version release update the table in <codeclass="file docutils literal notranslate"><spanclass="pre">SECURITY.md</span></code> to specify
that the 2 most recent minor releases in the current major version series are
supported.</p>
<p>For a major version release update the table in <codeclass="file docutils literal notranslate"><spanclass="pre">SECURITY.md</span></code> to specify
that the last minor version in the previous major version series is still
supported. Dropping support for the last version of a major version series
will be handled on an ad-hoc basis.</p>
</section>
</section>
<sectionid="create-release-commit-and-tag">
<spanid="release-tag"></span><h2>Create release commit and tag<aclass="headerlink" href="#create-release-commit-and-tag" title="Permalink to this headline">¶</a></h2>
<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 brackets" href="#id3" id="id2">1</a>:</p>
<dd><p>The tarball that is provided by GitHub is produced using <aclass="reference external" href="https://git-scm.com/docs/git-archive">git archive</a>.
We use <aclass="reference external" href="https://github.com/pypa/setuptools_scm">setuptools_scm</a> which uses a format string in
<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">setuptools_scm</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><h2>Release management / DOI<aclass="headerlink" href="#release-management-doi" title="Permalink to this headline">¶</a></h2>
<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><h2>Building binaries<aclass="headerlink" href="#building-binaries" title="Permalink to this headline">¶</a></h2>
<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><p>Windows, macOS and manylinux wheels are built on GitHub Actions. Builds are
triggered by the GitHub Action defined in
<codeclass="file docutils literal notranslate"><spanclass="pre">.github/workflows/cibuildwheel.yml</span></code>, and wheels will be available as
artifacts of the build.</p></li>
<li><p>Alternative 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.</p></li>
<li><p>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).</p></li>
</ul>
<divclass="admonition warning">
<pclass="admonition-title">Warning</p>
<p>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><p>Debian</p></li>
<li><p>Fedora</p></li>
<li><p>Arch</p></li>
<li><p>Gentoo</p></li>
<li><p>Macports</p></li>
<li><p>Homebrew</p></li>
<li><p>Continuum</p></li>
<li><p>Enthought</p></li>
</ul>
<p>This can be done ahead of collecting all of the binaries and uploading to pypi.</p>
<spanid="release-upload-bin"></span><h2>Make distribution and upload to PyPI<aclass="headerlink" href="#make-distribution-and-upload-to-pypi" title="Permalink to this headline">¶</a></h2>
<p>Once you have collected all of the wheels (expect this to take about a
<p>Congratulations, you have now done the second scariest part!</p>
</section>
<sectionid="build-and-deploy-documentation">
<spanid="release-docs"></span><h2>Build and deploy documentation<aclass="headerlink" href="#build-and-deploy-documentation" title="Permalink to this headline">¶</a></h2>
<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><spanclass="s2">"-t release -j</span><spanclass="k">$(</span>nproc<spanclass="k">)</span><spanclass="s2">"</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