monitor_repos.py 2.57 KB
Newer Older
1
import argparse
2
import json
3
import logging as log
4 5
import pickle
import requests
6
import yaml
7
from datetime import datetime
8 9
from git import Repo
from os import path
10
from pprint import pformat
11
from pymongo import MongoClient, DESCENDING
12
from stage_release import uri_from
13

14
def releases(repo):
15 16 17
    """
    Yield a list of all release candidates from the origin.
    """
18
    for ref in repo.refs:
19
        if ref.name.startswith('origin/rc/'):
20
            yield ref
21

22
def candidates_since(repo, time):
23 24 25 26
    """
    Given a repo yield a list of release candidate refs that have a
    commit on them after the passed in time
    """
27 28 29
    for rc in releases(repo):
        last_update = datetime.utcfromtimestamp(rc.commit.committed_date)
        if last_update > time:
30
            # New or updated RC
31
            yield rc
32

33
def stage_release(url, token, repo, rc):
34 35 36 37
    """
    Submit a job to stage a new release for the new rc of the repo.
    """
    # Setup the Jenkins params.
38 39 40 41 42 43 44 45 46 47 48
    params = []
    params.append({'name': "{}_REF".format(repo), 'value': True})
    params.append({'name': repo, 'value': rc.commit.hexsha})
    build_params = {'parameter': params}
    log.info("New rc found{}, staging new release.".format(rc.name))
    r = requests.post(url,
                      data={"token", token},
                      params={"json": json.dumps(build_params)})
    if r.status_code != 201:
        msg = "Failed to submit request with params: {}"
        raise Exception(msg.format(pformat(build_params)))
49 50 51 52

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Monitor git repos for new rc branches.")
53
    parser.add_argument('-c', '--config', required=True,
54
        help="Config file.")
55 56
    parser.add_argument('-p', '--pickle', default="data.pickle",
        help="Pickle of presistent data.")
57 58

    args = parser.parse_args()
59 60 61 62 63 64 65 66

    config = yaml.safe_load(open(args.config))

    if path.exists(args.pickle):
        data = pickle.load(open(args.pickle))
    else:
        data = {}

67
    # Presist the last time we made this check.
68 69 70 71 72 73 74 75 76 77 78 79 80
    if 'last_check' not in data:
        last_check = datetime.utcnow()
    else:
        last_check = data['last_check']

    data['last_check'] = datetime.utcnow()

    # Find plays that are affected by this repo.
    repos_with_changes = {}
    for repo in config['repos']:
        # Check for new rc candidates.
        for rc in candidates_since(Repo(repo), last_check):
            # Notify stage-release to build for the new repo.
81
            stage_release(config['abbey_url'], config['abbey_token'], repo, rc)
82 83

    pickle.dump(data, open(args.pickle, 'w'))