From ac90f2b9ac7479006432c97a90df6c75e6eafec9 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Sat, 29 Aug 2020 21:29:01 +0100 Subject: [PATCH] Add CI example test script --- bin/run_example_ci_configs.py | 133 ++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100755 bin/run_example_ci_configs.py diff --git a/bin/run_example_ci_configs.py b/bin/run_example_ci_configs.py new file mode 100755 index 00000000..d7b099e6 --- /dev/null +++ b/bin/run_example_ci_configs.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 + +import os +from pathlib import Path +import shutil +from subprocess import run +import sys +import textwrap +import time +import click +from collections import namedtuple +from urllib.parse import quote + + +def shell(cmd, **kwargs): + return run([cmd], shell=True, **kwargs) + + +def git_repo_has_changes(): + unstaged_changes = shell('git diff-index --quiet HEAD --').returncode != 0 + staged_changes = shell('git diff-index --quiet --cached HEAD --').returncode != 0 + return unstaged_changes or staged_changes + + +def generate_basic_project(path): + sys.path.insert(0, '') + from test.test_projects.c import new_c_project + + project = new_c_project() + project.generate(path) + + +CIService = namedtuple('CIService', 'name src_config_path dst_config_path badge_md') +services = [ + CIService( + name='appveyor', + src_config_path='examples/appveyor-minimal.yml', + dst_config_path='appveyor.yml', + badge_md='[![Build status](https://ci.appveyor.com/api/projects/status/wbsgxshp05tt1tif/branch/{branch}?svg=true)](https://ci.appveyor.com/project/joerick/cibuildwheel/branch/{branch})', + ), + CIService( + name='azure-pipelines', + src_config_path='examples/azure-pipelines-minimal.yml', + dst_config_path='azure-pipelines.yml', + badge_md='[![Build Status](https://dev.azure.com/joerick0429/cibuildwheel/_apis/build/status/joerick.cibuildwheel?branchName={branch})](https://dev.azure.com/joerick0429/cibuildwheel/_build/latest?definitionId=2&branchName={branch})', + ), + CIService( + name='circle-ci', + src_config_path='examples/circleci-minimal.yml', + dst_config_path='.circleci/config.yml', + badge_md='[![CircleCI](https://circleci.com/gh/joerick/cibuildwheel/tree/{branch_escaped}.svg?style=svg)](https://circleci.com/gh/joerick/cibuildwheel/tree/{branch})', + ), + CIService( + name='github', + src_config_path='examples/github-minimal.yml', + dst_config_path='.github/workflows/example.yml', + badge_md='![Build](https://github.com/joerick/cibuildwheel/workflows/Build/badge.svg?branch={branch})', + ), + CIService( + name='travis-ci', + src_config_path='examples/travis-ci-minimal.yml', + dst_config_path='.travis.yml', + badge_md='[![Build Status](https://travis-ci.org/joerick/cibuildwheel.svg?branch={branch})](https://travis-ci.org/joerick/cibuildwheel)', + ), + # CIService( + # name='gitlab', src_config_path='gitlab-minimal.yml', dst_config_path='.gitlab-ci.yml'), +] + + +@click.command() +def run_example_ci_configs(): + if git_repo_has_changes(): + print('Your git repo has uncommitted changes. Commit or stash before continuing.') + exit(1) + + previous_branch = shell('git rev-parse --abbrev-ref HEAD', + check=True, + capture_output=True, + encoding='utf8').stdout.strip() + + timestamp = time.strftime('%Y-%m-%dT%H-%M-%S', time.gmtime()) + branch_name = f'example-config-test---{previous_branch}-{timestamp}' + + try: + shell(f'git checkout --orphan {branch_name}', check=True) + + example_project = Path('example_root') + generate_basic_project(example_project) + + for service in services: + src_config_file = Path(service.src_config_path) + dst_config_file = example_project / service.dst_config_path + + dst_config_file.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(src_config_file, dst_config_file) + + run(['git', 'add', example_project], check=True) + run(['git', 'commit', '-m', textwrap.dedent(f''' + Test example minimal configs. + + Testing files: {[s.src_config_path for s in services]} + Generated from branch: {previous_branch} + Time: {timestamp} + ''')], check=True) + shell(f'git subtree --prefix={example_project} push origin {branch_name}', check=True) + + print('---') + print() + print('**Examples test run**') + print() + print(f'Branch: [{branch_name}](https://github.com/joerick/cibuildwheel/tree/{branch_name})') + print() + print('| Service | Config | Status |') + print('|---|---|---|') + for service in services: + badge = service.badge_md.format(branch=branch_name, branch_escaped=quote(branch_name, safe='')) + print(f'| {service.name} | {service.src_config_path} | {badge} |') + print() + print(f'Generated by `bin/run_example_ci_config.py`') + print() + print('---') + finally: + # remove any local changes + shutil.rmtree(example_project, ignore_errors=True) + shell('git checkout -- .') + shell(f'git checkout {previous_branch}', check=True) + shell(f'git branch -D --force {branch_name}', check=True) + + +if __name__ == '__main__': + os.chdir(os.path.dirname(__file__)) + os.chdir('..') + run_example_ci_configs(standalone_mode=True)