Add changelog and changelog automation (#3364)

* Add changelog and changelog automation

First, update the version in our setup.cfg and changelog:

    invoke prepare <version>

Then, hand edit and commit, added any release notes, etc. Tag manually or:

    invoke release <version>

Finally, push up your changes.

This:

* Uses setup.cfg instead of setup.py
* Parses setup.cfg for version
* Updates setup.cfg on release prepare task
* Show our release version in our footer
* Uses invoke for task execution
* Uses a node library to hit GitHub and fetch the changelog
* Imports this into our existing changelog

* Fix style with autolint

* Lint fixes
more-gsoc
Anthony 2017-12-07 11:03:00 -07:00 committed by GitHub
parent ba71aa1860
commit 01717c03fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 199 additions and 50 deletions

22
CHANGELOG.rst Normal file
View File

@ -0,0 +1,22 @@
Version 2.0
-----------
* `@ericholscher <http://github.com/ericholscher>`_: Email sending: Allow kwargs for other options (`#3355 <https://github.com/rtfd/readthedocs.org/pull/3355>`_)
* `@ericholscher <http://github.com/ericholscher>`_: Try and get folks to put more tags. (`#3350 <https://github.com/rtfd/readthedocs.org/pull/3350>`_)
* `@ericholscher <http://github.com/ericholscher>`_: Small changes to email sending to enable from email (`#3349 <https://github.com/rtfd/readthedocs.org/pull/3349>`_)
* `@dplanella <http://github.com/dplanella>`_: Duplicate TOC entries (`#3345 <https://github.com/rtfd/readthedocs.org/issues/3345>`_)
* `@ericholscher <http://github.com/ericholscher>`_: Small tweaks to ethical ads page (`#3344 <https://github.com/rtfd/readthedocs.org/pull/3344>`_)
* `@agjohnson <http://github.com/agjohnson>`_: Fix python usage around oauth pagination (`#3342 <https://github.com/rtfd/readthedocs.org/pull/3342>`_)
* `@tony <http://github.com/tony>`_: Fix isort link (`#3340 <https://github.com/rtfd/readthedocs.org/pull/3340>`_)
* `@ericholscher <http://github.com/ericholscher>`_: Change stable version switching to respect `active` (`#3336 <https://github.com/rtfd/readthedocs.org/pull/3336>`_)
* `@ericholscher <http://github.com/ericholscher>`_: Allow superusers to pass admin & member tests for projects (`#3335 <https://github.com/rtfd/readthedocs.org/pull/3335>`_)
* `@humitos <http://github.com/humitos>`_: Do not split before first argument (`#3333 <https://github.com/rtfd/readthedocs.org/pull/3333>`_)
* `@humitos <http://github.com/humitos>`_: Update docs for pre-commit (auto linting) (`#3332 <https://github.com/rtfd/readthedocs.org/pull/3332>`_)
* `@humitos <http://github.com/humitos>`_: Take preferece of tags over branches when selecting the stable version (`#3331 <https://github.com/rtfd/readthedocs.org/pull/3331>`_)
* `@humitos <http://github.com/humitos>`_: Add prospector as a pre-commit hook (`#3328 <https://github.com/rtfd/readthedocs.org/pull/3328>`_)
* `@andrewgodwin <http://github.com/andrewgodwin>`_: "stable" appearing to track future release branches (`#3268 <https://github.com/rtfd/readthedocs.org/issues/3268>`_)
* `@humitos <http://github.com/humitos>`_: Config files for auto linting (`#3264 <https://github.com/rtfd/readthedocs.org/pull/3264>`_)
* `@mekrip <http://github.com/mekrip>`_: Build is not working (`#3223 <https://github.com/rtfd/readthedocs.org/issues/3223>`_)
* `@skddc <http://github.com/skddc>`_: Add JSDoc to docs build environment (`#3069 <https://github.com/rtfd/readthedocs.org/issues/3069>`_)
* `@jakirkham <http://github.com/jakirkham>`_: Specifying conda version used (`#2076 <https://github.com/rtfd/readthedocs.org/issues/2076>`_)
* `@agjohnson <http://github.com/agjohnson>`_: Document code style guidelines (`#1475 <https://github.com/rtfd/readthedocs.org/issues/1475>`_)

5
contrib/changelog.hbs Normal file
View File

@ -0,0 +1,5 @@
{{header}}
{{toHeader header "-"}}
{{#issues}} * `@{{user.login}} <http://github.com/{{user.login}}>`_: {{title}} (`#{{number}} <{{html_url}}>`_)
{{/issues}}

View File

@ -1,16 +1,25 @@
# Changelog
Changelog
=========
This document will track major changes in the project.
.. include:: ../CHANGELOG.rst
Also note, this document is a Markdown file. This is mainly to keep parity with GitHub, and also because we can.
Previous releases
-----------------
## July 23, 2015
Starting with version ``2.0``, we will be incrementing the Read the Docs version
based on semantic versioning principles, and will be automating the update of
our changelog.
Below are some historical changes from when we have tried to add information
here in the past
July 23, 2015
~~~~~~~~~~~~~
* Django 1.8 Support Merged
### Code Notes
Code Notes
``````````
- Updated Django from `1.6.11` to `1.8.3`.
- Removed South and ported the South migrations to Django's migration framework.
@ -25,36 +34,32 @@ Also note, this document is a Markdown file. This is mainly to keep parity with
- Added `django.setup()` to `conf.py` to load django properly for doc builds.
- Added migrations for all apps with models in the `readthedocs/` directory
### Deployment Notes
Deployment Notes
````````````````
After you have updated the code and installed the new dependencies, you need to run these commands on the server:
After you have updated the code and installed the new dependencies, you need to run these commands on the server::
```bash
python manage.py migrate contenttypes
python manage.py migrate projects 0002 --fake
python manage.py migrate --fake-initial
```
python manage.py migrate contenttypes
python manage.py migrate projects 0002 --fake
python manage.py migrate --fake-initial
Locally I had trouble in a test environment that pip did not update to the specified commit of tastypie. It might be required to use `pip install -U -r requirements/deploy.txt` during deployment.
### Development Update Notes
Development Update Notes
````````````````````````
The readthedocs developers need to execute these commands when switching to this branch (or when this got merged into master):
- **Before updating** please make sure that all migrations are applied:
- **Before updating** please make sure that all migrations are applied::
```bash
python manage.py syncdb
python manage.py migrate
```
python manage.py syncdb
python manage.py migrate
- Update the codebase: `git pull`
- You need to update the requirements with `pip install -r requirements.txt`
- Now you need to fake the initial migrations:
- Now you need to fake the initial migrations::
```bash
python manage.py migrate contenttypes
python manage.py migrate projects 0002 --fake
python manage.py migrate --fake-initial
```
python manage.py migrate contenttypes
python manage.py migrate projects 0002 --fake
python manage.py migrate --fake-initial

View File

@ -4,7 +4,8 @@
"description": "Read the Docs build dependencies",
"author": "Anthony Johnson <anthony@readthedocs.com>",
"dependencies": {
"cssfilter": "0.0.8"
"cssfilter": "0.0.8",
"github-changelog": "git+https://github.com/agjohnson/github-changelog.git"
},
"devDependencies": {
"bower": "*",

View File

@ -1,4 +1,22 @@
"""Read the Docs"""
# -*- coding: utf-8 -*-
"""Read the Docs."""
import os.path
from future.moves.configparser import RawConfigParser
# Import the Celery application before anything else happens
from readthedocs.worker import app # noqa
def get_version():
"""Return package version from setup.cfg."""
setupcfg_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', 'setup.cfg'),
)
config = RawConfigParser()
config.read(setupcfg_path)
return config.get('metadata', 'version')
__version__ = get_version()

View File

@ -11,6 +11,7 @@ from django.utils.encoding import force_bytes, force_text
from django.utils.safestring import mark_safe
from future.backports.urllib.parse import urlencode
from readthedocs import __version__
from readthedocs.core.resolver import resolve
from readthedocs.projects.models import Project
@ -95,3 +96,8 @@ def url_replace(request, field, value):
@register.filter
def key(d, key_name):
return d[key_name]
@register.simple_tag
def readthedocs_version():
return __version__

View File

@ -1,5 +1,6 @@
{% load i18n %}
{% load copyrighttags %}
{% load core_tags %}
{% load static %}
<!DOCTYPE html>
<html>
@ -153,7 +154,10 @@
<div class="footer-bottom">
<div class="column-copyright">
<p>
<small>&copy; Copyright 2010-{% now "Y" %}, {% trans "Read the Docs, Inc & contributors" %}</small>
<small>
&copy; Copyright {% now "Y" %}, {% trans "Read the Docs, Inc & contributors" %} -
{% trans "Version" %} {% readthedocs_version %}
</small>
</p>
</div>

26
setup.cfg Normal file
View File

@ -0,0 +1,26 @@
[metadata]
name = readthedocs
version = 2.0
license = MIT
description = Read the Docs builds and hosts documentation
author = Read the Docs, Inc
author_email = dev@readthedocs.com
url = http://readthedocs.org
classifiers =
Development Status :: 5 - Production/Stable
Environment :: Web Environment
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Programming Language :: Python
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
Programming Language :: Python :: 3.6
Framework :: Django
[options]
packages = find:
include_package_data = True
zip_safe = False

View File

@ -1,24 +1,5 @@
from setuptools import setup, find_packages
from setuptools import setup
setup(
name='readthedocs',
version="1.0",
license="MIT",
description='A documentation hosting website',
author='Eric Holscher, Charles Leifer, Bobby Grace',
author_email='eric@ericholscher.com',
url='http://readthedocs.org',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Framework :: Django',
],
)
# Configuration is in setup.cfg
setup()

81
tasks.py Normal file
View File

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
"""Read the Docs invoke tasks."""
from __future__ import division, print_function, unicode_literals
import os
import textwrap
from future.moves.configparser import RawConfigParser
from invoke import task
@task
def prepare(ctx, version):
"""
Prepare the next release version by updating files.
This will stage a few updates for manual review and commit:
* Prepend the most recent PRs and issues that were closed to CHANGELOG.rst.
* Update the setup.cfg version
Changelog uses the file modification date to track the last time it was
updated. New entries will end up at the top of the file, under a heading
for the new version.
"""
print('Updating release version in setup.cfg')
setupcfg_path = os.path.join(os.path.dirname(__file__), 'setup.cfg')
config = RawConfigParser()
config.read(setupcfg_path)
config.set('metadata', 'version', version)
with open(setupcfg_path, 'wb') as configfile:
config.write(configfile)
print('Installing github-changelog')
ctx.run('npm install git+https://github.com/agjohnson/github-changelog.git')
changelog_path = os.path.join(os.path.dirname(__file__), 'CHANGELOG.rst')
template_path = os.path.join(
os.path.dirname(__file__),
'contrib',
'changelog.hbs',
)
cmd = (
'gh-changelog '
'-o rtfd -r readthedocs.org '
'--file {changelog_path} '
'--template {template_path} '
'--header "Version {version}"'
).format(
version=version,
template_path=template_path,
changelog_path=changelog_path,
) # yapf: disable
try:
token = os.environ['GITHUB_TOKEN']
cmd += '--token ' + token + ' '
except KeyError:
print('')
print(
'\n'.join(
textwrap.wrap(
'In order to avoid rate limiting on the GitHub API, you can specify '
'an environment variable `GITHUB_TOKEN` with a personal access token. '
'There is no need for the token to have any permissions unless the '
'repoistory is private.')))
print('')
print('Updating changelog')
ctx.run(cmd)
@task
def release(ctx, version):
"""
Tag release of Read the Docs.
Do this after prepare task and manual cleanup/commit
"""
ctx.run(
('git checkout master && '
'git tag {version} && '
'git push --tags').format(version=version))