ci: test with RCDB #6
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: CI | |
on: | |
workflow_call: | |
inputs: | |
id: | |
description: 'ID' | |
required: true | |
type: string | |
runner: | |
description: 'GitHub runner' | |
required: true | |
type: string | |
container: | |
description: 'Docker container' | |
required: false | |
type: string | |
default: '' | |
verset: | |
description: 'Dependency version set' | |
required: false | |
type: string | |
default: 'latest' | |
matrix: | |
description: 'Iguana job matrix' | |
required: true | |
type: string | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
cancel-in-progress: true | |
defaults: | |
run: | |
shell: bash | |
env: | |
hipo_fork: gavalian/hipo | |
hipo_ref: 20094876df040ec234dd376fa527cf58442b775a | |
# test options | |
num_events: 1000 | |
num_threads: 0 # use 0 for "all" available cores | |
verbose_test: 'false' # only set this to 'true' if `meson test` fails and you need more output to investigate | |
jobs: | |
# download test data | |
######################################################### | |
download_test_data: | |
name: Download test data | |
runs-on: ubuntu-latest # no need to run this job on other runners | |
outputs: | |
key: ${{ steps.key.outputs.key }} | |
steps: | |
- name: key # unique for ${{ inputs.id }}, to avoid cache collisions | |
id: key | |
run: echo key=test_data---${{ inputs.id }}---$(date +%Y-week%U) >> $GITHUB_OUTPUT | |
- uses: actions/cache@v4 | |
id: cache | |
with: | |
key: ${{ steps.key.outputs.key }} | |
path: test_data.hipo | |
lookup-only: true | |
- name: install xrootd-client | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: | | |
sudo apt -y update | |
sudo apt -y upgrade | |
sudo apt -y install xrootd-client | |
- name: download | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: xrdcp xroot://sci-xrootd.jlab.org//osgpool/hallb/clas12/validation/recon/dst/validation_files.tar.zst ./ | |
- name: rename | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: | | |
tar xvf validation_files.tar.zst | |
mv -v $(find validation_files -type f -name "*.hipo" | head -n1) test_data.hipo | |
# dependencies | |
######################################################### | |
build_root: | |
name: Build ROOT | |
runs-on: ${{ inputs.runner }} | |
container: | |
image: ${{ inputs.container }} | |
outputs: | |
key: ${{ steps.key.outputs.key }} | |
steps: | |
### define key | |
- name: checkout iguana | |
uses: actions/checkout@v4 | |
with: | |
path: iguana_src | |
- name: key | |
id: key | |
# FIXME: this builds the source code URL; using the GitHub REST API | |
# (via `curl --request`) is preferred to get the source code URL, but | |
# needs a PAT to mitigate API rate limits; for now just assume the URL | |
# - see https://github.com/JeffersonLab/iguana/pull/276 | |
run: | | |
[ "${{ inputs.verset }}" = "minver" ] && \ | |
root_version=$(iguana_src/meson/minimum-version.sh root tag) || \ | |
root_version=$(iguana_src/meson/minimum-version.sh root tag_latest) | |
echo root_url=https://api.github.com/repos/root-project/root/tarball/refs/tags/${root_version} >> $GITHUB_OUTPUT | |
echo key=root---${{ inputs.id }}---${root_version}---$(date +%Y-week%U) >> $GITHUB_OUTPUT | |
### cache restore | |
- uses: actions/cache/restore@v4 | |
id: cache | |
with: | |
key: ${{ steps.key.outputs.key }} | |
path: root.tar.zst | |
lookup-only: true | |
### download and build | |
- name: install dependencies | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: iguana_src/.github/install-dependency-packages.sh ${{ inputs.runner }} ${{ inputs.verset }} | |
- name: download ROOT source code | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: | | |
wget -nv --no-check-certificate --output-document root.tar.gz ${{ steps.key.outputs.root_url }} | |
tar xf root.tar.gz | |
ls -t | |
mv -v $(ls -td root-* | head -n1) root_src | |
- name: build ROOT | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: | | |
cmake -S root_src -B build -G Ninja --install-prefix $(pwd)/root -DCMAKE_CXX_STANDARD=17 | |
cmake --build build | |
cmake --install build | |
tar caf root{.tar.zst,} | |
### cache save | |
- uses: actions/cache/save@v4 | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
id: cache_save | |
with: | |
key: ${{ steps.key.outputs.key }} | |
path: root.tar.zst | |
build_hipo: | |
name: Build HIPO | |
needs: | |
- build_root # for dataframe support | |
runs-on: ${{ inputs.runner }} | |
container: | |
image: ${{ inputs.container }} | |
strategy: | |
fail-fast: true | |
matrix: | |
root_dep: | |
- noROOT # exclude dataframe lib, which depends on ROOT | |
- withROOT | |
outputs: | |
key: ${{ steps.key.outputs.key }} | |
steps: | |
### get ROOT | |
- name: get ROOT build | |
if: ${{ matrix.root_dep == 'withROOT' }} | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.build_root.outputs.key }} | |
path: root.tar.zst | |
- name: untar ROOT build | |
if: ${{ matrix.root_dep == 'withROOT' }} | |
run: ls *.tar.zst | xargs -I{} tar xvf {} | |
### define key | |
- name: key | |
id: key | |
run: echo key=hipo---${{ inputs.id }}---${{ env.hipo_ref }}---$(date +%Y-week%U) >> $GITHUB_OUTPUT | |
### cache restore | |
- uses: actions/cache/restore@v4 | |
id: cache | |
with: | |
key: ${{ steps.key.outputs.key }}---${{ matrix.root_dep }} | |
path: hipo.tar.zst | |
lookup-only: true | |
### build | |
- name: checkout iguana for dependency installation script | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
uses: actions/checkout@v4 | |
with: | |
path: iguana_src | |
- name: checkout hipo | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
uses: actions/checkout@v4 | |
with: | |
repository: ${{ env.hipo_fork }} | |
ref: ${{ env.hipo_ref }} | |
path: hipo_src | |
- name: build | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
run: | | |
iguana_src/.github/install-dependency-packages.sh ${{ inputs.runner }} ${{ inputs.verset }} | |
[ "${{ matrix.root_dep }}" = "withROOT" ] && source root/bin/thisroot.sh | |
meson setup build hipo_src --prefix=$(pwd)/hipo -Dbuildtype=debug -Db_pie=true # using PIE build, for sanitizer readibility | |
meson install -C build | |
tar cavf hipo{.tar.zst,} | |
### cache save | |
- uses: actions/cache/save@v4 | |
if: ${{ steps.cache.outputs.cache-hit != 'true' }} | |
id: cache_save | |
with: | |
key: ${{ steps.key.outputs.key }}---${{ matrix.root_dep }} | |
path: hipo.tar.zst | |
build_ruby_minver: | |
name: Build Minver Ruby | |
runs-on: ${{ inputs.runner }} | |
container: | |
image: ${{ inputs.container }} | |
outputs: | |
key: ${{ steps.key.outputs.key }} | |
steps: | |
- name: checkout iguana | |
if: ${{ inputs.verset == 'minver' }} | |
uses: actions/checkout@v4 | |
with: | |
path: iguana_src | |
- name: key | |
if: ${{ inputs.verset == 'minver' }} | |
id: key | |
run: | | |
ver=$(iguana_src/meson/minimum-version.sh ruby) | |
echo ver=$ver >> $GITHUB_OUTPUT | |
echo key=ruby---${{ inputs.id }}---${ver}---$(date +%Y-week%U) >> $GITHUB_OUTPUT | |
- uses: actions/cache/restore@v4 | |
if: ${{ inputs.verset == 'minver' }} | |
id: cache | |
with: | |
key: ${{ steps.key.outputs.key }} | |
path: ruby.tar.zst | |
lookup-only: true | |
- name: build ruby | |
if: ${{ steps.cache.outputs.cache-hit != 'true' && inputs.verset == 'minver' }} | |
run: | | |
iguana_src/.github/install-dependency-packages.sh ${{ inputs.runner }} ${{ inputs.verset }} | |
export RBENV_ROOT=$(pwd)/.rbenv | |
git clone https://github.com/rbenv/rbenv.git $RBENV_ROOT | |
eval "$($RBENV_ROOT/bin/rbenv init - bash)" | |
git clone https://github.com/rbenv/ruby-build.git $(rbenv root)/plugins/ruby-build | |
rbenv install ${{ steps.key.outputs.ver }} | |
rbenv global ${{ steps.key.outputs.ver }} | |
tar cavf ruby.tar.zst .rbenv | |
- uses: actions/cache/save@v4 | |
if: ${{ steps.cache.outputs.cache-hit != 'true' && inputs.verset == 'minver' }} | |
id: cache_save | |
with: | |
key: ${{ steps.key.outputs.key }} | |
path: ruby.tar.zst | |
# build and test Iguana | |
######################################################### | |
iguana: | |
name: Iguana | |
needs: | |
- download_test_data | |
- build_hipo | |
- build_root | |
- build_ruby_minver | |
runs-on: ${{ inputs.runner }} | |
container: | |
image: ${{ inputs.container }} | |
strategy: | |
fail-fast: false | |
matrix: ${{ fromJson(inputs.matrix) }} | |
env: | |
CC: ${{ matrix.CC }} | |
CXX: ${{ matrix.CXX }} | |
steps: | |
### setup | |
- uses: actions/checkout@v4 | |
with: # settings needed for version number detection | |
clean: false | |
fetch-tags: true | |
fetch-depth: 0 | |
path: iguana_src | |
### get test data | |
- name: get test data | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.download_test_data.outputs.key }} | |
path: test_data.hipo | |
### dependencies | |
###### system | |
- name: install dependency packages | |
run: iguana_src/.github/install-dependency-packages.sh ${{ inputs.runner }} ${{ inputs.verset }} | |
###### ruby | |
- name: install ruby from linux package manager | |
if: ${{ inputs.id != 'macOS' && inputs.verset != 'minver' }} | |
run: pacman -S --noconfirm ruby | |
- name: install ruby from cached minver build | |
if: ${{ inputs.id != 'macOS' && inputs.verset == 'minver' }} | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.build_ruby_minver.outputs.key }} | |
path: ruby.tar.zst | |
- name: source ruby from cached minver build | |
if: ${{ inputs.id != 'macOS' && inputs.verset == 'minver' }} | |
run: | | |
tar xf ruby.tar.zst | |
export RBENV_ROOT=$(pwd)/.rbenv | |
echo RBENV_ROOT=$RBENV_ROOT >> $GITHUB_ENV | |
eval "$($RBENV_ROOT/bin/rbenv init - bash)" | |
echo "ruby --version:" | |
ruby --version | |
echo PATH=$PATH >> $GITHUB_ENV | |
###### python bindings | |
- name: install python bindings dependencies | |
if: ${{ matrix.id == 'python' }} | |
run: | | |
python -m venv .venv | |
source .venv/bin/activate | |
echo PATH=$PATH >> $GITHUB_ENV | |
python -m pip install -r iguana_src/bind/python/requirements.txt | |
###### install doxygen | |
- name: install doxygen | |
if: ${{ matrix.id == 'documentation' }} | |
run: | | |
pacman -S --noconfirm doxygen graphviz | |
echo "INSTALLED VERSIONS:" | |
echo "doxygen: $(doxygen --version)" | |
echo "$(dot --version)" | |
###### hipo | |
- name: get `hipo-withROOT` build | |
if: ${{ matrix.id != 'noROOT' }} | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.build_hipo.outputs.key }}---withROOT | |
path: hipo.tar.zst | |
- name: get `hipo-noROOT` build | |
if: ${{ matrix.id == 'noROOT' }} | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.build_hipo.outputs.key }}---noROOT | |
path: hipo.tar.zst | |
- name: untar hipo build | |
run: tar xf hipo.tar.zst | |
- run: tree hipo | |
###### ROOT | |
- name: get `ROOT` build | |
if: ${{ matrix.id != 'noROOT' }} | |
uses: actions/cache/restore@v4 | |
with: | |
key: ${{ needs.build_root.outputs.key }} | |
path: root.tar.zst | |
- name: untar ROOT build | |
if: ${{ matrix.id != 'noROOT' }} | |
run: tar xf root.tar.zst | |
- name: set ROOT environment | |
if: ${{ matrix.id != 'noROOT' }} | |
run: iguana_src/.github/source-ROOT.sh root | |
###### RCDB | |
- name: get RCDB | |
- uses: actions/checkout@v4 | |
with: | |
repository: JeffersonLab/rcdb | |
ref: main | |
path: rcdb_src | |
- name: set RCDB env | |
id: rcdb_env | |
working-directory: rcdb_src | |
run: | | |
echo RCDB_HOME=$(pwd) >> $GITHUB_ENV | |
echo ver=$(git rev-parse HEAD | cut -c1-7) >> $GITHUB_OUTPUT | |
###### summarize dependencies | |
- name: summarize dependencies | |
if: ${{ matrix.id == 'cpp' }} | |
run: | | |
echo '### Dependencies' >> $GITHUB_STEP_SUMMARY | |
echo '| Dependency | Version |' >> $GITHUB_STEP_SUMMARY | |
echo '| --- | --- |' >> $GITHUB_STEP_SUMMARY | |
echo "| \`hipo\` | ${{ env.hipo_ref }} |" >> $GITHUB_STEP_SUMMARY | |
echo "| \`rcdb\` | commit hash \`${{ steps.rcdb_env.outputs.ver }}\` |" >> $GITHUB_STEP_SUMMARY | |
echo "| \`root\` | $(root --version 2>&1 | head -n1) |" >> $GITHUB_STEP_SUMMARY | |
echo "| \`ruby\` | $(ruby --version) |" >> $GITHUB_STEP_SUMMARY | |
cat pkg_summary.md >> $GITHUB_STEP_SUMMARY | |
### build | |
- name: meson setup | |
run: | | |
meson setup iguana_build iguana_src \ | |
--prefix=$(pwd)/iguana \ | |
--pkg-config-path=$(pwd)/hipo/lib/pkgconfig \ | |
-Drcdb:home=$RCDB_HOME \ | |
-Dwerror=true \ | |
-Dinstall_examples=true \ | |
-Dtest_data_file=$(pwd)/test_data.hipo \ | |
-Dtest_num_events=${{ env.num_events }} \ | |
-Dtest_output_dir=$(pwd)/validation_results \ | |
-Dtest_multithreading=${{ env.num_threads }} \ | |
${{ matrix.opts }} | |
- name: dump all build options | |
run: meson configure iguana_build --no-pager | |
- name: dump project build options | |
run: iguana_src/meson/dump-build-options.sh iguana_build | |
- run: meson compile | |
working-directory: iguana_build | |
- run: meson install | |
working-directory: iguana_build | |
### dump info about this build | |
- name: dump build log | |
if: always() | |
run: cat iguana_build/meson-logs/meson-log.txt | |
- name: cat pkg-config pc files | |
run: | | |
pcfiles=$(find iguana -type f -name "*.pc") | |
for pcfile in $pcfiles; do | |
echo "[+++] cat $pcfile" | |
cat $pcfile | |
done | |
- run: tree iguana | |
### run tests | |
- name: meson test | |
working-directory: iguana_build | |
run: | | |
if [ "${{ env.verbose_test }}" = "true" ]; then | |
[ ${{ inputs.runner }} = "macos-latest" ] && stdbuf_cmd=gstdbuf || stdbuf_cmd=stdbuf | |
$stdbuf_cmd -o0 meson test --print-errorlogs --verbose --no-stdsplit | |
else | |
meson test --print-errorlogs | |
fi | |
### run benchmarks | |
- name: benchmark algorithms | |
if: ${{ matrix.id == 'coverage' }} # use the coverage job's GITHUB_STEP_SUMMARY | |
run: | | |
for suite in single_threaded memoize; do | |
meson test --benchmark --suite $suite -C iguana_build | tee benchmark_$suite.txt | |
done | |
iguana_src/.github/make-benchmark-table.rb benchmark_{single_threaded,memoize}.txt | xargs -0 -I{} echo {} >> $GITHUB_STEP_SUMMARY | |
### coverage | |
- name: coverage | |
if: ${{ matrix.id == 'coverage' }} | |
run: | | |
ninja -C iguana_build coverage-html | |
ninja -C iguana_build coverage-text | |
mv iguana_build/meson-logs/coveragereport coverage-report | |
echo '### Coverage Report' >> $GITHUB_STEP_SUMMARY | |
echo '```' >> $GITHUB_STEP_SUMMARY | |
cat iguana_build/meson-logs/coverage.txt >> $GITHUB_STEP_SUMMARY | |
echo '```' >> $GITHUB_STEP_SUMMARY | |
echo '' >> $GITHUB_STEP_SUMMARY | |
echo '- for details, see the `coverage-report` artifact' >> $GITHUB_STEP_SUMMARY | |
echo '- to compare to the report from the `main` branch, see <https://jeffersonlab.github.io/iguana/coverage-report>' >> $GITHUB_STEP_SUMMARY | |
### test relocatability | |
- name: test relocatability | |
run: | | |
mv iguana relocated | |
source relocated/bin/this_iguana.sh --verbose # do not use --githubCI option, since we want this environment to be for only this step | |
relocated/bin/iguana_ex_cpp_00_run_functions test_data.hipo ${{ env.num_events }} | |
mv relocated iguana | |
### set iguana environment, since the next steps will check the iguana installation | |
- name: set iguana environment | |
run: source iguana/bin/this_iguana.sh --verbose --githubCI | |
### test installed examples | |
###### cpp | |
- run: iguana_ex_cpp_00_run_functions test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'cpp' }} | |
- run: iguana_ex_cpp_01_action_functions test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'cpp' }} | |
- run: iguana_ex_cpp_dataframes test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'cpp' }} | |
- run: iguana_ex_cpp_config_files iguana/etc/iguana/examples | |
if: ${{ matrix.id == 'cpp' }} | |
###### python | |
- run: iguana_ex_python_00_run_functions.py test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'python' }} | |
- run: iguana_ex_python_01_action_functions.py test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'python' }} | |
- run: iguana_ex_python_hipopy.py test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'python' }} | |
###### fortran | |
- run: iguana_ex_fortran_01_action_functions test_data.hipo ${{ env.num_events }} | |
if: ${{ matrix.id == 'fortran' }} | |
### test ROOT macro | |
- name: test iguana_ex_cpp_ROOT_macro.C interpreted | |
run: root -b -q iguana_src/examples/iguana_ex_cpp_ROOT_macro.C | |
if: ${{ matrix.id == 'cpp' }} | |
- name: test iguana_ex_cpp_ROOT_macro.C compiled | |
run: root -b -q iguana_src/examples/iguana_ex_cpp_ROOT_macro.C+ | |
if: ${{ matrix.id == 'cpp' }} | |
### test consumers | |
- name: consumer test make | |
if: ${{ matrix.id == 'cpp' }} | |
run: | | |
make -C iguana_src/examples/build_with_make | |
echo "========================================= TEST RUN =========================================" | |
iguana_src/examples/build_with_make/bin/iguana_ex_cpp_00_run_functions test_data.hipo 10 | |
- name: consumer test meson | |
if: ${{ matrix.id == 'cpp' }} | |
run: | | |
meson setup build_consumer_meson iguana_src/examples/build_with_meson --prefix=$(pwd)/install_consumer_meson | |
meson install -C build_consumer_meson | |
echo "========================================= TEST RUN =========================================" | |
install_consumer_meson/bin/iguana_ex_cpp_00_run_functions test_data.hipo 10 | |
- name: consumer test cmake | |
if: ${{ matrix.id == 'cpp' }} | |
run: | | |
cmake -B build_consumer_cmake -S iguana_src/examples/build_with_cmake -DCMAKE_PREFIX_PATH=$(pwd)/hipo -G Ninja --install-prefix=$(pwd)/install_consumer_cmake | |
cmake --build build_consumer_cmake | |
cmake --install build_consumer_cmake | |
echo "========================================= TEST RUN =========================================" | |
install_consumer_cmake/bin/iguana_ex_cpp_00_run_functions test_data.hipo 10 | |
### upload artifacts | |
- name: upload build log artifacts | |
uses: actions/upload-artifact@v4 | |
if: always() | |
with: | |
name: meson_logs_${{ matrix.id }} | |
retention-days: 5 | |
path: iguana_build/meson-logs | |
- name: upload coverage artifacts | |
uses: actions/upload-artifact@v4 | |
if: ${{ matrix.id == 'coverage' }} | |
with: | |
name: coverage-report | |
retention-days: 5 | |
path: coverage-report | |
- name: upload validator artifacts | |
uses: actions/upload-artifact@v4 | |
if: ${{ matrix.id == 'cpp' }} | |
with: | |
name: _validation_results | |
retention-days: 5 | |
path: validation_results | |
- name: upload documentation artifacts | |
uses: actions/upload-artifact@v4 | |
if: ${{ matrix.id == 'documentation' }} | |
with: | |
name: doc_doxygen | |
retention-days: 5 | |
path: iguana/share/doc/iguana/html/ | |
# deployment | |
######################################################### | |
collect_webpages: | |
if: ${{ github.ref == 'refs/heads/main' && inputs.id == 'linux-latest' }} | |
name: Collect webpages | |
needs: | |
- iguana | |
runs-on: ${{ inputs.runner }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
path: iguana_src | |
- name: download doxygen documentation | |
uses: actions/download-artifact@v4 | |
with: | |
name: doc_doxygen | |
path: doxygen | |
- name: download coverage report | |
uses: actions/download-artifact@v4 | |
with: | |
name: coverage-report | |
path: coverage-report | |
- run: tree | |
- name: collect | |
run: | | |
mkdir pages | |
cp iguana_src/.github/pages-index.html pages/index.html | |
mv doxygen pages/ | |
mv coverage-report pages/ | |
- run: tree | |
- uses: actions/upload-pages-artifact@v3 | |
with: | |
retention-days: 5 | |
path: pages/ | |
deploy_webpages: | |
if: ${{ github.ref == 'refs/heads/main' && inputs.id == 'linux-latest' }} | |
name: Deploy webpages | |
needs: collect_webpages | |
permissions: | |
pages: write | |
id-token: write | |
environment: | |
name: github-pages | |
url: ${{ steps.deployment.outputs.page_url }} | |
runs-on: ${{ inputs.runner }} | |
steps: | |
- name: deployment | |
id: deployment | |
uses: actions/deploy-pages@v4 | |
# finalize | |
######################################################### | |
final: | |
name: Final | |
needs: | |
- iguana | |
runs-on: ${{ inputs.runner }} | |
steps: | |
- run: exit 0 |