This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new d5d7df993c5 Add releaseDryRun.sh: CI dry run of the release process 
(#5252)
d5d7df993c5 is described below

commit d5d7df993c541e8cf6f299cbbddbc45cc45a951f
Author: David Smiley <[email protected]>
AuthorDate: Mon Nov 2 09:32:52 2026 -0500

    Add releaseDryRun.sh: CI dry run of the release process (#5252)
    
    It's for the Solr-Smoketest-* Jenkins jobs.
    * smokeTestRelease.py: SMOKETEST_SRC_TEST_TASK to reduce/eliminate unit 
tests to run
    * git-status.gradle: allow source only execution in a subdirectory of 
another git checkout
    
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 dev-tools/scripts/README.md           |  8 +++++++
 dev-tools/scripts/releaseDryRun.sh    | 42 +++++++++++++++++++++++++++++++++++
 dev-tools/scripts/smokeTestRelease.py |  6 +++--
 gradle/validation/git-status.gradle   | 25 ++++++++++++---------
 4 files changed, 69 insertions(+), 12 deletions(-)

diff --git a/dev-tools/scripts/README.md b/dev-tools/scripts/README.md
index b32b63c4a56..47c82582e14 100644
--- a/dev-tools/scripts/README.md
+++ b/dev-tools/scripts/README.md
@@ -38,6 +38,14 @@ the full tests.
     python3 -u dev-tools/scripts/smokeTestRelease.py 
https://dist.apache.org/repos/dist/dev/solr/solr-10.0.0-RC1-rev-c7510a0...
 
 
+### releaseDryRun.sh
+
+Dry run of the release process for the version in `build.gradle`, without 
signing or
+publishing anything: prepares the changelog on a local branch, builds an RC 
with
+`buildAndPushRelease.py`, and smoke tests it. Used by the `Solr-Smoketest-*` 
Jenkins jobs.
+
+    Usage: dev-tools/scripts/releaseDryRun.sh [TMP_DIR]
+
 ### releaseWizard.py
 
 The Release Wizard guides the Release Manager through the release process step
diff --git a/dev-tools/scripts/releaseDryRun.sh 
b/dev-tools/scripts/releaseDryRun.sh
new file mode 100755
index 00000000000..b34d78a87b9
--- /dev/null
+++ b/dev-tools/scripts/releaseDryRun.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+# Dry run of the release process for the version in build.gradle: prepares the
+# changelog (committed to a local "release-dry-run" branch, never pushed), 
builds
+# an unsigned RC with buildAndPushRelease.py, then runs smokeTestRelease.py on 
it.
+# Used by the Solr-Smoketest-* Jenkins jobs.
+#
+# Usage: dev-tools/scripts/releaseDryRun.sh [TMP_DIR]
+# TMP_DIR must be outside the git checkout; it is deleted first.
+
+set -euo pipefail
+cd "$(git rev-parse --show-toplevel)"
+
+TMP_ROOT="${1:-${WORKSPACE:-$(pwd)}_smoke}"
+
+if [[ -n "$(git status --porcelain --untracked-files=no)" ]]; then
+  echo "Working tree has uncommitted changes" >&2
+  exit 1
+fi
+
+pip3 install -r dev-tools/scripts/requirements.txt
+
+[[ -e "$TMP_ROOT" ]] && chmod -R u+w "$TMP_ROOT"
+rm -rf "$TMP_ROOT"
+mkdir -p "$TMP_ROOT"
+
+VERSION=$(cd dev-tools/scripts && python3 -c 'import 
scriptutil;print(scriptutil.find_current_version())')
+echo "Dry run of release $VERSION in $TMP_ROOT"
+
+ORIG_REF=$(git symbolic-ref -q --short HEAD || git rev-parse HEAD)
+trap 'git checkout -q "$ORIG_REF"' EXIT
+
+export GIT_AUTHOR_NAME=ci GIT_AUTHOR_EMAIL=ci@localhost GIT_COMMITTER_NAME=ci 
GIT_COMMITTER_EMAIL=ci@localhost
+git checkout -B release-dry-run
+python3 -u dev-tools/scripts/logchange.py prepare --version "$VERSION" 
--release-branch release-dry-run --commit
+
+python3 -u dev-tools/scripts/buildAndPushRelease.py --dev-mode --push-local 
"$TMP_ROOT/dist" --rc-num 1
+
+# Unit tests run in the regular CI jobs; here just check that the source 
release compiles.
+export SMOKETEST_SRC_TEST_TASK=testClasses
+
+python3 -u dev-tools/scripts/smokeTestRelease.py --not-signed --tmp-dir 
"$TMP_ROOT/smoke" \
+  "file://$TMP_ROOT/dist/solr-$VERSION-RC1-rev-$(git rev-parse HEAD)"
diff --git a/dev-tools/scripts/smokeTestRelease.py 
b/dev-tools/scripts/smokeTestRelease.py
index 746138fb103..e451f1cdacc 100755
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -651,8 +651,10 @@ def verifySrcUnpacked(java, artifact, unpackPath, version, 
testArgs, tmpDir):
   print('    run "%s"' % validateCmd)
   java.run_java(validateCmd, '%s/documentation.log' % logDir)
 
-  print("    run tests w/ Java %s and testArgs='%s'..." % (java.version, 
testArgs))
-  java.run_java('./gradlew test %s' % testArgs, '%s/test.log' % logDir)
+  # SMOKETEST_SRC_TEST_TASK lets CI swap the full test run for something 
lighter
+  testTask = os.environ.get('SMOKETEST_SRC_TEST_TASK', 'test')
+  print("    run %s w/ Java %s and testArgs='%s'..." % (testTask, 
java.version, testArgs))
+  java.run_java('./gradlew %s %s' % (testTask, testArgs), '%s/test.log' % 
logDir)
   # Some integration tests need the Docker image of the binary release, and 
skip without it
   if subprocess.call('docker info', shell=True, stdout=subprocess.DEVNULL, 
stderr=subprocess.DEVNULL) == 0:
     print("    build docker image from solr-%s.tgz" % version)
diff --git a/gradle/validation/git-status.gradle 
b/gradle/validation/git-status.gradle
index 3dc28394019..55dd7092907 100644
--- a/gradle/validation/git-status.gradle
+++ b/gradle/validation/git-status.gradle
@@ -37,14 +37,23 @@ buildscript {
 }
 
 configure(rootProject) {
+  // Only a repository rooted at the project dir counts, not a parent checkout 
that merely contains it
+  // (e.g. an unpacked source release inside a clone).
+  def findGitRepository = {
+    if (!rootProject.file(".git").exists()) {
+      throw new RepositoryNotFoundException(rootProject.projectDir)
+    }
+    return new FileRepositoryBuilder()
+        .findGitDir(rootProject.projectDir)
+        .setWorkTree(rootProject.projectDir)
+        .setMustExist(true)
+        .build()
+  }
+
   task gitStatus() {
     doFirst {
       try {
-        def repository = new FileRepositoryBuilder()
-            .findGitDir(rootProject.projectDir)
-            .setWorkTree(rootProject.projectDir)
-            .setMustExist(true)
-            .build()
+        def repository = findGitRepository()
 
         def ref = repository.findRef("HEAD").getObjectId()
         project.ext.gitRev = ref.name()
@@ -65,11 +74,7 @@ configure(rootProject) {
     doFirst {
       def status
       try {
-        def repository = new FileRepositoryBuilder()
-            .findGitDir(rootProject.projectDir)
-            .setWorkTree(rootProject.projectDir)
-            .setMustExist(true)
-            .build()
+        def repository = findGitRepository()
         status = new Git(repository).status().call()
       } catch (RepositoryNotFoundException | NoWorkTreeException e) {
         status = null

Reply via email to