Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add manager and description field to AutomationRule model #5995

Merged
merged 9 commits into from Aug 26, 2019
@@ -1,11 +1,10 @@
# -*- coding: utf-8 -*-

"""Build and Version class model Managers."""

import logging

from django.db import models
from django.core.exceptions import ObjectDoesNotExist
from django.db import models
from polymorphic.managers import PolymorphicManager

from readthedocs.core.utils.extend import (
SettingsOverrideObject,
@@ -14,14 +13,15 @@

from .constants import (
BRANCH,
EXTERNAL,
LATEST,
LATEST_VERBOSE_NAME,
STABLE,
STABLE_VERBOSE_NAME,
TAG,
EXTERNAL,
)
from .querysets import VersionQuerySet, BuildQuerySet
from .querysets import BuildQuerySet, VersionQuerySet


log = logging.getLogger(__name__)

@@ -179,3 +179,37 @@ class InternalBuildManager(SettingsOverrideObject):

class ExternalBuildManager(SettingsOverrideObject):
_default_class = ExternalBuildManagerBase


class VersionAutomationRuleManager(PolymorphicManager):
This conversation was marked as resolved by stsewd

This comment has been minimized.

Copy link
@ericholscher

ericholscher Aug 26, 2019

Member

This needs a docstring -- why is it using PolymorphicManager? That seems like a pretty huge thing that we should explain here.

This comment has been minimized.

Copy link
@stsewd

stsewd Aug 26, 2019

Author Member

Done


def append_rule(
This conversation was marked as resolved by stsewd

This comment has been minimized.

Copy link
@humitos

humitos Aug 14, 2019

Member

For consistency: #5998 (comment)

self, *, project, description, match_arg, version_type,
action, action_arg=None,
):
"""
Append an automation rule to `project`.
The rule is created with a priority higher than the last rule
in `project`.
"""
last_priority = (
project.automation_rules
.values_list('priority', flat=True)
.last()
)
This conversation was marked as resolved by stsewd

This comment has been minimized.

Copy link
@ericholscher

ericholscher Jul 31, 2019

Member

This should probably have an explicit order_by, no?

if last_priority is None:
priority = 0
else:
priority = last_priority + 1

rule = self.create(
project=project,
priority=priority,
description=description,
match_arg=match_arg,
version_type=version_type,
action=action,
action_arg=action_arg,
)
return rule
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.22 on 2019-07-25 17:24
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('builds', '0009_added_external_version_type'),
]

operations = [
migrations.AddField(
model_name='versionautomationrule',
name='description',
field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Description'),
),
]
@@ -17,47 +17,30 @@
from polymorphic.models import PolymorphicModel

import readthedocs.builds.automation_actions as actions
from readthedocs.config import LATEST_CONFIGURATION_VERSION
from readthedocs.core.utils import broadcast
from readthedocs.projects.constants import (
BITBUCKET_COMMIT_URL,
BITBUCKET_URL,
GITHUB_COMMIT_URL,
GITHUB_URL,
GITHUB_PULL_REQUEST_URL,
GITHUB_PULL_REQUEST_COMMIT_URL,
GITLAB_COMMIT_URL,
GITLAB_URL,
PRIVACY_CHOICES,
PRIVATE,
MEDIA_TYPES,
)
from readthedocs.projects.models import APIProject, Project
from readthedocs.projects.version_handling import determine_stable_version

from readthedocs.builds.constants import (
BRANCH,
BUILD_STATE,
BUILD_STATE_FINISHED,
BUILD_STATE_TRIGGERED,
BUILD_TYPES,
EXTERNAL,
GENERIC_EXTERNAL_VERSION_NAME,
GITHUB_EXTERNAL_VERSION_NAME,
INTERNAL,
LATEST,
NON_REPOSITORY_VERSIONS,
EXTERNAL,
STABLE,
TAG,
VERSION_TYPES,
)
from readthedocs.builds.managers import (
VersionManager,
InternalVersionManager,
ExternalVersionManager,
BuildManager,
InternalBuildManager,
ExternalBuildManager,
ExternalVersionManager,
InternalBuildManager,
InternalVersionManager,
VersionAutomationRuleManager,
VersionManager,
)
from readthedocs.builds.querysets import (
BuildQuerySet,
@@ -70,7 +53,24 @@
get_gitlab_username_repo,
)
from readthedocs.builds.version_slug import VersionSlugField
from readthedocs.config import LATEST_CONFIGURATION_VERSION
from readthedocs.core.utils import broadcast
from readthedocs.oauth.models import RemoteRepository
from readthedocs.projects.constants import (
BITBUCKET_COMMIT_URL,
BITBUCKET_URL,
GITHUB_COMMIT_URL,
GITHUB_PULL_REQUEST_COMMIT_URL,
GITHUB_PULL_REQUEST_URL,
GITHUB_URL,
GITLAB_COMMIT_URL,
GITLAB_URL,
MEDIA_TYPES,
PRIVACY_CHOICES,
PRIVATE,
)
from readthedocs.projects.models import APIProject, Project
from readthedocs.projects.version_handling import determine_stable_version


log = logging.getLogger(__name__)
@@ -928,6 +928,12 @@ class VersionAutomationRule(PolymorphicModel, TimeStampedModel):
_('Rule priority'),
help_text=_('A lower number (0) means a higher priority'),
)
description = models.CharField(
_('Description'),
max_length=255,
null=True,
blank=True,
)
match_arg = models.CharField(
_('Match argument'),
help_text=_('Value used for the rule to match the version'),
@@ -951,6 +957,8 @@ class VersionAutomationRule(PolymorphicModel, TimeStampedModel):
choices=VERSION_TYPES,
)

objects = VersionAutomationRuleManager()

class Meta:
unique_together = (('project', 'priority'),)
ordering = ('priority', '-modified', '-created')
@@ -994,6 +1002,15 @@ def apply_action(self, version, match_result):
raise NotImplementedError
action(version, match_result, self.action_arg)

def get_description(self):
if self.description:
return self.description
return f'{self.get_action_display()}'

@property
def edit_url(self):
raise NotImplementedError
This conversation was marked as resolved by stsewd

This comment has been minimized.

Copy link
@ericholscher

ericholscher Jul 31, 2019

Member

Why do we have this?

This comment has been minimized.

Copy link
@stsewd

stsewd Jul 31, 2019

Author Member

oops, that was part of another PR, not here


def __str__(self):
class_name = self.__class__.__name__
return (
@@ -125,3 +125,61 @@ def test_action_set_default_version(self):
assert self.project.get_default_version() == LATEST
assert rule.run(version) is True
assert self.project.get_default_version() == version.slug


@pytest.mark.django_db
class TestAutomationRuleManager:

@pytest.fixture(autouse=True)
def setup_method(self):
self.project = get(Project)

def test_append_rule_regex(self):
assert not self.project.automation_rules.all()

rule = RegexAutomationRule.objects.append_rule(
project=self.project,
description='First rule',
match_arg='.*',
version_type=TAG,
action=VersionAutomationRule.ACTIVATE_VERSION_ACTION,
)

# First rule gets added with priority 0
assert self.project.automation_rules.count() == 1
assert rule.priority == 0

# Adding a second rule
rule = RegexAutomationRule.objects.append_rule(
project=self.project,
description='Second rule',
match_arg='.*',
version_type=BRANCH,
action=VersionAutomationRule.ACTIVATE_VERSION_ACTION,
)
assert self.project.automation_rules.count() == 2
assert rule.priority == 1

# Adding a rule with a not secuencial priority
rule = get(
RegexAutomationRule,
description='Third rule',
project=self.project,
priority=9,
match_arg='.*',
version_type=TAG,
action=VersionAutomationRule.ACTIVATE_VERSION_ACTION,
)
assert self.project.automation_rules.count() == 3
assert rule.priority == 9

# Adding a new rule
rule = RegexAutomationRule.objects.append_rule(
project=self.project,
description='Fourth rule',
match_arg='.*',
version_type=BRANCH,
action=VersionAutomationRule.ACTIVATE_VERSION_ACTION,
)
assert self.project.automation_rules.count() == 4
assert rule.priority == 10
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.