Merge branch 'master' into config-file-v2-docs

ghowardsit
Santos Gallegos 2019-01-29 17:34:18 -05:00
commit eb1cd4e25a
22 changed files with 303 additions and 123 deletions

50
.github/mergeable.yml vendored
View File

@ -1,28 +1,30 @@
# ProBot Mergeable Bot
# https://github.com/jusx/mergeable
version: 2
mergeable:
pull_requests:
approvals:
# Minimum of approvals needed.
min: 1
message: 'The PR must have a minimum of 1 approvals.'
description:
no_empty:
# Do not allow empty descriptions on PR.
enabled: false
message: 'Description can not be empty.'
must_exclude:
# Do not allow 'DO NOT MERGE' phrase on PR's description.
regex: 'DO NOT MERGE'
message: 'Description says that the PR should not be merged yet.'
# Do not allow 'WIP' on PR's title.
title: 'WIP'
label:
# Do not allow PR with label 'PR: work in progress'
must_exclude: 'PR: work in progress'
message: 'This PR is work in progress.'
- when: pull_request.*
validate:
- do: title
# Do not merge when it is marked work in progress (WIP)
must_exclude:
regex: ^\[WIP\]
message: This is work in progress. Do not merge yet.
- do: description
must_exclude:
# Do not allow 'DO NOT MERGE' phrase on PR's description.
regex: 'DO NOT MERGE'
message: 'Description says that the PR should not be merged yet.'
no_empty:
# Do not allow empty descriptions on PR.
enabled: true
message: 'Description can not be empty.'
- do: approvals
min:
count: 1
message: 'The PR must have a minimum of 1 approvals.'
- do: label
# Do not allow PR with label 'PR: work in progress'
must_exclude:
regex: 'PR: work in progress'
message: 'This PR is work in progress.'

View File

@ -1,4 +1,4 @@
[rstcheck]
ignore_directives=automodule,http:get,tabs,tab,prompt
ignore_roles=djangosetting,setting,buildpyversions
ignore_roles=djangosetting,setting,featureflags,buildpyversions
ignore_messages=(Duplicate implicit target name: ".*")|(Hyperlink target ".*" is not referenced)

View File

@ -71,8 +71,8 @@ since it will stay up to date with your Read the Docs project::
.. _Read the Docs README: https://github.com/rtfd/readthedocs.org/blob/master/README.rst
.. _project page: https://readthedocs.org/projects/pip/
.. |green| image:: https://media.readthedocs.org/static/projects/badges/passing-flat.svg
.. |red| image:: https://media.readthedocs.org/static/projects/badges/failing-flat.svg
.. |yellow| image:: https://media.readthedocs.org/static/projects/badges/unknown-flat.svg
.. |green| image:: https://assets.readthedocs.org/static/projects/badges/passing-flat.svg
.. |red| image:: https://assets.readthedocs.org/static/projects/badges/failing-flat.svg
.. |yellow| image:: https://assets.readthedocs.org/static/projects/badges/unknown-flat.svg
.. |nbsp| unicode:: 0xA0
:trim:

View File

@ -61,7 +61,7 @@ After any build is successfully finished, `HTMLFile` objects are created for eac
`django-elasticsearch-dsl`_ package listens to the `post_create`/`post_delete` signals
to index/delete documents, but it has performance drawbacks as it send HTTP request whenever
any `HTMLFile` objects is created or deleted. To optimize the performance, `bulk_post_create`
and `bulk_post_delete` Signals_ are dispatched with list of `HTMLFIle` objects so its possible
and `bulk_post_delete` signals_ are dispatched with list of `HTMLFIle` objects so its possible
to bulk index documents in elasticsearch ( `bulk_post_create` signal is dispatched for created
and `bulk_post_delete` is dispatched for deleted objects). Both of the signals are dispatched
with the list of the instances of `HTMLFile` in `instance_list` parameter.
@ -107,4 +107,4 @@ As per requirements of `django-elasticsearch-dsl`_, it is stored in the
.. _Elasticsearch document: https://www.elastic.co/guide/en/elasticsearch/guide/current/document.html
.. _django-elasticsearch-dsl: https://github.com/sabricot/django-elasticsearch-dsl
.. _elasticsearch-dsl: http://elasticsearch-dsl.readthedocs.io/en/latest/
.. _Signals: https://docs.djangoproject.com/en/2.1/topics/signals/
.. _signals: https://docs.djangoproject.com/en/2.1/topics/signals/

View File

@ -15,6 +15,8 @@ buildpyversions
from django.conf import settings
from docutils import nodes, utils
from readthedocs.projects.models import Feature
def django_setting_role(typ, rawtext, text, lineno, inliner, options=None,
content=None):
@ -39,6 +41,17 @@ def python_supported_versions_role(typ, rawtext, text, lineno, inliner,
return (node_list, [])
def feature_flags_role(typ, rawtext, text, lineno, inliner, options=None,
content=None):
"""Up to date feature flags from the application."""
all_features = Feature.FEATURES
requested_feature = utils.unescape(text)
for feature in all_features:
if requested_feature.lower() == feature[0].lower():
desc = nodes.Text(feature[1], feature[1])
return [desc], []
def setup(_):
from docutils.parsers.rst import roles
roles.register_local_role(
@ -47,7 +60,11 @@ def setup(_):
)
roles.register_local_role(
'buildpyversions',
python_supported_versions_role
python_supported_versions_role,
)
roles.register_local_role(
'featureflags',
feature_flags_role,
)
return {

View File

@ -64,6 +64,16 @@ environment, and will be set to ``True`` when building on RTD::
Woo
{% endif %}
My project requires different settings than those available under Admin
-----------------------------------------------------------------------
Read the Docs offers some settings which can be used for a variety of purposes,
such as to use the latest version of sphinx or pip. To enable these settings,
please open a request issue on our `github`_ and we will change the settings for the project.
Read more about these settings :doc:`here <guides/feature-flags>`.
.. _github: https://github.com/rtfd/readthedocs.org
I get import errors on libraries that depend on C modules
---------------------------------------------------------

View File

@ -0,0 +1,31 @@
Feature Flags
=============
Read the Docs offers some additional flag settings which can be only be configured by the site admin.
These are optional settings and you might not need it for every project.
By default, these flags are disabled for every project.
A seperate request can be made by opening an issue on our `github`_ to enable
or disable one or more of these featured flags for a particular project.
.. _github: https://github.com/rtfd/readthedocs.org
Available Flags
---------------
``USE_SPHINX_LATEST``: :featureflags:`USE_SPHINX_LATEST`
``USE_SETUPTOOLS_LATEST``: :featureflags:`USE_SETUPTOOLS_LATEST`
``ALLOW_DEPRECATED_WEBHOOKS``: :featureflags:`ALLOW_DEPRECATED_WEBHOOKS`
``PIP_ALWAYS_UPGRADE``: :featureflags:`PIP_ALWAYS_UPGRADE`
``SKIP_SUBMODULES``: :featureflags:`SKIP_SUBMODULES`
``DONT_OVERWRITE_SPHINX_CONTEXT``: :featureflags:`DONT_OVERWRITE_SPHINX_CONTEXT`
``ALLOW_V2_CONFIG_FILE``: :featureflags:`ALLOW_V2_CONFIG_FILE`
``MKDOCS_THEME_RTD``: :featureflags:`MKDOCS_THEME_RTD`
``DONT_SHALLOW_CLONE``: :featureflags:`DONT_SHALLOW_CLONE`

View File

@ -4,6 +4,7 @@
import copy
import os
import re
from contextlib import contextmanager
from django.conf import settings
@ -146,6 +147,8 @@ class BuildConfigBase:
'mkdocs',
'submodules',
]
default_build_image = DOCKER_DEFAULT_VERSION
version = None
def __init__(self, env_config, raw_config, source_file):
@ -246,6 +249,40 @@ class BuildConfigBase:
)
return ver
@property
def valid_build_images(self):
"""
Return all the valid Docker image choices for ``build.image`` option.
The user can use any of this values in the YAML file. These values are
the keys of ``DOCKER_IMAGE_SETTINGS`` Django setting (without the
``readthedocs/build`` part) plus ``stable`` and ``latest``.
"""
images = {'stable', 'latest'}
for k in DOCKER_IMAGE_SETTINGS:
_, version = k.split(':')
if re.fullmatch(r'^[\d\.]+$', version):
images.add(version)
return images
def get_valid_python_versions_for_image(self, build_image):
"""
Return all the valid Python versions for a Docker image.
The Docker image (``build_image``) has to be its complete name, already
validated: ``readthedocs/build:4.0``, not just ``4.0``.
Returns supported versions for the ``DOCKER_DEFAULT_VERSION`` if not
``build_image`` found.
"""
if build_image not in DOCKER_IMAGE_SETTINGS:
build_image = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
self.default_build_image,
)
return DOCKER_IMAGE_SETTINGS[build_image]['python']['supported_versions']
def as_dict(self):
config = {}
for name in self.PUBLIC_ATTRIBUTES:
@ -268,18 +305,23 @@ class BuildConfigV1(BuildConfigBase):
'"python.extra_requirements" section must be a list.'
)
PYTHON_SUPPORTED_VERSIONS = [2, 2.7, 3, 3.5]
DOCKER_SUPPORTED_VERSIONS = ['1.0', '2.0', 'latest']
version = '1'
def get_valid_python_versions(self):
"""Get all valid python versions."""
"""
Return all valid Python versions.
.. note::
It does not take current build image used into account.
"""
try:
return self.env_config['python']['supported_versions']
except (KeyError, TypeError):
pass
return self.PYTHON_SUPPORTED_VERSIONS
versions = set()
for _, options in DOCKER_IMAGE_SETTINGS.items():
versions = versions.union(options['python']['supported_versions'])
return versions
def get_valid_formats(self): # noqa
"""Get all valid documentation formats."""
@ -339,7 +381,7 @@ class BuildConfigV1(BuildConfigBase):
with self.catch_validation_error('build'):
build['image'] = validate_choice(
str(_build['image']),
self.DOCKER_SUPPORTED_VERSIONS,
self.valid_build_images,
)
if ':' not in build['image']:
# Prepend proper image name to user's image name
@ -577,8 +619,6 @@ class BuildConfigV2(BuildConfigBase):
version = '2'
valid_formats = ['htmlzip', 'pdf', 'epub']
valid_build_images = ['1.0', '2.0', '3.0', 'stable', 'latest']
default_build_image = 'latest'
valid_install_method = [PIP, SETUPTOOLS]
valid_sphinx_builders = {
'html': 'sphinx',
@ -793,13 +833,7 @@ class BuildConfigV2(BuildConfigBase):
This should be called after ``validate_build()``.
"""
build_image = self.build.image
if build_image not in DOCKER_IMAGE_SETTINGS:
build_image = '{}:{}'.format(
DOCKER_DEFAULT_IMAGE,
self.default_build_image,
)
python = DOCKER_IMAGE_SETTINGS[build_image]['python']
return python['supported_versions']
return self.get_valid_python_versions_for_image(build_image)
def validate_doc_types(self):
"""

View File

@ -363,8 +363,8 @@ class TestValidatePythonVersion:
)
build.validate()
assert build.python.version == 3
assert build.python_interpreter == 'python3.5'
assert build.python_full_version == 3.5
assert build.python_interpreter == 'python3.7'
assert build.python_full_version == 3.7
def test_it_validates_env_supported_versions(self):
build = get_build_config(
@ -483,7 +483,7 @@ class TestValidateBuild:
apply_fs(tmpdir, yaml_config_dir)
build = BuildConfigV1(
{},
{'build': {'image': 3.0}},
{'build': {'image': 3.2}},
source_file=str(tmpdir.join('readthedocs.yml')),
)
with raises(InvalidConfig) as excinfo:
@ -513,7 +513,7 @@ class TestValidateBuild:
{},
{
'build': {'image': 'latest'},
'python': {'version': '3.3'},
'python': {'version': '3.6'},
},
source_file=str(tmpdir.join('readthedocs.yml')),
)
@ -538,7 +538,7 @@ class TestValidateBuild:
source_file=str(tmpdir.join('readthedocs.yml')),
)
build.validate()
assert build.build.image == 'readthedocs/build:2.0'
assert build.build.image == 'readthedocs/build:latest'
@pytest.mark.parametrize(
'image', ['latest', 'readthedocs/build:3.0', 'rtd/build:latest'],
@ -712,7 +712,7 @@ def test_as_dict(tmpdir):
'use_system_site_packages': False,
},
'build': {
'image': 'readthedocs/build:2.0',
'image': 'readthedocs/build:latest',
},
'conda': None,
'sphinx': {

View File

@ -27,8 +27,15 @@ from sphinx import version_info
if globals().get('source_suffix', False):
if isinstance(source_suffix, string_types):
SUFFIX = source_suffix
else:
elif isinstance(source_suffix, (list, tuple)):
# Sphinx >= 1.3 supports list/tuple to define multiple suffixes
SUFFIX = source_suffix[0]
elif isinstance(source_suffix, dict):
# Sphinx >= 1.8 supports a mapping dictionary for mulitple suffixes
SUFFIX = source_suffix.keys()[0]
else:
# default to .rst
SUFFIX = '.rst'
else:
SUFFIX = '.rst'

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""OAuth utility functions."""
import logging
@ -17,6 +15,13 @@ from requests_oauthlib import OAuth2Session
log = logging.getLogger(__name__)
class SyncServiceError(Exception):
"""Error raised when a service failed to sync."""
pass
class Service:
"""
@ -147,7 +152,7 @@ class Service:
# Bad credentials: the token we have in our database is not
# valid. Probably the user has revoked the access to our App. He
# needs to reconnect his account
raise Exception(
raise SyncServiceError(
'Our access to your {provider} account was revoked. '
'Please, reconnect it from your social account connections.'.format(
provider=self.provider_name,

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""OAuth utility functions."""
import json
@ -17,7 +15,7 @@ from readthedocs.builds import utils as build_utils
from readthedocs.integrations.models import Integration
from ..models import RemoteOrganization, RemoteRepository
from .base import Service
from .base import Service, SyncServiceError
log = logging.getLogger(__name__)
@ -47,10 +45,10 @@ class BitbucketService(Service):
for repo in repos:
self.create_repository(repo)
except (TypeError, ValueError):
log.exception('Error syncing Bitbucket repositories')
raise Exception(
log.warning('Error syncing Bitbucket repositories')
raise SyncServiceError(
'Could not sync your Bitbucket repositories, '
'try reconnecting your account',
'try reconnecting your account'
)
# Because privileges aren't returned with repository data, run query
@ -85,8 +83,8 @@ class BitbucketService(Service):
for repo in repos:
self.create_repository(repo, organization=org)
except ValueError:
log.exception('Error syncing Bitbucket organizations')
raise Exception(
log.warning('Error syncing Bitbucket organizations')
raise SyncServiceError(
'Could not sync your Bitbucket team repositories, '
'try reconnecting your account',
)

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""OAuth utility functions."""
import json
@ -17,7 +15,8 @@ from readthedocs.integrations.models import Integration
from readthedocs.restapi.client import api
from ..models import RemoteOrganization, RemoteRepository
from .base import Service
from .base import Service, SyncServiceError
log = logging.getLogger(__name__)
@ -43,10 +42,10 @@ class GitHubService(Service):
for repo in repos:
self.create_repository(repo)
except (TypeError, ValueError):
log.exception('Error syncing GitHub repositories')
raise Exception(
log.warning('Error syncing GitHub repositories')
raise SyncServiceError(
'Could not sync your GitHub repositories, '
'try reconnecting your account',
'try reconnecting your account'
)
def sync_organizations(self):
@ -64,10 +63,10 @@ class GitHubService(Service):
for repo in org_repos:
self.create_repository(repo, organization=org_obj)
except (TypeError, ValueError):
log.exception('Error syncing GitHub organizations')
raise Exception(
log.warning('Error syncing GitHub organizations')
raise SyncServiceError(
'Could not sync your GitHub organizations, '
'try reconnecting your account',
'try reconnecting your account'
)
def create_repository(self, fields, privacy=None, organization=None):

View File

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
"""OAuth utility functions."""
import json
@ -16,7 +14,8 @@ from readthedocs.integrations.models import Integration
from readthedocs.projects.models import Project
from ..models import RemoteOrganization, RemoteRepository
from .base import Service
from .base import Service, SyncServiceError
try:
@ -92,10 +91,10 @@ class GitLabService(Service):
for repo in repos:
self.create_repository(repo)
except (TypeError, ValueError):
log.exception('Error syncing GitLab repositories')
raise Exception(
'Could not sync your GitLab repositories, try reconnecting '
'your account',
log.warning('Error syncing GitLab repositories')
raise SyncServiceError(
'Could not sync your GitLab repositories, '
'try reconnecting your account'
)
def sync_organizations(self):
@ -123,10 +122,10 @@ class GitLabService(Service):
for repo in org_repos:
self.create_repository(repo, organization=org_obj)
except (TypeError, ValueError):
log.exception('Error syncing GitLab organizations')
raise Exception(
'Could not sync your GitLab organization, try reconnecting '
'your account',
log.warning('Error syncing GitLab organizations')
raise SyncServiceError(
'Could not sync your GitLab organization, '
'try reconnecting your account'
)
def is_owned_by(self, owner_id):

View File

@ -1,17 +1,17 @@
# -*- coding: utf-8 -*-
"""Tasks for OAuth services."""
import logging
from allauth.socialaccount.providers import registry as allauth_registry
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _
from readthedocs.core.utils.tasks import PublicTask, user_id_matches
from readthedocs.oauth.notifications import (
AttachWebhookNotification,
InvalidProjectWebhookNotification,
)
from readthedocs.oauth.services.base import SyncServiceError
from readthedocs.projects.models import Project
from readthedocs.worker import app
@ -25,9 +25,21 @@ log = logging.getLogger(__name__)
@app.task(queue='web', base=PublicTask)
def sync_remote_repositories(user_id):
user = User.objects.get(pk=user_id)
failed_services = set()
for service_cls in registry:
for service in service_cls.for_user(user):
service.sync()
try:
service.sync()
except SyncServiceError:
failed_services.add(service.provider_name)
if failed_services:
msg = _(
'Our access to your following accounts was revoked: {providers}. '
'Please, reconnect them from your social account connections.'
)
raise Exception(
msg.format(providers=', '.join(failed_services))
)
@app.task(queue='web')

View File

@ -105,7 +105,6 @@ class ProjectViewSet(UserSelectViewSet):
admin_serializer_class = ProjectAdminSerializer
model = Project
pagination_class = api_utils.ProjectPagination
filter_fields = ('slug',) # django-filter<2.0.0
filterset_fields = ('slug',)
@decorators.action(detail=True)
@ -250,10 +249,6 @@ class VersionViewSet(UserSelectViewSet):
serializer_class = VersionSerializer
admin_serializer_class = VersionAdminSerializer
model = Version
filter_fields = (
'active',
'project__slug',
) # django-filter<2.0.0
filterset_fields = (
'active',
'project__slug',
@ -266,7 +261,6 @@ class BuildViewSetBase(UserSelectViewSet):
serializer_class = BuildSerializer
admin_serializer_class = BuildAdminSerializer
model = Build
filter_fields = ('project__slug', 'commit') # django-filter<2.0.0
filterset_fields = ('project__slug', 'commit')

View File

@ -145,7 +145,7 @@ class LoadConfigTests(TestCase):
config = load_yaml_config(self.version)
self.assertEqual(
config.get_valid_python_versions(),
[2, 2.7, 3, 3.3, 3.4, 3.5, 3.6],
[2, 2.7, 3, 3.5, 3.6, 3.7],
)
@mock.patch('readthedocs.doc_builder.config.load_config')
@ -507,7 +507,7 @@ class TestLoadConfigV2:
config = self.get_update_docs_task().config
assert config.python.version == 3
assert config.python_full_version == 3.6
assert config.python_full_version == 3.7
@patch('readthedocs.doc_builder.environments.BuildEnvironment.run')
def test_python_install_requirements(self, run, checkout_path, tmpdir):

View File

@ -0,0 +1,75 @@
from allauth.socialaccount.models import SocialAccount
from allauth.socialaccount.providers.bitbucket_oauth2.views import (
BitbucketOAuth2Adapter,
)
from allauth.socialaccount.providers.github.views import GitHubOAuth2Adapter
from allauth.socialaccount.providers.gitlab.views import GitLabOAuth2Adapter
from django.contrib.auth.models import User
from django.test import TestCase
from django_dynamic_fixture import get
from mock import patch
from readthedocs.builds.models import Version
from readthedocs.oauth.services.base import SyncServiceError
from readthedocs.oauth.tasks import sync_remote_repositories
from readthedocs.projects.models import Project
class SyncRemoteRepositoriesTests(TestCase):
def setUp(self):
self.user = get(User)
self.project = get(Project, users=[self.user])
self.version = get(Version, project=self.project)
self.socialaccount_gh = get(
SocialAccount,
user=self.user,
provider=GitHubOAuth2Adapter.provider_id,
)
self.socialaccount_gl = get(
SocialAccount,
user=self.user,
provider=GitLabOAuth2Adapter.provider_id,
)
self.socialaccount_bb = get(
SocialAccount,
user=self.user,
provider=BitbucketOAuth2Adapter.provider_id,
)
@patch('readthedocs.oauth.services.github.GitHubService.sync')
@patch('readthedocs.oauth.services.gitlab.GitLabService.sync')
@patch('readthedocs.oauth.services.bitbucket.BitbucketService.sync')
def test_sync_repository(self, sync_bb, sync_gl, sync_gh):
r = sync_remote_repositories(self.user.pk)
self.assertNotIn('error', r)
sync_bb.assert_called_once()
sync_gl.assert_called_once()
sync_gh.assert_called_once()
@patch('readthedocs.oauth.services.github.GitHubService.sync')
@patch('readthedocs.oauth.services.gitlab.GitLabService.sync')
@patch('readthedocs.oauth.services.bitbucket.BitbucketService.sync')
def test_sync_repository_failsync(self, sync_bb, sync_gl, sync_gh):
sync_gh.side_effect = SyncServiceError
r = sync_remote_repositories(self.user.pk)
self.assertIn('GitHub', r['error'])
self.assertNotIn('GitLab', r['error'])
self.assertNotIn('Bitbucket', r['error'])
sync_bb.assert_called_once()
sync_gl.assert_called_once()
sync_gh.assert_called_once()
@patch('readthedocs.oauth.services.github.GitHubService.sync')
@patch('readthedocs.oauth.services.gitlab.GitLabService.sync')
@patch('readthedocs.oauth.services.bitbucket.BitbucketService.sync')
def test_sync_repository_failsync_more_than_one(self, sync_bb, sync_gl, sync_gh):
sync_gh.side_effect = SyncServiceError
sync_bb.side_effect = SyncServiceError
r = sync_remote_repositories(self.user.pk)
self.assertIn('GitHub', r['error'])
self.assertIn('Bitbucket', r['error'])
self.assertNotIn('GitLab', r['error'])
sync_bb.assert_called_once()
sync_gl.assert_called_once()
sync_gh.assert_called_once()

View File

@ -274,7 +274,7 @@ class CommunityBaseSettings(Settings):
# Docker
DOCKER_ENABLE = False
DOCKER_DEFAULT_IMAGE = 'readthedocs/build'
DOCKER_DEFAULT_VERSION = '2.0'
DOCKER_DEFAULT_VERSION = 'latest'
DOCKER_IMAGE = '{}:{}'.format(DOCKER_DEFAULT_IMAGE, DOCKER_DEFAULT_VERSION)
DOCKER_IMAGE_SETTINGS = {
'readthedocs/build:1.0': {
@ -286,14 +286,17 @@ class CommunityBaseSettings(Settings):
'readthedocs/build:3.0': {
'python': {'supported_versions': [2, 2.7, 3, 3.3, 3.4, 3.5, 3.6]},
},
'readthedocs/build:stable': {
'python': {'supported_versions': [2, 2.7, 3, 3.3, 3.4, 3.5, 3.6]},
},
'readthedocs/build:latest': {
'python': {'supported_versions': [2, 2.7, 3, 3.3, 3.4, 3.5, 3.6]},
'readthedocs/build:4.0': {
'python': {'supported_versions': [2, 2.7, 3, 3.5, 3.6, 3.7]},
},
}
# Alias tagged via ``docker tag`` on the build servers
DOCKER_IMAGE_SETTINGS.update({
'readthedocs/build:stable': DOCKER_IMAGE_SETTINGS.get('readthedocs/build:3.0'),
'readthedocs/build:latest': DOCKER_IMAGE_SETTINGS.get('readthedocs/build:4.0'),
})
# All auth
ACCOUNT_ADAPTER = 'readthedocs.core.adapters.AccountAdapter'
ACCOUNT_EMAIL_REQUIRED = True

View File

@ -1,6 +1,6 @@
-r pip.txt
# http://initd.org/psycopg/docs/install.html#binary-install-from-pypi
psycopg2==2.7.6.1 --no-binary psycopg2
psycopg2==2.7.7 --no-binary psycopg2
gunicorn==19.9.0
django-redis-cache==1.8.1

View File

@ -1,15 +1,9 @@
-r pip.txt
# We need these special cases of Python < 3 because we run tests with
# Python 2 still
# prospector 1.1.6.2 is not compatible with 2.1.0
astroid==2.0.4; python_version > '3'
astroid<1.7; python_version < '3'
astroid<=2.0.4
# prospector 1.1.6.2 is not compatible with 2.2.2
pylint==2.1.1; python_version > '3'
pylint<2; python_version < '3'
# prospector 1.1.6.2 is not compatible with 2.0.5
pylint-django==2.0.2; python_version > '3'
pylint-django<0.12; python_version < '3'
pylint<=2.1.1
pylint-django<2.0.5
pylint-celery==0.3
prospector==1.1.6.2
# prospector 1.1.6.2 is not compatible with 2.0.0

View File

@ -1,7 +1,7 @@
# Base packages
pip==18.1
pip==19.0.1
appdirs==1.4.3
virtualenv==16.2.0
virtualenv==16.3.0
django==1.11.18
django-tastypie==0.14.2
@ -11,13 +11,7 @@ django-extensions==2.1.4
djangorestframework==3.9.1
# Filtering for the REST API
# When Python2 gets deprecated we can upgrade django-filter
# > from .filterset import FilterSet
# E File "/home/travis/build/rtfd/readthedocs.org/.tox/py27/lib/python2.7/site-packages/django_filters/filterset.py", line 184
# E def __init__(self, data=None, queryset=None, *, request=None, prefix=None):
# E ^
# E SyntaxError: invalid syntax
django-filter<2.0.0
django-filter==2.1.0
django-vanilla-views==1.0.6
jsonfield==2.0.2
@ -57,8 +51,14 @@ GitPython==2.1.10
# Search
elasticsearch==6.2.0
# elasticsearch-dsl==6.3.1 produces this error
# File "/home/travis/build/rtfd/readthedocs.org/.tox/py36/lib/python3.6/site-packages/django_elasticsearch_dsl/documents.py", line 8, in <module>
# from elasticsearch_dsl.document import DocTypeMeta as DSLDocTypeMeta
# ImportError: cannot import name 'DocTypeMeta'
elasticsearch-dsl==6.1.0
django-elasticsearch-dsl==0.5.0
django-elasticsearch-dsl==0.5.1
pyquery==1.4.0
# Utils
@ -68,7 +68,7 @@ beautifulsoup4==4.7.1
Unipath==1.1
django-kombu==0.9.4
mock==2.0.0
stripe==2.18.0
stripe==2.19.0
django-formtools==2.1