Skip to content

Add releaseDryRun.sh: CI dry run of the release process - #5252

Merged
dsmiley merged 6 commits into
apache:mainfrom
dsmiley:releaseDryRun
Nov 2, 2026
Merged

dsmiley merged 6 commits into
apache:mainfrom
dsmiley:releaseDryRun

Conversation

@dsmiley

@dsmiley dsmiley commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

🤖 Adds dev-tools/scripts/releaseDryRun.sh, a dry run of the release process for the version in build.gradle (e.g. 11.0.0 on main). It's for the Solr-Smoketest-* Jenkins jobs, which have been broken for months, and it can also be run locally.

Steps, mirroring the release wizard:

  1. logchange.py prepare --commit on a local release-dry-run branch (never pushed). Pretending a real version, rather than a SNAPSHOT, exercises the version-specific checks, e.g. "Release X" in Changes.html.
  2. buildAndPushRelease.py --dev-mode --push-local, unsigned. This also covers Changes.html generation, which moved out of the Gradle build in SOLR-18119 (SOLR-18119: Generate changes HTML only for releases #5180).
  3. smokeTestRelease.py --not-signed against the local RC.

The temp dir defaults to outside the checkout. When the unpacked source release sits inside a git checkout, checkWorkingCopyClean finds the parent repo, which fails the smoke test.

Status: Solr-Smoketest-main runs this script inline. Build #1 passed everything up to and including the source-release tests, then failed on the temp-dir issue above, which is now fixed. Once this merges, the job's shell step becomes dev-tools/scripts/releaseDryRun.sh.

Not covered: signing, svn staging, and publishing.

🤖 Generated with Claude Code

Prepares the changelog on a local branch, builds an unsigned RC with buildAndPushRelease.py, and runs smokeTestRelease.py on it. For the Solr-Smoketest-* Jenkins jobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dsmiley

dsmiley commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

I'm looking forward to having the release process (namely smoketester) back to green in CI. And a script we can run locally to validate changes to the smoketester and some other scripts.

If no input; will merge in 48 hours.

@dsmiley

dsmiley commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

BTW won't merge until https://ci-builds.apache.org/job/Solr/job/Solr-Smoketest-main/ is green. I just updated it to match this bash script.

… it also works pasted inline in Jenkins

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dsmiley

dsmiley commented Oct 28, 2026

Copy link
Copy Markdown
Contributor Author

there is one quirkiness related to git-status that this script works around by CD'ing to another dir...
I'm sharing that below and a possible solution by modifying git-status.gradle. It's not a current problem with this script because of the script puts the temp dir somewhere else. Nonetheless it's worth considering doing in addition or instead. Sharing Claude's description:

🤖
The problem: checkWorkingCopyClean uses JGit's findGitDir(rootProject.projectDir), which walks up the parent directories. If you unpack a source release (which has no .git) inside another git checkout, it finds the parent repo and compares against it. In Jenkins build #1 the temp dir was inside the workspace clone. The check then failed with "Working copy is not a clean git checkout … .asf.yaml (missing)", because the unpacked tree didn't match the parent repo.

What I worked around: releaseDryRun.sh puts the temp dir outside the workspace (${WORKSPACE}_smoke). That avoids the problem without touching Gradle. Build #4 shows it working: the check now prints only a warning, Directory is not a valid git checkout (won't check dirty files).

The optional change: make git-status.gradle ignore a repo whose work tree isn't rootProject.projectDir. Then the check would behave the same wherever an unpacked source release sits. It would help anyone unpacking a release under a checkout, such as a developer testing locally. I haven't looked closely at how large or safe the change is. It's unneeded for the CI job now, so I'd drop it unless that local case matters to you.

dsmiley and others added 3 commits October 28, 2026 21:57
…le before cleanup

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
checkWorkingCopyClean and gitStatus now only consider a git repository rooted at the project dir. Previously an unpacked source release inside another git checkout was compared against the parent's index and reported every file as missing.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…l unit tests

smokeTestRelease.py runs the Gradle task named by SMOKETEST_SRC_TEST_TASK (default test) on the unpacked source release. releaseDryRun.sh sets it to testClasses since unit tests run in the regular CI jobs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@dsmiley

dsmiley commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

Jenkins job passed finally! https://ci-builds.apache.org/job/Solr/job/Solr-Smoketest-main/7/

@dsmiley dsmiley left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will merge tonight.


pip3 install -r dev-tools/scripts/requirements.txt

[[ -e "$TMP_ROOT" ]] && chmod -R u+w "$TMP_ROOT"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was quirky... had to do because our release process actually goes out of its way to remove the write permission! No justification given.

set -euo pipefail
cd "$(git rev-parse --show-toplevel)"

TMP_ROOT="${1:-${WORKSPACE:-$(pwd)}_smoke}"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a sibling dir.


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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small feature here to run this without running all tests

// (e.g. an unpacked source release inside a clone).
def findGitRepository = {
if (!rootProject.file(".git").exists()) {
throw new RepositoryNotFoundException(rootProject.projectDir)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: will be caught; not a new failure scenario

@dsmiley
dsmiley merged commit d5d7df9 into apache:main Nov 2, 2026
3 checks passed
@dsmiley
dsmiley deleted the releaseDryRun branch November 2, 2026 14:32
@dsmiley dsmiley added this to the 10.x milestone Nov 3, 2026
dsmiley added a commit that referenced this pull request Nov 3, 2026
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 <noreply@anthropic.com>
(cherry picked from commit d5d7df9)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant