fix: make release script more robust (#717)
diff --git a/ci/scripts/build_example.sh b/ci/scripts/build_example.sh
index ff98ae6..77abbc3 100755
--- a/ci/scripts/build_example.sh
+++ b/ci/scripts/build_example.sh
@@ -21,6 +21,7 @@
 
 source_dir=${1}
 build_dir=${1}/build
+run_example=${ICEBERG_RUN_EXAMPLE:-OFF}
 
 mkdir ${build_dir}
 pushd ${build_dir}
@@ -44,8 +45,18 @@
 cmake "${CMAKE_ARGS[@]}" ${source_dir}
 if is_windows; then
   cmake --build . --config Release
+  if [[ "${run_example}" == "ON" ]]; then
+    if [[ -x ./demo_example.exe ]]; then
+      ./demo_example.exe
+    else
+      ./Release/demo_example.exe
+    fi
+  fi
 else
   cmake --build .
+  if [[ "${run_example}" == "ON" ]]; then
+    ./demo_example
+  fi
 fi
 
 popd
diff --git a/ci/scripts/build_iceberg.sh b/ci/scripts/build_iceberg.sh
index 4c88427..406ef56 100755
--- a/ci/scripts/build_iceberg.sh
+++ b/ci/scripts/build_iceberg.sh
@@ -26,6 +26,7 @@
 build_rest_integration_test=${2:-OFF}
 build_enable_sccache=${3:-OFF}
 build_enable_s3=${4:-OFF}
+run_tests=${ICEBERG_RUN_TESTS:-ON}
 
 mkdir ${build_dir}
 pushd ${build_dir}
@@ -60,13 +61,22 @@
     CMAKE_ARGS+=("-DCMAKE_C_COMPILER_LAUNCHER=sccache")
 fi
 
+if [[ -n "${ICEBERG_EXTRA_CMAKE_ARGS:-}" ]]; then
+    read -r -a EXTRA_CMAKE_ARGS <<< "${ICEBERG_EXTRA_CMAKE_ARGS}"
+    CMAKE_ARGS+=("${EXTRA_CMAKE_ARGS[@]}")
+fi
+
 cmake "${CMAKE_ARGS[@]}" ${source_dir}
 if is_windows; then
   cmake --build . --config Release --target install
-  ctest --output-on-failure -C Release
+  if [[ "${run_tests}" == "ON" ]]; then
+    ctest --output-on-failure -C Release
+  fi
 else
   cmake --build . --target install
-  ctest --output-on-failure
+  if [[ "${run_tests}" == "ON" ]]; then
+    ctest --output-on-failure
+  fi
 fi
 
 popd
diff --git a/cmake_modules/IcebergThirdpartyToolchain.cmake b/cmake_modules/IcebergThirdpartyToolchain.cmake
index 9b5d95a..152af0c 100644
--- a/cmake_modules/IcebergThirdpartyToolchain.cmake
+++ b/cmake_modules/IcebergThirdpartyToolchain.cmake
@@ -464,6 +464,7 @@
   set(CPR_ENABLE_CURL_HTTP_ONLY ON)
   set(CPR_ENABLE_SSL ON)
   set(CPR_USE_SYSTEM_CURL ON)
+  set(CPR_USE_EXISTING_CURL_TARGET ON)
 
   if(DEFINED ENV{ICEBERG_CPR_URL})
     set(CPR_URL "$ENV{ICEBERG_CPR_URL}")
@@ -471,6 +472,10 @@
     set(CPR_URL "https://github.com/libcpr/cpr/archive/refs/tags/1.14.1.tar.gz")
   endif()
 
+  if(NOT TARGET CURL::libcurl)
+    find_package(CURL REQUIRED)
+  endif()
+
   fetchcontent_declare(cpr
                        ${FC_DECLARE_COMMON_OPTIONS}
                        URL ${CPR_URL}
diff --git a/dev/release/release_rc.sh b/dev/release/release_rc.sh
index 1e13e52..fe919f2 100755
--- a/dev/release/release_rc.sh
+++ b/dev/release/release_rc.sh
@@ -44,7 +44,6 @@
 : "${RELEASE_PUSH_TAG:=${RELEASE_DEFAULT}}"
 : "${RELEASE_SIGN:=${RELEASE_DEFAULT}}"
 : "${RELEASE_UPLOAD:=${RELEASE_DEFAULT}}"
-: "${RELEASE_WATCH:=${RELEASE_DEFAULT}}"
 : "${RELEASE_WATCH_INTERVAL:=30}"
 
 cd "${SOURCE_TOP_DIR}"
@@ -83,6 +82,9 @@
   repository="${repository%.git}"
 
   echo "Looking for GitHub Actions workflow on ${repository}:${rc_tag}"
+  # If this script is interrupted or times out after the RC tag is pushed,
+  # resume from the existing GitHub Actions run without creating the tag again:
+  #   RELEASE_PULL=0 RELEASE_PUSH_TAG=0 RELEASE_RUN_ID=<run_id> ./dev/release/release_rc.sh <version> <rc>
   run_id="${RELEASE_RUN_ID:-}"
   while [ -z "${run_id}" ]; do
     echo "Waiting for run to start..."
@@ -95,33 +97,29 @@
   done
 
   echo "Found GitHub Actions workflow with ID: ${run_id}"
-  if [ "${RELEASE_WATCH}" -gt 0 ]; then
-    gh run watch --repo "${repository}" --exit-status "${run_id}"
-  else
-    while true; do
-      run_status=$(gh run view \
-        --repo "${repository}" \
-        --json 'status,conclusion' \
-        --jq '.status + " " + (.conclusion // "")' \
-        "${run_id}")
-      echo "$(date -u '+%Y-%m-%dT%H:%M:%SZ') GitHub Actions workflow status: ${run_status}"
-      gh run view \
-        --repo "${repository}" \
-        --json jobs \
-        --jq '.jobs[] | "  " + .name + ": " + .status + " " + (.conclusion // "")' \
-        "${run_id}"
-      case "${run_status}" in
-        "completed success")
-          break
-          ;;
-        completed\ *)
-          echo "GitHub Actions workflow did not complete successfully: ${run_status}"
-          exit 1
-          ;;
-      esac
-      sleep "${RELEASE_WATCH_INTERVAL}"
-    done
-  fi
+  while true; do
+    run_status=$(gh run view \
+      --repo "${repository}" \
+      --json 'status,conclusion' \
+      --jq '.status + " " + (.conclusion // "")' \
+      "${run_id}")
+    echo "$(date -u '+%Y-%m-%dT%H:%M:%SZ') GitHub Actions workflow status: ${run_status}"
+    gh run view \
+      --repo "${repository}" \
+      --json jobs \
+      --jq '.jobs[] | "  " + .name + ": " + .status + " " + (.conclusion // "")' \
+      "${run_id}"
+    case "${run_status}" in
+      "completed success")
+        break
+        ;;
+      completed\ *)
+        echo "GitHub Actions workflow did not complete successfully: ${run_status}"
+        exit 1
+        ;;
+    esac
+    sleep "${RELEASE_WATCH_INTERVAL}"
+  done
 
   mkdir -p "${rc_id}"
 
diff --git a/dev/release/verify_rc.sh b/dev/release/verify_rc.sh
index c1db295..5928fd5 100755
--- a/dev/release/verify_rc.sh
+++ b/dev/release/verify_rc.sh
@@ -48,6 +48,9 @@
 : "${VERIFY_DEFAULT:=1}"
 : "${VERIFY_DOWNLOAD:=${VERIFY_DEFAULT}}"
 : "${VERIFY_SIGN:=${VERIFY_DEFAULT}}"
+: "${VERIFY_REST:=${VERIFY_DEFAULT}}"
+: "${VERIFY_SQL:=0}"
+: "${VERIFY_INSTALL_SMOKE:=0}"
 
 VERIFY_SUCCESS=no
 
@@ -116,12 +119,27 @@
 test_source_distribution() {
   echo "Building and testing Apache Iceberg C++..."
 
+  if [ "${VERIFY_REST}" -gt 0 ]; then
+    verify_rest=ON
+  else
+    verify_rest=OFF
+  fi
+
+  if [ "${VERIFY_SQL}" -gt 0 ]; then
+    verify_sql=ON
+  else
+    verify_sql=OFF
+  fi
+
   # Configure build
   cmake -S . -B build \
     -DCMAKE_CXX_FLAGS="-Wno-deprecated-declarations" \
     -DCMAKE_BUILD_TYPE=Release \
     -DICEBERG_BUILD_STATIC=ON \
     -DICEBERG_BUILD_SHARED=ON \
+    -DICEBERG_BUILD_REST="${verify_rest}" \
+    -DICEBERG_BUILD_SQL_CATALOG="${verify_sql}" \
+    -DFETCHCONTENT_TRY_FIND_PACKAGE_MODE=NEVER \
     --compile-no-warning-as-error
 
   # Build
@@ -134,6 +152,14 @@
   mkdir -p ./install_test
   cmake --install build --prefix ./install_test
 
+  if [ "${VERIFY_INSTALL_SMOKE}" -gt 0 ]; then
+    cmake -S example -B example_build \
+      -DCMAKE_PREFIX_PATH="${PWD}/install_test" \
+      -DCMAKE_BUILD_TYPE=Release
+    cmake --build example_build --parallel $(nproc || sysctl -n hw.ncpu || echo 4)
+    ./example_build/demo_example
+  fi
+
   echo "Build, test and install completed successfully!"
 }