Choosing Between FetchContent and ExternalProject_Add for Secure Integration Tests
0 reputation · 08 Jul 2023, 03:23 UTC
0 reputation · 08 Jul 2023, 03:23 UTC
Run integration tests that require pulling a private repository during CMake configuration without exposing production credentials.
Both FetchContent and ExternalProject_Add can retrieve private sources, but their credential propagation differs: FetchContent relies on the global Git helper or environment variables at configure time, whereas ExternalProject_Add invokes Git in a separate build directory and accepts explicit command‑line options or a temporary credentials file. The trade‑off lies in how each mechanism handles credential persistence, cache reuse, and isolation from the main build tree.
ExternalProject_Add offer a cleaner way to inject a temporary .netrc or environment variable without altering the global Git configuration?FetchContent react to stale source checks when a new token is supplied on subsequent runs?ExternalProject_Add’s own build sub‑directory, isolated from the main build tree.git clone command via GIT_ARGS or a temporary .netrc; they never appear in any CMake cache entry..netrc can be created in a unique /tmp location and deleted immediately after the clone, ensuring no residue.# 1. Create a temporary .netrc with the short‑lived token
set( NETRC_PATH "${CMAKE_CURRENT_BINARY_DIR}/tmp_netrc_${PROJECT_NAME}.netrc" )
file( WRITE ${NETRC_PATH} "machine github.com\n login <dummy_user>\n password <YOUR_TEMP_TOKEN>\n" )
# 2. Configure ExternalProject_Add with GIT_ARGS that use the temp .netrc
ExternalProject_Add( my_private_repo
GIT_REPOSITORY "https://github.com/yourorg/privaterepo.git"
GIT_TAG "main"
GIT_ARGS "-c credential.helper=store -c netrc=${NETRC_PATH}"
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/src/privaterepo"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
# 3. Delete the .netrc after the clone succeeds
add_custom_command(
TARGET my_private_repo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove ${NETRC_PATH}
COMMENT "Clean up temporary .netrc"
)
Because the GIT_ARGS string is passed only to the git clone command, the token never reaches CMakeCache.txt. The temporary .netrc is removed in a POST_BUILD step, leaving no trace.
cmake -S . -B build and inspect build/CMakeCache.txt – no reference to YOUR_TEMP_TOKEN should be present.build/_deps/my_private_repo-src (the clone location). The .netrc file should not exist there.build/my_private_repo.log; it will contain the git command but the token is only passed via the -c netrc=… option, not echoed.FetchContent can still be used securely by:
GIT_ASKPASS to a script that returns the temporary token, and ensuring GIT_ASKPASS is unset after configure.GIT_TAG to force a fresh clone.CMakeCache.txt contains no token, which is guaranteed by CMake’s design.However, because FetchContent inherits the global Git configuration, any inadvertent change to the user’s ~/.gitconfig could expose the token to other projects. ExternalProject_Add’s isolation makes it the safer choice for integration tests that must keep credentials strictly temporary.
If you are using a custom GIT_ASKPASS script or have a non‑standard Git helper, let us know so we can adjust the recommendation accordingly.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.