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 autopush boolean to an update. #3090

Merged
merged 1 commit into from Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions bodhi/client/__init__.py
Expand Up @@ -117,6 +117,9 @@ def _set_logging_debug(ctx, param, value):
click.option('--close-bugs', is_flag=True, help='Automatically close bugs'),
click.option('--request', help='Requested repository',
type=click.Choice(['testing', 'stable', 'unpush'])),
click.option('--autotime', is_flag=True, help='Enable stable push base on time in testing'),
click.option('--stable-days', type=click.INT,
help='Days in testing required to push to stable'),
click.option('--autokarma', is_flag=True, help='Enable karma automatism'),
click.option('--stable-karma', type=click.INT, help='Stable karma threshold'),
click.option('--unstable-karma', type=click.INT, help='Unstable karma threshold'),
Expand Down
5 changes: 5 additions & 0 deletions bodhi/client/bindings.py
Expand Up @@ -245,6 +245,11 @@ def save(self, **kwargs) -> 'munch.Munch':
close_bugs (bool): Close bugs when update is stable.
suggest (str): Suggest that the user reboot or logout after update.
(``reboot``, ``logout``).
autotime (bool): Allow bodhi to automatically change the state of this
update based on the time spent in testing by this update. It
will push your update to ``stable`` once it reaches the ``stable_days``.
stable_days (int): The minimun amount of time an update has to spend in
``testing`` before being automatically pushed to ``stable``.
autokarma (bool): Allow bodhi to automatically change the state of this
update based on the ``karma`` from user feedback. It will
push your update to ``stable`` once it reaches the ``stable_karma``
Expand Down
8 changes: 1 addition & 7 deletions bodhi/server/config.py
Expand Up @@ -514,14 +514,8 @@ class BodhiConfig(dict):
'test_case_base_url': {
'value': 'https://fedoraproject.org/wiki/',
'validator': str},
'testing_approval_msg_based_on_karma': {
'value': ('This update has reached the stable karma threshold and can be pushed to '
'stable now if the maintainer wishes.'),
'validator': str
},
'testing_approval_msg': {
'value': ('This update has reached %d days in testing and can be pushed to stable now '
'if the maintainer wishes'),
'value': ('This update can be pushed to stable now if the maintainer wishes'),
'validator': str},
'testing_bug_epel_msg': {
'value': (
Expand Down
@@ -0,0 +1,50 @@
# Copyright (c) 2019 Red Hat, Inc.
#
# This file is part of Bodhi.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
"""
Add autotime boolean and stable_days to Update.

Revision ID: b1fd856efcf6
Revises: 5703ddfe855d
Create Date: 2019-03-22 09:51:53.941289
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b1fd856efcf6'
down_revision = '5703ddfe855d'


def upgrade():
"""Add the autotime boolean and stable_days integer to the updates table."""
# autotime
op.add_column('updates', sa.Column('autotime', sa.Boolean()))
op.execute('UPDATE updates SET autotime=FALSE')
op.alter_column('updates', 'autotime', existing_type=sa.Boolean(), nullable=False)

# stable_days
op.add_column('updates', sa.Column('stable_days', sa.Integer()))
op.execute('UPDATE updates SET stable_days=0')
op.alter_column('updates', 'stable_days', existing_type=sa.Integer(), nullable=False)


def downgrade():
"""Drop the autotime boolean and the stable_days integer from the updates table."""
op.drop_column('updates', 'autotime')
op.drop_column('updates', 'stable_days')
33 changes: 29 additions & 4 deletions bodhi/server/models.py
Expand Up @@ -1555,8 +1555,12 @@ class Update(Base):
Attributes:
autokarma (bool): A boolean that indicates whether or not the update will
be automatically pushed when the stable_karma threshold is reached.
autotime (bool): A boolean that indicates whether or not the update will
be automatically pushed when the time threshold is reached.
stable_karma (int): A positive integer that indicates the amount of "good"
karma the update must receive before being automatically marked as stable.
stable_days (int): A positive integer that indicates the number of days an update
needs to spend in testing before being automatically marked as stable.
unstable_karma (int): A positive integer that indicates the amount of "bad"
karma the update must receive before being automatically marked as unstable.
requirements (str): A list of taskotron tests that must pass for this
Expand Down Expand Up @@ -1625,7 +1629,9 @@ class Update(Base):
__get_by__ = ('alias',)

autokarma = Column(Boolean, default=True, nullable=False)
autotime = Column(Boolean, default=True, nullable=False)
stable_karma = Column(Integer, nullable=False)
stable_days = Column(Integer, nullable=False, default=0)
unstable_karma = Column(Integer, nullable=False)
requirements = Column(UnicodeText)
require_bugs = Column(Boolean, default=False)
Expand Down Expand Up @@ -2034,6 +2040,16 @@ def new(cls, request, data):
release = data.pop('release', None)
up = Update(**data, release=release)

# We want to make sure that the value of stable_days
# will not be lower than the mandatory_days_in_testing.
if up.mandatory_days_in_testing > up.stable_days:
up.stable_days = up.mandatory_days_in_testing
caveats.append({
'name': 'stable days',
'description': "The number of stable days required was set to the mandatory "
cverna marked this conversation as resolved.
Show resolved Hide resolved
f"release value of {up.mandatory_days_in_testing} days"
})

log.debug("Setting request for new update.")
up.set_request(db, req, request.user.name)

Expand Down Expand Up @@ -2073,6 +2089,16 @@ def edit(cls, request, data):
caveats = []
edited_builds = [build.nvr for build in up.builds]

# stable_days can be set by the user. We want to make sure that the value
# will not be lower than the mandatory_days_in_testing.
if up.mandatory_days_in_testing > data.get('stable_days', up.stable_days):
data['stable_days'] = up.mandatory_days_in_testing
caveats.append({
'name': 'stable days',
'description': "The number of stable days required was raised to the mandatory "
f"release value of {up.mandatory_days_in_testing} days"
})

# Determine which builds have been added
new_builds = []
for build in data['builds']:
Expand Down Expand Up @@ -3261,7 +3287,7 @@ def check_karma_thresholds(self, db, agent):
notifications.publish(update_schemas.UpdateKarmaThresholdV1.from_dict(
dict(update=self, status='stable')))
else:
# Add the 'testing_approval_msg_based_on_karma' message now
# Add the stable approval message now
log.info((
"%s update has reached the stable karma threshold and can be pushed to "
"stable now if the maintainer wishes"), self.alias)
Expand Down Expand Up @@ -3391,9 +3417,8 @@ def has_stable_comment(self):
"""
for comment in self.comments_since_karma_reset:
if comment.user.name == 'bodhi' and \
comment.text.startswith('This update has reached') and \
'and can be pushed to stable now if the ' \
'maintainer wishes' in comment.text:
comment.text.startswith('This update ') and \
'can be pushed to stable now if the maintainer wishes' in comment.text:
return True
return False

Expand Down
9 changes: 9 additions & 0 deletions bodhi/server/schemas.py
Expand Up @@ -235,6 +235,15 @@ class SaveUpdateSchema(CSRFProtectedSchema, colander.MappingSchema):
colander.Boolean(),
missing=True,
)
autotime = colander.SchemaNode(
colander.Boolean(),
missing=True,
)
stable_days = colander.SchemaNode(
colander.Integer(),
validator=colander.Range(min=0),
missing=0,
)


class Cosmetics(colander.MappingSchema):
Expand Down
29 changes: 12 additions & 17 deletions bodhi/server/scripts/approve_testing.py
Expand Up @@ -30,7 +30,7 @@

from bodhi.messages.schemas import update as update_schemas
from bodhi.server import Session, initialize_db, notifications
from ..models import Update, UpdateStatus
from ..models import Update, UpdateStatus, UpdateRequest
from ..config import config


Expand Down Expand Up @@ -77,37 +77,32 @@ def main(argv=sys.argv):
testing = db.query(Update).filter_by(status=UpdateStatus.testing,
request=None)
for update in testing:
# If this release does not have any testing requirements, skip it
if not update.release.mandatory_days_in_testing:
print('%s doesn\'t have mandatory days in testing' % update.release.name)
if not update.release.mandatory_days_in_testing and not update.autotime:
# If this release does not have any testing requirements and is not autotime,
# skip it
print(f"{update.release.name} doesn't have mandatory days in testing")
continue

# If this update was already commented, skip it
if update.has_stable_comment:
continue

# Approval message when testing based on karma threshold
if update.karma >= update.stable_karma \
and not update.autokarma and update.meets_testing_requirements:
print(f'{update.alias} now reaches stable karma threshold')
text = config.get('testing_approval_msg_based_on_karma')
update.comment(db, text, author='bodhi')
db.commit()
continue

# If autokarma updates have reached the testing threshold, say something! Keep in mind
# If updates have reached the testing threshold, say something! Keep in mind
# that we don't care about karma here, because autokarma updates get their request set
# to stable by the Update.comment() workflow when they hit the required threshold. Thus,
# this function only needs to consider the time requirements because these updates have
# not reached the karma threshold.
if update.meets_testing_requirements:
print(f'{update.alias} now meets testing requirements')
text = str(
config.get('testing_approval_msg') % update.mandatory_days_in_testing)
update.comment(db, text, author='bodhi')
update.comment(db, str(config.get('testing_approval_msg')), author='bodhi')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for curiosity: Do we really need this type cast here? testing_approval_msg setting already has: 'validator': str


notifications.publish(update_schemas.UpdateRequirementsMetStableV1.from_dict(
dict(update=update)))

if update.autotime and update.days_in_testing >= update.stable_days:
print(f"Automatically marking {update.alias} as stable")
update.set_request(db=db, action=UpdateRequest.stable, username="bodhi")
cverna marked this conversation as resolved.
Show resolved Hide resolved

db.commit()

except Exception as e:
Expand Down
39 changes: 29 additions & 10 deletions bodhi/server/templates/new_update.html
Expand Up @@ -234,20 +234,29 @@ <h2 class="pull-left">Edit
checked
% endif
></dd>
<dt data-toggle="tooltip" title="If checked, this option allows bodhi to automatically move your update from testing to stable once enough positive karma has been given.">
Auto-request stable based on karma ?</dt>
<dd> <input type="checkbox" name="autokarma" data-singleton="true"
% if update and update.autokarma:
checked
% elif not update:
checked
% endif>
</dd>
<dt data-toggle="tooltip" title="If checked, this option allows bodhi to automatically move your update from testing to stable once enough time was spent in testing.">
Auto-request stable based on time ?</dt>
<dd> <input type="checkbox" name="autotime" data-singleton="true"
% if update and update.autotime:
checked
% elif not update:
checked
% endif>
</dd>
</dl>
</div>

<div class="col-md-5">
<dl id='radios'>
<dt data-toggle="tooltip" title="If checked, this option allows bodhi to automatically move your update from testing to stable once enough positive karma has been given.">
Auto-request stable?</dt>
<dd> <input type="checkbox" name="autokarma" data-singleton="true"
% if update and update.autokarma:
checked
% elif not update:
checked
% endif
></dd>
<dl>
<dt data-toggle="tooltip" title="This is the threshold of positive karma required to automatically push an update from testing to stable.">
Stable karma</dt>
<dd> <input type="number" name="stable_karma" min="1" required
Expand All @@ -268,6 +277,16 @@ <h2 class="pull-left">Edit
% endif
></dd>

<dt data-toggle="tooltip" title="This is the number of days an update needs to spend in testing to be automatically pushed to stable.">
Stable days</dt>
<dd> <input type="number" name="stable_days" min="1"
% if update:
value="${update.stable_days}"
% elif not update:
value=""
% endif
></dd>

<dt data-toggle="tooltip" title="If checked, this will require that positive feedback be given on all associated bugs before the update can pass to stable. If your update has no associated bugs, this option has no effect.">
Require bugs
</dt>
Expand Down
29 changes: 26 additions & 3 deletions bodhi/server/templates/update.html
Expand Up @@ -927,7 +927,7 @@ <h4>Add Comment &amp; Feedback</h4>

<div class="p-b-1">
<div>
<strong>Autopush</strong>
<strong>Autopush (karma)</strong>
</div>
<div>
% if update.autokarma is True:
Expand All @@ -939,8 +939,31 @@ <h4>Add Comment &amp; Feedback</h4>
</td>
% elif update.autokarma is False:
<td>
<span class='text-muted' data-toggle='tooltip' title='The update will never be automatically pushed
to stable.'>
<span class='text-muted' data-toggle='tooltip' title='The update will not be automatically pushed
to stable based on karma.'>
<span class='label label-danger'>Disabled</span>
</span>
</td>
% endif
</div>
</div>

<div class="p-b-1">
<div>
<strong>Autopush (time)</strong>
</div>
<div>
% if update.autotime is True:
<td>
<span class='text-muted' data-toggle='tooltip' title='The update will be automatically pushed
to stable once the required time in testing is reached.'>
<span class='label label-success'>Enabled</span>
</span>
</td>
% elif update.autotime is False:
<td>
<span class='text-muted' data-toggle='tooltip' title='The update will not be automatically pushed
to stable base on time in testing.'>
<span class='label label-danger'>Disabled</span>
</span>
</td>
Expand Down