Skip to content

Commit

Permalink
fix(gha): s/github-actions/github/ (#427)
Browse files Browse the repository at this point in the history
Thanks to @andy-maier for the research on this one!
  • Loading branch information
TheKevJames committed Apr 29, 2024
1 parent d541af2 commit 44e9563
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 54 deletions.
66 changes: 31 additions & 35 deletions coveralls/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import json
import logging
import os
import random
import re
import sys

import coverage
import requests
Expand Down Expand Up @@ -107,6 +105,8 @@ def load_config_from_circle():
return 'circleci', job, number, pr

def load_config_from_github(self):
# See https://github.com/lemurheavy/coveralls-public/issues/1710

# Github tokens and standard Coveralls tokens are almost but not quite
# the same -- forceibly using Github's flow seems to be more stable
self.config['repo_token'] = os.environ.get('GITHUB_TOKEN')
Expand All @@ -115,11 +115,24 @@ def load_config_from_github(self):
if os.environ.get('GITHUB_REF', '').startswith('refs/pull/'):
pr = os.environ.get('GITHUB_REF', '//').split('/')[2]

# N.B. some users require this to be 'github' and some require it to
# be 'github-actions'. Defaulting to 'github-actions' as it seems more
# common -- users can specify the service name manually to override
# this.
return 'github-actions', None, os.environ.get('GITHUB_RUN_ID'), pr
# TODO: coveralls suggests using the RUN_ID for both these values:
# https://github.com/lemurheavy/coveralls-public/issues/1710#issuecomment-1539203555
# However, they also suggest following this successful config approach:
# https://github.com/lemurheavy/coveralls-public/issues/1710#issuecomment-1913696022
# which instead sets:
# COVERALLS_SERVICE_JOB_ID: $GITHUB_RUN_ID
# COVERALLS_SERVICE_NUMBER: $GITHUB_WORKFLOW-$GITHUB_RUN_NUMBER
# should we do the same?
job = os.environ.get('GITHUB_RUN_ID')
number = os.environ.get('GITHUB_RUN_ID')

# N.B. per Coveralls:
# > When you want to identify the repo at Coveralls by its
# > GITHUB_TOKEN, you should choose github, and when you want to
# > identify it by its Coveralls Repo Token, you should choose
# > github-action.
# https://github.com/lemurheavy/coveralls-public/issues/1710#issuecomment-1539203555
return 'github', job, number, pr

@staticmethod
def load_config_from_jenkins():
Expand Down Expand Up @@ -189,9 +202,6 @@ def load_config_from_ci_environment(self):
elif os.environ.get('CIRCLECI'):
name, job, number, pr = self.load_config_from_circle()
elif os.environ.get('GITHUB_ACTIONS'):
# N.B. Github Actions fails if this is not set even when null.
# Other services fail if this is set to null. Sigh.
self.config['service_job_id'] = None
name, job, number, pr = self.load_config_from_github()
elif os.environ.get('JENKINS_HOME'):
name, job, number, pr = self.load_config_from_jenkins()
Expand Down Expand Up @@ -271,32 +281,18 @@ def submit_report(self, json_string):
endpoint, files={'json_file': json_string}, verify=verify,
)

# check and adjust/resubmit if submission looks like it failed due to
# resubmission (non-unique)
if response.status_code == 422:
# attach a random value to ensure uniqueness
# TODO: an auto-incrementing integer might be easier to reason
# about if we could fetch the previous value
# N.B. Github Actions fails if this is not set to null.
# Other services fail if this is set to null. Sigh x2.
if os.environ.get('GITHUB_REPOSITORY'):
new_id = None
else:
new_id = '-'.join((
self.config.get('service_job_id', '42'),
str(random.randint(0, sys.maxsize)),
))
print(f'resubmitting with id {new_id}')

self.config['service_job_id'] = new_id
self._data = None # force create_report to use updated data
json_string = self.create_report()

response = requests.post(
endpoint,
files={'json_file': json_string},
verify=verify,
)
if self.config['service_name'].startswith('github'):
print(
'Received 422 submitting job via Github Actions. By '
'default, coveralls-python uses the "github" service '
'name, which requires you to set the $GITHUB_TOKEN '
'environment variable. If you want to use a '
'COVERALLS_REPO_TOKEN instead, please manually override '
'$COVERALLS_SERVICE_NAME to "github-actions". For more '
'info, see https://coveralls-python.readthedocs.io/en'
'/latest/usage/configuration.html#github-actions-support',
)

try:
response.raise_for_status()
Expand Down
33 changes: 18 additions & 15 deletions docs/usage/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,27 @@ Github Actions support
Coveralls natively supports jobs running on Github Actions. You can directly
pass the default-provided secret GITHUB_TOKEN::

run: coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
coveralls --service=github

Passing a coveralls.io token via the ``COVERALLS_REPO_TOKEN`` environment variable
(or via the ``repo_token`` parameter in the config file) is not needed for
Github Actions.

Sometimes Github Actions gets a little picky about the service name which needs
to be used in various cases. If you run into issues, try setting the
``COVERALLS_SERVICE_NAME`` explicitly to either ``github`` or
``github-actions``. It seems to be the case that you should use the
``--service=github`` value if you are also planning to use the ``GITHUB_TOKEN``
env var, and ``github-actions`` (which is the default) in any other case, but
we've have conflicting reports on this: YMMV! See
`#452 <https://github.com/TheKevJames/coveralls-python/issues/252>`_ for more
info.
Github Actions by default (eg. with the default value of ``--service=github``).

Github Actions can get a bit finicky as to how coverage is submitted. If you
find yourself getting 422 error responses, you can also try specifying the
``github-actions`` service name instead. If you do so, you will need to proved
a ``COVERALLS_REPO_TOKEN`` *instead* of a ``GITHUB_TOKEN``::

run: coveralls --service=github-actions
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

If you're still having issues after tryingt both of the above, please read through
the following issues for more information:
`#252 <https://github.com/TheKevJames/coveralls-python/issues/252>`_ and
`coveralls-public#1710 <https://github.com/lemurheavy/coveralls-public/issues/1710>`_.

For parallel builds, you have to add a final step to let coveralls.io know the
parallel build is finished::
Expand All @@ -110,7 +113,7 @@ parallel build is finished::
- name: Test
run: ./run_tests.sh ${{ matrix.test-name }}
- name: Upload coverage data to coveralls.io
run: coveralls --service=github
run: coveralls
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERALLS_FLAG_NAME: ${{ matrix.test-name }}
Expand All @@ -124,7 +127,7 @@ parallel build is finished::
- name: Install coveralls
run: pip3 install --upgrade coveralls
- name: Finished
run: coveralls --service=github --finish
run: coveralls --finish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Expand Down
8 changes: 4 additions & 4 deletions tests/api/configuration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ def test_circleci_parallel_no_config(self):
)
def test_github_no_config(self):
cover = Coveralls()
assert cover.config['service_name'] == 'github-actions'
assert cover.config['service_name'] == 'github'
assert cover.config['service_pull_request'] == '1234'
assert cover.config['service_number'] == '123456789'
assert 'service_job_id' in cover.config
assert cover.config['service_job_id'] == '123456789'

@mock.patch.dict(
os.environ,
Expand All @@ -193,9 +193,9 @@ def test_github_no_config(self):
)
def test_github_no_config_no_pr(self):
cover = Coveralls()
assert cover.config['service_name'] == 'github-actions'
assert cover.config['service_name'] == 'github'
assert cover.config['service_number'] == '987654321'
assert 'service_job_id' in cover.config
assert cover.config['service_job_id'] == '987654321'
assert 'service_pull_request' not in cover.config

@mock.patch.dict(
Expand Down

0 comments on commit 44e9563

Please sign in to comment.