Skip to content
Snippets Groups Projects
Commit ffbf6dba authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Merge branch 'badges' into 'master'

Add script to automatically update badges from gitlab projects

See merge request !154
parents a277b633 a52eab87
No related branches found
No related tags found
1 merge request!154Add script to automatically update badges from gitlab projects
Pipeline #39179 passed
......@@ -534,6 +534,7 @@ def git_clean_build(runner, verbose):
exclude_from_cleanup = [
"miniconda.sh", # the installer, cached
"sphinx", # build artifact -- documentation
"coverage.xml", # build artifact -- coverage report
]
# artifacts
......
#!/usr/bin/env python
import os
import click
import gitlab
from . import bdt
from ..release import get_gitlab_instance, update_files_at_master
from ..log import verbosity_option, get_logger, echo_normal, echo_warning
logger = get_logger(__name__)
# These show on the gitlab project landing page (not visible on PyPI)
PROJECT_BADGES = [
{
"name": "Docs (stable)",
"link_url": "https://www.idiap.ch/software/{group}/docs/%{{project_path}}/stable/index.html",
"image_url": "https://img.shields.io/badge/docs-stable-yellow.svg",
},
{
"name": "Docs (latest)",
"link_url": "https://www.idiap.ch/software/{group}/docs/%{{project_path}}/%{{default_branch}}/index.html",
"image_url": "https://img.shields.io/badge/docs-latest-orange.svg",
},
{
"name": "Pipeline (status)",
"link_url": "https://gitlab.idiap.ch/%{{project_path}}/commits/%{{default_branch}}",
"image_url": "https://gitlab.idiap.ch/%{{project_path}}/badges/%{{default_branch}}/pipeline.svg",
},
{
"name": "Coverage (latest)",
"link_url": "https://gitlab.idiap.ch/%{{project_path}}/commits/%{{default_branch}}",
"image_url": "https://gitlab.idiap.ch/%{{project_path}}/badges/%{{default_branch}}/coverage.svg",
},
{
"name": "PyPI (version)",
"link_url": "https://pypi.python.org/pypi/{name}",
"image_url": "https://img.shields.io/pypi/v/{name}.svg",
},
]
# These show on the README and will be visible in PyPI
README_BADGES = [
{
"name": "Docs (current)",
"link_url": "https://www.idiap.ch/software/{group}/docs/{group}/{name}/master/index.html",
"image_url": "https://img.shields.io/badge/docs-available-orage.svg",
},
{
"name": "Pipeline (current)",
"link_url": "https://gitlab.idiap.ch/{group}/{name}/commits/master",
"image_url": "https://gitlab.idiap.ch/{group}/{name}/badges/master/pipeline.svg",
},
{
"name": "Coverage (current)",
"link_url": "https://gitlab.idiap.ch/{group}/{name}/commits/master",
"image_url": "https://gitlab.idiap.ch/{group}/{name}/badges/master/coverage.svg",
},
{
"name": "Gitlab project",
"link_url": "https://gitlab.idiap.ch/{group}/{name}",
"image_url": "https://img.shields.io/badge/gitlab-project-0000c0.svg",
},
]
def _update_readme(content, info):
"""Updates the README content provided, replacing badges"""
import re
new_badges_text = []
for badge in README_BADGES:
data = dict((k, v.format(**info)) for (k,v) in badge.items())
new_badges_text.append(".. image:: {image_url}".format(**data))
new_badges_text.append(" :target: {link_url}".format(**data))
new_badges_text = '\n'.join(new_badges_text) + '\n'
# matches only 3 or more occurences of ..image::/:target: occurences
expression = r"(\.\.\s*image.+\n\s+:target:\s*.+\b\n){3,}"
return re.sub(expression, new_badges_text, content)
@click.command(
epilog="""
Examples:
1. Creates (by replacing) all existing badges in a gitlab project
(bob/bob.devtools):
$ bdt gitlab badges bob/bob.devtools
N.B.: This command also affects the README.rst file.
"""
)
@click.argument("package")
@click.option(
"-d",
"--dry-run/--no-dry-run",
default=False,
help="Only goes through the actions, but does not execute them "
"(combine with the verbosity flags - e.g. ``-vvv``) to enable "
"printing to help you understand what will be done",
)
@verbosity_option()
@bdt.raise_on_error
def badges(package, dry_run):
"""Creates stock badges for a project repository"""
# if we are in a dry-run mode, let's let it be known
if dry_run:
logger.warn("!!!! DRY RUN MODE !!!!")
logger.warn("Nothing is being changed at Gitlab")
if "/" not in package:
raise RuntimeError('PACKAGE should be specified as "group/name"')
gl = get_gitlab_instance()
# we lookup the gitlab package once
try:
use_package = gl.projects.get(package)
logger.info(
"Found gitlab project %s (id=%d)",
use_package.attributes["path_with_namespace"],
use_package.id,
)
badges = use_package.badges.list()
for badge in badges:
logger.info(
"Removing badge '%s' (id=%d) => '%s'",
badge.name,
badge.id,
badge.link_url,
)
if not dry_run: badge.delete()
# creates all stock badges, preserve positions
info = dict(zip(("group", "name"), package.split("/", 1)))
for position, badge in enumerate(PROJECT_BADGES):
data = dict([(k,v.format(**info)) for (k,v) in badge.items()])
data["position"] = position
logger.info(
"Creating badge '%s' => '%s'",
data["name"],
data["link_url"],
)
if not dry_run: use_package.badges.create(data)
# download and edit README to setup badges
readme_file = use_package.files.get(file_path="README.rst", ref="master")
readme_content = readme_file.decode().decode()
readme_content = _update_readme(readme_content, info)
# commit and push changes
logger.info("Changing README.rst badges...")
update_files_at_master(use_package, {"README.rst": readme_content},
"Updated badges section [ci skip]", dry_run)
logger.info("All done.")
except gitlab.GitlabGetError as e:
logger.warn("Gitlab access error - package %s does not exist?", package)
echo_warning("%s: unknown" % (package,))
......@@ -106,6 +106,7 @@ test:
- bdt gitlab process-pipelines --help
- bdt gitlab get-pipelines --help
- bdt gitlab graph --help
- bdt gitlab badges --help
- sphinx-build -aEW ${PREFIX}/share/doc/{{ name }}/doc sphinx
- if [ -n "${CI_PROJECT_DIR}" ]; then mv sphinx "${CI_PROJECT_DIR}/"; fi
......
......@@ -59,6 +59,7 @@ setup(
],
'bdt.gitlab.cli': [
'badges = bob.devtools.scripts.badges:badges',
'commitfile = bob.devtools.scripts.commitfile:commitfile',
'release = bob.devtools.scripts.release:release',
'changelog = bob.devtools.scripts.changelog:changelog',
......@@ -68,7 +69,7 @@ setup(
'visibility = bob.devtools.scripts.visibility:visibility',
'getpath = bob.devtools.scripts.getpath:getpath',
'process-pipelines = bob.devtools.scripts.pipelines:process_pipelines',
'get-pipelines- = bob.devtools.scripts.pipelines:get_pipelines',
'get-pipelines = bob.devtools.scripts.pipelines:get_pipelines',
'graph = bob.devtools.scripts.graph:graph',
'update-bob = bob.devtools.scripts.update_bob:update_bob',
],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment