Skip to content

Commit

Permalink
Speed up CI jobs with parallelism and caching (#33)
Browse files Browse the repository at this point in the history
* Speed up CI jobs with parallelism and caching

The zenoh-c build can take nearly four minutes to complete. This change
allows zenoh-c and up-cpp to build in parallel and caches zenoh-c's
build results (using zenoh-c's HEAD hash as the cache key).

When the upstream zenoh-c repo has change (and therefore no valid cache
exists), this change saves around 40 seconds of build time by not making
up-cpp wait for zenoh-c.

When the cache is valid, the zenoh-c build is skipped resulting in a
further three minute reduction in total CI run time.

* Additional CI speed-ups

Adding a cache for up-cpp build artifacts cuts another 30 seconds out of
the best-case build times (i.e. when cache is valid).

The same technique of checking the HEAD hash for the upstream repo and
providing that as the cache key is used here. Whenever HEAD is changed
in up-cpp (typically a new PR is merged), the cache is invalidated and
up-cpp is rebuilt.

Also cuts ~10 seconds out by reusing the caches we already have in the
up-client-zenoh-cpp build step. Caches load faster than uploading and
downloading additional artifacts.

* Capture up-client-zenoh-cpp's tests as artifacts

This will allow the tests to be reused in future jobs (checking
coverage, running valgrind, producing test reports, etc.)
  • Loading branch information
gregmedd authored Apr 12, 2024
1 parent 3afec75 commit c6a6380
Showing 1 changed file with 125 additions and 21 deletions.
146 changes: 125 additions & 21 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,142 @@ on:
workflow_dispatch:

jobs:
build:
name: Build
build-zenoh-c:
name: Build Zenoh-C
runs-on: ubuntu-latest
env:
Zenoh_C_Repo: https://github.com/eclipse-zenoh/zenoh-c.git
Zenoh_C_Cache_PFX: libzenohc
outputs:
Zenoh_C_Cache: ${{ env.Zenoh_C_Cache_PFX }}-${{ steps.zenoh-c-head.outputs.Zenoh_C_HEAD }}

steps:
- uses: actions/checkout@v4
- name: Check remote head hash
id: zenoh-c-head
shell: bash
run: '{ echo -n "Zenoh_C_HEAD="; git ls-remote "$Zenoh_C_Repo" HEAD | cut -f1; } | tee -a "$GITHUB_OUTPUT"'

- name: Cache compiled zenoh-c library
id: cache-libzenohc
uses: actions/cache@v4
with:
key: ${{ env.Zenoh_C_Cache_PFX }}-${{ steps.zenoh-c-head.outputs.Zenoh_C_HEAD }}
path: |
~/local
- name: Install Rust toolchain
if: ${{ steps.cache-libzenohc.outputs.cache-hit != 'true' }}
run: rustup component add rustfmt clippy

# NOTE: Checks out the head revision we found using ls-remote above
# to avoid race conditions resulting in mismatch between cache
# and contents of repo.
- name: Clone Zenoh-C
if: ${{ steps.cache-libzenohc.outputs.cache-hit != 'true' }}
env:
Zenoh_C_HEAD: ${{ steps.zenoh-c-head.outputs.Zenoh_C_HEAD }}
shell: bash
run: |
pwd
git clone "$Zenoh_C_Repo"
cd zenoh-c && git checkout "$Zenoh_C_HEAD"
- name: Build and install Zenoh-C
if: ${{ steps.cache-libzenohc.outputs.cache-hit != 'true' }}
shell: bash
run: |
mkdir -p zenoh-c/build && cd zenoh-c/build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/local
cmake --build . --target install --config Release -- -j
build-up-cpp:
name: Build up-cpp
runs-on: ubuntu-latest
env:
UP_CPP_Repo: https://github.com/eclipse-uprotocol/up-cpp.git
UP_CPP_Cache_PFX: up-cpp-conan2
outputs:
UP_CPP_Cache: ${{ env.UP_CPP_Cache_PFX }}-${{ steps.up-cpp-head.outputs.UP_CPP_HEAD }}

steps:
- name: Check remote head hash
id: up-cpp-head
shell: bash
run: '{ echo -n "UP_CPP_HEAD="; git ls-remote "$UP_CPP_Repo" HEAD | cut -f1; } | tee -a "$GITHUB_OUTPUT"'

- name: Cache conan artifacts
id: cache-conan2
uses: actions/cache@v4
with:
key: ${{ env.UP_CPP_Cache_PFX }}-${{ steps.up-cpp-head.outputs.UP_CPP_HEAD }}
path: |
~/.conan2
- name: Install Conan
if: ${{ steps.cache-conan2.outputs.cache-hit != 'true' }}
id: conan
uses: turtlebrowser/get-conan@main

- name: Conan version
run: echo "${{ steps.conan.outputs.version }}"


- name: Create default Conan profile
if: ${{ steps.cache-conan2.outputs.cache-hit != 'true' }}
run: conan profile detect

- name: Install Rust toolchain
run: rustup component add rustfmt clippy
# NOTE: Checks out the head revision we found using ls-remote above
# to avoid race conditions resulting in mismatch between cache
# and contents of repo.
- name: Clone up-cpp repo
if: ${{ steps.cache-conan2.outputs.cache-hit != 'true' }}
shell: bash
env:
UP_CPP_HEAD: ${{ steps.up-cpp-head.outputs.UP_CPP_HEAD }}
run: |
git clone "$UP_CPP_Repo"
cd up-cpp && git checkout "$UP_CPP_HEAD"
git submodule update --init --recursive
- name: Create up-cpp Conan package
if: ${{ steps.cache-conan2.outputs.cache-hit != 'true' }}
shell: bash
run: |
git clone https://github.com/eclipse-uprotocol/up-cpp.git
cd up-cpp
git submodule update --init --recursive
conan create . --build=missing
- name: Build and install Zenoh-C
shell: bash
run: |
git clone https://github.com/eclipse-zenoh/zenoh-c.git
cd zenoh-c && mkdir -p build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/local
cmake --build . --target install --config Release -- -j
- name: Clean up conan build files
if: ${{ steps.cache-conan2.outputs.cache-hit != 'true' }}
run: conan cache clean '*'

- name: Build && install up-client-zenoh-cpp
build-up-client-zenoh-cpp:
name: Build up-client-zenoh-cpp
needs: [ build-zenoh-c, build-up-cpp ]
runs-on: ubuntu-latest
env:
Zenoh_C_Cache: ${{ needs.build-zenoh-c.outputs.Zenoh_C_Cache }}
UP_CPP_Cache: ${{ needs.build-up-cpp.outputs.UP_CPP_Cache }}

steps:
# Note: will never update here since it will always match from previous job
- name: Get cached zenoh-c library
uses: actions/cache@v4
with:
key: ${{ env.Zenoh_C_Cache }}
path: |
~/local
# Note: will never update here since it will always match from previous job
- name: Get cached up-cpp conan artifacts
uses: actions/cache@v4
with:
key: ${{ env.UP_CPP_Cache }}
path: |
~/.conan2
- name: Install Conan
id: conan
uses: turtlebrowser/get-conan@main

- uses: actions/checkout@v4

- name: Build and install up-client-zenoh-cpp
shell: bash
run: |
export CMAKE_PREFIX_PATH="$HOME/local"
Expand All @@ -57,8 +155,14 @@ jobs:
cmake ../ -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/local
cmake --build . --target install --config Release -- -j
- name: Upload test binaries
uses: actions/upload-artifact@v4
with:
name: tests_up-client-zenoh-cpp
path: |
build/bin
retention-days: 1

# NOTE: In GitHub repository settings, the "Require status checks to pass
# before merging" branch protection rule ensures that commits are only merged
# from branches where specific status checks have passed. These checks are
Expand All @@ -67,7 +171,7 @@ jobs:
ci:
name: CI status checks
runs-on: ubuntu-latest
needs: build
needs: [ build-zenoh-c, build-up-cpp, build-up-client-zenoh-cpp ]
if: always()
steps:
- name: Check whether all jobs pass
Expand Down

0 comments on commit c6a6380

Please sign in to comment.