Hello community,

here is the log from the commit of package python-coveralls for 
openSUSE:Factory checked in at 2020-07-29 17:20:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-coveralls (Old)
 and      /work/SRC/openSUSE:Factory/.python-coveralls.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-coveralls"

Wed Jul 29 17:20:22 2020 rev:11 rq:823293 version:2.1.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-coveralls/python-coveralls.changes        
2020-06-17 14:55:07.109963419 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-coveralls.new.3592/python-coveralls.changes  
    2020-07-29 17:21:48.284627753 +0200
@@ -1,0 +2,8 @@
+Wed Jul 29 04:37:06 UTC 2020 - Steve Kowalik <[email protected]>
+
+- Update to 2.1.1:
+  * fix unhashable CoverallsException
+  * **cli**:  add new `--finish` flag for finalizing parallel builds
+  * **github:**  fix Github Actions support
+
+-------------------------------------------------------------------

Old:
----
  2.0.0.tar.gz

New:
----
  2.1.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-coveralls.spec ++++++
--- /var/tmp/diff_new_pack.p8Iv6C/_old  2020-07-29 17:21:51.088630166 +0200
+++ /var/tmp/diff_new_pack.p8Iv6C/_new  2020-07-29 17:21:51.092630169 +0200
@@ -19,19 +19,20 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-coveralls
-Version:        2.0.0
+Version:        2.1.1
 Release:        0
 Summary:        Module for showing coverage stats online via coverallsio
 License:        MIT
 URL:            https://github.com/coveralls-clients/coveralls-python
 Source:         
https://github.com/coveralls-clients/coveralls-python/archive/%{version}.tar.gz
 BuildRequires:  %{python_module PyYAML >= 3.10}
-BuildRequires:  %{python_module coverage >= 3.6}
+BuildRequires:  %{python_module coverage >= 4.1}
 BuildRequires:  %{python_module docopt >= 0.6.1}
 BuildRequires:  %{python_module mock}
 BuildRequires:  %{python_module pytest-runner}
 BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module requests >= 1.0.0}
+BuildRequires:  %{python_module responses}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  %{python_module sh >= 1.08}
 BuildRequires:  fdupes

++++++ 2.0.0.tar.gz -> 2.1.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/CHANGELOG.md 
new/coveralls-python-2.1.1/CHANGELOG.md
--- old/coveralls-python-2.0.0/CHANGELOG.md     2020-04-07 04:53:40.000000000 
+0200
+++ new/coveralls-python-2.1.1/CHANGELOG.md     2020-07-08 20:56:06.000000000 
+0200
@@ -1,3 +1,24 @@
+<a name="2.1.1"></a>
+## 2.1.1 (2020-07-08)
+
+#### Bug Fixes
+
+*  fix unhashable CoverallsException (#230) ([aa55335d](aa55335d))
+   This fixes a regression introduced in v2.1.0 which affected (at least) any
+   Python 3.5 installations.
+
+
+<a name="2.1.0"></a>
+## 2.1.0 (2020-07-07)
+
+#### Features
+
+* **cli**:  add new `--finish` flag for finalizing parallel builds (#277) 
([f597109b](f597109b))
+
+#### Bug Fixes
+
+* **github:**  fix Github Actions support (#227) ([f597109b](f597109b))
+
 <a name="2.0.0"></a>
 ## 2.0.0 (2020-04-07)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/coveralls/api.py 
new/coveralls-python-2.1.1/coveralls/api.py
--- old/coveralls-python-2.0.0/coveralls/api.py 2020-04-07 04:53:40.000000000 
+0200
+++ new/coveralls-python-2.1.1/coveralls/api.py 2020-07-08 20:56:06.000000000 
+0200
@@ -49,16 +49,12 @@
 
         self.load_config_from_environment()
 
-        name, job, pr = self.load_config_from_ci_environment()
+        name, job, number, pr = self.load_config_from_ci_environment()
         self.config['service_name'] = self.config.get('service_name', name)
         if job:
-            # N.B. Github Actions uses a different chunk of the Coveralls
-            # config when running parallel builds, ie. `service_number` instead
-            # of `service_job_id`.
-            if name.startswith('github'):
-                self.config['service_number'] = job
-            else:
-                self.config['service_job_id'] = job
+            self.config['service_job_id'] = job
+        if number:
+            self.config['service_number'] = number
         if pr:
             self.config['service_pull_request'] = pr
 
@@ -76,67 +72,78 @@
     @staticmethod
     def load_config_from_appveyor():
         pr = os.environ.get('APPVEYOR_PULL_REQUEST_NUMBER')
-        return 'appveyor', os.environ.get('APPVEYOR_BUILD_ID'), pr
+        return 'appveyor', os.environ.get('APPVEYOR_BUILD_ID'), None, pr
 
     @staticmethod
     def load_config_from_buildkite():
         pr = os.environ.get('BUILDKITE_PULL_REQUEST')
         if pr == 'false':
             pr = None
-        return 'buildkite', os.environ.get('BUILDKITE_JOB_ID'), pr
+        return 'buildkite', os.environ.get('BUILDKITE_JOB_ID'), None, pr
 
     @staticmethod
     def load_config_from_circle():
         pr = os.environ.get('CI_PULL_REQUEST', '').split('/')[-1] or None
-        return 'circle-ci', os.environ.get('CIRCLE_BUILD_NUM'), pr
+        return 'circle-ci', os.environ.get('CIRCLE_BUILD_NUM'), None, pr
 
-    @staticmethod
-    def load_config_from_github():
-        service_number = os.environ.get('GITHUB_SHA')
+    def load_config_from_github(self):
+        service = 'github'
+        if self.config.get('repo_token'):
+            service = 'github-actions'
+        else:
+            gh_token = os.environ.get('GITHUB_TOKEN')
+            if not gh_token:
+                raise CoverallsException(
+                    'Running on Github Actions but GITHUB_TOKEN is not set. '
+                    'Add "env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}" to '
+                    'your step config.')
+            self.config['repo_token'] = gh_token
+
+        number = os.environ.get('GITHUB_RUN_ID')
         pr = None
         if os.environ.get('GITHUB_REF', '').startswith('refs/pull/'):
             pr = os.environ.get('GITHUB_REF', '//').split('/')[2]
-            service_number += '-PR-{}'.format(pr)
-        return 'github-actions', service_number, pr
+        return service, None, number, pr
 
     @staticmethod
     def load_config_from_jenkins():
         pr = os.environ.get('CI_PULL_REQUEST', '').split('/')[-1] or None
-        return 'jenkins', os.environ.get('BUILD_NUMBER'), pr
+        return 'jenkins', os.environ.get('BUILD_NUMBER'), None, pr
 
     @staticmethod
     def load_config_from_travis():
         pr = os.environ.get('TRAVIS_PULL_REQUEST')
-        return 'travis-ci', os.environ.get('TRAVIS_JOB_ID'), pr
+        return 'travis-ci', os.environ.get('TRAVIS_JOB_ID'), None, pr
 
     @staticmethod
     def load_config_from_semaphore():
+        job = os.environ.get('SEMAPHORE_BUILD_NUMBER')
         pr = os.environ.get('PULL_REQUEST_NUMBER')
-        return 'semaphore-ci', os.environ.get('SEMAPHORE_BUILD_NUMBER'), pr
+        return 'semaphore-ci', job, None, pr
 
     @staticmethod
     def load_config_from_unknown():
-        return 'coveralls-python', None, None
+        return 'coveralls-python', None, None, None
 
     def load_config_from_ci_environment(self):
         if os.environ.get('APPVEYOR'):
-            name, job, pr = self.load_config_from_appveyor()
+            name, job, number, pr = self.load_config_from_appveyor()
         elif os.environ.get('BUILDKITE'):
-            name, job, pr = self.load_config_from_buildkite()
+            name, job, number, pr = self.load_config_from_buildkite()
         elif os.environ.get('CIRCLECI'):
-            name, job, pr = self.load_config_from_circle()
+            name, job, number, pr = self.load_config_from_circle()
         elif os.environ.get('GITHUB_ACTIONS'):
-            name, job, pr = self.load_config_from_github()
+            name, job, number, pr = self.load_config_from_github()
         elif os.environ.get('JENKINS_HOME'):
-            name, job, pr = self.load_config_from_jenkins()
+            name, job, number, pr = self.load_config_from_jenkins()
         elif os.environ.get('TRAVIS'):
             self._token_required = False
-            name, job, pr = self.load_config_from_travis()
+            name, job, number, pr = self.load_config_from_travis()
         elif os.environ.get('SEMAPHORE'):
-            name, job, pr = self.load_config_from_semaphore()
+            name, job, number, pr = self.load_config_from_semaphore()
         else:
-            name, job, pr = self.load_config_from_unknown()
-        return (name, job, pr)
+            name, job, number, pr = self.load_config_from_unknown()
+        return (name, job, number, pr)
 
     def load_config_from_environment(self):
         coveralls_host = os.environ.get('COVERALLS_HOST')
@@ -159,6 +166,10 @@
         if flag_name:
             self.config['flag_name'] = flag_name
 
+        number = os.environ.get('COVERALLS_SERVICE_JOB_NUMBER')
+        if number:
+            self.config['service_number'] = number
+
     def load_config_from_file(self):
         try:
             with open(os.path.join(os.getcwd(),
@@ -196,6 +207,39 @@
         except Exception as e:
             raise CoverallsException('Could not submit coverage: {}'.format(e))
 
+    # https://docs.coveralls.io/parallel-build-webhook
+    def parallel_finish(self):
+        payload = {'payload': {'status': 'done'}}
+
+        # required args
+        if self.config.get('repo_token'):
+            payload['repo_token'] = self.config['repo_token']
+        if self.config.get('service_number'):
+            payload['payload']['build_num'] = self.config['service_number']
+
+        # service-specific parameters
+        if os.environ.get('GITHUB_REPOSITORY'):
+            # Github Actions only
+            payload['repo_name'] = os.environ.get('GITHUB_REPOSITORY')
+
+        endpoint = '{}/webhook'.format(self._coveralls_host.rstrip('/'))
+        verify = not bool(os.environ.get('COVERALLS_SKIP_SSL_VERIFY'))
+        response = requests.post(endpoint, json=payload, verify=verify)
+        try:
+            response.raise_for_status()
+            response = response.json()
+        except Exception as e:
+            raise CoverallsException('Parallel finish failed: {}'.format(e))
+
+        if 'error' in response:
+            e = response['error']
+            raise CoverallsException('Parallel finish failed: {}'.format(e))
+
+        if 'done' not in response or not response['done']:
+            raise CoverallsException('Parallel finish failed')
+
+        return response
+
     def create_report(self):
         """Generate json dumped report for coveralls api."""
         data = self.create_data()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/coveralls/cli.py 
new/coveralls-python-2.1.1/coveralls/cli.py
--- old/coveralls-python-2.0.0/coveralls/cli.py 2020-04-07 04:53:40.000000000 
+0200
+++ new/coveralls-python-2.1.1/coveralls/cli.py 2020-07-08 20:56:06.000000000 
+0200
@@ -21,6 +21,7 @@
     --rcfile=<file>   Specify configuration file. [default: .coveragerc]
     --output=<file>   Write report to file. Doesn't send anything.
     --merge=<file>    Merge report from file when submitting.
+    --finish          Finish parallel jobs.
     -h --help         Display this help.
     -v --verbose      Print extra info, always enabled when debugging.
 
@@ -74,6 +75,12 @@
             coverallz.save_report(options['--output'])
             return
 
+        if options['--finish']:
+            log.info('Finishing parallel jobs...')
+            coverallz.parallel_finish()
+            log.info('Done')
+            return
+
         log.info('Submitting coverage to coveralls.io...')
         result = coverallz.wear()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/coveralls/exception.py 
new/coveralls-python-2.1.1/coveralls/exception.py
--- old/coveralls-python-2.0.0/coveralls/exception.py   2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/coveralls/exception.py   2020-07-08 
20:56:06.000000000 +0200
@@ -1,2 +1,11 @@
 class CoverallsException(Exception):
-    pass
+    def __eq__(self, other):
+        if isinstance(other, self.__class__):
+            return str(self) == str(other)
+        return False
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __hash__(self):
+        return hash(str(self))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/coveralls/version.py 
new/coveralls-python-2.1.1/coveralls/version.py
--- old/coveralls-python-2.0.0/coveralls/version.py     2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/coveralls/version.py     2020-07-08 
20:56:06.000000000 +0200
@@ -1 +1 @@
-__version__ = '2.0.0'
+__version__ = '2.1.1'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/docs/usage/configuration.rst 
new/coveralls-python-2.1.1/docs/usage/configuration.rst
--- old/coveralls-python-2.0.0/docs/usage/configuration.rst     2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/docs/usage/configuration.rst     2020-07-08 
20:56:06.000000000 +0200
@@ -29,6 +29,10 @@
 
     COVERALLS_PARALLEL=true coveralls
 
+Later on, you can use ``coveralls --finish`` to let the Coveralls service know 
you have completed all your parallel runs::
+
+    coveralls --finish
+
 If you are using a non-public coveralls.io instance (for example: self-hosted 
Coveralls Enterprise), you can set ``COVERALLS_HOST`` to the base URL of that 
insance::
 
     COVERALLS_HOST="https://coveralls.aperture.com"; coveralls
@@ -49,3 +53,47 @@
     repo_token: mV2Jajb8y3c6AFlcVNagHO20fiZNkXPVy
     parallel: true
     coveralls_host: https://coveralls.aperture.com
+
+Github Actions Gotcha
+---------------------
+
+Coveralls natively supports jobs running on Github Actions. You can directly 
pass the default-provided secret GITHUB_TOKEN::
+
+    env:
+        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+    run: |
+        coveralls
+
+For parallel builds, you have to add a final step to let coveralls know the 
parallel build is finished. You also have to set COVERALLS_FLAG_NAME to 
something unique to the specific step, so re-runs of the same job don't keep 
piling up builds::
+
+    jobs:
+      test:
+        strategy:
+          matrix:
+            test-name:
+              - test1
+              - test2
+        runs-on: ubuntu-latest
+        steps:
+          - name: Checkout
+            uses: actions/checkout@v2
+          - name: Test
+            run: ./run_tests.sh ${{ matrix.test-name }}
+          - name: Upload Coverage
+            run: coveralls
+            env:
+              GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+              COVERALLS_FLAG_NAME: ${{ matrix.test-name }}
+              COVERALLS_PARALLEL: true
+      coveralls:
+        name: Finish Coveralls
+        needs: test
+        runs-on: ubuntu-latest
+        container: python:3-slim
+        steps:
+        - name: Finished
+          run: |
+            pip3 install --upgrade coveralls
+            coveralls --finish
+          env:
+            GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/docs/usage/tox.rst 
new/coveralls-python-2.1.1/docs/usage/tox.rst
--- old/coveralls-python-2.0.0/docs/usage/tox.rst       2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/docs/usage/tox.rst       2020-07-08 
20:56:06.000000000 +0200
@@ -68,6 +68,9 @@
 - ``GITHUB_REF``
 - ``GITHUB_SHA``
 - ``GITHUB_HEAD_REF``
+- ``GITHUB_REPOSITORY``
+- ``GITHUB_RUN_ID``
+- ``GITHUB_TOKEN``
 
 Jenkins
 -------
@@ -98,7 +101,7 @@
 
 
 SemaphoreCI
--------
+-----------
 ::
 
     passenv = SEMAPHORE SEMAPHORE_BUILD_NUMBER BRANCH_NAME PULL_REQUEST_NUMBER
@@ -109,4 +112,5 @@
 - ``SEMAPHORE_BUILD_NUMBER``
 - ``BRANCH_NAME``
 - ``PULL_REQUEST_NUMBER``
+
 .. _tox: https://tox.readthedocs.io/en/latest/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/setup.py 
new/coveralls-python-2.1.1/setup.py
--- old/coveralls-python-2.0.0/setup.py 2020-04-07 04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/setup.py 2020-07-08 20:56:06.000000000 +0200
@@ -38,7 +38,7 @@
         'docopt>=0.6.1',
         'requests>=1.0.0',
     ],
-    tests_require=['mock', 'pytest'],
+    tests_require=['mock', 'responses', 'pytest'],
     extras_require={
         'yaml': ['PyYAML>=3.10'],
     },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/coveralls-python-2.0.0/tests/api/configuration_test.py 
new/coveralls-python-2.1.1/tests/api/configuration_test.py
--- old/coveralls-python-2.0.0/tests/api/configuration_test.py  2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/tests/api/configuration_test.py  2020-07-08 
20:56:06.000000000 +0200
@@ -66,6 +66,14 @@
             'Not on TravisCI. You have to provide either repo_token in '
             '.coveralls.mock or set the COVERALLS_REPO_TOKEN env var.')
 
+    @mock.patch.dict(os.environ, {'GITHUB_ACTIONS': 'true'}, clear=True)
+    def test_misconfigured_github(self):
+        with pytest.raises(Exception) as excinfo:
+            Coveralls()
+
+        assert str(excinfo.value).startswith(
+            'Running on Github Actions but GITHUB_TOKEN is not set.')
+
     @mock.patch.dict(os.environ, {'APPVEYOR': 'True',
                                   'APPVEYOR_BUILD_ID': '1234567',
                                   'APPVEYOR_PULL_REQUEST_NUMBER': '1234'},
@@ -113,26 +121,34 @@
         {'GITHUB_ACTIONS': 'true',
          'GITHUB_REF': 'refs/pull/1234/merge',
          'GITHUB_SHA': 'bb0e00166b28f49db04d6a8b8cb4bddb5afa529f',
-         'GITHUB_HEAD_REF': 'fixup-branch'},
+         'GITHUB_RUN_ID': '123456789',
+         'GITHUB_RUN_NUMBER': '12',
+         'GITHUB_HEAD_REF': 'fixup-branch',
+         'COVERALLS_REPO_TOKEN': 'xxx'},
         clear=True)
     def test_github_no_config(self):
-        cover = Coveralls(repo_token='xxx')
+        cover = Coveralls()
         assert cover.config['service_name'] == 'github-actions'
         assert cover.config['service_pull_request'] == '1234'
+        assert cover.config['service_number'] == '123456789'
         assert 'service_job_id' not in cover.config
 
     @mock.patch.dict(
         os.environ,
         {'GITHUB_ACTIONS': 'true',
+         'GITHUB_TOKEN': 'xxx',
          'GITHUB_REF': 'refs/heads/master',
          'GITHUB_SHA': 'bb0e00166b28f49db04d6a8b8cb4bddb5afa529f',
+         'GITHUB_RUN_ID': '987654321',
+         'GITHUB_RUN_NUMBER': '21',
          'GITHUB_HEAD_REF': ''},
         clear=True)
     def test_github_no_config_no_pr(self):
-        cover = Coveralls(repo_token='xxx')
-        assert cover.config['service_name'] == 'github-actions'
-        assert 'service_pull_request' not in cover.config
+        cover = Coveralls()
+        assert cover.config['service_name'] == 'github'
+        assert cover.config['service_number'] == '987654321'
         assert 'service_job_id' not in cover.config
+        assert 'service_pull_request' not in cover.config
 
     @mock.patch.dict(
         os.environ,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/tests/api/exception_test.py 
new/coveralls-python-2.1.1/tests/api/exception_test.py
--- old/coveralls-python-2.0.0/tests/api/exception_test.py      1970-01-01 
01:00:00.000000000 +0100
+++ new/coveralls-python-2.1.1/tests/api/exception_test.py      2020-07-08 
20:56:06.000000000 +0200
@@ -0,0 +1,41 @@
+# pylint: disable=no-self-use
+import logging
+import unittest
+
+import pytest
+
+from coveralls.exception import CoverallsException
+
+class CoverallsExceptionTest(unittest.TestCase):
+
+    _caplog = None
+
+    @pytest.fixture(autouse=True)
+    def inject_fixtures(self, caplog):
+        self._caplog = caplog
+
+    def test_log(self):
+        self._caplog.set_level(logging.INFO)
+        exc_value = ''
+        try:
+            raise CoverallsException('Some exception')
+        except CoverallsException as e:
+            logging.exception('Found exception')
+            assert 'raise CoverallsException(' in \
+                self._caplog.text
+            exc_value = str(e)
+
+        assert exc_value == 'Some exception'
+
+    def test_eq(self):
+        exc1 = CoverallsException('Value1')
+        exc2 = CoverallsException('Value1')
+        assert exc1 == exc2
+        assert not exc1 == 35  # pylint: disable=unneeded-not
+        assert exc1 is not exc2
+
+    def test_ne(self):
+        exc1 = CoverallsException('Value1')
+        exc2 = CoverallsException('Value2')
+        assert exc1 != exc2
+        assert exc1 is not exc2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/tests/cli_test.py 
new/coveralls-python-2.1.1/tests/cli_test.py
--- old/coveralls-python-2.0.0/tests/cli_test.py        2020-04-07 
04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/tests/cli_test.py        2020-07-08 
20:56:06.000000000 +0200
@@ -1,6 +1,8 @@
+import json
 import os
 
 import mock
+import responses
 
 import coveralls.cli
 from coveralls.exception import CoverallsException
@@ -9,6 +11,10 @@
 EXC = CoverallsException('bad stuff happened')
 
 
+def req_json(request):
+    return json.loads(request.body.decode('utf-8'))
+
+
 @mock.patch.dict(os.environ, {'TRAVIS': 'True'}, clear=True)
 @mock.patch.object(coveralls.cli.log, 'info')
 @mock.patch.object(coveralls.Coveralls, 'wear')
@@ -18,6 +24,7 @@
     mock_log.assert_has_calls([mock.call('Testing coveralls-python...')])
 
 
[email protected](os.environ, clear=True)
 @mock.patch.object(coveralls.cli.log, 'info')
 @mock.patch.object(coveralls.Coveralls, 'wear')
 def test_debug_no_token(mock_wear, mock_log):
@@ -26,6 +33,61 @@
     mock_log.assert_has_calls([mock.call('Testing coveralls-python...')])
 
 
[email protected](
+    os.environ,
+    {'GITHUB_ACTIONS': 'true',
+     'GITHUB_REPOSITORY': 'test/repo',
+     'GITHUB_TOKEN': 'xxx',
+     'GITHUB_RUN_ID': '123456789',
+     'GITHUB_RUN_NUMBER': '123'},
+    clear=True)
[email protected](coveralls.cli.log, 'info')
[email protected]
+def test_finish(mock_log):
+    responses.add(responses.POST, 'https://coveralls.io/webhook',
+                  json={'done': True}, status=200)
+    expected_json = {
+        'repo_token': 'xxx',
+        'repo_name': 'test/repo',
+        'payload': {
+            'status': 'done',
+            'build_num': '123456789'
+        }
+    }
+
+    coveralls.cli.main(argv=['--finish'])
+
+    mock_log.assert_has_calls(
+        [mock.call('Finishing parallel jobs...'),
+         mock.call('Done')])
+    assert len(responses.calls) == 1
+    assert req_json(responses.calls[0].request) == expected_json
+
+
[email protected](os.environ, {'TRAVIS': 'True'}, clear=True)
[email protected](coveralls.cli.log, 'exception')
[email protected]
+def test_finish_exception(mock_log):
+    responses.add(responses.POST, 'https://coveralls.io/webhook',
+                  json={'error': 'Mocked'}, status=200)
+    expected_json = {
+        'payload': {
+            'status': 'done'
+        }
+    }
+    msg = 'Parallel finish failed: Mocked'
+
+    try:
+        coveralls.cli.main(argv=['--finish'])
+        assert 0 == 1  # Should never reach this line
+    except SystemExit:
+        pass
+
+    mock_log.assert_has_calls([mock.call(CoverallsException(msg))])
+    assert len(responses.calls) == 1
+    assert req_json(responses.calls[0].request) == expected_json
+
+
 @mock.patch.object(coveralls.cli.log, 'info')
 @mock.patch.object(coveralls.Coveralls, 'wear')
 @mock.patch.dict(os.environ, {'TRAVIS': 'True'}, clear=True)
@@ -74,6 +136,7 @@
     mock_coveralls.assert_called_with('test.log')
 
 
[email protected](os.environ, clear=True)
 @mock.patch.object(coveralls.Coveralls, 'save_report')
 def test_save_report_to_file_no_token(mock_coveralls):
     """Check save_report api usage when token is not set."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/coveralls-python-2.0.0/tox.ini 
new/coveralls-python-2.1.1/tox.ini
--- old/coveralls-python-2.0.0/tox.ini  2020-04-07 04:53:40.000000000 +0200
+++ new/coveralls-python-2.1.1/tox.ini  2020-07-08 20:56:06.000000000 +0200
@@ -13,6 +13,7 @@
 usedevelop = true
 deps =
     mock
+    responses
     pytest
     pyyaml: PyYAML>=3.10,<5.3
     cov41: coverage>=4.1,<5.0


Reply via email to