feat: Lepton PID #440
This file contains hidden or 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: | |
| pull_request: | |
| push: | |
| branches: [ main ] | |
| tags: [ '*' ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| defaults: | |
| run: | |
| shell: bash | |
| env: | |
| # 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 | |
| # additional options | |
| ## use offsite DB URIs, since GitHub actions does not respect the image's entrypoint, which is supposed | |
| ## to automatically choose between the onsite and offsite URIs based on hostname | |
| RCDB_CONNECTION: mysql://rcdb@clasdb.jlab.org/rcdb | |
| jobs: | |
| # download test data | |
| ######################################################### | |
| download_test_data: | |
| name: Download test data | |
| runs-on: ubuntu-latest | |
| # NOTE: using Ubuntu runner, rather than a `container-forge` image, since it's much faster for cache hits | |
| steps: | |
| - uses: actions/cache@v4 | |
| id: cache | |
| with: | |
| key: test_data # fixed key will always hit; clear cache to trigger cache miss | |
| 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 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 ./ | |
| tar xvf validation_files.tar.zst | |
| mv -v $(find validation_files -type f -name "*.hipo" | head -n1) test_data.hipo | |
| # build and test Iguana | |
| ######################################################### | |
| iguana: | |
| name: Iguana | |
| needs: | |
| - download_test_data | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| id: | |
| - cpp | |
| - python | |
| - fortran | |
| - address-sanitizer | |
| - thread-sanitizer | |
| - undefined-sanitizer | |
| - leak-sanitizer | |
| - coverage | |
| - noROOT | |
| include: | |
| # main C++ test | |
| - { id: cpp, image: base_root, CC: gcc, CXX: g++, opts: -Dbuildtype=release -Dz_require_root=true -Dtest_validator_all_stats=true } | |
| # bindings | |
| - { id: python, image: base_root, CC: gcc, CXX: g++, opts: -Dbuildtype=release -Dz_require_root=true -Dbind_python=true } | |
| - { id: fortran, image: base_root, CC: gcc, CXX: g++, opts: -Dbuildtype=release -Dz_require_root=true -Dbind_fortran=true } | |
| # sanitizers | |
| # FIXME: `b_sanitize=memory` is not used because `libc++` needs to be re-compiled with `-fsanitize=memory`; otherwise | |
| # we are bothered by false positives (e.g. from `std::map` insertion) | |
| - { id: address-sanitizer, image: base_root, CC: clang, CXX: clang++, opts: -Dbuildtype=debug -Dz_require_root=true -Db_sanitize=address -Db_lundef=false -Db_pie=true } | |
| - { id: thread-sanitizer, image: base_root, CC: clang, CXX: clang++, opts: -Dbuildtype=debug -Dz_require_root=true -Db_sanitize=thread -Db_lundef=false -Db_pie=true } | |
| - { id: undefined-sanitizer, image: base_root, CC: clang, CXX: clang++, opts: -Dbuildtype=debug -Dz_require_root=true -Db_sanitize=undefined -Db_lundef=false -Db_pie=true } | |
| - { id: leak-sanitizer, image: base_root, CC: clang, CXX: clang++, opts: -Dbuildtype=debug -Dz_require_root=true -Db_sanitize=leak -Db_lundef=false -Db_pie=true } | |
| # misc. | |
| - { id: coverage, image: base_root, CC: gcc, CXX: g++, opts: -Dbuildtype=release -Dz_require_root=true -Db_coverage=true -Dz_test_multithreading=false } | |
| - { id: noROOT, image: base, CC: gcc, CXX: g++, opts: -Dbuildtype=release -Dz_require_root=false } | |
| runs-on: ubuntu-latest | |
| container: | |
| image: codecr.jlab.org/hallb/clas12/container-forge/${{ matrix.image }}:latest | |
| options: --user root | |
| env: | |
| CC: ${{ matrix.CC }} | |
| CXX: ${{ matrix.CXX }} | |
| outputs: | |
| validation_name: ${{ steps.artifact_names.outputs.validation_name }} | |
| validation_dir: ${{ steps.artifact_names.outputs.validation_dir }} | |
| steps: | |
| - run: whoami | |
| - run: container_info | |
| - name: echo RCDB_CONNECTION | |
| run: echo $RCDB_CONNECTION | |
| ### setup | |
| - uses: actions/checkout@v6 | |
| with: | |
| path: iguana_src | |
| ### get test data | |
| - name: get test data | |
| uses: actions/cache/restore@v4 | |
| with: | |
| key: test_data | |
| path: test_data.hipo | |
| ### dependencies | |
| ###### for iguana | |
| - name: install packages for iguana | |
| run: | | |
| pacman -Sy --noconfirm | |
| pacman -S --noconfirm \ | |
| fmt \ | |
| yaml-cpp | |
| ###### for coverage | |
| - name: install packages for coverage tests | |
| if: ${{ matrix.id == 'coverage' }} | |
| run: | | |
| pacman -S --noconfirm \ | |
| python-colorlog \ | |
| python-pygments \ | |
| gcovr | |
| ###### for 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 | |
| ### artifact control | |
| - name: set artifact names | |
| id: artifact_names | |
| run: | | |
| validation_name=_validation_results__$(echo ${GITHUB_REF} | sed 's;refs/heads/;;g' | sed 's;refs/pull/;PR_;g' | sed 's;/merge$;;' | sed 's;/;__;g') | |
| validation_dir=$GITHUB_WORKSPACE/validation_results/$validation_name | |
| echo validation_name=$validation_name | tee -a $GITHUB_OUTPUT | |
| echo validation_dir=$validation_dir | tee -a $GITHUB_OUTPUT | |
| ### build | |
| - name: meson setup | |
| run: | | |
| meson setup iguana_build iguana_src \ | |
| --prefix=$GITHUB_WORKSPACE/iguana \ | |
| -Drcdb:home=$RCDB_HOME \ | |
| -Dz_require_rcdb=true \ | |
| -Dwerror=true \ | |
| -Dinstall_examples=true \ | |
| -Dtest_data_file=$GITHUB_WORKSPACE/test_data.hipo \ | |
| -Dtest_num_events=${{ env.num_events }} \ | |
| -Dtest_output_dir=${{ steps.artifact_names.outputs.validation_dir }} \ | |
| -Dtest_num_threads=${{ 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 | |
| stdbuf -o0 meson test --print-errorlogs --verbose --no-stdsplit | |
| else | |
| meson test --print-errorlogs | |
| fi | |
| ### run algorithm checks | |
| - name: algorithm code checks | |
| if: ${{ matrix.id == 'cpp' }} | |
| working-directory: iguana_src | |
| run: src/iguana/tests/algo_check.rb | |
| ### run benchmarks | |
| - name: benchmark algorithms | |
| if: ${{ matrix.id == 'cpp' }} | |
| 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 | |
| ### reproducible build test | |
| - name: reproducible build test | |
| if: ${{ matrix.id == 'cpp' }} | |
| working-directory: iguana_src | |
| run: | | |
| meson reprotest -- \ | |
| -Drcdb:home=$RCDB_HOME | |
| ### 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 | |
| if: ${{ matrix.id == 'cpp' }} # don't bother re-running santizers, etc. | |
| 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 | |
| - name: test example iguana_ex_cpp_00_run_functions.cc | |
| run: stdbuf -o0 iguana_ex_cpp_00_run_functions test_data.hipo ${{ env.num_events }} | tee equivalence.00.cpp.txt | |
| if: ${{ matrix.id == 'cpp' || matrix.id == 'python' }} | |
| - name: test example iguana_ex_cpp_00_run_functions_with_banks.cc | |
| run: stdbuf -o0 iguana_ex_cpp_00_run_functions_with_banks test_data.hipo ${{ env.num_events }} | |
| if: ${{ matrix.id == 'cpp' || matrix.id == 'python' }} | |
| - name: test example iguana_ex_cpp_01_action_functions.cc | |
| run: stdbuf -o0 iguana_ex_cpp_01_action_functions test_data.hipo ${{ env.num_events }} | tee equivalence.01.cpp.txt | |
| if: ${{ matrix.id == 'cpp' || matrix.id == 'python' }} | |
| - name: test example iguana_ex_cpp_config_files.cc | |
| run: iguana_ex_cpp_config_files iguana/etc/iguana/examples | |
| if: ${{ matrix.id == 'cpp' }} | |
| ###### python | |
| - name: test example iguana_ex_python_00_run_functions.py | |
| run: stdbuf -o0 iguana_ex_python_00_run_functions.py test_data.hipo ${{ env.num_events }} | tee equivalence.00.py.txt | |
| if: ${{ matrix.id == 'python' }} | |
| - name: test example iguana_ex_python_01_action_functions.py | |
| run: stdbuf -o0 iguana_ex_python_01_action_functions.py test_data.hipo ${{ env.num_events }} | tee equivalence.01.py.txt | |
| if: ${{ matrix.id == 'python' }} | |
| - name: test example iguana_ex_python_hipopy.py | |
| run: stdbuf -o0 iguana_ex_python_hipopy.py test_data.hipo ${{ env.num_events }} | tee equivalence.01.hipopy.txt | |
| if: ${{ matrix.id == 'python' }} | |
| ###### cpp and python equivalence | |
| - name: equivalence of C++ and Python for 00_run_functions examples | |
| if: ${{ matrix.id == 'python' }} | |
| run: diff equivalence.00.{cpp,py}.txt | |
| - name: equivalence of C++ and Python for 01_action_functions examples | |
| if: ${{ matrix.id == 'python' }} | |
| run: diff equivalence.01.{cpp,py}.txt | |
| - name: equivalence of Python HIPO bindings and HipoPy examples | |
| if: ${{ matrix.id == 'python' }} | |
| run: | | |
| grep -v 'compression type' equivalence.01.hipopy.txt > equivalence.01.hipopy.txt.tmp | |
| mv equivalence.01.hipopy.txt{.tmp,} | |
| diff equivalence.01.{py,hipopy}.txt | |
| ###### 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=$GITHUB_WORKSPACE/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=$GITHUB_WORKSPACE/hipo -G Ninja --install-prefix=$GITHUB_WORKSPACE/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@v5 | |
| if: always() | |
| with: | |
| name: meson_logs_${{ matrix.id }} | |
| retention-days: 5 | |
| path: iguana_build/meson-logs | |
| - name: upload coverage artifacts | |
| uses: actions/upload-artifact@v5 | |
| if: ${{ matrix.id == 'coverage' }} | |
| with: | |
| name: coverage-report | |
| retention-days: 5 | |
| path: coverage-report | |
| - name: upload validator artifacts | |
| uses: actions/upload-artifact@v5 | |
| if: ${{ matrix.id == 'cpp' }} | |
| with: | |
| name: ${{ steps.artifact_names.outputs.validation_name }} | |
| retention-days: 90 | |
| path: validation_results | |
| # documentation | |
| ######################################################### | |
| index_documentation: | |
| name: Index documentation | |
| runs-on: ubuntu-latest | |
| outputs: | |
| versions: ${{ steps.versions.outputs.versions }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| ### get list of versions from git tags; exclude old versions | |
| - name: get versions for documentation generation | |
| id: versions | |
| run: | | |
| echo latest | tee version_list | |
| git tag --list --sort=-v:refname |\ | |
| grep -v v0.1.0 |\ | |
| grep -v v0.2.0 |\ | |
| grep -v v0.3.0 |\ | |
| grep -v v0.4.0 |\ | |
| grep -v v0.4.1 |\ | |
| grep -v v0.5.0 |\ | |
| grep -v v0.6.0 |\ | |
| grep -v v0.7.0 |\ | |
| grep -v v0.7.1 |\ | |
| tee -a version_list | |
| versions=$(cat version_list | jq -R -s -c 'split("\n") | map(select(length > 0))') | |
| echo "versions=$versions" | tee -a $GITHUB_OUTPUT | |
| ### dependencies | |
| - name: install packages for mkdocs | |
| run: python -m pip install -r doc/mkdocs/requirements.txt | |
| ### front index page | |
| - name: mkdocs | |
| run: doc/mkdocs/generate.sh build_mkdocs pages $(cat version_list) | |
| - run: tree pages | |
| ### artifacts | |
| - name: upload documentation artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: doc_web | |
| retention-days: 5 | |
| path: pages | |
| generate_documentation: | |
| name: Generate documentation | |
| needs: [ index_documentation ] | |
| runs-on: ubuntu-latest | |
| container: | |
| image: codecr.jlab.org/hallb/clas12/container-forge/base_root:latest | |
| options: --user root | |
| strategy: | |
| matrix: | |
| version: ${{ fromJson(needs.index_documentation.outputs.versions) }} | |
| fail-fast: false | |
| steps: | |
| ### checkout | |
| - uses: actions/checkout@v6 # checkout tagged version | |
| if: ${{ matrix.version != 'latest' }} | |
| with: | |
| ref: ${{ matrix.version }} | |
| path: iguana_src | |
| - uses: actions/checkout@v6 # checkout HEAD version | |
| if: ${{ matrix.version == 'latest' }} | |
| with: | |
| path: iguana_src | |
| ### dependencies | |
| - name: install packages for iguana and doxygen | |
| run: | | |
| pacman -Sy --noconfirm | |
| pacman -S --noconfirm \ | |
| doxygen \ | |
| fmt \ | |
| graphviz \ | |
| yaml-cpp | |
| ### build | |
| - name: set latest version number to latest | |
| if: ${{ matrix.version == 'latest' }} | |
| working-directory: iguana_src | |
| run: sed -i 's;^PROJECT_NUMBER.*=.*;PROJECT_NUMBER = "LATEST";' $(find doc -name Doxyfile.in) | |
| - name: meson setup | |
| run: | | |
| meson setup iguana_build iguana_src \ | |
| --prefix=$GITHUB_WORKSPACE/iguana \ | |
| -Drcdb:home=$RCDB_HOME \ | |
| -Dz_require_rcdb=true \ | |
| -Dz_require_root=true \ | |
| -Dinstall_examples=false \ | |
| -Dinstall_documentation=true | |
| - run: meson compile | |
| working-directory: iguana_build | |
| - run: meson install | |
| working-directory: iguana_build | |
| - name: rename directory | |
| run: | | |
| mkdir pages | |
| cd pages | |
| mkdir ${{ matrix.version }} | |
| mv ../iguana/share/doc/iguana/html/* ${{ matrix.version }}/ | |
| ### artifacts | |
| - name: upload documentation artifacts | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: doc_web_${{ matrix.version }} | |
| retention-days: 5 | |
| path: pages | |
| # deployment | |
| ######################################################### | |
| collect_webpages: | |
| name: Collect webpages | |
| needs: | |
| - iguana | |
| - generate_documentation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| path: iguana_src | |
| - name: download documentation artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| pattern: doc_web* | |
| path: pages | |
| merge-multiple: true | |
| - name: download coverage report | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: coverage-report | |
| path: coverage-report | |
| - run: mv coverage-report pages/ | |
| - run: tree pages | |
| - uses: actions/upload-pages-artifact@v4 | |
| with: | |
| retention-days: 5 | |
| path: pages/ | |
| deploy_webpages: | |
| if: ${{ github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/') }} | |
| name: Deploy webpages | |
| needs: collect_webpages | |
| permissions: | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deployment.outputs.page_url }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: deployment | |
| id: deployment | |
| uses: actions/deploy-pages@v4 | |
| # finalize | |
| ######################################################### | |
| final: | |
| name: Final | |
| needs: | |
| - iguana | |
| runs-on: ubuntu-latest | |
| steps: | |
| - run: exit 0 |