internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: fedora-infra/bodhi

Issue:
Blank dark-gray banner at the top of screen in chrome
![](http://threebean.org/img/bodhi-banner.png)

It only shows up for me in chrome, but not firefox.

/cc @ryanlerch


Discussion:
I think this is just due to browser caching of some of the old UI files - try CTRL-F5 to force a cacheless reload. Please reopen if that doesn't fix it!
@puiterwijk suggested adding a ```GET``` parameter that would be unique per static file to the static file URLs so that new Bodhi deployments would cause browser caches not to be used.

We could just add a ```?bodhi_version={bodhi_version}``` onto the static URLs so that when we deploy new Bodhi versions the users will not used cached versions of all the static files. This would mean that we would get a bit more load on the server after each release, but that's probably OK because it would automatically solve this problem for future changes too.
I had a look at #1464 and to @bowlofeggs comment about modify `request.static_url()`.
From Pyramid docs it seems the recommended way would be adding a new method to `request` with the `add_request()` method and then use the new method in the template in place of `${request.static_url()}`.
That means modify all the template files to use the new method.

I would instead propose to modify https://github.com/fedora-infra/bodhi/blob/ed53abdda445216708f80ede6c6ea9d8c4bb1d47/bodhi/server/__init__.py#L257
to something like
`config.add_static_view(f'static/{bodhi.util.version()}', 'bodhi:server/static')`
so that with a single change we get all static files served under a versioned directory like `static/4.0.2/`, thus solving the browser cache problem after a bodhi upgrade.

It seems acceptable to you?
On Mon, 2019-06-17 at 11:32 -0700, Mattia Verga wrote:
> It seems acceptable to you?

Putting the Bodhi version into the static URL does seem like a good way
to solve that problem. @puiterwijk has suggested that before as well.


Resolving patch:
diff --git a/bodhi/server/__init__.py b/bodhi/server/__init__.py
--- a/bodhi/server/__init__.py
+++ b/bodhi/server/__init__.py
@@ -28,6 +28,7 @@
 from pyramid.renderers import JSONP
 from sqlalchemy import engine_from_config, event
 from sqlalchemy.orm import scoped_session, sessionmaker
+import pkg_resources
 
 from bodhi.server import bugs, buildsys
 from bodhi.server.config import config as bodhi_config
@@ -254,7 +255,8 @@ def main(global_config, testing=None, session=None, **settings):
 
     # Templating
     config.add_mako_renderer('.html', settings_prefix='mako.')
-    config.add_static_view('static', 'bodhi:server/static')
+    config.add_static_view(f'static/v{pkg_resources.get_distribution("bodhi").version}',
+                           'bodhi:server/static')
 
     from bodhi.server.renderers import rss
     config.add_renderer('rss', rss)


Test patch:
Repository: fedora-infra/bodhi

Issue:
Bodhi puhsed to stable an update with negative karma
The following update was reported on #fedora-devel, https://bodhi.fedoraproject.org/updates/FEDORA-2019-0f5dd9fe0d.

It received -1 karma but was still pushed to stable by bodhi after reaching 7 days in testing. 


Discussion:

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -3412,10 +3412,11 @@ def check_karma_thresholds(self, db, agent):
         if self.status not in (UpdateStatus.testing, UpdateStatus.pending):
             return
         # If an update receives negative karma disable autopush
-        if self.autokarma and self._composite_karma[1] != 0 and self.status is \
+        if (self.autokarma or self.autotime) and self._composite_karma[1] != 0 and self.status is \
                 UpdateStatus.testing and self.request is not UpdateRequest.stable:
             log.info("Disabling Auto Push since the update has received negative karma")
             self.autokarma = False
+            self.autotime = False
             text = config.get('disable_automatic_push_to_stable')
             self.comment(db, text, author='bodhi')
         elif self.stable_karma and self.karma >= self.stable_karma:


Test patch:
diff --git a/bodhi/tests/server/scripts/test_approve_testing.py b/bodhi/tests/server/scripts/test_approve_testing.py
--- a/bodhi/tests/server/scripts/test_approve_testing.py
+++ b/bodhi/tests/server/scripts/test_approve_testing.py
@@ -822,6 +822,30 @@ def test_autotime_update_with_autokarma_met_karma_and_time_requirements_get_push
         assert cmnts.count() == 1
         assert cmnts[0].text == 'This update has been submitted for stable by bodhi. '
 
+    def test_autotime_update_no_autokarma_negative_karma_not_pushed(self):
+        """
+        Ensure that an autotime update which negative karma does not get pushed.
+        """
+        update = self.db.query(models.Update).all()[0]
+        update.autokarma = False
+        update.autotime = True
+        update.request = None
+        update.stable_karma = 1
+        update.stable_days = 0
+        update.date_testing = datetime.utcnow() - timedelta(days=8)
+        update.status = models.UpdateStatus.testing
+        update.comment(self.db, u'Broken', author=u'luke', karma=-1)
+        with fml_testing.mock_sends(api.Message):
+            self.db.commit()
+
+        with patch('bodhi.server.scripts.approve_testing.initialize_db'):
+            with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
+                with fml_testing.mock_sends(api.Message):
+                    approve_testing.main(['nosetests', 'some_config.ini'])
+
+        assert update.request is None
+        assert update.autotime == False
+
     @patch('sys.exit')
     def test_log_level_is_left_alone(self, exit):
         """Ensure calling main() here leaves the global log level alone.
Repository: fedora-infra/bodhi

Issue:
Bodhi puhsed to stable an update with negative karma
The following update was reported on #fedora-devel, https://bodhi.fedoraproject.org/updates/FEDORA-2019-0f5dd9fe0d.

It received -1 karma but was still pushed to stable by bodhi after reaching 7 days in testing. 


Discussion:

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -3318,10 +3318,11 @@ def check_karma_thresholds(self, db, agent):
         if self.status not in (UpdateStatus.testing, UpdateStatus.pending):
             return
         # If an update receives negative karma disable autopush
-        if self.autokarma and self._composite_karma[1] != 0 and self.status is \
+        if (self.autokarma or self.autotime) and self._composite_karma[1] != 0 and self.status is \
                 UpdateStatus.testing and self.request is not UpdateRequest.stable:
             log.info("Disabling Auto Push since the update has received negative karma")
             self.autokarma = False
+            self.autotime = False
             text = config.get('disable_automatic_push_to_stable')
             self.comment(db, text, author='bodhi')
         elif self.stable_karma and self.karma >= self.stable_karma:


Test patch:
diff --git a/bodhi/tests/server/scripts/test_approve_testing.py b/bodhi/tests/server/scripts/test_approve_testing.py
--- a/bodhi/tests/server/scripts/test_approve_testing.py
+++ b/bodhi/tests/server/scripts/test_approve_testing.py
@@ -822,6 +822,30 @@ def test_autotime_update_with_autokarma_met_karma_and_time_requirements_get_push
         assert cmnts.count() == 1
         assert cmnts[0].text == 'This update has been submitted for stable by bodhi. '
 
+    def test_autotime_update_no_autokarma_negative_karma_not_pushed(self):
+        """
+        Ensure that an autotime update which negative karma does not get pushed.
+        """
+        update = self.db.query(models.Update).all()[0]
+        update.autokarma = False
+        update.autotime = True
+        update.request = None
+        update.stable_karma = 1
+        update.stable_days = 0
+        update.date_testing = datetime.utcnow() - timedelta(days=8)
+        update.status = models.UpdateStatus.testing
+        update.comment(self.db, u'Broken', author=u'luke', karma=-1)
+        with fml_testing.mock_sends(api.Message):
+            self.db.commit()
+
+        with patch('bodhi.server.scripts.approve_testing.initialize_db'):
+            with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
+                with fml_testing.mock_sends(api.Message):
+                    approve_testing.main(['nosetests', 'some_config.ini'])
+
+        assert update.request is None
+        assert update.autotime == False
+
     @patch('sys.exit')
     def test_log_level_is_left_alone(self, exit):
         """Ensure calling main() here leaves the global log level alone.
Repository: fedora-infra/bodhi

Issue:
Do not allow buildroot override in rawhide
If the user creates a buildroot override in rawhide it ends up messing with our entire workflow. The builds are no longer in their appropriate tags, they appear in bodhi's database but aren't linked to any update (cf PR: #3446) that leads to basically builds being stuck.

Preventing buildroot override creation in rawhide should just solve that :)


Discussion:
One possible easy way to do this is to not configure the override tag for the rawhide release.
Wfm, we just need to document this enough to make sure we don't miss it at branching

Resolving patch:
diff --git a/bodhi/server/schemas.py b/bodhi/server/schemas.py
--- a/bodhi/server/schemas.py
+++ b/bodhi/server/schemas.py
@@ -397,6 +397,7 @@ class SaveReleaseSchema(CSRFProtectedSchema, colander.MappingSchema):
     )
     override_tag = colander.SchemaNode(
         colander.String(),
+        missing="",
     )
     state = colander.SchemaNode(
         colander.String(),
diff --git a/bodhi/server/validators.py b/bodhi/server/validators.py
--- a/bodhi/server/validators.py
+++ b/bodhi/server/validators.py
@@ -1091,6 +1091,11 @@ def _validate_override_build(request, nvr, db):
 
             build.release = release
 
+        if not build.release.override_tag:
+            request.errors.add("body", "nvr", "Cannot create a buildroot override because the"
+                               " release associated with the build does not support it.")
+            return
+
         for tag in build.get_tags():
             if tag in (build.release.candidate_tag, build.release.testing_tag):
                 # The build is tagged as a candidate or testing


Test patch:
diff --git a/bodhi/tests/server/test_validators.py b/bodhi/tests/server/test_validators.py
--- a/bodhi/tests/server/test_validators.py
+++ b/bodhi/tests/server/test_validators.py
@@ -518,6 +518,30 @@ def test_no_nvrs_given(self):
               'description': 'A comma-separated list of NVRs is required.'}])
         self.assertEqual(request.errors.status, exceptions.HTTPBadRequest.code)
 
+    def test_release_with_no_override_tag(self):
+        """If the request has a build associated to a release with no override tag,
+        it should add an error to the request."""
+
+        build = self.db.query(models.Build).filter_by(
+            nvr='bodhi-2.0-1.fc17').first()
+
+        build.release.override_tag = ""
+        self.db.commit()
+
+        request = mock.Mock()
+        request.db = self.db
+        request.errors = Errors()
+        request.validated = {'nvr': 'bodhi-2.0-1.fc17', 'edited': False}
+
+        validators.validate_override_builds(request)
+
+        self.assertEqual(
+            request.errors,
+            [{'location': 'body', 'name': 'nvr',
+              'description': 'Cannot create a buildroot override because the'
+                             ' release associated with the build does not support it.'}])
+        self.assertEqual(request.errors.status, exceptions.HTTPBadRequest.code)
+
 
 class TestValidateRelease(BaseTestCase):
     """Test the validate_release() function."""
Repository: fedora-infra/bodhi

Issue:
Update without build can be created
It appears that an update without build can be created (https://bodhi.fedoraproject.org/updates/FEDORA-2019-e4e61bb84b). 
We need to make sure that the validators are not letting an update without a build being created.

In that case the update made the compose failed. 


Discussion:
This seems to happen if you create an update with build A, then create the another update with the same build.
Related: #3495
This happened again today, some more info from the IRC log
```
15:37 <RemiFedora> cverna, bodhi hangs during the "submit" (btw, it have properly obsolete an old update)
15:37 <RemiFedora> so I press "submit" another time, and get the proper update, with the build (but without the changelog from the obsoleted one...)
```
It seems to happen when bodhi hangs, I guess that we could check if an update has a build before commiting to the db.

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -4041,6 +4041,9 @@ def from_updates(cls, updates):
                 continue
             # ASSUMPTION: For now, updates can only be of a single type.
             ctype = None
+            if not update.builds:
+                log.info(f"No builds in {update.alias}. Skipping.")
+                continue
             for build in update.builds:
                 if ctype is None:
                     ctype = build.type


Test patch:
diff --git a/bodhi/tests/server/test_models.py b/bodhi/tests/server/test_models.py
--- a/bodhi/tests/server/test_models.py
+++ b/bodhi/tests/server/test_models.py
@@ -582,6 +582,16 @@ def assert_compose_has_update(compose, update):
         assert_compose_has_update(composes[1], update_4)
         assert_compose_has_update(composes[2], update_1)
 
+    def test_from_updates_no_builds(self):
+        """Assert that update without builds is not added to compose."""
+        update = self.create_update(['bodhi-{}-1.fc27'.format(uuid.uuid4())])
+        update.builds = []
+
+        composes = model.Compose.from_updates([update])
+
+        self.assertTrue(isinstance(composes, list))
+        self.assertEqual(len(composes), 0)
+
     def test_security_false(self):
         """Assert that security is False if none of the Updates are security updates."""
         compose = self._generate_compose(model.UpdateRequest.stable, False)
Repository: fedora-infra/bodhi

Issue:
Override active time typo
The time remaining for Overrides says something like "still active for in 7 days". There is an extra 'in' in that statement. Or it should say 'Expires in 7 days'.


Discussion:

Resolving patch:
diff --git a/bodhi/server/util.py b/bodhi/server/util.py
--- a/bodhi/server/util.py
+++ b/bodhi/server/util.py
@@ -375,7 +375,7 @@ def sanity_check_repodata_dnf(tempdir, myurl, *dnf_args):
     return subprocess.check_output(cmd, encoding='utf-8')
 
 
-def age(context, date, nuke_ago=False):
+def age(context, date, only_distance=False):
     """
     Return a human readable age since the given date.
 
@@ -386,11 +386,7 @@ def age(context, date, nuke_ago=False):
     Returns:
         str: A human readable age since the given date.
     """
-    humanized = arrow.get(date).humanize()
-    if nuke_ago:
-        return humanized.replace(' ago', '')
-    else:
-        return humanized
+    return arrow.get(date).humanize(only_distance=only_distance)
 
 
 hardcoded_avatars = {


Test patch:
diff --git a/bodhi/tests/server/services/test_overrides.py b/bodhi/tests/server/services/test_overrides.py
--- a/bodhi/tests/server/services/test_overrides.py
+++ b/bodhi/tests/server/services/test_overrides.py
@@ -766,7 +766,7 @@ def test_override_expired_date(self, get):
         """
         Test that a User can see the expired date of the override
         """
-        get.return_value.humanize.return_value = '82 seconds bro'
+        get.return_value.humanize.return_value = '82 seconds bro ago'
         expiration_date = datetime.utcnow() + timedelta(days=1)
         data = {'nvr': 'bodhi-2.0-1.fc17', 'notes': 'blah blah blah',
                 'expiration_date': expiration_date,
Repository: fedora-infra/bodhi

Issue:
empty update title makes it un-clickable in list views due to empty <a> element
I just noticed that if somebody sets the update title to an empty string (or it accidentally gets assigned an empty string), the created update is not clickable in list views since the generated `<a href=URL></a>` element is empty.

For example: https://bodhi.fedoraproject.org/updates/FEDORA-2019-110533d946

Not sure if this link is going to be valid for long:
https://bodhi.fedoraproject.org/updates/?status=pending&releases=F31&page=6

But there are multiple updates that are affected by this. Maybe a buggy version of the bodhi web interface inserted empty strings instead of leaving that argument as `None`.

![Screenshot from 2019-12-29 01-05-27](https://user-images.githubusercontent.com/12836693/71550735-6d7f7b00-29d7-11ea-88a2-03b081fd2f44.png)



Discussion:

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -2225,6 +2225,11 @@ def new(cls, request, data):
         data['critpath'] = cls.contains_critpath_component(
             data['builds'], data['release'].name)
 
+        # Be sure to not add an empty string as alternative title
+        # and strip whitespaces from it
+        if 'display_name' in data:
+            data['display_name'] = data['display_name'].strip()
+
         # Create the Bug entities, but don't talk to rhbz yet.  We do that
         # offline in the UpdatesHandler task worker now.
         bugs = []
@@ -2306,6 +2311,11 @@ def edit(cls, request, data):
         caveats = []
         edited_builds = [build.nvr for build in up.builds]
 
+        # Be sure to not add an empty string as alternative title
+        # and strip whitespaces from it
+        if 'display_name' in data:
+            data['display_name'] = data['display_name'].strip()
+
         # 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):


Test patch:
diff --git a/bodhi/tests/server/test_models.py b/bodhi/tests/server/test_models.py
--- a/bodhi/tests/server/test_models.py
+++ b/bodhi/tests/server/test_models.py
@@ -1739,6 +1739,21 @@ def test_remove_builds_from_locked_update(self):
         with pytest.raises(model.LockedUpdateException):
             model.Update.edit(request, data)
 
+    def test_empty_display_name(self):
+        """An only whitespaces string should not be set as display name."""
+        update = model.Update.query.first()
+        data = {
+            'edited': update.alias, 'builds': [update.builds[0].nvr],
+            'bugs': [], 'display_name': '  '}
+        request = mock.MagicMock()
+        request.db = self.db
+        request.user.name = 'tester'
+
+        model.Update.edit(request, data)
+
+        update = model.Update.query.first()
+        assert update.display_name == ''
+
 
 @mock.patch("bodhi.server.models.handle_update", mock.Mock())
 class TestUpdateVersionHash(BasePyTestCase):
Repository: fedora-infra/bodhi

Issue:
Broken search updates pagination with filters
If you use multiple values in search filters for updates search, as soon as you change page the filter gets broken.
For example, a simple search with `status = pending or testing` will produce a first page which is fine (`updates/?search=&status=pending&status=testing`), but when switching to second page the filter is broken (`updates/?search=&status=testing&page=2`).

The same happens for the other filters.


Discussion:

Resolving patch:
diff --git a/bodhi/server/util.py b/bodhi/server/util.py
--- a/bodhi/server/util.py
+++ b/bodhi/server/util.py
@@ -663,9 +663,9 @@ def page_url(context, page):
         str: The current path appended with a GET query for the requested page.
     """
     request = context.get('request')
-    params = dict(request.params)
+    params = request.params.mixed()
     params['page'] = page
-    return request.path_url + "?" + urlencode(params)
+    return f'{request.path_url}?{urlencode(params, doseq=True)}'
 
 
 def bug_link(context, bug, short=False):


Test patch:
diff --git a/bodhi/tests/server/test_util.py b/bodhi/tests/server/test_util.py
--- a/bodhi/tests/server/test_util.py
+++ b/bodhi/tests/server/test_util.py
@@ -23,6 +23,7 @@
 import subprocess
 import tempfile
 
+from webob.multidict import MultiDict
 import bleach
 import pkg_resources
 import pytest
@@ -1580,3 +1581,17 @@ def test_doublequotes_escaped(self):
         """Test that double quotes are escaped correctly for JSON.parse()."""
         title = 'This is a "terrible" bug title!'
         assert util.json_escape(title) == 'This is a \\"terrible\\" bug title!'
+
+
+class TestPageUrl:
+    """Tests for the page_url() method."""
+    def test_multi_values_parameter(self):
+        """Ensure correct url is generated from multiple values for same filter."""
+        context = mock.Mock()
+        context.get().path_url = 'http://localhost:6543'
+        context.get().params = MultiDict([('search', ''),
+                                          ('status', 'pending'),
+                                          ('status', 'testing')])
+        page = 2
+        expected_url = 'http://localhost:6543?search=&status=pending&status=testing&page=2'
+        assert util.page_url(context, page) == expected_url
Repository: fedora-infra/bodhi

Issue:
Cannot create new update after unpushing old one
To work around the issue with [not being able to edit updates](https://github.com/fedora-infra/bodhi/issues/3714), I wanted to unpush the updates ([f30](https://bodhi.fedoraproject.org/updates/FEDORA-2019-7cafbe66ba), [f31](https://bodhi.fedoraproject.org/updates/FEDORA-2019-94393775ec)) and create new ones with some of the builds in higher version. However, when clicking "Submit", I am getting the following error: "Builds : Update for dnf-plugins-core-4.0.11-1.fc30 already exists"

Even though I think that editing the update would be better approach, I don't understand why unpushed update should influence a creation of new update. 



Discussion:

Resolving patch:
diff --git a/bodhi/server/validators.py b/bodhi/server/validators.py
--- a/bodhi/server/validators.py
+++ b/bodhi/server/validators.py
@@ -295,9 +295,10 @@ def validate_builds(request, **kwargs):
     for nvr in builds:
         build = request.db.query(Build).filter_by(nvr=nvr).first()
         if build and build.update is not None:
-            request.errors.add('body', 'builds',
-                               "Update for {} already exists".format(nvr))
-            return
+            if build.update.status != UpdateStatus.unpushed:
+                request.errors.add('body', 'builds',
+                                   "Update for {} already exists".format(nvr))
+                return
 
 
 @postschema_validator


Test patch:
diff --git a/bodhi/tests/server/services/test_updates.py b/bodhi/tests/server/services/test_updates.py
--- a/bodhi/tests/server/services/test_updates.py
+++ b/bodhi/tests/server/services/test_updates.py
@@ -171,6 +171,18 @@ def test_duplicate_update(self, *args):
                                  status=400)
         assert 'Update for bodhi-2.0-1.fc17 already exists' in res
 
+    @mock.patch(**mock_valid_requirements)
+    def test_unpushed_update(self, *args):
+        """Allow posting a duplicate build if the old update is unpushed."""
+        unpushed_update = self.create_update(['whoopsie-1.0.0-1.fc17'])
+        unpushed_update.status = UpdateStatus.unpushed
+        self.db.commit()
+
+        with fml_testing.mock_sends(update_schemas.UpdateRequestTestingV1):
+            res = self.app.post_json('/updates/', self.get_update('whoopsie-1.0.0-1.fc17'))
+
+        assert res.json['alias'] != unpushed_update.alias
+
     @mock.patch(**mock_valid_requirements)
     def test_invalid_requirements(self, *args):
         update = self.get_update()