From be0b69971a4d8447d86f77b3d09b3820e8c9cb67 Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Mon, 3 Jul 2023 22:31:15 +0200 Subject: remove project.ci The weird magic going on in the ci-{boost,build} scripts is honestly too weird. With hindsight, it seems to me that it's much better to just build a project with the same command during a CI run as when developing locally. Plus, I haven't really used either Travis or AppVeyor in quite some time, so this code was mostly untested really. --- .github/workflows/ci_appveyor.yml | 53 ------------ .github/workflows/ci_github.yml | 52 ----------- .github/workflows/ci_travis.yml | 51 ----------- README.md | 23 ----- docs/ci.md | 69 --------------- project/ci/__init__.py | 0 project/ci/appveyor/__init__.py | 0 project/ci/appveyor/generator.py | 64 -------------- project/ci/boost.py | 75 ---------------- project/ci/build.py | 79 ----------------- project/ci/dirs.py | 176 -------------------------------------- pyproject.toml | 2 - 12 files changed, 644 deletions(-) delete mode 100644 .github/workflows/ci_appveyor.yml delete mode 100644 .github/workflows/ci_github.yml delete mode 100644 .github/workflows/ci_travis.yml delete mode 100644 docs/ci.md delete mode 100644 project/ci/__init__.py delete mode 100644 project/ci/appveyor/__init__.py delete mode 100644 project/ci/appveyor/generator.py delete mode 100644 project/ci/boost.py delete mode 100644 project/ci/build.py delete mode 100644 project/ci/dirs.py diff --git a/.github/workflows/ci_appveyor.yml b/.github/workflows/ci_appveyor.yml deleted file mode 100644 index 1bd0625..0000000 --- a/.github/workflows/ci_appveyor.yml +++ /dev/null @@ -1,53 +0,0 @@ -# This workflow pretends like it's being run on AppVeyor by setting the -# appropriate environment variables. - -name: CI (AppVeyor) - -on: - push: - paths: - - 'examples/**' - - 'project/**' - pull_request: - schedule: - # Weekly, at 5:30 AM on Saturday (somewhat randomly chosen). - - cron: '30 5 * * 6' - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - platform: [Win32, x64] - configuration: [Debug, Release] - runs-on: windows-2019 - name: '${{ matrix.platform }} / ${{ matrix.configuration }}' - defaults: - run: - shell: pwsh - env: - # https://www.appveyor.com/docs/environment-variables/ - APPVEYOR: 'True' - APPVEYOR_BUILD_FOLDER: '${{ github.workspace }}\examples\boost' - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - PLATFORM: '${{ matrix.platform }}' - CONFIGURATION: '${{ matrix.configuration }}' - BOOST_VERSION: 1.81.0 - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Cache Boost - uses: actions/cache@v3 - with: - path: '${{ github.workspace }}/examples/build/boost_*.tar.gz' - key: 'boost_${{ env.BOOST_VERSION }}' - - name: Build Boost - run: python -m project.ci.boost --hint AppVeyor -- --with-filesystem - - name: Build example project - run: python -m project.ci.build --hint AppVeyor --install - - name: Run example project - run: ./.ci/run_foo.ps1 (Join-Path $env:APPVEYOR_BUILD_FOLDER .. build install bin foo) diff --git a/.github/workflows/ci_github.yml b/.github/workflows/ci_github.yml deleted file mode 100644 index 96a52a2..0000000 --- a/.github/workflows/ci_github.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: CI (GitHub) - -on: - push: - paths: - - 'examples/**' - - 'project/**' - pull_request: - schedule: - # Weekly, at 5:30 AM on Saturday (somewhat randomly chosen). - - cron: '30 5 * * 6' - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - toolset: [gcc, clang, msvc] - configuration: [Debug, Release] - exclude: - - {os: ubuntu-latest, toolset: msvc} - - {os: windows-latest, toolset: gcc} - - {os: windows-latest, toolset: clang} - runs-on: '${{ matrix.os }}' - name: '${{ matrix.os }} / ${{ matrix.toolset }} / ${{ matrix.configuration }}' - defaults: - run: - shell: pwsh - env: - TOOLSET: '${{ matrix.toolset }}' - PLATFORM: x64 - CONFIGURATION: '${{ matrix.configuration }}' - BOOST_VERSION: 1.81.0 - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Cache Boost - uses: actions/cache@v3 - with: - path: '${{ runner.workspace }}/build/boost_*.tar.gz' - key: 'boost_${{ env.BOOST_VERSION }}' - - name: Build Boost - run: python -m project.ci.boost -- --with-filesystem - - name: Build example project - run: python -m project.ci.build --install --subdir examples/boost - - name: Run example project - run: ./.ci/run_foo.ps1 (Join-Path $env:GITHUB_WORKSPACE .. build install bin foo) diff --git a/.github/workflows/ci_travis.yml b/.github/workflows/ci_travis.yml deleted file mode 100644 index 256e61c..0000000 --- a/.github/workflows/ci_travis.yml +++ /dev/null @@ -1,51 +0,0 @@ -# This workflow pretends like it's being run on Travis by setting the -# appropriate environment variables. - -name: CI (Travis) - -on: - push: - paths: - - 'examples/**' - - 'project/**' - pull_request: - schedule: - # Weekly, at 5:30 AM on Saturday (somewhat randomly chosen). - - cron: '30 5 * * 6' - workflow_dispatch: - -jobs: - build: - strategy: - matrix: - configuration: [Debug, Release] - runs-on: ubuntu-latest - name: '${{ matrix.configuration }}' - defaults: - run: - shell: pwsh - env: - # https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - TRAVIS: 'true' - TRAVIS_BUILD_DIR: '${{ github.workspace }}/examples/boost' - PLATFORM: x64 - CONFIGURATION: '${{ matrix.configuration }}' - BOOST_VERSION: 1.81.0 - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - name: Cache Boost - uses: actions/cache@v3 - with: - path: '${{ github.workspace }}/examples/build/boost_*.tar.gz' - key: 'boost_${{ env.BOOST_VERSION }}' - - name: Build Boost - run: python -m project.ci.boost --hint Travis -- --with-filesystem - - name: Build example project - run: python -m project.ci.build --hint Travis --install - - name: Run example project - run: ./.ci/run_foo.ps1 (Join-Path $env:TRAVIS_BUILD_DIR .. build install bin foo) diff --git a/README.md b/README.md index 9786fd9..2738964 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,6 @@ Installation | boost-download | `python3 -m project.boost.download` | boost-build | `python3 -m project.boost.build` | project-build | `python3 -m project.build` - | ci-boost | `python3 -m project.ci.boost` - | ci-build | `python3 -m project.ci.build` Toolsets -------- @@ -102,27 +100,6 @@ Windows-specific macros, strips debug symbols in release builds, etc.). Everything is optional (use the `CC_*` CMake options to opt out). -### CI - -Utility scripts `ci-boost` and `ci-build` allow building Boost and CMake -projects on multiple CI systems. -They work by calling the generic scripts from above, auto-filling some -parameters from environment variables. - -| | Travis | AppVeyor | GitHub Actions -| ----------------- | ------------------------------------ | ------------------------------------------ | -------------- -| `--toolset` | `$TOOLSET` | `%TOOLSET%` | `$TOOLSET` -| `--platform` | `$PLATFORM` | `%PLATFORM%` | `$PLATFORM` -| `--configuration` | `$CONFIGURATION` | `%CONFIGURATION%` | `$CONFIGURATION` -| Boost version | `$BOOST_VERSION` | `%BOOST_VERSION%` | `$BOOST_VERSION` -| Boost path | `$TRAVIS_BUILD_DIR/../build/boost` | `%APPVEYOR_BUILD_FOLDER%\..\build\boost` | `$GITHUB_WORKSPACE/../build/boost` -| Build path | `$TRAVIS_BUILD_DIR/../build/cmake` | `%APPVEYOR_BUILD_FOLDER%\..\build\cmake` | `$GITHUB_WORKSPACE/../build/cmake` -| Install path | `$TRAVIS_BUILD_DIR/../build/install` | `%APPVEYOR_BUILD_FOLDER%\..\build\install` | `$GITHUB_WORKSPACE/../build/install` - - -For an example of how to integrate `ci-boost` and `ci-build` into a CI -workflow, see [docs/ci.md](docs/ci.md). - Tools ----- diff --git a/docs/ci.md b/docs/ci.md deleted file mode 100644 index 6f31b6f..0000000 --- a/docs/ci.md +++ /dev/null @@ -1,69 +0,0 @@ -`ci-boost` and `ci-build` are thin wrappers around `boost-download`/`boost-build` -and `project-build` accordingly. They work by reading environment variables -and passing their values as command line parameters to the more generic scripts. -This facilitates matrix-building the project without too much fuss. - -For example, the following Travis workflow: - -``` -language: cpp -os: linux -dist: focal - -env: - global: - BOOST_VERSION: 1.65.0 - jobs: - - CONFIGURATION=Debug PLATFORM=x64 - - CONFIGURATION=Release PLATFORM=x64 - -before_script: ci-boost -- --with-filesystem -script: ci-build --install -``` - -is roughly equivalent to running - -``` -boost-download --cache "$TRAVIS_BUILD_DIR/../build" -- 1.65.0 -mv -- \ - "$TRAVIS_BUILD_DIR/../build/boost_1_65_0" \ - "$TRAVIS_BUILD_DIR/../build/boost" - -boost-build \ - --platform x64 \ - --configuration Debug Release \ - -- \ - "$TRAVIS_BUILD_DIR/../build/boost" \ - --with-filesystem - -for configuration in Debug Release; do - project-build \ - --platform x64 \ - --configuration "$configuration" \ - --boost "$TRAVIS_BUILD_DIR/../build/boost" \ - --build "$TRAVIS_BUILD_DIR/../build/cmake" \ - --install "$TRAVIS_BUILD_DIR/../build/install" \ - -- \ - "$TRAVIS_BUILD_DIR" \ - TMP -done -``` - -Caching -------- - -`ci-boost` downloads the Boost distribution archive to the "../build/" -directory (resolved relatively to the root checkout directory). You can cache -the archive like this (using GitHub Actions as an example): - -``` -- name: Cache Boost - uses: actions/cache@v2 - with: - path: '${{ runner.workspace }}/build/boost_*.tar.gz' - key: 'boost_${{ env.BOOST_VERSION }}' - -- name: Build Boost - # This won't re-download the archive unnecessarily. - run: ci-boost -- --with-filesystem -``` diff --git a/project/ci/__init__.py b/project/ci/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/project/ci/appveyor/__init__.py b/project/ci/appveyor/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/project/ci/appveyor/generator.py b/project/ci/appveyor/generator.py deleted file mode 100644 index 454bd4a..0000000 --- a/project/ci/appveyor/generator.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2020 Egor Tensin -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -from enum import Enum - -from project.utils import env - - -class Image(Enum): - VS_2013 = 'Visual Studio 2013' - VS_2015 = 'Visual Studio 2015' - VS_2017 = 'Visual Studio 2017' - VS_2019 = 'Visual Studio 2019' - - def __str__(self): - return str(self.value) - - @staticmethod - def parse(s): - try: - return Image(s) - except ValueError as e: - raise ValueError(f'unsupported AppVeyor image: {s}') from e - - @staticmethod - def get(): - return Image.parse(env('APPVEYOR_BUILD_WORKER_IMAGE')) - - def get_prebuilt_boost_dir(self): - # As of 2021-01-25, these are the latest pre-built Boost distributions: - # https://www.appveyor.com/docs/windows-images-software/#boost - if self is Image.VS_2013: - return 'C:\\Libraries\\boost_1_58_0' - if self is Image.VS_2015: - return 'C:\\Libraries\\boost_1_69_0' - if self is Image.VS_2017: - return 'C:\\Libraries\\boost_1_69_0' - if self is Image.VS_2019: - return 'C:\\Libraries\\boost_1_73_0' - raise NotImplementedError(f'unsupported AppVeyor image: {self}') - - -class Generator(Enum): - VS_2013 = 'Visual Studio 12 2013' - VS_2015 = 'Visual Studio 14 2015' - VS_2017 = 'Visual Studio 15 2017' - VS_2019 = 'Visual Studio 16 2019' - - def __str__(self): - return str(self.value) - - @staticmethod - def from_image(image): - if image is Image.VS_2013: - return Generator.VS_2013 - if image is Image.VS_2015: - return Generator.VS_2015 - if image is Image.VS_2017: - return Generator.VS_2017 - if image is Image.VS_2019: - return Generator.VS_2019 - raise RuntimeError(f"don't know which generator to use for image: {image}") diff --git a/project/ci/boost.py b/project/ci/boost.py deleted file mode 100644 index 65f4da0..0000000 --- a/project/ci/boost.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2020 Egor Tensin -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -import argparse -import sys - -from project.boost.build import BuildParameters, build -from project.boost.download import Download, download -from project.ci.dirs import Dirs -from project.linkage import Linkage -from project.utils import setup_logging -import project.version - - -def _parse_args(argv=None): - if argv is None: - argv = sys.argv[1:] - - parser = argparse.ArgumentParser( - description=Dirs.get_boost_help(), - formatter_class=argparse.RawDescriptionHelpFormatter) - - project.version.add_to_arg_parser(parser) - - parser.add_argument('--link', metavar='LINKAGE', - nargs='*', type=Linkage.parse, - help='how the libraries are linked') - parser.add_argument('--runtime-link', metavar='LINKAGE', - type=Linkage.parse, - help='how the libraries link to the runtime') - - # The hint parameter is basically a workaround for when this is run on a - # CI, _but_ testing another CI is desired. This shouldn't be used in a - # real CI workflow. - parser.add_argument('--hint', metavar='CI_NAME', - choices=Dirs.all_ci_names(), - help=argparse.SUPPRESS) - - parser.add_argument('b2_args', metavar='B2_ARG', - nargs='*', default=[], - help='additional b2 arguments, to be passed verbatim') - - return parser.parse_args(argv) - - -def build_ci(dirs, argv=None): - args = _parse_args(argv) - with setup_logging(): - if dirs is None: - dirs = Dirs.detect(args.hint) - - version = dirs.get_boost_version() - build_dir = dirs.get_build_dir() - boost_dir = dirs.get_boost_dir() - params = Download(version, cache_dir=build_dir, dest_path=boost_dir) - download(params) - - params = BuildParameters(boost_dir, - platforms=(dirs.get_platform(),), - configurations=(dirs.get_configuration(),), - link=args.link, - runtime_link=args.runtime_link, - toolset_version=dirs.get_toolset(), - b2_args=args.b2_args) - build(params) - - -def main(argv=None): - build_ci(None, argv) - - -if __name__ == '__main__': - main() diff --git a/project/ci/build.py b/project/ci/build.py deleted file mode 100644 index 24fe34c..0000000 --- a/project/ci/build.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2020 Egor Tensin -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -import argparse -import os.path -import sys - -from project.ci.dirs import Dirs -from project.build import BuildParameters, build -from project.utils import setup_logging -import project.version - - -def _parse_args(argv=None): - if argv is None: - argv = sys.argv[1:] - - parser = argparse.ArgumentParser( - description=Dirs.get_cmake_help(), - formatter_class=argparse.RawDescriptionHelpFormatter) - - project.version.add_to_arg_parser(parser) - - # The hint parameter is basically a workaround for when this is run on a - # CI, _but_ testing another CI is desired. This shouldn't be used in a - # real CI workflow. - parser.add_argument('--hint', metavar='CI_NAME', - choices=Dirs.all_ci_names(), - help=argparse.SUPPRESS) - parser.add_argument('--install', action='store_true', - help='install the project') - parser.add_argument('--boost', metavar='DIR', dest='boost_dir', - help='set Boost directory path') - parser.add_argument('--subdir', metavar='DIR', - help='relative project directory path') - parser.add_argument('cmake_args', nargs='*', metavar='CMAKE_ARG', default=[], - help='additional CMake arguments, to be passed verbatim') - return parser.parse_args(argv) - - -def build_ci(dirs, argv=None): - args = _parse_args(argv) - with setup_logging(): - if dirs is None: - dirs = Dirs.detect(args.hint) - - src_dir = dirs.get_src_dir() - if args.subdir: - src_dir = os.path.join(src_dir, args.subdir) - install_dir = dirs.get_install_dir() if args.install else None - - boost_dir = args.boost_dir - if not boost_dir: - # If we've built Boost using project.ci.boost already, use that. - # Otherwise, try to use the latest pre-built Boost provided by the CI - # system. - boost_dir = dirs.get_boost_dir() - if not os.path.isdir(boost_dir): - boost_dir = dirs.get_prebuilt_boost_dir() - - params = BuildParameters(src_dir, - build_dir=dirs.get_cmake_dir(), - install_dir=install_dir, - platform=dirs.get_platform(), - configuration=dirs.get_configuration(), - boost_dir=boost_dir, - toolset_version=dirs.get_toolset(), - cmake_args=dirs.get_cmake_args() + args.cmake_args) - build(params) - - -def main(argv=None): - build_ci(None, argv) - - -if __name__ == '__main__': - main() diff --git a/project/ci/dirs.py b/project/ci/dirs.py deleted file mode 100644 index 6de9509..0000000 --- a/project/ci/dirs.py +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (c) 2020 Egor Tensin -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -import abc -import os -import os.path - -from project.boost.version import Version -from project.ci.appveyor.generator import Generator, Image -from project.configuration import Configuration -from project.platform import Platform -from project.toolset import ToolsetVersion -from project.utils import env - - -class Dirs(abc.ABC): - @staticmethod - def detect(hint=None): - matching = [ci for ci in _ALL_CI_LIST if ci.this_one()] - if len(matching) == 0: - raise RuntimeError('no CI system was detected') - if len(matching) == 1: - return matching[0] - # The hint parameter is basically a workaround for when this is run - # on a CI, _but_ testing another CI is desired. - if hint is not None: - for ci in matching: - if ci.get_name() == hint: - return ci - names = ', '.join(ci.get_name() for ci in matching) - raise RuntimeError(f"can't select a single CI system out of these: {names}") - - def __init__(self): - pass - - @staticmethod - @abc.abstractmethod - def get_name(): - pass - - @abc.abstractmethod - def this_one(self): - pass - - @staticmethod - def get_toolset(): - if 'TOOLSET' in os.environ: - return ToolsetVersion.parse(os.environ['TOOLSET']) - return None - - @staticmethod - def get_platform(): - return Platform.parse(env('PLATFORM')) - - @staticmethod - def get_configuration(): - return Configuration.parse(env('CONFIGURATION')) - - @abc.abstractmethod - def get_src_dir(self): - pass - - def get_build_dir(self): - return os.path.join(os.path.dirname(self.get_src_dir()), 'build') - - @abc.abstractmethod - def get_prebuilt_boost_dir(self): - pass - - @staticmethod - def get_boost_version(): - return Version.from_string(env('BOOST_VERSION')) - - def get_boost_dir(self): - return os.path.join(self.get_build_dir(), 'boost') - - def get_cmake_dir(self): - return os.path.join(self.get_build_dir(), 'cmake') - - def get_install_dir(self): - return os.path.join(self.get_build_dir(), 'install') - - @abc.abstractmethod - def get_cmake_args(self): - pass - - @staticmethod - def all_ci_names(): - return [ci.get_name() for ci in _ALL_CI_LIST] - - @staticmethod - def join_ci_names(): - return ', '.join(Dirs.all_ci_names()) - - @staticmethod - def get_boost_help(): - return f'''Download & build Boost during a CI run. - -This is similar to running both project.boost.download & project.boost.build, -but auto-fills some parameters from environment variables. - -The supported CI systems are: {Dirs.join_ci_names()}. -''' - - @staticmethod - def get_cmake_help(): - return f'''Build a CMake project during a CI run. - -This is similar to running project.build, but auto-fills some parameters -from environment variables. - -The supported CI systems are: {Dirs.join_ci_names()}. -''' - - -class Travis(Dirs): - @staticmethod - def get_name(): - return 'Travis' - - def this_one(self): - return 'TRAVIS' in os.environ - - def get_src_dir(self): - return env('TRAVIS_BUILD_DIR') - - def get_prebuilt_boost_dir(self): - # Travis doesn't have pre-built Boost (available for installation from - # the official Ubuntu repositories though). - return None - - def get_cmake_args(self): - return [] - - -class AppVeyor(Dirs): - @staticmethod - def get_name(): - return 'AppVeyor' - - def this_one(self): - return 'APPVEYOR' in os.environ - - def get_src_dir(self): - return env('APPVEYOR_BUILD_FOLDER') - - def get_prebuilt_boost_dir(self): - return Image.get().get_prebuilt_boost_dir() - - def get_cmake_args(self): - return ['-G', str(Generator.from_image(Image.get()))] - - -class GitHub(Dirs): - @staticmethod - def get_name(): - return 'GitHub Actions' - - def this_one(self): - return 'GITHUB_ACTIONS' in os.environ - - def get_src_dir(self): - return env('GITHUB_WORKSPACE') - - def get_prebuilt_boost_dir(self): - # Used to have 1.72.0 pre-built binaries, but not anymore: - # https://github.com/actions/virtual-environments/issues/2667 - return None - - def get_cmake_args(self): - return [] - - -_ALL_CI_LIST = (Travis(), AppVeyor(), GitHub()) diff --git a/pyproject.toml b/pyproject.toml index c6797f5..80f5b5b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,6 @@ classifiers = [ [project.scripts] boost-build = "project.boost.build:_main" boost-download = "project.boost.download:_main" -ci-boost = "project.ci.boost:main" -ci-build = "project.ci.build:main" project-build = "project.build:main" [tool.setuptools] -- cgit v1.2.3