qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Cleber Rosa <crosa@redhat.com>
Cc: "Fam Zheng" <fam@euphon.net>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Thomas Huth" <thuth@redhat.com>,
	"Eduardo Habkost" <ehabkost@redhat.com>,
	"Erik Skultety" <eskultet@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Wainer Moschetta" <wmoschet@redhat.com>,
	qemu-devel@nongnu.org,
	"Wainer dos Santos Moschetta" <wainersm@redhat.com>,
	"Willian Rampazzo" <wrampazz@redhat.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	"Beraldo Leal" <bleal@redhat.com>
Subject: Re: [PATCH 4/5] GitLab Gating CI: introduce pipeline-status contrib script
Date: Thu, 18 Jun 2020 12:45:24 +0100	[thread overview]
Message-ID: <20200618114524.GA677518@redhat.com> (raw)
In-Reply-To: <20200312193616.438922-5-crosa@redhat.com>

On Thu, Mar 12, 2020 at 03:36:15PM -0400, Cleber Rosa wrote:
> This script is intended to be used right after a push to a branch.
> 
> By default, it will look for the pipeline associated with the commit
> that is the HEAD of the *local* staging branch.  It can be used as a
> one time check, or with the `--wait` option to wait until the pipeline
> completes.
> 
> If the pipeline is successful, then a merge of the staging branch into
> the master branch should be the next step.

On IRC yesterday we were discussing the current .gitlab-ci.yml status,
and how frustrating it is that every time we get it green, more code is
soon merged that turns it red again.

It feels like it should be an easy win to declare that the current GitLab
CI jobs are to be used as a gating tests for merges to master.

As & when custom runners come online, their jobs can simply augment the
existing jobs. IOW, use of GitLab CI for gating master shouldn't be
dependant on setup of custom runners which we've been waiting on for a
long term.

Peter indicated that his main requirement is a way to automate the task
of kicking off the CI job & getting its status. It seems like the script
in this patch should fullfill that requirement.

Assuming Peter (or whomever is going todo the merge) has a fork of

   https://gitlab.com/qemu-project/qemu

then they need to find the "ID" number of their fork. This is
visible at the top for the page for their fork eg mine:

   https://gitlab.com/berrange/qemu

reports:

   "Project ID: 18588805 "

Assuming the fork is configured as a git remote called "gitlab", then
to use GitLab CI as gating test, all that appears to be needed is

   $ git push gitlab
   $ ./contrib/ci/scripts/gitlab-pipeline-status --wait -p 18588805

If this is an acceptable level of automation for Peter, then can we
get this specific patch merged right now and make current GitLab CI
be gating for master.


With GitLab as gating, then we have further incentive to move all
the jobs currently on Travis CI and Shippable, over to use GitLab
too, and also use cirrus-run  to make Cirrus CI jobs be proxied
from GitLab.  All this can be in parallel with adding custom GitLab
runners for expanding testing coverage still further.

> Signed-off-by: Cleber Rosa <crosa@redhat.com>
> ---
>  contrib/ci/scripts/gitlab-pipeline-status | 148 ++++++++++++++++++++++
>  1 file changed, 148 insertions(+)
>  create mode 100755 contrib/ci/scripts/gitlab-pipeline-status
> 
> diff --git a/contrib/ci/scripts/gitlab-pipeline-status b/contrib/ci/scripts/gitlab-pipeline-status
> new file mode 100755
> index 0000000000..83d412daec
> --- /dev/null
> +++ b/contrib/ci/scripts/gitlab-pipeline-status
> @@ -0,0 +1,148 @@
> +#!/usr/bin/env python3
> +
> +"""
> +Checks the GitLab pipeline status for a given commit commit
> +"""
> +
> +# pylint: disable=C0103
> +
> +import argparse
> +import http.client
> +import json
> +import os
> +import subprocess
> +import time
> +import sys
> +
> +
> +def get_local_staging_branch_commit():
> +    """
> +    Returns the commit sha1 for the *local* branch named "staging"
> +    """
> +    result = subprocess.run(['git', 'rev-parse', 'staging'],
> +                            stdin=subprocess.DEVNULL,
> +                            stdout=subprocess.PIPE,
> +                            stderr=subprocess.DEVNULL,
> +                            cwd=os.path.dirname(__file__),
> +                            universal_newlines=True).stdout.strip()
> +    if result == 'staging':
> +        raise ValueError("There's no local staging branch")
> +    if len(result) != 40:
> +        raise ValueError("Branch staging HEAD doesn't look like a sha1")
> +    return result
> +
> +
> +def get_pipeline_status(project_id, commit_sha1):
> +    """
> +    Returns the JSON content of the pipeline status API response
> +    """
> +    url = '/api/v4/projects/{}/pipelines?sha={}'.format(project_id,
> +                                                        commit_sha1)
> +    connection = http.client.HTTPSConnection('gitlab.com')
> +    connection.request('GET', url=url)
> +    response = connection.getresponse()
> +    if response.code != http.HTTPStatus.OK:
> +        raise ValueError("Failed to receive a successful response")
> +    json_response = json.loads(response.read())
> +    # afaict, there should one one pipeline for the same project + commit
> +    # if this assumption is false, we can add further filters to the
> +    # url, such as username, and order_by.
> +    if not json_response:
> +        raise ValueError("No pipeline found")
> +    return json_response[0]
> +
> +
> +def wait_on_pipeline_success(timeout, interval,
> +                             project_id, commit_sha):
> +    """
> +    Waits for the pipeline to end up to the timeout given
> +    """
> +    start = time.time()
> +    while True:
> +        if time.time() >= (start + timeout):
> +            print("Waiting on the pipeline success timed out")
> +            return False
> +
> +        status = get_pipeline_status(project_id, commit_sha)
> +        if status['status'] == 'running':
> +            time.sleep(interval)
> +            print('running...')
> +            continue
> +
> +        if status['status'] == 'success':
> +            return True
> +
> +        msg = "Pipeline ended unsuccessfully, check: %s" % status['web_url']
> +        print(msg)
> +        return False
> +
> +
> +def main():
> +    """
> +    Script entry point
> +    """
> +    parser = argparse.ArgumentParser(
> +        prog='pipeline-status',
> +        description='check or wait on a pipeline status')
> +
> +    parser.add_argument('-t', '--timeout', type=int, default=7200,
> +                        help=('Amount of time (in seconds) to wait for the '
> +                              'pipeline to complete.  Defaults to '
> +                              '%(default)s'))
> +    parser.add_argument('-i', '--interval', type=int, default=60,
> +                        help=('Amount of time (in seconds) to wait between '
> +                              'checks of the pipeline status.  Defaults '
> +                              'to %(default)s'))
> +    parser.add_argument('-w', '--wait', action='store_true', default=False,
> +                        help=('Wether to wait, instead of checking only once '
> +                              'the status of a pipeline'))
> +    parser.add_argument('-p', '--project-id', type=int, default=11167699,
> +                        help=('The GitLab project ID. Defaults to the project '
> +                              'for https://gitlab.com/qemu-project/qemu, that '
> +                              'is, "%(default)s"'))
> +    try:
> +        default_commit = get_local_staging_branch_commit()
> +        commit_required = False
> +    except ValueError:
> +        default_commit = ''
> +        commit_required = True
> +    parser.add_argument('-c', '--commit', required=commit_required,
> +                        default=default_commit,
> +                        help=('Look for a pipeline associated with the given '
> +                              'commit.  If one is not explicitly given, the '
> +                              'commit associated with the local branch named '
> +                              '"staging" is used.  Default: %(default)s'))
> +    parser.add_argument('--verbose', action='store_true', default=False,
> +                        help=('A minimal verbosity level that prints the '
> +                              'overall result of the check/wait'))
> +
> +    args = parser.parse_args()
> +
> +    try:
> +        if args.wait:
> +            success = wait_on_pipeline_success(
> +                args.timeout,
> +                args.interval,
> +                args.project_id,
> +                args.commit)
> +        else:
> +            status = get_pipeline_status(args.project_id,
> +                                         args.commit)
> +            success = status['status'] == 'success'
> +    except Exception as error:      # pylint: disable=W0703
> +        success = False
> +        if args.verbose:
> +            print("ERROR: %s" % error.args[0])
> +
> +    if success:
> +        if args.verbose:
> +            print('success')
> +        sys.exit(0)
> +    else:
> +        if args.verbose:
> +            print('failure')
> +        sys.exit(1)
> +
> +
> +if __name__ == '__main__':
> +    main()
> -- 
> 2.24.1
> 
> 

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



  parent reply	other threads:[~2020-06-18 11:46 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-12 19:36 [PATCH 0/5] QEMU Gating CI Cleber Rosa
2020-03-12 19:36 ` [PATCH 1/5] tests/docker: add CentOS 8 Dockerfile Cleber Rosa
2020-03-13  8:46   ` Erik Skultety
2020-03-13 14:06     ` Alex Bennée
2020-03-13 14:59     ` Cleber Rosa
2020-03-13 14:07   ` Alex Bennée
2020-03-12 19:36 ` [PATCH 2/5] tests/docker: make "buildah bud" output similar to "docker build" Cleber Rosa
2020-03-14 15:26   ` Alex Bennée
2020-03-12 19:36 ` [PATCH 3/5] GitLab CI: avoid calling before_scripts on unintended jobs Cleber Rosa
2020-03-12 19:36 ` [PATCH 4/5] GitLab Gating CI: introduce pipeline-status contrib script Cleber Rosa
2020-03-13 13:56   ` Peter Maydell
2020-03-13 15:01     ` Cleber Rosa
2020-06-18 11:45   ` Daniel P. Berrangé [this message]
2020-06-22 14:20     ` Cleber Rosa
2020-06-23 17:59       ` Cleber Rosa
2020-07-02  8:55         ` Philippe Mathieu-Daudé
2020-03-12 19:36 ` [PATCH 5/5] GitLab Gating CI: initial set of jobs, documentation and scripts Cleber Rosa
2020-03-12 22:00 ` [PATCH 0/5] QEMU Gating CI Peter Maydell
2020-03-12 22:16   ` Cleber Rosa
2020-03-13 13:55     ` Peter Maydell
2020-03-13 14:58       ` Cleber Rosa
2020-03-16 11:57     ` Peter Maydell
2020-03-16 12:04       ` Cleber Rosa
2020-03-16 12:12         ` Peter Maydell
2020-03-16 12:26           ` Cleber Rosa
2020-03-16 12:30             ` Cleber Rosa
2020-03-16 14:57             ` Peter Maydell
2020-03-17  4:59               ` Cleber Rosa
2020-03-17  9:29                 ` Peter Maydell
2020-03-17 14:12                   ` Cleber Rosa
2020-03-17 14:24                     ` Peter Maydell
2020-03-19 16:33                       ` Markus Armbruster
2020-03-19 23:53                         ` Cleber Rosa
2020-04-21 12:53                         ` Peter Maydell
2020-04-23 17:04                           ` Cleber Rosa
2020-04-23 17:13                             ` Daniel P. Berrangé
2020-04-23 17:36                               ` Cleber Rosa
2020-04-23 17:50                                 ` Peter Maydell
2020-04-27  4:43                                   ` Cleber Rosa
2020-04-24  9:30                                 ` Daniel P. Berrangé
2020-04-24  9:39                                   ` Philippe Mathieu-Daudé
2020-04-27  5:36                                   ` Cleber Rosa
2020-04-23 21:28                               ` Philippe Mathieu-Daudé
2020-04-24  6:57                                 ` Erik Skultety
2020-04-27  5:24                                   ` Cleber Rosa
2020-04-27  8:51                                     ` Andrea Bolognani
2020-04-27  5:12                                 ` Cleber Rosa
2020-04-27 10:51                                   ` Philippe Mathieu-Daudé
2020-04-27 14:28                                     ` Cleber Rosa
2020-04-27 14:41                                       ` Philippe Mathieu-Daudé
2020-04-27 15:19                                         ` Cleber Rosa
2020-04-27 15:20                                         ` Daniel P. Berrangé
2020-06-16  1:27                             ` Cleber Rosa
2020-03-16 12:38 ` Daniel P. Berrangé
2020-03-16 12:46   ` Cleber Rosa
2020-03-16 13:11   ` Alex Bennée
2020-03-16 15:38     ` Aleksandar Markovic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200618114524.GA677518@redhat.com \
    --to=berrange@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=bleal@redhat.com \
    --cc=crosa@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=eskultet@redhat.com \
    --cc=fam@euphon.net \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    --cc=wainersm@redhat.com \
    --cc=wmoschet@redhat.com \
    --cc=wrampazz@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).