ci.py 2.88 KB
Newer Older
1 2 3 4 5 6 7
#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Tools to help CI-based builds and artifact deployment'''


import git
8
import distutils.version
9

10 11 12
from .log import get_logger
logger = get_logger(__name__)

13

14
def is_master(refname, tag, repodir):
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  '''Tells if we're on the master branch via ref_name or tag

  This function checks if the name of the branch being built is "master".  If a
  tag is set, then it checks if the tag is on the master branch.  If so, then
  also returns ``True``, otherwise, ``False``.

  Args:

    refname: The value of the environment variable ``CI_COMMIT_REF_NAME``
    tag: The value of the environment variable ``CI_COMMIT_TAG`` - (may be
      ``None``)

  Returns: a boolean, indicating we're building the master branch **or** that
  the tag being built was issued on the master branch.
  '''

  if tag is not None:
32
    repo = git.Repo(repodir)
33 34 35 36 37 38
    _tag = repo.tag('refs/tags/%s' % tag)
    return _tag.commit in repo.iter_commits(rev='master')

  return refname == 'master'


39
def is_stable(package, refname, tag, repodir):
40 41 42 43 44 45 46 47 48 49 50 51
  '''Determines if the package being published is stable

  This is done by checking if a tag was set for the package.  If that is the
  case, we still cross-check the tag is on the "master" branch.  If everything
  checks out, we return ``True``.  Else, ``False``.

  Args:

    package: Package name in the format "group/name"
    refname: The current value of the environment ``CI_COMMIT_REF_NAME``
    tag: The current value of the enviroment ``CI_COMMIT_TAG`` (may be
      ``None``)
52
    repodir: The directory that contains the clone of the git repository
53 54 55 56 57 58

  Returns: a boolean, indicating if the current build is for a stable release
  '''

  if tag is not None:
    logger.info('Project %s tag is "%s"', package, tag)
59 60
    parsed_tag = distutils.version.LooseVersion(tag[1:]).version  #remove 'v'
    is_prerelease = any([isinstance(k, str) for k in parsed_tag])
61

62
    if is_prerelease:
63 64 65
      logger.warn('Pre-release detected - not publishing to stable channels')
      return False

66
    if is_master(refname, tag, repodir):
67 68 69 70 71 72 73 74
      return True
    else:
      logger.warn('Tag %s in non-master branch will be ignored', tag)
      return False

  logger.info('No tag information available at build')
  logger.info('Considering this to be a pre-release build')
  return False
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95


def read_packages(filename):
  """
  Return a python list of tuples (repository, branch), given a file containing
  one package (and branch) per line.  Comments are excluded

  """
  # loads dirnames from order file (accepts # comments and empty lines)
  packages = []
  with open(filename, 'rt') as f:
    for line in f:
      line = line.partition('#')[0].strip()
      if line:
        if ',' in line:  #user specified a branch
          path, branch = [k.strip() for k in line.split(',', 1)]
          packages.append((path, branch))
        else:
          packages.append((line, 'master'))

  return packages