Skip to content

Commit c71d804

Browse files
authored
ci: improve CI caching scheme (#1994)
I recently discovered that the caching of our ccache was either not working at all, or was much less efficient/helpful than I thought. So there are a number of improvements here: - Split caching into separate restore/save, and rearrange the step order so we save cache before tests run. This allows us to save the ccache even for jobs with failed tests (where the job fails), or for jobs that we purposely end early (maybe because we see failing tests), not only when all tests finish and succeed. This makes subsequent builds, that we do on the same branch while attempting to fix failures, go faster by using the cache. - Make subsequent pushes to the same PR or REF to cancel any previous jobs, so if we push updates before the last CI run of the same branch completes, it won't keep those going as useless zombie jobs. - Change the cache key names we use to remove the github ref to encourage cache reuse across different commits or branches (I think), and to fix a couple errors where we had mis-named things and were sharing caches between jobs when we shouldn't or vice versa. - Be more careful about the location of the cache, making sure we were for sure telling the GHA cache action to be saving/restoring the same directory location that we told ccache to use as its cache. - Use CCACHE_COMPRESSION env var to be extra sure we're using compressed caches to be sure we get the best bang for buck on the limited cache storage we're allowed. In all, there were a number of subtle things broken. Give it a good scrubbing. I'm not really sure exactly which one of these, or which combination, was most responsible for getting things unstuck, but it definitely works! Some results from two test pushes in a row I did after these changes: build deps build osl VFXP 2024 / cold 4:12 6:11 VFXP 2024 / cached 1:42 (2.5x) 0:48 (7x) ABI check / cold 4:11 6:14 + 5:38(abi ref) ABI check / cached 0:57 (4.4x) 0:46 + 0:16 (11.5x) bleeding edge / cold 8:12 9:57 bleeding edge / cached 1:39 (5x) 0:44 (13.6x) It varies across jobs and from run to run, but let's call it something in the neighbourhood of 4x speedup building dependencies and 10x building OSL itself. It's not better because it doesn't speed up linking, and not all of the dependencies' build systems are doing things in a way that is amenable to ccache inserting itself into the process. Still, this should be a big help in reducing the time of our CI runs. --------- Signed-off-by: Larry Gritz <lg@larrygritz.com>
1 parent 915b3fa commit c71d804

File tree

5 files changed

+68
-50
lines changed

5 files changed

+68
-50
lines changed

.github/workflows/build-steps.yml

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,23 @@ jobs:
115115
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
116116
with:
117117
fetch-depth: '0'
118-
- name: Prepare ccache timestamp
119-
id: ccache_cache_keys
120-
shell: bash
121-
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
122-
- name: ccache
123-
id: ccache
124-
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
125-
with:
126-
path: ./ccache
127-
key: ${{github.job}}-${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
128-
restore-keys: ${{github.job}}-
129118
- name: Build setup
130119
shell: bash
131120
run: |
132121
${{inputs.setenvs}}
133122
src/build-scripts/ci-startup.bash
123+
- name: Prepare ccache timestamp
124+
id: ccache_cache_keys
125+
shell: bash
126+
run: echo "date=`date -u +'%Y-%m-%dT%H:%M:%SZ'`" >> $GITHUB_OUTPUT
127+
- name: ccache-restore
128+
id: ccache-restore
129+
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
130+
with:
131+
path: ${{ env.CCACHE_DIR }}
132+
# path: ./ccache
133+
key: ${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
134+
restore-keys: ${{inputs.nametag}}
134135
- name: Install LLVM and Clang
135136
if: inputs.llvm_action_ver != ''
136137
uses: KyleMayes/install-llvm-action@6ba6e2cd3813def9879be378609d87cb3ef3bac3 # v2.0.6
@@ -162,6 +163,26 @@ jobs:
162163
if: inputs.skip_build != '1'
163164
shell: bash
164165
run: src/build-scripts/ci-build.bash
166+
- name: Check out ABI standard
167+
if: inputs.abi_check != ''
168+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
169+
with:
170+
ref: ${{inputs.abi_check}}
171+
path: abi_standard
172+
- name: Build ABI standard
173+
if: inputs.abi_check != ''
174+
shell: bash
175+
run: |
176+
mkdir -p abi_standard/build
177+
pushd abi_standard
178+
src/build-scripts/ci-build.bash
179+
popd
180+
- name: ccache-save
181+
id: ccache-save
182+
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
183+
with:
184+
path: ${{ env.CCACHE_DIR }}
185+
key: ${{inputs.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
165186
- name: Testsuite
166187
if: inputs.skip_tests != '1'
167188
shell: bash
@@ -186,20 +207,6 @@ jobs:
186207
# sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}"
187208
time sonar-scanner --define sonar.host.url="${{ env.SONAR_SERVER_URL }}" --define sonar.cfamily.build-wrapper-output="$BUILD_WRAPPER_OUT_DIR" --define sonar.cfamily.gcov.reportsPath="_coverage" --define sonar.cfamily.threads="$PARALLEL"
188209
# Consult https://docs.sonarcloud.io/advanced-setup/ci-based-analysis/sonarscanner-cli/ for more information and options
189-
- name: Check out ABI standard
190-
if: inputs.abi_check != ''
191-
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
192-
with:
193-
ref: ${{inputs.abi_check}}
194-
path: abi_standard
195-
- name: Build ABI standard
196-
if: inputs.abi_check != ''
197-
shell: bash
198-
run: |
199-
mkdir -p abi_standard/build
200-
pushd abi_standard
201-
src/build-scripts/ci-build.bash
202-
popd
203210
- name: Check ABI
204211
if: inputs.abi_check != ''
205212
shell: bash

.github/workflows/ci.yml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ on:
3636

3737
permissions: read-all
3838

39+
# Allow subsequent pushes to the same PR or REF to cancel any previous jobs.
40+
concurrency:
41+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
42+
cancel-in-progress: true
43+
3944

4045
jobs:
4146

@@ -87,7 +92,7 @@ jobs:
8792
batched: b8_AVX2,b8_AVX512,b16_AVX512
8893
setenvs: USE_OPENVDB=0
8994
- desc: gcc9/C++17 llvm11 py3.9 exr3.1 oiio3.0 sse2 batch-b4sse2
90-
nametag: linux-vfx2021
95+
nametag: linux-vfx2022-clang
9196
runner: ubuntu-latest
9297
container: aswftesting/ci-osl:2022-clang13
9398
vfxyear: 2022
@@ -151,20 +156,21 @@ jobs:
151156
# with:
152157
# egress-policy: audit # TODO: change to 'egress-policy: block' after couple of runs
153158
- uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # v3.0.2
159+
- name: Build setup
160+
run: |
161+
${{matrix.setenvs}}
162+
src/build-scripts/ci-startup.bash
154163
- name: Prepare ccache timestamp
155164
id: ccache_cache_keys
156165
run: echo "::set-output name=date::`date -u +'%Y-%m-%dT%H:%M:%SZ'`"
157166
- name: ccache
158167
id: ccache
159-
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
168+
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
160169
with:
161-
path: /tmp/ccache
162-
key: ${{github.job}}-${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
163-
restore-keys: ${{github.job}}-${{matrix.nametag}}-
164-
- name: Build setup
165-
run: |
166-
${{matrix.setenvs}}
167-
src/build-scripts/ci-startup.bash
170+
path: ${{ env.CCACHE_DIR }}
171+
key: ${{matrix.nametag}}-${{steps.ccache_cache_keys.outputs.date}}
172+
restore-keys: ${{matrix.nametag}}-
173+
save-always: true
168174
- name: Remove existing OpenEXR
169175
if: matrix.openexr_ver != ''
170176
run: |
@@ -307,7 +313,7 @@ jobs:
307313
# break the ABI. Basically, we will build that version as well as
308314
# the current one, and compare the resulting libraries.
309315
- desc: abi check
310-
nametag: linux-vfx2023
316+
nametag: linux-abi
311317
runner: ubuntu-latest
312318
container: aswftesting/ci-osl:2023-clang15
313319
cc_compiler: gcc

src/build-scripts/ci-build.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ cp -r ${OSL_BUILD_DIR}/CMake* ${OSL_BUILD_DIR}/*.cmake ${OSL_BUILD_DIR}/cmake-sa
4141
if [[ "$BUILDTARGET" != "none" ]] ; then
4242
echo "Parallel build ${CMAKE_BUILD_PARALLEL_LEVEL} of target ${BUILDTARGET}"
4343
time ${OSL_CMAKE_BUILD_WRAPPER} cmake --build ${OSL_BUILD_DIR} --target ${BUILDTARGET} --config ${OSL_CMAKE_BUILD_TYPE}
44+
ccache --show-stats || true
4445
fi
4546

4647
if [[ "${DEBUG_CI:=0}" != "0" ]] ; then

src/build-scripts/ci-startup.bash

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ export PATH=/usr/local/bin/_ccache:/usr/lib/ccache:$PATH
1313
export USE_CCACHE=${USE_CCACHE:=1}
1414
export CCACHE_CPP2=
1515
export CCACHE_DIR=$HOME/.ccache
16+
export CCACHE_COMPRESSION=yes
17+
if [[ "$(which ccache)" != "" ]] ; then
18+
# Try to coax dependency building into also using ccache
19+
# Wait, no, this breaks old OIIO!
20+
# export CMAKE_CXX_COMPILER_LAUNCHER="ccache"
21+
# export CMAKE_C_COMPILER_LAUNCHER="ccache"
22+
ccache -z
23+
fi
1624
mkdir -p $CCACHE_DIR
1725

1826
export DISTDIR=$PWD/dist

src/cmake/compiler.cmake

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,6 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD"
217217
endif ()
218218

219219

220-
# We will use this for ccache and timing
221-
set (MY_RULE_LAUNCH "")
222-
223-
224220
###########################################################################
225221
# Use ccache if found
226222
#
@@ -229,12 +225,18 @@ set (MY_RULE_LAUNCH "")
229225
# logic here makes it work even if the user is unaware of ccache. If it's
230226
# not found on the system, it will simply be silently not used.
231227
option (USE_CCACHE "Use ccache if found" ON)
232-
find_program (CCACHE_FOUND ccache)
233-
if (CCACHE_FOUND AND USE_CCACHE)
228+
find_program (CCACHE_EXE ccache)
229+
if (CCACHE_EXE AND USE_CCACHE)
234230
if (CMAKE_COMPILER_IS_CLANG AND USE_QT AND (NOT DEFINED ENV{CCACHE_CPP2}))
235231
message (STATUS "Ignoring ccache because clang + Qt + env CCACHE_CPP2 is not set")
236232
else ()
237-
set (MY_RULE_LAUNCH ccache)
233+
if (NOT ${CXX_COMPILER_LAUNCHER} MATCHES "ccache")
234+
set (CXX_COMPILER_LAUNCHER ${CCACHE_EXR} ${CXX_COMPILER_LAUNCHER})
235+
endif ()
236+
if (NOT ${C_COMPILER_LAUNCHER} MATCHES "ccache")
237+
set (C_COMPILER_LAUNCHER ${CCACHE_EXR} ${C_COMPILER_LAUNCHER})
238+
endif ()
239+
message (STATUS "ccache enabled: ${CCACHE_EXE}")
238240
endif ()
239241
endif ()
240242

@@ -247,14 +249,8 @@ endif ()
247249
# set `-j 1` or CMAKE_BUILD_PARALLEL_LEVEL to 1.
248250
option (TIME_COMMANDS "Time each compile and link command" OFF)
249251
if (TIME_COMMANDS)
250-
set (MY_RULE_LAUNCH "${CMAKE_COMMAND} -E time ${MY_RULE_LAUNCH}")
251-
endif ()
252-
253-
254-
# Note: This must be after any option that alters MY_RULE_LAUNCH
255-
if (MY_RULE_LAUNCH)
256-
set_property (GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${MY_RULE_LAUNCH})
257-
set_property (GLOBAL PROPERTY RULE_LAUNCH_LINK ${MY_RULE_LAUNCH})
252+
set (CXX_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E time ${CXX_COMPILER_LAUNCHER})
253+
set (C_COMPILER_LAUNCHER ${CMAKE_COMMAND} -E time ${C_COMPILER_LAUNCHER})
258254
endif ()
259255

260256

0 commit comments

Comments
 (0)