From a5bf21c94eac3b3d5015368badc4ab023032a07b Mon Sep 17 00:00:00 2001 From: Kevin Peterson Date: Thu, 28 Apr 2022 14:55:43 -0500 Subject: [PATCH 1/3] Configured to build with github-actions --- .ci | 2 +- .ci-local/github-actions/post-prepare.py | 70 +++++++ .ci-local/github-actions/sanity-check.py | 9 + .ci-local/modules.set | 8 +- .github/workflows/ci-scripts-build-full.yml | 210 ++++++++++++++++++++ .github/workflows/ci-scripts-build.yml | 103 ++++++++++ README.md | 3 +- 7 files changed, 399 insertions(+), 6 deletions(-) create mode 100755 .ci-local/github-actions/post-prepare.py create mode 100644 .ci-local/github-actions/sanity-check.py create mode 100644 .github/workflows/ci-scripts-build-full.yml create mode 100644 .github/workflows/ci-scripts-build.yml diff --git a/.ci b/.ci index 12d76983..57646016 160000 --- a/.ci +++ b/.ci @@ -1 +1 @@ -Subproject commit 12d769835e1ee88e94b5b0b4bc0cf7068e678064 +Subproject commit 576460163031255c09948566dd2f2409d86ab8d4 diff --git a/.ci-local/github-actions/post-prepare.py b/.ci-local/github-actions/post-prepare.py new file mode 100755 index 00000000..7dccc497 --- /dev/null +++ b/.ci-local/github-actions/post-prepare.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +import os +import shutil +import re + +# Setup ANSI Colors (copied from cue.py) +ANSI_RED = "\033[31;1m" +ANSI_GREEN = "\033[32;1m" +ANSI_YELLOW = "\033[33;1m" +ANSI_BLUE = "\033[34;1m" +ANSI_MAGENTA = "\033[35;1m" +ANSI_CYAN = "\033[36;1m" +ANSI_RESET = "\033[0m" +ANSI_CLEAR = "\033[0K" + +def cat(filename): + ''' + Print the contents of a file + ''' + with open(filename, 'r') as fh: + for line in fh: + print(line.strip()) + +def sanity_check(filename): + ''' + Include the contents of a file in the github-actions log + ''' + print("{}Contents of {}{}".format(ANSI_BLUE, filename, ANSI_RESET)) + cat(filename) + print("{}End of {}{}".format(ANSI_BLUE, filename, ANSI_RESET)) + +if 'HOME' in os.environ: + # Linux & OS X + cache_dir = os.path.join(os.environ['HOME'], ".cache") +else: + # Windows + cache_dir = os.path.join(os.environ['HOMEDRIVE'], os.environ['HOMEPATH'], ".cache") + +module_dir = os.getenv('GITHUB_WORKSPACE') + +# Copy the github-actions RELEASE.local to the configure dir +filename = "configure/RELEASE.local" +shutil.copy("{}/RELEASE.local".format(cache_dir), filename) + +# Get the variable from the example release file +example = "configure/EXAMPLE_RELEASE.local" +fh = open(example, "r") +lines = fh.readlines() +fh.close() +pObj = re.compile('(MOTOR_[^=]+)') +module_var = None +for line in lines: + mObj = pObj.match(line) + if mObj != None: + module_var = mObj.group() + break + +# Add the path to the driver module to the RELEASE.local file, since it is needed by the example IOC +fh = open(filename, "a") +fh.write("{}={}\n".format(module_var, module_dir)) +fh.close() +sanity_check(filename) + +# Enable the building of example IOCs +filename = "configure/CONFIG_SITE.local" +fh = open(filename, 'w') +fh.write("BUILD_IOCS = YES") +fh.close() +sanity_check(filename) diff --git a/.ci-local/github-actions/sanity-check.py b/.ci-local/github-actions/sanity-check.py new file mode 100644 index 00000000..4e32f6d3 --- /dev/null +++ b/.ci-local/github-actions/sanity-check.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import os +import pprint + +pprint.pprint(dict(os.environ), width = 1) + +#!print("{}", breakmehere) + diff --git a/.ci-local/modules.set b/.ci-local/modules.set index 9479f5db..8ccd765f 100644 --- a/.ci-local/modules.set +++ b/.ci-local/modules.set @@ -1,7 +1,7 @@ MODULES="sncseq ipac asyn autosave busy" -SNCSEQ=R2-2-8 +SNCSEQ=R2-2-9 IPAC=master -ASYN=R4-38 -AUTOSAVE=R5-9 -BUSY=R1-7-1 +ASYN=R4-42 +AUTOSAVE=R5-10-2 +BUSY=R1-7-3 diff --git a/.github/workflows/ci-scripts-build-full.yml b/.github/workflows/ci-scripts-build-full.yml new file mode 100644 index 00000000..707a4d5d --- /dev/null +++ b/.github/workflows/ci-scripts-build-full.yml @@ -0,0 +1,210 @@ +# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts +# (see: https://github.com/epics-base/ci-scripts) + +# This is YAML - indentation levels are crucial + +# Set the 'name:' properties to values that work for you (MYMODULE) + +name: "GHA full build" + +# Only run manually +on: + workflow_dispatch + +env: + SETUP_PATH: .ci-local:.ci + # For the sequencer on Linux/Windows/MacOS + APT: re2c + CHOCO: re2c + BREW: re2c + +jobs: + build-base: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + # Set environment variables from matrix parameters + env: + CMP: ${{ matrix.cmp }} + BCFG: ${{ matrix.configuration }} + WINE: ${{ matrix.wine }} + RTEMS: ${{ matrix.rtems }} + RTEMS_TARGET: ${{ matrix.rtems_target }} + EXTRA: ${{ matrix.extra }} + TEST: ${{ matrix.test }} + SET: ${{ matrix.set }} + strategy: + fail-fast: false + matrix: + # Job names also name artifacts, character limitations apply + include: + - os: ubuntu-20.04 + cmp: gcc + configuration: default + wine: "64" + base: "7.0" + set: modules + name: "Ub-20 gcc-9 + MinGW" + + - os: ubuntu-20.04 + cmp: gcc + configuration: static + wine: "64" + base: "7.0" + set: modules + name: "Ub-20 gcc-9 + MinGW, static" + + - os: ubuntu-20.04 + cmp: gcc + configuration: static + extra: "CMD_CXXFLAGS=-std=c++11" + base: "7.0" + set: modules + name: "Ub-20 gcc-9 C++11, static" + + - os: ubuntu-20.04 + cmp: clang + configuration: default + extra: "CMD_CXXFLAGS=-std=c++11" + base: "7.0" + set: modules + name: "Ub-20 clang-10 C++11" + + ### fails building autosave + #!- os: ubuntu-20.04 + #! cmp: gcc + #! configuration: default + #! rtems: "4.10" + #! base: "7.0" + #! set: modules + #! name: "Ub-20 gcc-9 + RT-4.10" + + - os: ubuntu-20.04 + cmp: gcc + configuration: default + rtems: "4.9" + base: "7.0" + set: modules + name: "Ub-20 gcc-9 + RT-4.9" + + ### fails building asyn + #!- os: ubuntu-20.04 + #! cmp: gcc + #! configuration: default + #! rtems: "5" + #! rtems_target: RTEMS-pc686-qemu + #! base: "7.0" + #! set: modules + #! name: "Ub-20 gcc-9 + RT-5.1 pc686" + + ### fails building autosave + #!- os: ubuntu-20.04 + #! cmp: gcc + #! configuration: default + #! rtems: "5" + #! rtems_target: RTEMS-beatnik + #! test: NO + #! base: "7.0" + #! set: modules + #! name: "Ub-20 gcc-9 + RT-5.1 beatnik" + + - os: ubuntu-18.04 + cmp: gcc + configuration: default + base: "7.0" + set: modules + name: "Ub-18 gcc-7" + + ### g++-8 not found + #!- os: ubuntu-18.04 + #! cmp: gcc-8 + #! utoolchain: true + #! configuration: default + #! base: "7.0" + #! set: modules + #! name: "Ub-18 gcc-8" + + #!- os: ubuntu-20.04 + #! cmp: gcc-8 + #! utoolchain: true + #! configuration: default + #! base: "7.0" + #! set: modules + #! name: "Ub-20 gcc-8" + + - os: ubuntu-20.04 + cmp: clang + configuration: default + base: "7.0" + set: modules + name: "Ub-20 clang-10" + + - os: macos-latest + cmp: clang + configuration: default + base: "7.0" + set: modules + name: "MacOS clang-12" + + - os: windows-2019 + cmp: gcc + configuration: default + base: "7.0" + set: modules + name: "Win2019 MinGW" + + - os: windows-2019 + cmp: gcc + configuration: static + base: "7.0" + set: modules + name: "Win2019 MinGW, static" + + - os: windows-2019 + cmp: vs2019 + configuration: default + base: "7.0" + set: modules + name: "Win2019 MSC-19" + + - os: windows-2019 + cmp: vs2019 + configuration: static + base: "7.0" + set: modules + name: "Win2019 MSC-19, static" + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Automatic core dumper analysis + uses: mdavidsaver/ci-core-dumper@master + - name: "apt-get install" + run: | + sudo apt-get update + sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb + if: runner.os == 'Linux' + - name: "apt-get install ${{ matrix.cmp }}" + run: | + sudo apt-get -y install software-properties-common + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get -y install ${{ matrix.cmp }} + if: matrix.utoolchain + - name: Sanity Check + run: python .ci-local/github-actions/sanity-check.py + - name: Prepare and compile dependencies + run: python .ci/cue.py prepare + - name: Patch main module + run: python .ci-local/github-actions/post-prepare.py + - name: Build main module + run: python .ci/cue.py build + - name: Run main module tests + run: python .ci/cue.py test + - name: Upload tapfiles Artifact + uses: actions/upload-artifact@v2 + with: + name: tapfiles ${{ matrix.name }} + path: '**/O.*/*.tap' + - name: Collect and show test results + run: python .ci/cue.py test-results diff --git a/.github/workflows/ci-scripts-build.yml b/.github/workflows/ci-scripts-build.yml new file mode 100644 index 00000000..ee404d85 --- /dev/null +++ b/.github/workflows/ci-scripts-build.yml @@ -0,0 +1,103 @@ +# .github/workflows/ci-scripts-build.yml for use with EPICS Base ci-scripts +# (see: https://github.com/epics-base/ci-scripts) + +# This is YAML - indentation levels are crucial + +# Set the 'name:' properties to values that work for you (MYMODULE) + +name: "GHA build" + +# Trigger on pushes to the master branch and PRs +on: + push: + paths-ignore: + - 'documentation/*' + - '**/*.html' + - '**/*.md' + - '.github/workflows/ci-scripts-build-full.yml' + branches: + - master + pull_request: + +env: + SETUP_PATH: .ci-local:.ci + # For the sequencer on Linux/Windows/MacOS + APT: re2c + CHOCO: re2c + BREW: re2c + +jobs: + build-base: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + # Set environment variables from matrix parameters + env: + CMP: ${{ matrix.cmp }} + BCFG: ${{ matrix.configuration }} + WINE: ${{ matrix.wine }} + RTEMS: ${{ matrix.rtems }} + RTEMS_TARGET: ${{ matrix.rtems_target }} + EXTRA: ${{ matrix.extra }} + TEST: ${{ matrix.test }} + SET: ${{ matrix.set }} + strategy: + fail-fast: false + matrix: + # Job names also name artifacts, character limitations apply + include: + - os: ubuntu-20.04 + cmp: gcc + configuration: default + base: "7.0" + set: modules + name: "7.0 Ub-20 gcc-9" + + - os: macos-latest + cmp: clang + configuration: default + base: "3.15" + set: modules + name: "3.15 MacOS clang-12" + + - os: windows-2019 + cmp: vs2019 + configuration: static + base: "3.15" + set: modules + name: "3.15 Win VS2019, static" + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Automatic core dumper analysis + uses: mdavidsaver/ci-core-dumper@master + - name: "apt-get install" + run: | + sudo apt-get update + sudo apt-get -y install qemu-system-x86 g++-mingw-w64-x86-64 gdb + if: runner.os == 'Linux' + - name: "apt-get install ${{ matrix.cmp }}" + run: | + sudo apt-get -y install software-properties-common + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-get update + sudo apt-get -y install ${{ matrix.cmp }} + if: matrix.utoolchain + - name: Sanity Check + run: python .ci-local/github-actions/sanity-check.py + - name: Prepare and compile dependencies + run: python .ci/cue.py prepare + - name: Patch main module + run: python .ci-local/github-actions/post-prepare.py + - name: Build main module + run: python .ci/cue.py build + - name: Run main module tests + run: python .ci/cue.py test + - name: Upload tapfiles Artifact + uses: actions/upload-artifact@v2 + with: + name: tapfiles ${{ matrix.name }} + path: '**/O.*/*.tap' + - name: Collect and show test results + run: python .ci/cue.py test-results diff --git a/README.md b/README.md index 738cdc1c..741bd684 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # motor -[![Build Status](https://travis-ci.org/epics-modules/motor.png)](https://travis-ci.org/epics-modules/motor) +[![Build Status](https://github.com/epics-modules/motor/actions/workflows/ci-scripts-build.yml/badge.svg)](https://github.com/epics-modules/motor/actions/workflows/ci-scripts-build.yml) + This module contains motor support for the Experimental Physics and Industrial Control System (EPICS). From cba123e69a8f18be12a700004cf27cf0814f05f9 Mon Sep 17 00:00:00 2001 From: Kevin Peterson Date: Thu, 28 Apr 2022 15:21:20 -0500 Subject: [PATCH 2/3] Use the travis post-prepare.py and util.py scripts --- .ci-local/github-actions/post-prepare.py | 88 +++++++----------------- .ci-local/github-actions/util.py | 68 ++++++++++++++++++ 2 files changed, 93 insertions(+), 63 deletions(-) create mode 100644 .ci-local/github-actions/util.py diff --git a/.ci-local/github-actions/post-prepare.py b/.ci-local/github-actions/post-prepare.py index 7dccc497..01e985b6 100755 --- a/.ci-local/github-actions/post-prepare.py +++ b/.ci-local/github-actions/post-prepare.py @@ -1,70 +1,32 @@ #!/usr/bin/env python import os -import shutil -import re +import sys +import subprocess -# Setup ANSI Colors (copied from cue.py) -ANSI_RED = "\033[31;1m" -ANSI_GREEN = "\033[32;1m" -ANSI_YELLOW = "\033[33;1m" -ANSI_BLUE = "\033[34;1m" -ANSI_MAGENTA = "\033[35;1m" -ANSI_CYAN = "\033[36;1m" -ANSI_RESET = "\033[0m" -ANSI_CLEAR = "\033[0K" +from util import * -def cat(filename): - ''' - Print the contents of a file - ''' - with open(filename, 'r') as fh: - for line in fh: - print(line.strip()) +def get_submodule_releases(): + # + releases = [] + for root, dirs, files in os.walk('modules'): + for submodule in dirs: + if 'motor' in submodule: + release_path = "modules/{}/configure/RELEASE".format(submodule) + if os.path.exists(release_path): + releases.append(release_path) + return releases[:] -def sanity_check(filename): - ''' - Include the contents of a file in the github-actions log - ''' - print("{}Contents of {}{}".format(ANSI_BLUE, filename, ANSI_RESET)) - cat(filename) - print("{}End of {}{}".format(ANSI_BLUE, filename, ANSI_RESET)) +# Comment out SUPPORT from motor's RELEASE file +motor_release = "configure/RELEASE" +update_release_file(motor_release, "SUPPORT", '#') +print("{}Updated {}{}".format(ANSI_BLUE, motor_release, ANSI_RESET)) +grep_release_file(motor_release, "#SUPPORT") -if 'HOME' in os.environ: - # Linux & OS X - cache_dir = os.path.join(os.environ['HOME'], ".cache") -else: - # Windows - cache_dir = os.path.join(os.environ['HOMEDRIVE'], os.environ['HOMEPATH'], ".cache") - -module_dir = os.getenv('GITHUB_WORKSPACE') - -# Copy the github-actions RELEASE.local to the configure dir -filename = "configure/RELEASE.local" -shutil.copy("{}/RELEASE.local".format(cache_dir), filename) - -# Get the variable from the example release file -example = "configure/EXAMPLE_RELEASE.local" -fh = open(example, "r") -lines = fh.readlines() -fh.close() -pObj = re.compile('(MOTOR_[^=]+)') -module_var = None -for line in lines: - mObj = pObj.match(line) - if mObj != None: - module_var = mObj.group() - break - -# Add the path to the driver module to the RELEASE.local file, since it is needed by the example IOC -fh = open(filename, "a") -fh.write("{}={}\n".format(module_var, module_dir)) -fh.close() -sanity_check(filename) - -# Enable the building of example IOCs -filename = "configure/CONFIG_SITE.local" -fh = open(filename, 'w') -fh.write("BUILD_IOCS = YES") -fh.close() -sanity_check(filename) +# Comment out SUPPORT from the driver module RELEASE files +releases = get_submodule_releases() +for release in releases: + updated = update_release_file(release, "SUPPORT", '#') + if updated: + print("{}Updated {}{}".format(ANSI_BLUE, release, ANSI_RESET)) + grep_release_file(release, "#SUPPORT") diff --git a/.ci-local/github-actions/util.py b/.ci-local/github-actions/util.py new file mode 100644 index 00000000..8b2af1e2 --- /dev/null +++ b/.ci-local/github-actions/util.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +from __future__ import print_function + +import logging +import fileinput +import os + +# Setup ANSI Colors +ANSI_RED = "\033[31;1m" +ANSI_GREEN = "\033[32;1m" +ANSI_YELLOW = "\033[33;1m" +ANSI_BLUE = "\033[34;1m" +ANSI_MAGENTA = "\033[35;1m" +ANSI_CYAN = "\033[36;1m" +ANSI_RESET = "\033[0m" +ANSI_CLEAR = "\033[0K" + +logger = logging.getLogger(__name__) + +def create_file(filename): + dirname = os.path.dirname(filename) + print(dirname) + if not os.path.exists(dirname): + os.makedirs(dirname, 0755) + if not os.path.exists(filename): + fh = open(filename, 'w') + fh.close() + else: + logger.debug("{} already exists".format(filename)) + +# Update a definition in a release file that already exists +# Append a defintion to a release file that already exists +# Commented out a definition in a release file (location='#') +def update_release_file(filename, var, location): + updated_line = '{0}={1}'.format(var, location.replace('\\', '/')) + + found = False + logger.debug("Opening '%s' for adding '%s'", filename, updated_line) + for line in fileinput.input(filename, inplace=1): + output_line = line.strip() + if '{0}='.format(var) in line: + logger.debug("Found '%s=' line, replacing", var) + found = True + if location != '#': + output_line = updated_line + else: + if output_line[0] != '#': + output_line = "#{}".format(output_line) + logger.debug("Writing line to '%s': '%s'", filename, output_line) + print(output_line) + fileinput.close() + + if not found and location != '#': + fh = open(release_local, "a") + logger.debug("Adding new definition: '%s'", updated_line) + print(updated_line, file=fh) + fh.close() + + return found + +def grep_release_file(filename, var): + fh = open(filename, 'r') + for line in fh: + if '{0}='.format(var) in line: + print(line) + fh.close() + From 642fcf541da47d4224c98ec662abcdab174f6016 Mon Sep 17 00:00:00 2001 From: Kevin Peterson Date: Thu, 28 Apr 2022 15:35:10 -0500 Subject: [PATCH 3/3] Fixed ambiguous directory mask --- .ci-local/github-actions/util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci-local/github-actions/util.py b/.ci-local/github-actions/util.py index 8b2af1e2..9bca4879 100644 --- a/.ci-local/github-actions/util.py +++ b/.ci-local/github-actions/util.py @@ -22,7 +22,7 @@ def create_file(filename): dirname = os.path.dirname(filename) print(dirname) if not os.path.exists(dirname): - os.makedirs(dirname, 0755) + os.makedirs(dirname, 0o0755) if not os.path.exists(filename): fh = open(filename, 'w') fh.close()