cmake_minimum_required(VERSION 2.17) SET(CTEST_DO_SUBMIT ON) SET(CTEST_TEST_TYPE Nightly) set(CTEST_BUILD_CONFIGURATION RelWithDebInfo) set(CTEST_NIGHTLY_START_TIME "17:00:00 EST") set(CTEST_SITE "checkers.scorec.rpi.edu" ) set(CTEST_DROP_METHOD "http") set(CTEST_DROP_SITE "my.cdash.org") set(CTEST_DROP_LOCATION "/submit.php?project=SCOREC") set(CTEST_DROP_SITE_CDASH TRUE) set(CTEST_BUILD_NAME "linux-gcc-${CTEST_BUILD_CONFIGURATION}") set(CTEST_DASHBOARD_ROOT "/lore/smithc11/nightlyBuilds/" ) set(CTEST_CMAKE_GENERATOR "Unix Makefiles") set(CTEST_BUILD_FLAGS -j4) set(CTEST_PROJECT_NAME "SCOREC") set(CTEST_SOURCE_NAME src) set(CTEST_BINARY_NAME build) set(REPO_URL_BASE "git@github.com:SCOREC/core") set(BRANCHES "master;develop") set(MERGE_AUTHOR "Nightly Bot ") set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_SOURCE_NAME}") set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${CTEST_BINARY_NAME}") set(MESH_URL_BASE "git@github.com:SCOREC/pumi-meshes") set(MESHES "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}/") set(CTEST_CUSTOM_WARNING_EXCEPTION ${CTEST_CUSTOM_WARNING_EXCEPTION} "tmpnam") if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") file(MAKE_DIRECTORY "${CTEST_SOURCE_DIRECTORY}") endif() if(EXISTS "${CTEST_BINARY_DIRECTORY}") file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}") endif() file(MAKE_DIRECTORY "${CTEST_BINARY_DIRECTORY}") find_program(CTEST_GIT_COMMAND NAMES git) set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") function(setup_repo) if(EXISTS "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}") cleanup_merge(develop master) endif() if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}") message("Running \"git clone ${REPO_URL_BASE}.git ${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}\"") execute_process(COMMAND "${CTEST_GIT_COMMAND}" clone ${REPO_URL_BASE}.git "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RESULT_VARIABLE CLONE_RET) if(CLONE_RET) message(FATAL_ERROR "Cloning ${REPO_URL_BASE}.git failed (code ${RETVAR})!") else() message("Cloning ${REPO_URL_BASE}.git succeeded") endif() # make local tracking versions of all remote branches foreach(BRANCH IN LISTS BRANCHES) if(NOT "${BRANCH}" STREQUAL "master") create_branch(${BRANCH} origin/${BRANCH}) endif() endforeach() endif() endfunction(setup_repo) function(setup_meshes) execute_process(COMMAND rm -rf "${MESHES}/meshes" WORKING_DIRECTORY "${MESHES}" RESULT_VARIABLE RM_RET) execute_process(COMMAND "${CTEST_GIT_COMMAND}" clone ${MESH_URL_BASE}.git meshes WORKING_DIRECTORY "${MESHES}" RESULT_VARIABLE RETVAR) if(RETVAR) message(FATAL_ERROR "failed to clone meshes repository") else() message("check out meshes repository") endif() endfunction(setup_meshes) function(git_exec CMD ACTION) string(REPLACE " " ";" CMD2 "${CMD}") message("Running \"git ${CMD}\"") execute_process(COMMAND "${CTEST_GIT_COMMAND}" ${CMD2} WORKING_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RESULT_VARIABLE RETVAR) if(RETVAR) message(FATAL_ERROR "${ACTION} failed (code ${RETVAR})!") else() message("${ACTION} succeeded") endif() endfunction(git_exec) function(remove_branch_if_exists BRANCH_NAME) message("Attempting to delete ${BRANCH_NAME} if it exists") execute_process(COMMAND "${CTEST_GIT_COMMAND}" show-ref --quiet refs/heads/${BRANCH_NAME} WORKING_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RESULT_VARIABLE BRANCH_RET) message("git branch --list returned: ${BRANCH_RET}!") if(NOT BRANCH_RET) message("${BRANCH_NAME} exists. Attempting to delete it.") git_exec("branch -D ${BRANCH_NAME}" "Deleted ${BRANCH_NAME}.") endif() endfunction() function(create_branch BRANCH_NAME TRACKING_NAME) git_exec("branch --track ${BRANCH_NAME} ${TRACKING_NAME}" "Creating branch ${BRANCH_NAME}") endfunction(create_branch) function(checkout_branch BRANCH_NAME) git_exec("checkout ${BRANCH_NAME}" "Checking out branch ${BRANCH_NAME}") endfunction(checkout_branch) function(setup_repo) if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}") message("Running \"git clone ${REPO_URL_BASE}.git ${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}\"") execute_process(COMMAND "${CTEST_GIT_COMMAND}" clone ${REPO_URL_BASE}.git "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RESULT_VARIABLE CLONE_RET) if(CLONE_RET) message(FATAL_ERROR "Cloning ${REPO_URL_BASE}.git failed (code ${RETVAR})!") else() message("Cloning ${REPO_URL_BASE}.git succeeded") endif() # make local tracking versions of all remote branches foreach(BRANCH IN LISTS BRANCHES) if(NOT "${BRANCH}" STREQUAL "master") create_branch(${BRANCH} origin/${BRANCH}) endif() endforeach() endif() endfunction(setup_repo) function(check_current_branch BRANCH_NAME CONFIG_OPTS ERRVAR) file(MAKE_DIRECTORY "${CTEST_BINARY_DIRECTORY}/${BRANCH_NAME}") execute_process(COMMAND df -h /tmp OUTPUT_VARIABLE outVar) message(STATUS "df result {\n${outVar}}") execute_process(COMMAND pwd OUTPUT_VARIABLE outVar) message(STATUS "pwd result output {\n${outVar}}") ctest_configure( BUILD "${CTEST_BINARY_DIRECTORY}/${BRANCH_NAME}" SOURCE "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" OPTIONS "${CONFIG_OPTS}" RETURN_VALUE CONFIG_RET) if(CONFIG_RET) message(WARNING "${BRANCH_NAME} config failed (code ${CONFIG_RET})!") else() message("${BRANCH_NAME} config passed") endif() execute_process(COMMAND df -h /tmp OUTPUT_VARIABLE outVar) message(STATUS "df result {\n${outVar}}") execute_process(COMMAND pwd OUTPUT_VARIABLE outVar) message(STATUS "pwd result output {\n${outVar}}") ctest_build( BUILD "${CTEST_BINARY_DIRECTORY}/${BRANCH_NAME}" NUMBER_ERRORS NUM_BUILD_ERRORS NUMBER_WARNINGS NUM_BUILD_WARNINGS RETURN_VALUE BUILD_RET) if(NUM_BUILD_WARNINGS OR NUM_BUILD_ERRORS OR BUILD_RET) message(WARNING " ${BRANCH_NAME} build failed! ${NUM_BUILD_WARNINGS} warnings ${NUM_BUILD_ERRORS} errors code ${BUILD_RET}") else() message("${BRANCH_NAME} build passed") endif() ctest_test( BUILD "${CTEST_BINARY_DIRECTORY}/${BRANCH_NAME}" RETURN_VALUE TEST_RET) if(TEST_RET) message(WARNING "${BRANCH_NAME} testing failed (code ${TEST_RET})!") else() message("${BRANCH_NAME} testing passed") endif() if(CONFIG_RET OR NUM_BUILD_WARNINGS OR NUM_BUILD_ERRORS OR BUILD_RET OR TEST_RET) message(WARNING "some ${BRANCH_NAME} checks failed!") set(${ERRVAR} True PARENT_SCOPE) else() message("all ${BRANCH_NAME} checks passed") set(${ERRVAR} False PARENT_SCOPE) endif() if(CTEST_DO_SUBMIT) ctest_submit(PARTS Update Configure Build Test RETRY_COUNT 4 RETRY_DELAY 30 RETURN_VALUE SUBMIT_ERROR) if(SUBMIT_ERROR) message(WARNING "Could not submit ${BRANCH_NAME} results to CDash (code ${SUBMIT_ERROR})!") else() message("Submitted ${BRANCH_NAME} results to CDash") endif() endif() endfunction(check_current_branch) function(check_tracking_branch BRANCH_NAME CONFIG_OPTS ERRVAR) checkout_branch("${BRANCH_NAME}") set_property(GLOBAL PROPERTY SubProject "${BRANCH_NAME}") set_property(GLOBAL PROPERTY Label "${BRANCH_NAME}") ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RETURN_VALUE NUM_UPDATES) if("${NUM_UPDATES}" EQUAL "-1") message(FATAL_ERROR "Could not update ${BRANCH_NAME} branch!") endif() message("Updated ${NUM_UPDATES} files") check_current_branch(${BRANCH_NAME} "${CONFIG_OPTS}" ERRVAL2) set(${ERRVAR} ${ERRVAL2} PARENT_SCOPE) endfunction(check_tracking_branch) function(check_merge_branch BRANCH_NAME CONFIG_OPTS ERRVAR) set_property(GLOBAL PROPERTY SubProject "${BRANCH_NAME}") set_property(GLOBAL PROPERTY Label "${BRANCH_NAME}") check_current_branch(${BRANCH_NAME} "${CONFIG_OPTS}" ERRVAL2) set(${ERRVAR} ${ERRVAL2} PARENT_SCOPE) endfunction(check_merge_branch) function(update_branch BRANCH_NAME) checkout_branch(${BRANCH_NAME}) git_exec("pull --ff-only" "Fast-forward pulling ${BRANCH_NAME}") endfunction(update_branch) function(start_merge FIRST_BRANCH SECOND_BRANCH NEXT_ACTION) update_branch(${FIRST_BRANCH}) update_branch(${SECOND_BRANCH}) set(NEW_BRANCH "${SECOND_BRANCH}-into-${FIRST_BRANCH}") remove_branch_if_exists(${NEW_BRANCH}) create_branch(${NEW_BRANCH} origin/${FIRST_BRANCH}) checkout_branch(${NEW_BRANCH}) message("Running \"git merge --no-ff --no-commit ${SECOND_BRANCH}\"") execute_process(COMMAND "${CTEST_GIT_COMMAND}" merge --no-ff --no-commit ${SECOND_BRANCH} WORKING_DIRECTORY ${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME} OUTPUT_VARIABLE MERGE_OUTPUT RESULT_VARIABLE MERGE_RET) if("${MERGE_OUTPUT}" MATCHES "CONFLICT") message(WARNING "Merging ${SECOND_BRANCH} into ${FIRST_BRANCH} causes conflicts!") set(${NEXT_ACTION} ABORT PARENT_SCOPE) return() endif() if("${MERGE_OUTPUT}" MATCHES "Already up-to-date") message("${FIRST_BRANCH} up-to-date with ${SECOND_BRANCH}, stopping merge") set(${NEXT_ACTION} CLEANUP PARENT_SCOPE) return() endif() if(MERGE_RET) message(FATAL_ERROR "Merging ${SECOND_BRANCH} into ${FIRST_BRANCH} failed (code ${MERGE_RET})!") endif() message("Merging ${SECOND_BRANCH} into ${FIRST_BRANCH} worked okay...") set(${NEXT_ACTION} PROCEED PARENT_SCOPE) endfunction(start_merge) function(cleanup_merge FIRST_BRANCH SECOND_BRANCH) set(NEW_BRANCH "${SECOND_BRANCH}-into-${FIRST_BRANCH}") checkout_branch(master) git_exec("branch -D ${NEW_BRANCH}" "Deleting temporary branch ${NEW_BRANCH}") endfunction(cleanup_merge) function(accept_merge FIRST_BRANCH SECOND_BRANCH) set(NEW_BRANCH "${SECOND_BRANCH}-into-${FIRST_BRANCH}") message("Running \"git commit -m \"Merging ${SECOND_BRANCH} into ${FIRST_BRANCH}\" --author=\"${MERGE_AUTHOR}\"\"") execute_process(COMMAND "${CTEST_GIT_COMMAND}" commit -m "Merging ${SECOND_BRANCH} into ${FIRST_BRANCH}" --author="${MERGE_AUTHOR}" WORKING_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/${CTEST_PROJECT_NAME}" RESULT_VARIABLE RETVAR) if(RETVAR) message(FATAL_ERROR "Commiting merge ${NEW_BRANCH} failed (code ${RETVAR})!") else() message("Commiting merge ${NEW_BRANCH} succeeded") endif() git_exec("push origin ${NEW_BRANCH}:${FIRST_BRANCH}" "Pushing merge ${NEW_BRANCH}") cleanup_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) endfunction(accept_merge) function(abort_merge FIRST_BRANCH SECOND_BRANCH) set(NEW_BRANCH "${SECOND_BRANCH}-into-${FIRST_BRANCH}") git_exec("merge --abort" "Aborting ${NEW_BRANCH} merge") cleanup_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) endfunction(abort_merge) function(try_merge FIRST_BRANCH SECOND_BRANCH CONFIG) start_merge(${FIRST_BRANCH} ${SECOND_BRANCH} NEXT_ACTION) if("${NEXT_ACTION}" STREQUAL "CLEANUP") cleanup_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) return() elseif("${NEXT_ACTION}" STREQUAL "ABORT") abort_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) return() endif() set(NEW_BRANCH "${SECOND_BRANCH}-into-${FIRST_BRANCH}") check_merge_branch("${NEW_BRANCH}" "${CONFIG}" CHECK_ERR) if(CHECK_ERR) abort_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) return() endif() accept_merge(${FIRST_BRANCH} ${SECOND_BRANCH}) endfunction(try_merge) # Main code ! ctest_start(${CTEST_TEST_TYPE}) if(CTEST_DO_SUBMIT) ctest_submit(FILES "${CTEST_SCRIPT_DIRECTORY}/Project.xml" RETURN_VALUE HAD_ERROR) if(HAD_ERROR) message(WARNING "Cannot submit SCOREC Project.xml!") endif() endif() SET(CONFIGURE_OPTIONS "-DCMAKE_C_COMPILER:FILEPATH=mpicc" "-DCMAKE_CXX_COMPILER:FILEPATH=mpicxx" "-DENABLE_ZOLTAN:BOOL=ON" "-DPCU_COMPRESS:BOOL=ON" "-DIS_TESTING:BOOL=True" "-DSCOREC_CXX_WARNINGS:BOOL=ON" "-DMESHES:STRING=${MESHES}/meshes" ) SET(CONFIGURE_OPTIONS-sim "${CONFIGURE_OPTIONS}" "-DENABLE_SIMMETRIX:BOOL=ON" "-DSIM_PARASOLID:BOOL=ON" "-DSIM_MPI:STRING=mpich4.1.1" ) setup_repo() setup_meshes() foreach(BRANCH IN LISTS BRANCHES) check_tracking_branch("${BRANCH}" "${CONFIGURE_OPTIONS-sim}" CHECK_ERR) endforeach() try_merge(master develop "${CONFIGURE_OPTIONS-sim}" ${ALLOWED_WARNINGS-sim})