diff --git a/.github/workflows/dev-nightly-tests.yml b/.github/workflows/dev-nightly-tests.yml index a373b0e5..55befdb5 100644 --- a/.github/workflows/dev-nightly-tests.yml +++ b/.github/workflows/dev-nightly-tests.yml @@ -26,30 +26,22 @@ jobs: with: ref: dev - - name: Install build tools (Linux) - if: runner.os == 'Linux' - shell: bash - run: | - sudo apt update && sudo apt install -y automake libtool autogen mcpp - sudo apt install -y openjdk-21-jdk - sudo apt install -y gcc-multilib - sudo apt install -y gcc-i686-linux-gnu - sudo apt install -y gcc-aarch64-linux-gnu - - - name: Install Rust Toolchain (Linux) - if: runner.os == 'Linux' - uses: dtolnay/rust-toolchain@stable - - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.x" - - name: Create shell envs (Linux) + - name: Install build tools (Linux) if: runner.os == 'Linux' shell: bash run: | echo "PYTHON=python3" >> $GITHUB_ENV + sudo apt update + python3 $GITHUB_WORKSPACE/scripts/tools-versions-ubuntu.py --install + + - name: Install Rust Toolchain (Linux) + if: runner.os == 'Linux' + uses: dtolnay/rust-toolchain@stable - name: Create shell envs (Windows) if: runner.os == 'Windows' diff --git a/scripts/tools-versions-ubuntu.py b/scripts/tools-versions-ubuntu.py new file mode 100755 index 00000000..0edbba78 --- /dev/null +++ b/scripts/tools-versions-ubuntu.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 + +# +# To make the build deterministic between a local ubuntu machine +# and the Github ubuntu-latest CI, the same version of tools +# must be used. +# +# This script updates the tool-versions-ubuntu.txt file to +# reflect the versions of the tools installed on your local machine. +# +# This file can then be used by the CI to mimic your setup. +# +# Who and how to maintain tool-versions-ubuntu.txt? +# ------------------------------------------------- +# Every few years, it migth be wise to have the CI use more +# recent versions. +# +# Also, using the same versions reduce repackaging by the CI (e.g. CI +# producing different Makefile.in just because different version). +# +# You can either manually update the file or use this +# script to generate the file. When using the script +# the versions will be set with whatever is installed +# on the local machine. +# +# In short, once you have a local Ubuntu setup running the latest +# to your satisfaction, you can run this script to generate +# the file. +# + +# Get the version installed on the system. Intended to be used +# exclusively on Ubuntu. +import argparse +import subprocess +from typing import List + +from utilities.common import is_ubuntu, verify_git_repo +from utilities.files import path_join + +def get_package_version(package_name: str): + try: + result = subprocess.run( + ['apt-cache', 'policy', package_name], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + check=True + ) + for line in result.stdout.split('\n'): + if 'Installed:' in line: + version = line.split(':', 1)[1].strip() + if version != '(none)': + return version + return None + except subprocess.CalledProcessError as e: + print(f"Error getting version for package {package_name}: {e}") + return None + +def display_tools_file(file_path: str): + with open(file_path, 'r') as f: + for line in f: + print(line.strip()) + +def write_tools_to_file(file_path: str, packages: List[str]): + with open(file_path, 'w') as f: + for package in packages: + version = get_package_version(package) + if version: + f.write(f"{package}={version}\n") + else: + f.write(f"{package}=not installed\n") + display_tools_file(file_path) + +def install_tools_from_file(file_path: str): + with open(file_path, 'r') as f: + for line in f: + package, version = line.strip().split('=') + if version != 'not installed': + try: + subprocess.run( + ['sudo', 'apt', 'install', '-y', f"{package}={version}"], + check=True + ) + except subprocess.CalledProcessError as e: + print(f"Error installing package {package}: {e}") + display_tools_file(file_path) + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Process tools-versions-ubuntu.txt") + parser.add_argument('-w', '--write', action='store_true', help="Write tool-versions-ubuntu.txt using local platform versions") + parser.add_argument('-i', '--install', action='store_true', help="Install tools with specific version taken from tool-versions-ubuntu.txt") + args = parser.parse_args() + + if not is_ubuntu(): + print("This script is intended to be run on Ubuntu platform only") + exit(1) + + root_dir = verify_git_repo() + + packages = [ + 'automake', + 'libtool', + 'autogen', + 'mcpp', + 'openjdk-22-jdk-headless', + 'gcc-i686-linux-gnu', + 'gcc-aarch64-linux-gnu' + ] + + if not args.write and not args.install: + print("One of --write (-w) or --install (-i) must be specified") + exit(1) + + if args.write and args.install: + print("Only one of --write (-w) or --install (-i) can be specified") + exit(1) + + file_path = path_join(root_dir, 'scripts', 'tools-versions-ubuntu.txt') + if args.write: + write_tools_to_file(file_path, packages) + + + if args.install: + install_tools_from_file(file_path) + print(f"All tools installed successfully") \ No newline at end of file diff --git a/scripts/tools-versions-ubuntu.txt b/scripts/tools-versions-ubuntu.txt new file mode 100644 index 00000000..997ccb81 --- /dev/null +++ b/scripts/tools-versions-ubuntu.txt @@ -0,0 +1,7 @@ +automake=1:1.16.5-1.3ubuntu1 +libtool=2.4.7-7build1 +autogen=1:5.18.16-5build1 +mcpp=2.7.2-5.1 +openjdk-22-jdk-headless=22~16ea-1 +gcc-i686-linux-gnu=4:13.2.0-7ubuntu1 +gcc-aarch64-linux-gnu=4:13.2.0-7ubuntu1