qemu/.gitlab-ci.d/check-dco.py
<<
>>
Prefs
   1#!/usr/bin/env python3
   2#
   3# check-dco.py: validate all commits are signed off
   4#
   5# Copyright (C) 2020 Red Hat, Inc.
   6#
   7# SPDX-License-Identifier: GPL-2.0-or-later
   8
   9import os
  10import os.path
  11import sys
  12import subprocess
  13
  14namespace = "qemu-project"
  15if len(sys.argv) >= 2:
  16    namespace = sys.argv[1]
  17
  18cwd = os.getcwd()
  19reponame = os.path.basename(cwd)
  20repourl = "https://gitlab.com/%s/%s.git" % (namespace, reponame)
  21
  22subprocess.check_call(["git", "remote", "add", "check-dco", repourl])
  23subprocess.check_call(["git", "fetch", "check-dco", "master"],
  24                      stdout=subprocess.DEVNULL,
  25                      stderr=subprocess.DEVNULL)
  26
  27ancestor = subprocess.check_output(["git", "merge-base",
  28                                    "check-dco/master", "HEAD"],
  29                                   universal_newlines=True)
  30
  31ancestor = ancestor.strip()
  32
  33subprocess.check_call(["git", "remote", "rm", "check-dco"])
  34
  35errors = False
  36
  37print("\nChecking for 'Signed-off-by: NAME <EMAIL>' " +
  38      "on all commits since %s...\n" % ancestor)
  39
  40log = subprocess.check_output(["git", "log", "--format=%H %s",
  41                               ancestor + "..."],
  42                              universal_newlines=True)
  43
  44if log == "":
  45    commits = []
  46else:
  47    commits = [[c[0:40], c[41:]] for c in log.strip().split("\n")]
  48
  49for sha, subject in commits:
  50
  51    msg = subprocess.check_output(["git", "show", "-s", sha],
  52                                  universal_newlines=True)
  53    lines = msg.strip().split("\n")
  54
  55    print("🔍 %s %s" % (sha, subject))
  56    sob = False
  57    for line in lines:
  58        if "Signed-off-by:" in line:
  59            sob = True
  60            if "localhost" in line:
  61                print("    ❌ FAIL: bad email in %s" % line)
  62                errors = True
  63
  64    if not sob:
  65        print("    ❌ FAIL missing Signed-off-by tag")
  66        errors = True
  67
  68if errors:
  69    print("""
  70
  71❌ ERROR: One or more commits are missing a valid Signed-off-By tag.
  72
  73
  74This project requires all contributors to assert that their contributions
  75are provided in compliance with the terms of the Developer's Certificate
  76of Origin 1.1 (DCO):
  77
  78  https://developercertificate.org/
  79
  80To indicate acceptance of the DCO every commit must have a tag
  81
  82  Signed-off-by: REAL NAME <EMAIL>
  83
  84This can be achieved by passing the "-s" flag to the "git commit" command.
  85
  86To bulk update all commits on current branch "git rebase" can be used:
  87
  88  git rebase -i master -x 'git commit --amend --no-edit -s'
  89
  90""")
  91
  92    sys.exit(1)
  93
  94sys.exit(0)
  95