Repository: fedora-infra/bodhi

Issue:
TypeError: '>' not supported between instances of 'int' and 'list'
Another composer crash, possibly related to the Python 3 deployment:

```
[2018-11-21 14:30:50][fedmsg.consumers   ERROR]epel7-testing Exception in ComposerThread(epel7-testing)
Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/bodhi/server/consumers/masher.py", line 411, in work
    self._compose_updates()
  File "/usr/lib/python3.7/site-packages/bodhi/server/consumers/masher.py", line 942, in _compose_updates
    self.generate_testing_digest()
  File "/usr/lib/python3.7/site-packages/bodhi/server/consumers/masher.py", line 704, in generate_testing_digest
    self.add_to_digest(update)
  File "/usr/lib/python3.7/site-packages/bodhi/server/consumers/masher.py", line 696, in add_to_digest
    update, use_template='maillist_template')):
  File "/usr/lib/python3.7/site-packages/bodhi/server/mail.py", line 359, in get_template
    (to_unicode(build.get_changelog(oldtime)), line)
  File "/usr/lib/python3.7/site-packages/bodhi/server/models.py", line 1634, in get_changelog
    while (i < num) and (when[i] > timelimit):
TypeError: '>' not supported between instances of 'int' and 'list'
```


Discussion:
Welp, I now have a reproducer:

```
from threading import Lock

import koji

from bodhi.server import buildsys, config, mail, models, initialize_db


initialize_db(config.config)
buildsys._buildsystem = lambda: koji.ClientSession('https://koji.fedoraproject.org/kojihub')
buildsys._buildsystem_login_lock = Lock()

b = models.Build.query.filter_by(nvr='libpeas-loader-python3-1.22.0-1.el7').one()
print(mail.get_template(b.update))
```
The issue seems to be [here](https://github.com/fedora-infra/bodhi/blob/3.11.0/bodhi/server/mail.py#L350-L359):

```
            oldh = get_rpm_header(lastpkg)
            oldtime = oldh['changelogtime']
            text = oldh['changelogtext']
            del oldh
            if not text:
                oldtime = 0
            elif len(text) != 1:
                oldtime = oldtime[0]
            info['changelog'] = u"ChangeLog:\n\n%s%s" % \
                (to_unicode(build.get_changelog(oldtime)), line)
```

With the package given above, there is a ```lastpkg```, and ```oldh``` looks like this:

```
{'description': 'This package contains the Python 3 loader that is needed to\nrun Python 3 plugins that use libpeas.', 'url': 'https://wiki.gnome.org/Projects/Libpeas', 'changelogname': ['Björn Esser <besser82@fedoraproject.org> - 1.20.0-1'], 'summary': 'Python 3 loader for libpeas', 'version': '1.20.0', 'changelogtime': [1510920000], 'changelogtext': ['- Initial rpm release for EPEL7 (rhbz#1514458)'], 'release': '1.el7', 'name': 'libpeas-loader-python3'}
```

Note that ```changelogtime``` is a list of one element, so ```oldtime``` is set to ```[1510920000]```. ```text``` is ```['- Initial rpm release for EPEL7 (rhbz#1514458)']``` and so has one element, so nothing ever converts the single element list to an int before passing it to ```build.get_changelog()```, which results in comparing an int to a list.

Resolving patch:
diff --git a/bodhi/server/buildsys.py b/bodhi/server/buildsys.py
--- a/bodhi/server/buildsys.py
+++ b/bodhi/server/buildsys.py
@@ -565,6 +565,11 @@ def getRPMHeaders(self, rpmID, headers):
                 headers['changelogtime'].insert(0, 1375531201)
             elif rpmID == 'TurboGears-1.9.1-1.fc17.src':
                 headers['changelogtext'] = []
+            elif rpmID == 'TurboGears-1.9.1-42.fc17.src':
+                # Make sure only a single changelog entry is present
+                headers['changelogname'] = ['Randy Barlow <bowlofeggs@fp.o> - 1.9.1-42']
+                headers['changelogtext'] = ["- Hope I didn't break anything!"]
+                headers['changelogtime'] = [1375531200]
             return headers
 
 
diff --git a/bodhi/server/mail.py b/bodhi/server/mail.py
--- a/bodhi/server/mail.py
+++ b/bodhi/server/mail.py
@@ -353,7 +353,7 @@ def get_template(update, use_template='fedora_errata_template'):
             del oldh
             if not text:
                 oldtime = 0
-            elif len(text) != 1:
+            elif isinstance(oldtime, list):
                 oldtime = oldtime[0]
             info['changelog'] = u"ChangeLog:\n\n%s%s" % \
                 (to_unicode(build.get_changelog(oldtime)), line)


Test patch:
diff --git a/bodhi/tests/server/test_mail.py b/bodhi/tests/server/test_mail.py
--- a/bodhi/tests/server/test_mail.py
+++ b/bodhi/tests/server/test_mail.py
@@ -48,6 +48,21 @@ def test_changelog(self):
         self.assertFalse('* Tue Jul 10 2012 Paul Moore <pmoore@redhat.com> - 0.1.0-1' in t)
         self.assertFalse('- Limit package to x86/x86_64 platforms (RHBZ #837888)' in t)
 
+    @mock.patch('bodhi.server.models.RpmBuild.get_latest')
+    def test_changelog_single_entry(self, get_latest):
+        """Test that we handle a changelog with a single entry correctly."""
+        get_latest.return_value = 'TurboGears-1.9.1-42.fc17'
+        u = self.create_update(['TurboGears-2.0.0.0-1.fc17'])
+
+        # This should not blow up like it did in https://github.com/fedora-infra/bodhi/issues/2768
+        t = mail.get_template(u)
+
+        # Assemble the template for easier asserting.
+        t = '\n'.join([l for l in t[0]])
+        self.assertTrue('ChangeLog:' in t)
+        self.assertTrue('* Sat Aug  3 2013 Randy Barlow <bowlofeggs@fp.o> - 2.2.0-1' in t)
+        self.assertTrue('- Added some bowlofeggs charm.' in t)
+
     @mock.patch('bodhi.server.models.RpmBuild.get_latest')
     def test_changelog_no_old_text(self, get_latest):
         """Ensure that a changelog gets generated when there is an older Build with no text."""