Skip to content

Commit d3be2c6

Browse files
authored
Restructure CI to use reusable workflow (#455)
This follows the pattern adopted by OpenEXR see AcademySoftwareFoundation/openexr#1921 for details. * Introduce the process of validating the installed files by comparing the install_manifest.txt files to archived versions, one per build. * Factor out the jobs for the outdated VFX reference platform years, which require workarounds for the outdated glibc. * Add a build that validates custom namespaces. This also fixes several problems with building the python bindings when the library has been built with a custom namespace. The code had "Imath::" where it should have had "IMATH_NAMESPACE::". Signed-off-by: Cary Phillips <[email protected]>
1 parent 2e78172 commit d3be2c6

31 files changed

+2196
-1143
lines changed

.github/workflows/ci_steps.yml

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright (c) Contributors to the OpenEXR Project.
3+
4+
# These are the steps for all CI jobs. Linux, macOS, and Windows all
5+
# share a common set of configure/build/validate steps. The input
6+
# variables control all variations of the jobs.
7+
#
8+
# Each job validates that the proper files are installed by comparing
9+
# the install_manifest.txt to a reference for that job. This requires
10+
# that each job have a corresponding reference, and that thes
11+
# references are updated when any change is made to the installation
12+
# headers/libraries/cmake/etc.
13+
14+
name: CI Steps
15+
16+
on:
17+
workflow_call:
18+
# This inputs receive values via the "with:" section in ci_workflow.yml
19+
inputs:
20+
build:
21+
type: string
22+
os:
23+
type: string
24+
container:
25+
type: string
26+
cxx-standard:
27+
type: string
28+
cxx-compiler:
29+
type: string
30+
cc-compiler:
31+
type: string
32+
build-type:
33+
type: string
34+
python:
35+
type: string
36+
pybind11:
37+
type: string
38+
IMATH_INSTALL_PKG_CONFIG:
39+
type: string
40+
BUILD_SHARED_LIBS:
41+
type: string
42+
BUILD_TESTING:
43+
type: string
44+
namespace:
45+
type: string
46+
validate_install:
47+
type: string
48+
49+
jobs:
50+
steps:
51+
runs-on: ${{ inputs.os }}
52+
53+
container:
54+
image: ${{ inputs.container }}
55+
56+
env:
57+
CXX: ${{ inputs.cxx-compiler }}
58+
CC: ${{ inputs.cc-compiler }}
59+
60+
steps:
61+
62+
- name: Checkout
63+
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
64+
65+
- name: Create build directories
66+
run: mkdir _install _build _examples
67+
shell: bash
68+
69+
- name: Construct CMake command
70+
run: |
71+
# Construct the cmake command as a variable, so the
72+
# Configure step below can execute it, but also so we can store
73+
# in in the install_manifest as a debugging reference
74+
CMAKE_COMMAND="cmake -B . -S .. \
75+
-DCMAKE_INSTALL_PREFIX=../_install \
76+
-DCMAKE_BUILD_TYPE=${{ inputs.build-type }} \
77+
-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }} \
78+
-DBUILD_SHARED_LIBS=${{ inputs.BUILD_SHARED_LIBS }} \
79+
-DIMATH_INSTALL_PKG_CONFIG=${{ inputs.IMATH_INSTALL_PKG_CONFIG }} \
80+
-DBUILD_TESTING=${{ inputs.BUILD_TESTING }} \
81+
-DPYTHON=${{ inputs.python }} \
82+
-DPYBIND11=${{ inputs.pybind11 }} \
83+
-DCMAKE_VERBOSE_MAKEFILE=ON"
84+
if [ -n "${{ inputs.namespace }}" ]; then
85+
CMAKE_COMMAND="$CMAKE_COMMAND -DIMATH_NAMESPACE=${{ inputs.namespace }}"
86+
fi
87+
echo "CMAKE_COMMAND=$CMAKE_COMMAND" >> $GITHUB_ENV
88+
89+
# Remove the os version from the manifest name, so it only
90+
# contains "ubuntu", "macos", or "windows", so the name is,
91+
# e.g. install_manifest.macos.1.txt
92+
echo "INSTALL_MANIFEST=$(echo 'install_manifest.${{ inputs.os }}' | cut -d'-' -f1).${{ inputs.build }}.txt" >> $GITHUB_ENV
93+
working-directory: _build
94+
shell: bash
95+
96+
- name: Configure
97+
run: |
98+
$CMAKE_COMMAND
99+
working-directory: _build
100+
shell: bash
101+
102+
- name: Build
103+
run: |
104+
cmake --build . --target install --config ${{ inputs.build-type }}
105+
working-directory: _build
106+
shell: bash
107+
108+
- name: Find python version
109+
run: |
110+
echo Finding python version in _build directory:
111+
grep -r PYTHON
112+
working-directory: _build
113+
shell: bash
114+
115+
- name: Prepare install_manifest
116+
# Store the cmake command as the first line of the manifest,
117+
# and remove the path prefix, so the manifest contains only
118+
# the local filenames.
119+
run: |
120+
echo "# $CMAKE_COMMAND" > "_build/$INSTALL_MANIFEST"
121+
sort _build/install_manifest.txt | sed -e "s:^.*/_install/::" >> "_build/$INSTALL_MANIFEST"
122+
shell: bash
123+
124+
- name: Upload install_manifest.txt
125+
# Upload the manifest to make it possible to download for inspection and debugging
126+
uses: actions/upload-artifact@v3
127+
with:
128+
name: install_manifest
129+
path: _build/${{ env.INSTALL_MANIFEST }}
130+
131+
- name: Validate install
132+
if: ${{ inputs.validate_install == 'ON' }}
133+
# Validate that the build has installed the proper files by comparing against the appropriate reference manifest
134+
run: |
135+
share/ci/scripts/validate_install.py "_build/$INSTALL_MANIFEST" "share/ci/install_manifest/$INSTALL_MANIFEST" _build/CMakeCache.txt
136+
shell: bash
137+
138+
- name: Test standalone
139+
continue-on-error: true
140+
run: |
141+
# Make sure we can build the tests when configured as a
142+
# standalone application linking against the just-installed
143+
# Imath library.
144+
cmake ../src/ImathTest \
145+
-DCMAKE_PREFIX_PATH=../../_install \
146+
-DCMAKE_BUILD_TYPE=${{ inputs.build-type }} \
147+
-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }} \
148+
-DCMAKE_CXX_FLAGS=${{ inputs.cxx-flags }}
149+
cmake --build . \
150+
--config ${{ inputs.build-type }}
151+
152+
if [[ "$RUNNER_OS" == "Windows" ]]; then
153+
./bin/"${{ inputs.build-type }}"/ImathTest.exe || true
154+
else
155+
./bin/ImathTest
156+
fi
157+
shell: bash
158+
working-directory: _examples
159+
160+
- name: Examples
161+
# The example code use the Imath:: namespace explicitly, they won't work with a custom namespace, so skip the test in that case.
162+
if: ${{ inputs.namespace == '' }}
163+
run: |
164+
# Confirm the examples compile and execute
165+
rm -rf bin CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
166+
cmake ../website/examples \
167+
-DCMAKE_PREFIX_PATH=../../_install \
168+
-DCMAKE_BUILD_TYPE=${{ inputs.build-type }} \
169+
-DCMAKE_CXX_STANDARD=${{ inputs.cxx-standard }}
170+
cmake --build . --config ${{ inputs.build-type }}
171+
if [[ "$RUNNER_OS" == "Windows" ]]; then
172+
./bin/"${{ inputs.build-type }}"/imath-intro.exe || true
173+
./bin/"${{ inputs.build-type }}"/imath-examples.exe || true
174+
else
175+
./bin/imath-intro
176+
./bin/imath-examples
177+
fi
178+
179+
shell: bash
180+
working-directory: _examples
181+
182+
- name: Test Python
183+
if: ${{ inputs.python == 'ON' }}
184+
run: |
185+
# Confirm the python module loads. Set PYTHONPATH to the
186+
# _install directory of the module (better to find it
187+
# procedurally than hard code a path).
188+
if [[ "${{ inputs.python }}" == "ON" ]]; then
189+
export PYTHONPATH=`find ../_install -name imath.so | xargs dirname`
190+
python -c "import imath;print(imath.__version__)"
191+
fi
192+
if [[ "${{ inputs.pybind11 }}" == "ON" ]]; then
193+
export PYTHONPATH=`find ../_install -name 'pybindimath.*.so' | xargs dirname`
194+
python -c "import pybindimath;print(pybindimath.__version__)"
195+
fi
196+
shell: bash
197+
working-directory: _build
198+
199+
- name: Test
200+
run: |
201+
ctest -T Test -C ${{ inputs.build-type }} --timeout 7200 --output-on-failure -VV
202+
working-directory: _build
203+
shell: bash

0 commit comments

Comments
 (0)