Files
cibuildwheel/bin/run_example_ci_configs.py
T

169 lines
5.9 KiB
Python
Raw Normal View History

2020-08-29 21:29:01 +01:00
#!/usr/bin/env python3
2021-04-25 03:45:27 -04:00
from __future__ import annotations
2020-08-29 21:29:01 +01:00
import os
import shutil
import sys
import textwrap
import time
from collections import namedtuple
2021-01-06 13:50:58 -05:00
from glob import glob
from pathlib import Path
from subprocess import run
2020-08-29 21:29:01 +01:00
from urllib.parse import quote
2021-01-06 13:50:58 -05:00
import click
2020-08-29 21:29:01 +01:00
def shell(cmd, **kwargs):
return run([cmd], shell=True, **kwargs)
def git_repo_has_changes():
2021-05-03 11:45:43 -04:00
unstaged_changes = shell("git diff-index --quiet HEAD --").returncode != 0
staged_changes = shell("git diff-index --quiet --cached HEAD --").returncode != 0
2020-08-29 21:29:01 +01:00
return unstaged_changes or staged_changes
def generate_basic_project(path):
2021-05-03 11:45:43 -04:00
sys.path.insert(0, "")
2020-08-29 21:29:01 +01:00
from test.test_projects.c import new_c_project
project = new_c_project()
project.generate(path)
2021-05-03 11:45:43 -04:00
CIService = namedtuple("CIService", "name dst_config_path badge_md")
2020-08-29 21:29:01 +01:00
services = [
CIService(
2021-05-03 11:45:43 -04:00
name="appveyor",
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/pypa/cibuildwheel/branch/{branch})",
2020-08-29 21:29:01 +01:00
),
CIService(
2021-05-03 11:45:43 -04:00
name="azure-pipelines",
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})",
2020-08-29 21:29:01 +01:00
),
CIService(
2021-05-03 11:45:43 -04:00
name="circleci",
dst_config_path=".circleci/config.yml",
badge_md="[![CircleCI](https://circleci.com/gh/pypa/cibuildwheel/tree/{branch_escaped}.svg?style=svg)](https://circleci.com/gh/pypa/cibuildwheel/tree/{branch})",
2020-08-29 21:29:01 +01:00
),
CIService(
2021-05-03 11:45:43 -04:00
name="github",
dst_config_path=".github/workflows/example.yml",
badge_md="[![Build](https://github.com/pypa/cibuildwheel/workflows/Build/badge.svg?branch={branch})](https://github.com/pypa/cibuildwheel/actions)",
2020-08-29 21:29:01 +01:00
),
CIService(
2021-05-03 11:45:43 -04:00
name="travis-ci",
dst_config_path=".travis.yml",
badge_md="[![Build Status](https://travis-ci.org/pypa/cibuildwheel.svg?branch={branch})](https://travis-ci.org/pypa/cibuildwheel)",
2020-08-29 21:29:01 +01:00
),
2020-08-31 19:32:45 +01:00
CIService(
2021-05-03 11:45:43 -04:00
name="gitlab",
dst_config_path=".gitlab-ci.yml",
badge_md="[![Gitlab](https://gitlab.com/pypa/cibuildwheel/badges/{branch}/pipeline.svg)](https://gitlab.com/pypa/cibuildwheel/-/commits/{branch})",
2020-08-31 19:32:45 +01:00
),
2020-08-29 21:29:01 +01:00
]
def ci_service_for_config_file(config_file):
2021-05-03 11:45:43 -04:00
service_name = Path(config_file).name.rsplit("-", 1)[0]
2020-12-31 14:56:19 +00:00
for service in services:
2020-12-31 14:56:19 +00:00
if service.name == service_name:
return service
2020-12-31 14:56:19 +00:00
2021-05-03 11:45:43 -04:00
raise ValueError(f"unknown ci service for config file {config_file}")
2020-08-29 21:29:01 +01:00
@click.command()
2021-05-03 11:45:43 -04:00
@click.argument("config_files", nargs=-1, type=click.Path())
def run_example_ci_configs(config_files=None):
2021-05-03 11:45:43 -04:00
"""
2021-04-30 17:56:34 -04:00
Test the example configs. If no files are specified, will test
examples/*-minimal.yml
2021-05-03 11:45:43 -04:00
"""
if len(config_files) == 0:
2021-05-03 11:45:43 -04:00
config_files = glob("examples/*-minimal.yml")
# check each CI service has at most 1 config file
configs_by_service = {}
for config_file in config_files:
service = ci_service_for_config_file(config_file)
if service.name in configs_by_service:
2021-05-03 11:45:43 -04:00
raise Exception("You cannot specify more than one config per CI service")
configs_by_service[service.name] = config_file
2020-08-29 21:29:01 +01:00
if git_repo_has_changes():
2021-05-03 11:45:43 -04:00
print("Your git repo has uncommitted changes. Commit or stash before continuing.")
2021-01-17 14:13:26 -05:00
sys.exit(1)
2020-08-29 21:29:01 +01:00
2021-04-30 17:56:34 -04:00
previous_branch = shell(
2021-05-03 11:45:43 -04:00
"git rev-parse --abbrev-ref HEAD", check=True, capture_output=True, encoding="utf8"
2021-04-30 17:56:34 -04:00
).stdout.strip()
2020-08-29 21:29:01 +01:00
2021-05-03 11:45:43 -04:00
timestamp = time.strftime("%Y-%m-%dT%H-%M-%S", time.gmtime())
branch_name = f"example-config-test---{previous_branch}-{timestamp}"
2020-08-29 21:29:01 +01:00
try:
2021-05-03 11:45:43 -04:00
shell(f"git checkout --orphan {branch_name}", check=True)
2020-08-29 21:29:01 +01:00
2021-05-03 11:45:43 -04:00
example_project = Path("example_root")
2020-08-29 21:29:01 +01:00
generate_basic_project(example_project)
for config_file in config_files:
service = ci_service_for_config_file(config_file)
src_config_file = Path(config_file)
2020-08-29 21:29:01 +01:00
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)
2021-05-03 11:45:43 -04:00
run(["git", "add", example_project], check=True)
2021-04-30 17:56:34 -04:00
message = textwrap.dedent(
2021-05-03 11:45:43 -04:00
f"""\
2020-08-31 18:59:32 +01:00
Test example minimal configs
2020-08-29 21:29:01 +01:00
Testing files: {config_files}
2020-08-29 21:29:01 +01:00
Generated from branch: {previous_branch}
Time: {timestamp}
2021-05-03 11:45:43 -04:00
"""
2021-04-30 17:56:34 -04:00
)
2021-05-03 11:45:43 -04:00
run(["git", "commit", "--no-verify", "--message", message], check=True)
shell(f"git subtree --prefix={example_project} push origin {branch_name}", check=True)
2020-08-29 21:29:01 +01:00
2021-05-03 11:45:43 -04:00
print("---")
2020-08-29 21:29:01 +01:00
print()
2021-05-03 11:45:43 -04:00
print("> **Examples test run**")
print("> ")
print(f"> Branch: [{branch_name}](https://github.com/pypa/cibuildwheel/tree/{branch_name})")
2021-05-03 11:45:43 -04:00
print("> ")
print("> | Service | Config | Status |")
print("> |---|---|---|")
for config_file in config_files:
service = ci_service_for_config_file(config_file)
2021-04-30 17:56:34 -04:00
badge = service.badge_md.format(
2021-05-03 11:45:43 -04:00
branch=branch_name, branch_escaped=quote(branch_name, safe="")
2021-04-30 17:56:34 -04:00
)
2021-05-03 11:45:43 -04:00
print(f"> | {service.name} | `{config_file}` | {badge} |")
print("> ")
print("> Generated by `bin/run_example_ci_config.py`")
2020-08-29 21:29:01 +01:00
print()
2021-05-03 11:45:43 -04:00
print("---")
2020-08-29 21:29:01 +01:00
finally:
# remove any local changes
shutil.rmtree(example_project, ignore_errors=True)
2021-05-03 11:45:43 -04:00
shell("git checkout -- .")
shell(f"git checkout {previous_branch}", check=True)
shell(f"git branch -D --force {branch_name}", check=True)
2020-08-29 21:29:01 +01:00
2021-05-03 11:45:43 -04:00
if __name__ == "__main__":
2020-08-29 21:29:01 +01:00
os.chdir(os.path.dirname(__file__))
2021-05-03 11:45:43 -04:00
os.chdir("..")
2020-08-29 21:29:01 +01:00
run_example_ci_configs(standalone_mode=True)