From 950438f8bf082247e6c8798e35418c5b9eee53c6 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 15 May 2025 17:56:20 -0500 Subject: [PATCH 01/16] class-version.sh: recognize G:A:V:C coords --- class-version.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/class-version.sh b/class-version.sh index 96ddb53..ed77a66 100755 --- a/class-version.sh +++ b/class-version.sh @@ -55,8 +55,20 @@ first_class() { for arg in "$@" do + # Resolve Maven dependency coordinates into local files. case "$arg" in - *:*:*) + *:*:*:*) # g:a:v:c + gav=${arg%:*} + g=${gav%%:*} + av=${gav#*:} + a=${av%:*} + v=${av#*:} + c=${arg##*:} + f="$HOME/.m2/repository/$(echo "$g" | tr '.' '/')/$a/$v/$a-$v-$c.jar" + test -f "$f" || mvn dependency:get -Dartifact="$g:$a:$v:jar:$c" + arg="$f" + ;; + *:*:*) # g:a:v ga=${arg%:*} g=${ga%%:*} a=${ga#*:} @@ -66,6 +78,7 @@ do arg="$f" ;; esac + # Handle the various local file cases. case "$arg" in *.class) version=$(cat "$arg" | class_version) @@ -84,6 +97,6 @@ do continue esac - # report the results + # Report the results. echo "$arg: $version" done From e6ecc162064b4ba9f2155032efbe993f0efc4635 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 15 Jul 2025 15:53:36 -0500 Subject: [PATCH 02/16] Update repository ID for OSSRH -> Central Portal See: * https://central.sonatype.org/pages/ossrh-eol/ * https://central.sonatype.org/publish/publish-portal-maven/ For the moment, we leave the environment variable names alone, even though the prefix "OSSRH" is a misnomer now. Reason: it is possible that the existing OSSRH user tokens were migrated directly. If they don't work, I'll change this script again to use new environment variables, and issue a better error if the new variables are missing. --- ci-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-build.sh b/ci-build.sh index e1093eb..98a57b6 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -97,7 +97,7 @@ if [ -f pom.xml ]; then $(escapeXML "$MAVEN_PASS") - sonatype-nexus-releases + central $OSSRH_USER $(escapeXML "$OSSRH_PASS") From eaf2bd8194747020132e2b656b7865fcc8c86de6 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 15 Jul 2025 16:15:41 -0500 Subject: [PATCH 03/16] Rename Central Portal deployment env vars OK, now I'm renaming the credentials, because my first release failed: Error: [ERROR] Unable to upload bundle for deployment: Deployment [INFO] java.lang.RuntimeException: Invalid request. Status: 401 Response body: [INFO] at org.sonatype.central.publisher.client.httpclient.UploadPublisherEndpoint.call (UploadPublisherEndpoint.java:33) I am not actually certain the user token changed (it may just be that the legacy `OSSRH_USER=scijava-ci` value was the culprit), but that's OK: going through the few orgs that actually deploy to Maven Central to update to a new token is not really such a big hassle. --- ci-build.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index 98a57b6..191096f 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -75,14 +75,14 @@ if [ -f pom.xml ]; then mkdir -p "$HOME/.m2" settingsFile="$HOME/.m2/settings.xml" customSettings=.ci/settings.xml - if [ -z "$MAVEN_PASS" -a -z "$OSSRH_PASS" ]; then + if [ "$OSSRH_USER" -o "$OSSRH_PASS" ]; then + echo "[WARNING] Obsolete OSSRH vars detected. Secrets may need updating to deploy to Maven Central." + fi + if [ -z "$MAVEN_PASS" -a -z "$CENTRAL_PASS" ]; then echo "[WARNING] Skipping settings.xml generation (no deployment credentials)." elif [ -f "$customSettings" ]; then cp "$customSettings" "$settingsFile" else - if [ -z "$OSSRH_USER" ]; then - OSSRH_USER=scijava-ci - fi cat >"$settingsFile" < @@ -98,8 +98,8 @@ if [ -f pom.xml ]; then central - $OSSRH_USER - $(escapeXML "$OSSRH_PASS") + $CENTRAL_USER + $(escapeXML "$CENTRAL_PASS") From d2e429255a25af02fdf290ebfb369ab75d338718 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 15 Jul 2025 16:41:08 -0500 Subject: [PATCH 04/16] Rename Central Portal deployment env vars harder I missed some references earlier. --- ci-build.sh | 2 +- github-actionify.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index 191096f..b9397a0 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -138,7 +138,7 @@ EOL scmURL=${scmURL%/} if [ "$NO_DEPLOY" ]; then echo "No deploy -- the NO_DEPLOY flag is set" - elif [ ! "$SIGNING_ASC" -o ! "$GPG_KEY_NAME" -o ! "$GPG_PASSPHRASE" -o ! "$MAVEN_PASS" -o ! "$OSSRH_PASS" ]; then + elif [ ! "$SIGNING_ASC" -o ! "$GPG_KEY_NAME" -o ! "$GPG_PASSPHRASE" -o ! "$MAVEN_PASS" -o ! "$CENTRAL_PASS" ]; then echo "No deploy -- secure environment variables not available" elif [ "$BUILD_REPOSITORY" -a "$BUILD_REPOSITORY" != "$scmURL" ]; then echo "No deploy -- repository fork: $BUILD_REPOSITORY != $scmURL" diff --git a/github-actionify.sh b/github-actionify.sh index 6707c5f..a88d24f 100755 --- a/github-actionify.sh +++ b/github-actionify.sh @@ -129,8 +129,8 @@ process() { GPG_PASSPHRASE: \${{ secrets.GPG_PASSPHRASE }} MAVEN_USER: \${{ secrets.MAVEN_USER }} MAVEN_PASS: \${{ secrets.MAVEN_PASS }} - OSSRH_USER: \${{ secrets.OSSRH_USER }} - OSSRH_PASS: \${{ secrets.OSSRH_PASS }} + CENTRAL_USER: \${{ secrets.CENTRAL_USER }} + CENTRAL_PASS: \${{ secrets.CENTRAL_PASS }} SIGNING_ASC: \${{ secrets.SIGNING_ASC }}" # -- Do things -- From 0461f7bf971c43d0ed197ab2a833fd81ed3c6f0e Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 17 Jul 2025 15:06:11 -0500 Subject: [PATCH 05/16] ci-build.sh: write out settings.xml in pieces If some env vars are missing, we can still partially write it. This is especially important if CENTRAL_* vars are missing, but MAVEN_* vars are present, which as of this writing will be the case for the vast majority of SciJava-based community projects deploying to maven.scijava.org, since the transition from OSSRH to Central Portal is still very recent and many orgs have not yet been updated to match. --- ci-build.sh | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index b9397a0..4dca6ae 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -78,14 +78,19 @@ if [ -f pom.xml ]; then if [ "$OSSRH_USER" -o "$OSSRH_PASS" ]; then echo "[WARNING] Obsolete OSSRH vars detected. Secrets may need updating to deploy to Maven Central." fi - if [ -z "$MAVEN_PASS" -a -z "$CENTRAL_PASS" ]; then - echo "[WARNING] Skipping settings.xml generation (no deployment credentials)." - elif [ -f "$customSettings" ]; then + if [ -f "$customSettings" ]; then cp "$customSettings" "$settingsFile" + elif [ -z "$BUILD_REPOSITORY" ]; then + echo "Skipping settings.xml generation (no BUILD_REPOSITORY; assuming we are running locally)" else + # settings.xml header cat >"$settingsFile" < +EOL + # settings.xml scijava servers + if [ "$MAVEN_USER" -a "$MAVEN_PASS" ]; then + cat >>"$settingsFile" < scijava.releases $MAVEN_USER @@ -96,12 +101,28 @@ if [ -f pom.xml ]; then $MAVEN_USER $(escapeXML "$MAVEN_PASS") +EOL + else + echo "[WARNING] Skipping settings.xml scijava servers (no MAVEN deployment credentials)." + fi + # settings.xml central server + if [ "$CENTRAL_USER" -a "$CENTRAL_PASS" ]; then + cat >>"$settingsFile" < central $CENTRAL_USER $(escapeXML "$CENTRAL_PASS") +EOL + else + echo "[WARNING] Skipping settings.xml central server (no CENTRAL deployment credentials)." + fi + cat >>"$settingsFile" < +EOL + # settings.xml GPG profile + if [ "$GPG_KEY_NAME" -a "$GPG_PASSPHRASE" ]; then + cat >>"$settingsFile" < gpg @@ -116,6 +137,12 @@ if [ -f pom.xml ]; then +EOL + else + echo "[WARNING] Skipping settings.xml gpg profile (no GPG credentials)." + fi + # settings.xml footer + cat >>"$settingsFile" < EOL fi From 1e1b1ebbc9ac47579944430339a03dab8deb01c9 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 17 Jul 2025 15:24:05 -0500 Subject: [PATCH 06/16] ci-build.sh: skip GPG setup if no GPG credentials --- ci-build.sh | 82 ++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 39 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index 4dca6ae..194b0de 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -216,48 +216,52 @@ EOL # --== GPG SETUP ==-- - # Install GPG on macOS - if [ "$platform" = Darwin ]; then - HOMEBREW_NO_AUTO_UPDATE=1 brew install gnupg2 - fi - - # Avoid "signing failed: Inappropriate ioctl for device" error. - export GPG_TTY=$(tty) - - # Import the GPG signing key. - keyFile=.ci/signingkey.asc - if [ "$deployOK" ]; then - echo "== Importing GPG keypair ==" - mkdir -p .ci - echo "$SIGNING_ASC" > "$keyFile" - ls -la "$keyFile" - gpg --version - gpg --batch --fast-import "$keyFile" - checkSuccess $? - fi + if [ "$GPG_KEY_NAME" -a "$GPG_PASSPHRASE" ]; then + # Install GPG on macOS + if [ "$platform" = Darwin ]; then + HOMEBREW_NO_AUTO_UPDATE=1 brew install gnupg2 + fi - # HACK: Use maven-gpg-plugin 3.0.1+. Avoids "signing failed: No such file or directory" error. - maven_gpg_plugin_version=$(mavenEvaluate '${maven-gpg-plugin.version}') - case "$maven_gpg_plugin_version" in - 0.*|1.*|2.*|3.0.0) - echo "--> Forcing maven-gpg-plugin version from $maven_gpg_plugin_version to 3.0.1" - BUILD_ARGS="$BUILD_ARGS -Dmaven-gpg-plugin.version=3.0.1 -Darguments=-Dmaven-gpg-plugin.version=3.0.1" - ;; - *) - echo "--> maven-gpg-plugin version OK: $maven_gpg_plugin_version" - ;; - esac - - # HACK: Install pinentry helper program if missing. Avoids "signing failed: No pinentry" error. - if ! which pinentry >/dev/null 2>&1; then - echo '--> Installing missing pinentry helper for GPG' - sudo apt-get install -y pinentry-tty - # HACK: Restart the gpg agent, to notice the newly installed pinentry. - if { pgrep gpg-agent >/dev/null && which gpgconf >/dev/null 2>&1; } then - echo '--> Restarting gpg-agent' - gpgconf --reload gpg-agent + # Avoid "signing failed: Inappropriate ioctl for device" error. + export GPG_TTY=$(tty) + + # Import the GPG signing key. + keyFile=.ci/signingkey.asc + if [ "$deployOK" ]; then + echo "== Importing GPG keypair ==" + mkdir -p .ci + echo "$SIGNING_ASC" > "$keyFile" + ls -la "$keyFile" + gpg --version + gpg --batch --fast-import "$keyFile" checkSuccess $? fi + + # HACK: Use maven-gpg-plugin 3.0.1+. Avoids "signing failed: No such file or directory" error. + maven_gpg_plugin_version=$(mavenEvaluate '${maven-gpg-plugin.version}') + case "$maven_gpg_plugin_version" in + 0.*|1.*|2.*|3.0.0) + echo "--> Forcing maven-gpg-plugin version from $maven_gpg_plugin_version to 3.0.1" + BUILD_ARGS="$BUILD_ARGS -Dmaven-gpg-plugin.version=3.0.1 -Darguments=-Dmaven-gpg-plugin.version=3.0.1" + ;; + *) + echo "--> maven-gpg-plugin version OK: $maven_gpg_plugin_version" + ;; + esac + + # HACK: Install pinentry helper program if missing. Avoids "signing failed: No pinentry" error. + if ! which pinentry >/dev/null 2>&1; then + echo '--> Installing missing pinentry helper for GPG' + sudo apt-get install -y pinentry-tty + # HACK: Restart the gpg agent, to notice the newly installed pinentry. + if { pgrep gpg-agent >/dev/null && which gpgconf >/dev/null 2>&1; } then + echo '--> Restarting gpg-agent' + gpgconf --reload gpg-agent + checkSuccess $? + fi + fi + else + echo "[WARNING] Skipping gpg setup (no GPG credentials)." fi # --== BUILD EXECUTION ==-- From c06b42fa765dccef4d7c96cfacd5855c9d62e4ca Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 17 Jul 2025 15:55:45 -0500 Subject: [PATCH 07/16] ci-build.sh: validate deploy credentials better We don't need CENTRAL env vars when deploying to maven.scijava.org. We don't need MAVEN env vars when deploying to Central. --- ci-build.sh | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index 194b0de..a9ed6d2 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -165,10 +165,10 @@ EOL scmURL=${scmURL%/} if [ "$NO_DEPLOY" ]; then echo "No deploy -- the NO_DEPLOY flag is set" - elif [ ! "$SIGNING_ASC" -o ! "$GPG_KEY_NAME" -o ! "$GPG_PASSPHRASE" -o ! "$MAVEN_PASS" -o ! "$CENTRAL_PASS" ]; then - echo "No deploy -- secure environment variables not available" elif [ "$BUILD_REPOSITORY" -a "$BUILD_REPOSITORY" != "$scmURL" ]; then echo "No deploy -- repository fork: $BUILD_REPOSITORY != $scmURL" + elif [ "$BUILD_BASE_REF" -o "$BUILD_HEAD_REF" ]; then + echo "No deploy -- proposed change: $BUILD_HEAD_REF -> $BUILD_BASE_REF" else # Are we building a snapshot version, or a release version? version=$(mavenEvaluate '${project.version}') @@ -187,6 +187,13 @@ EOL echo "Remove the file from version control and try again." exit 1 fi + + # Check for SciJava Maven repository credentials. + if [ "$MAVEN_USER" -a "$MAVEN_PASS" ]; then + deployOK=1 + else + echo "No deploy -- MAVEN environment variables not available" + fi ;; *) # Release version -- ensure release.properties is present. @@ -195,14 +202,43 @@ EOL echo "You must use release-version.sh to release -- see https://imagej.net/develop/releasing" exit 1 fi + + # To which repository are we releasing? + releaseProfiles=$(mavenEvaluate '${releaseProfiles}') + result=$? + checkSuccess $result + if [ $result -ne 0 ]; then + echo "No deploy -- could not extract releaseProfiles string" + echo "Output of failed attempt follows:" + echo "$releaseProfiles" + fi + case "$releaseProfiles" in + *deploy-to-scijava*) + # Check for SciJava Maven repository credentials. + if [ "$MAVEN_USER" -a "$MAVEN_PASS" ]; then + deployOK=1 + else + echo "[ERROR] Cannot deploy: MAVEN environment variables not available" + exit 1 + fi + ;; + *sonatype-oss-release*) + # Check for Central Portal deployment credentials. + # Deploy to Central requires GPG-signed artifacts. + if [ "$CENTRAL_USER" -a "$CENTRAL_PASS" -a "$SIGNING_ASC" -a "$GPG_KEY_NAME" -a "$GPG_PASSPHRASE" ]; then + deployOK=1 + else + echo "[ERROR] Cannot deploy: CENTRAL environment variables not available" + exit 1 + fi + ;; + *) + echo "Unknown deploy target -- attempting to deploy anyway" + deployOK=1 + ;; + esac ;; esac - if [ "$BUILD_BASE_REF" -o "$BUILD_HEAD_REF" ] - then - echo "No deploy -- proposed change: $BUILD_HEAD_REF -> $BUILD_BASE_REF" - else - deployOK=1 - fi fi fi fi From 7b58554c9d59adfb1b7ffd6fc4a7a5acd16b6c37 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 5 Aug 2025 16:02:20 -0500 Subject: [PATCH 08/16] Remove obsolete Travis CI build script We aren't maintaining it anymore. If you want to keep using Travis CI, you can pin to an older commit in this repository, or else just fork the script from just prior to deletion and add it to your repository. --- travis-build.sh | 243 ------------------------------------------------ 1 file changed, 243 deletions(-) delete mode 100644 travis-build.sh diff --git a/travis-build.sh b/travis-build.sh deleted file mode 100644 index 1a759e1..0000000 --- a/travis-build.sh +++ /dev/null @@ -1,243 +0,0 @@ -#!/bin/bash - -# -# travis-build.sh - A script to build and/or release SciJava-based projects. -# - -dir="$(dirname "$0")" - -success=0 -checkSuccess() { - # Log non-zero exit code. - test $1 -eq 0 || echo "==> FAILED: EXIT CODE $1" 1>&2 - - # Record the first non-zero exit code. - test $success -eq 0 && success=$1 -} - -# Build Maven projects. -if [ -f pom.xml ] -then - echo travis_fold:start:scijava-maven - echo "= Maven build =" - echo - echo "== Configuring Maven ==" - - # NB: Suppress "Downloading/Downloaded" messages. - # See: https://stackoverflow.com/a/35653426/1207769 - export MAVEN_OPTS="$MAVEN_OPTS -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn" - - # Populate the settings.xml configuration. - mkdir -p "$HOME/.m2" - settingsFile="$HOME/.m2/settings.xml" - customSettings=.travis/settings.xml - if [ -f "$customSettings" ] - then - cp "$customSettings" "$settingsFile" - else - cat >"$settingsFile" < - - - scijava.releases - travis - \${env.MAVEN_PASS} - - - scijava.snapshots - travis - \${env.MAVEN_PASS} - - - sonatype-nexus-releases - scijava-ci - \${env.OSSRH_PASS} - - -EOL - # NB: Use maven.scijava.org instead of Central if defined in repositories. - # This hopefully avoids intermittent "ReasonPhrase:Forbidden" errors - # when the Travis build pings Maven Central; see travis-ci/travis-ci#6593. - grep -A 2 '' pom.xml | grep -q 'maven.scijava.org' && - cat >>"$settingsFile" < - - scijava-mirror - SciJava mirror - https://maven.scijava.org/content/groups/public/ - central - - -EOL - cat >>"$settingsFile" < - - gpg - - - \${env.HOME}/.gnupg - - - - \${env.GPG_KEY_NAME} - \${env.GPG_PASSPHRASE} - - - - -EOL - fi - - # Determine whether deploying will be possible. - deployOK= - ciURL=$(mvn -q -Denforcer.skip=true -Dexec.executable=echo -Dexec.args='${project.ciManagement.url}' --non-recursive validate exec:exec 2>&1) - if [ $? -ne 0 ] - then - echo "No deploy -- could not extract ciManagement URL" - echo "Output of failed attempt follows:" - echo "$ciURL" - else - ciRepo=${ciURL##*/} - ciPrefix=${ciURL%/*} - ciOrg=${ciPrefix##*/} - if [ "$TRAVIS_SECURE_ENV_VARS" != true ] - then - echo "No deploy -- secure environment variables not available" - elif [ "$TRAVIS_PULL_REQUEST" != false ] - then - echo "No deploy -- pull request detected" - elif [ "$TRAVIS_REPO_SLUG" != "$ciOrg/$ciRepo" ] - then - echo "No deploy -- repository fork: $TRAVIS_REPO_SLUG != $ciOrg/$ciRepo" - # TODO: Detect travis-ci.org versus travis-ci.com? - else - echo "All checks passed for artifact deployment" - deployOK=1 - fi - fi - - # Install GPG on OSX/macOS - if [ "$TRAVIS_OS_NAME" = osx ] - then - HOMEBREW_NO_AUTO_UPDATE=1 brew install gnupg2 - fi - - # Import the GPG signing key. - keyFile=.travis/signingkey.asc - key=$1 - iv=$2 - if [ "$key" -a "$iv" -a -f "$keyFile.enc" ] - then - # NB: Key and iv values were given as arguments. - echo - echo "== Decrypting GPG keypair ==" - openssl aes-256-cbc -K "$key" -iv "$iv" -in "$keyFile.enc" -out "$keyFile" -d - checkSuccess $? - fi - if [ "$deployOK" -a -f "$keyFile" ] - then - echo - echo "== Importing GPG keypair ==" - gpg --batch --fast-import "$keyFile" - checkSuccess $? - fi - - # Run the build. - BUILD_ARGS='-B -Djdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"' - if [ "$deployOK" -a "$TRAVIS_BRANCH" = master ] - then - echo - echo "== Building and deploying master SNAPSHOT ==" - mvn -Pdeploy-to-scijava $BUILD_ARGS deploy - checkSuccess $? - elif [ "$deployOK" -a -f release.properties ] - then - echo - echo "== Cutting and deploying release version ==" - mvn -B $BUILD_ARGS release:perform - checkSuccess $? - echo "== Invalidating SciJava Maven repository cache ==" - curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/maven-helper.sh && - gav=$(sh maven-helper.sh gav-from-pom pom.xml) && - ga=${gav%:*} && - echo "--> Artifact to invalidate = $ga" && - echo "machine maven.scijava.org" > "$HOME/.netrc" && - echo " login travis" >> "$HOME/.netrc" && - echo " password $MAVEN_PASS" >> "$HOME/.netrc" && - sh maven-helper.sh invalidate-cache "$ga" - checkSuccess $? - else - echo - echo "== Building the artifact locally only ==" - mvn $BUILD_ARGS install javadoc:javadoc - checkSuccess $? - fi - echo travis_fold:end:scijava-maven -fi - -# Configure conda environment, if one is needed. -if [ -f environment.yml ] -then - echo travis_fold:start:scijava-conda - echo "= Conda setup =" - - condaDir=$HOME/miniconda - condaSh=$condaDir/etc/profile.d/conda.sh - if [ ! -f "$condaSh" ]; then - echo - echo "== Installing conda ==" - if [ "$TRAVIS_PYTHON_VERSION" = "2.7" ]; then - wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh - else - wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh - fi - rm -rf "$condaDir" - bash miniconda.sh -b -p "$condaDir" - checkSuccess $? - fi - - echo - echo "== Updating conda ==" - . "$condaSh" && - conda config --set always_yes yes --set changeps1 no && - conda update -q conda && - conda info -a - checkSuccess $? - - echo - echo "== Configuring environment ==" - condaEnv=travis-scijava - test -d "$condaDir/envs/$condaEnv" && condaAction=update || condaAction=create - conda env "$condaAction" -n "$condaEnv" -f environment.yml && - conda activate "$condaEnv" - checkSuccess $? - - echo travis_fold:end:scijava-conda -fi - -# Execute Jupyter notebooks. -if which jupyter >/dev/null 2>/dev/null -then - echo travis_fold:start:scijava-jupyter - echo "= Jupyter notebooks =" - # NB: This part is fiddly. We want to loop over files even with spaces, - # so we use the "find ... -print0 | while read $'\0' ..." idiom. - # However, that runs the piped expression in a subshell, which means - # that any updates to the success variable will not persist outside - # the loop. So we suppress all stdout inside the loop, echoing only - # the final value of success upon completion, and then capture the - # echoed value back into the parent shell's success variable. - success=$(find . -name '*.ipynb' -print0 | { - while read -d $'\0' nbf - do - echo 1>&2 - echo "== $nbf ==" 1>&2 - jupyter nbconvert --execute --stdout "$nbf" >/dev/null - checkSuccess $? - done - echo $success - }) - echo travis_fold:end:scijava-jupyter -fi - -exit $success From a74c2dd6083d634fa08e47cc6d3dfe2a1ba4485f Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 6 Aug 2025 10:57:44 -0500 Subject: [PATCH 09/16] ci-build.sh: echo the mvn command used to build --- ci-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-build.sh b/ci-build.sh index a9ed6d2..95fa727 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -317,7 +317,7 @@ EOL BUILD_ARGS="$BUILD_ARGS install javadoc:javadoc" fi # Check the build result. - { mvn $BUILD_ARGS; echo $? > exit-code; } | tee mvn-log + { (set -x; mvn $BUILD_ARGS); echo $? > exit-code; } | tee mvn-log checkSuccess "$(cat exit-code)" mvn-log # --== POST-BUILD ACTIONS ==-- From dfb5cf9ac28622398168571aacc8ac398dcbb3b7 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Sat, 16 Aug 2025 17:10:40 -0500 Subject: [PATCH 10/16] Remove no-longer-functional cache invalidation With the upgrade from Nexus v2 to v3, this trick no longer works. I briefly investigated how to adjust the code to still do it, but was not immediately successful at doing so. Claude.ai suggests: # Invalidate specific paths using the browse API # First, you'd need to identify the asset and use: curl --netrc -X DELETE \ "$NEXUS_BASE_URL/service/rest/v1/assets/{assetId}" But I do not know if this would actually work, and I do not know how to obtain the assetId for a given resource. We can figure it out later if needed. But first, let's proceed without it for a while, to see what problems it creates. --- ci-build.sh | 14 -------------- maven-helper.sh | 31 ------------------------------- 2 files changed, 45 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index 95fa727..d9ab7bf 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -336,20 +336,6 @@ EOL done fi - if [ "$deployOK" -a "$success" -eq 0 ]; then - echo - echo "== Invalidating SciJava Maven repository cache ==" - curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/bdd932af4c4816f88cb6a52cdd7449f175934634/maven-helper.sh && - gav=$(sh maven-helper.sh gav-from-pom pom.xml) && - ga=${gav%:*} && - echo "--> Artifact to invalidate = $ga" && - echo "machine maven.scijava.org" >"$HOME/.netrc" && - echo " login $MAVEN_USER" >>"$HOME/.netrc" && - echo " password $MAVEN_PASS" >>"$HOME/.netrc" && - sh maven-helper.sh invalidate-cache "$ga" - checkSuccess $? - fi - echo ::endgroup:: fi diff --git a/maven-helper.sh b/maven-helper.sh index 54766c2..f5f6153 100755 --- a/maven-helper.sh +++ b/maven-helper.sh @@ -232,29 +232,6 @@ latest_version () { echo "$latest" } -# Given a GA parameter, invalidate the cache in SciJava's Nexus' group/public - -SONATYPE_DATA_CACHE_URL=https://maven.scijava.org/service/local/data_cache/repositories/sonatype/content -SONATYPE_SNAPSHOTS_DATA_CACHE_URL=https://maven.scijava.org/service/local/data_cache/repositories/sonatype-snapshots/content -invalidate_cache () { - ga="$1" - artifactId="$(artifactId "$ga")" - infix="$(groupId "$ga" | tr . /)/$artifactId" - curl --netrc -i -X DELETE \ - $SONATYPE_DATA_CACHE_URL/$infix/maven-metadata.xml && - curl --netrc -i -X DELETE \ - $SONATYPE_SNAPSHOTS_DATA_CACHE_URL/$infix/maven-metadata.xml && - version="$(latest_version "$ga")" && - infix="$infix/$version" && - curl --netrc -i -X DELETE \ - $SONATYPE_DATA_CACHE_URL/$infix/$artifactId-$version.pom && - if test "$artifactId" = "${artifactId#pom-}" - then - curl --netrc -i -X DELETE \ - $SONATYPE_DATA_CACHE_URL/$infix/$artifactId-$version.jar - fi -} - # Generate a temporary file; not thread-safe tmpfile () { @@ -477,9 +454,6 @@ all-deps|all-dependencies) latest-version) latest_version "$2" ;; -invalidate-cache) - invalidate_cache "$2" - ;; gav-from-pom) gav_from_pom "$2" ;; @@ -530,11 +504,6 @@ latest-version :[:] passed as version, it prints the current snapshot version rather than the release one). -invalidate-cache : - Invalidates the version cached in the SciJava Nexus from OSS Sonatype, - e.g. after releasing a new version to Sonatype. Requires appropriate - credentials in $HOME/.netrc for https://maven.scijava.org/. - parent-gav :[:] Prints the GAV parameter of the parent project of the given artifact. From 90b2b83cb402e562fd857ad59473263ee0e29b54 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 17 Sep 2025 07:26:52 -0700 Subject: [PATCH 11/16] release-version.sh: fix pom-scijava version check We can't ask maven.scijava.org anymore, because it no longer proxies Maven Central since the upgrade to Nexus v3. So instead, we ask Maven Central directly, which works well. --- release-version.sh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/release-version.sh b/release-version.sh index b0eb696..8f95226 100755 --- a/release-version.sh +++ b/release-version.sh @@ -181,13 +181,10 @@ test "$SKIP_VERSION_CHECK" || { } # Check that the project extends the latest version of pom-scijava. -MAVEN_HELPER="$(cd "$(dirname "$0")" && pwd)/maven-helper.sh" -test -f "$MAVEN_HELPER" || - die "Missing helper script at '$MAVEN_HELPER' -Do you have a full clone of https://github.com/scijava/scijava-scripts?" test "$SKIP_VERSION_CHECK" -o "$parentGAV" != "${parentGAV#$}" || { debug "Checking pom-scijava parent version" - latestParentVersion=$(sh -$- "$MAVEN_HELPER" latest-version "$parentGAV") + psjMavenMetadata=https://repo1.maven.org/maven2/org/scijava/pom-scijava/maven-metadata.xml + latestParentVersion=$(curl -fsL "$psjMavenMetadata" | grep '' | sed 's;.*>\([^<]*\)<.*;\1;') currentParentVersion=${parentGAV##*:} test "$currentParentVersion" = "$latestParentVersion" || die "Newer version of parent '$parentGAV' is available: $latestParentVersion. From c51053ad780df2e40ed8d47e7529bcfd9177b5f8 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Mon, 8 Sep 2025 12:34:05 -0500 Subject: [PATCH 12/16] Remove the awesome maven-helper.sh script :-( It saddens me to do this. But many of the functions are now broken, because maven.scijava.org cannot proxy Maven Central any longer, due to Sonatype deciding that Nexus v3 should be crippleware from now on. --- maven-helper.sh | 536 ------------------------------------------------ 1 file changed, 536 deletions(-) delete mode 100755 maven-helper.sh diff --git a/maven-helper.sh b/maven-helper.sh deleted file mode 100755 index f5f6153..0000000 --- a/maven-helper.sh +++ /dev/null @@ -1,536 +0,0 @@ -#!/bin/sh - -# This script uses the SciJava Maven repository at https://maven.scijava.org/ -# to fetch an artifact, or to determine the state of it. - -# error out whenever a command fails -set -e - -root_url () { - test snapshots != "$2" || { - if curl -fs https://maven.scijava.org/service/local/repositories/sonatype-snapshots/content/"$1"/maven-metadata.xml > /dev/null 2>&1 - then - echo https://maven.scijava.org/service/local/repositories/sonatype-snapshots/content - else - echo https://maven.scijava.org/content/repositories/snapshots - fi - return - } - echo https://maven.scijava.org/service/local/repo_groups/public/content -} - -die () { - echo "$*" >&2 - exit 1 -} - -# Helper (thanks, BSD!) - -get_mtime () { - stat -c %Y "$1" -} -case "$(uname -s 2> /dev/null)" in -MINGW*) - get_mtime () { - date -r "$1" +%s - } - ;; -Darwin) - get_mtime () { - stat -f %m "$1" - } - ;; -esac - -# Parse :: triplets (i.e. GAV parameters) - -groupId () { - echo "${1%%:*}" -} - -artifactId () { - result="${1#*:}" - echo "${result%%:*}" -} - -version () { - result="${1#*:}" - case "$result" in - *:*) - echo "${1##*:}" - ;; - esac -} - -# Given an xml, extract the first - -extract_tag () { - result="${2%%*}" - case "$result" in - "$2") - ;; - *) - echo "${result#*<$1>}" - ;; - esac -} - -# Given an xml, extract the last - -extract_last_tag () { - result="${2##*<$1>}" - case "$result" in - "$2") - ;; - *) - echo "${result%%*}" - ;; - esac -} - -# Given an xml, skip all sections - -skip_tag () { - result="$2" - while true - do - case "$result" in - *"<$1>"*) - result="${result%%<$1>*}${result#*}" - ;; - *) - break - ;; - esac - done - echo "$result" -} - -# Given the xml of a POM, find the parent GAV - -parent_gav_from_pom_xml () { - pom="$1" - parent="$(extract_tag parent "$pom")" - test -n "$parent" || return - groupId="$(extract_tag groupId "$parent")" - artifactId="$(extract_tag artifactId "$parent")" - version="$(extract_tag version "$parent")" - echo "$groupId:$artifactId:$version" -} - -# Given a GAV parameter, determine the base URL of the project - -project_url () { - gav="$1" - artifactId="$(artifactId "$gav")" - infix="$(groupId "$gav" | tr . /)/$artifactId" - version="$(version "$gav")" - case "$version" in - *SNAPSHOT) - echo "$(root_url $infix snapshots)/$infix" - ;; - *) - # Release could be in either releases or thirdparty; try releases first - project_url="$(root_url $infix releases)/$infix" - header=$(curl -Is "$project_url/") - case "$header" in - HTTP/1.?" 200 OK"*) - ;; - *) - project_url="$(root_url $infix thirdparty)/$infix" - ;; - esac - echo "$project_url" - ;; - esac -} - -# Given a GAV parameter, determine the URL of the .jar file - -jar_url () { - gav="$1" - artifactId="$(artifactId "$gav")" - version="$(version "$gav")" - infix="$(groupId "$gav" | tr . /)/$artifactId/$version" - case "$version" in - *-SNAPSHOT) - url="$(root_url $infix snapshots)/$infix/maven-metadata.xml" - metadata="$(curl -s "$url")" - timestamp="$(extract_tag timestamp "$metadata")" - buildNumber="$(extract_tag buildNumber "$metadata")" - version=${version%-SNAPSHOT}-$timestamp-$buildNumber - echo "$(root_url $infix snapshots)/$infix/$artifactId-$version.jar" - ;; - *) - echo "$(root_url $infix releases)/$infix/$artifactId-$version.jar" - ;; - esac -} - -# Given a GAV parameter, return the URL to the corresponding .pom file - -pom_url () { - url="$(jar_url "$1")" - echo "${url%.jar}.pom" -} - -# Given a POM file, find its GAV parameter - -gav_from_pom () { - pom="$(cat "$1")" - parent="$(extract_tag parent "$pom")" - pom="$(skip_tag parent "$pom")" - pom="$(skip_tag dependencies "$pom")" - pom="$(skip_tag profiles "$pom")" - pom="$(skip_tag build "$pom")" - groupId="$(extract_tag groupId "$pom")" - test -n "$groupId" || groupId="$(extract_tag groupId "$parent")" - artifactId="$(extract_tag artifactId "$pom")" - version="$(extract_tag version "$pom")" - test -n "$version" || version="$(extract_tag version "$parent")" - echo "$groupId:$artifactId:$version" -} - -# Given a GAV parameter, find its parent's GAV - -parent_gav () { - gav="$1" - groupId="$(groupId "$gav")" - artifactId="$(artifactId "$gav")" - version="$(version "$gav")" - test -n "$version" || version="$(latest_version "$gav")" - pom="$(read_pom "$groupId:$artifactId:$version")" - parent_gav_from_pom_xml "$pom" -} - -# Given a POM file, find its parent's GAV - -parent_gav_from_pom () { - pom="$(cat "$1")" - parent_gav_from_pom_xml "$pom" -} - -# Given a POM file, extract its packaging - -packaging_from_pom () { - pom="$(cat "$1")" - pom="$(skip_tag parent "$pom")" - pom="$(skip_tag dependencies "$pom")" - pom="$(skip_tag profiles "$pom")" - pom="$(skip_tag build "$pom")" - packaging="$(extract_tag packaging "$pom")" - echo "${packaging:-jar}" -} - -# Given a GAV parameter possibly lacking a version, determine the latest version - -latest_version () { - metadata="$(curl -s "$(project_url "$1")"/maven-metadata.xml)" - latest="$(extract_tag release "$metadata")" - test -n "$latest" || latest="$(extract_tag latest "$metadata")" - test -n "$latest" || latest="$(extract_last_tag version "$metadata")" - echo "$latest" -} - -# Generate a temporary file; not thread-safe - -tmpfile () { - i=1 - while test -f /tmp/precompiled.$i"$1" - do - i=$(($i+1)) - done - echo /tmp/precompiled.$i"$1" -} - -# Given a GAV or a path, read the POM - -read_pom () { - case "$1" in - pom.xml|*/pom.xml|*\\pom.xml) - cat "$1" - ;; - *) - curl -s "$(pom_url "$1")" - ;; - esac -} - -# Given a GAV parameter (or pom.xml path) and a name, resolve a property (falling back to parents) - -get_property () { - gav="$1" - key="$2" - case "$key" in - imagej1.version) - latest_version net.imagej:ij - return - ;; - project.groupId) - groupId "$gav" - return - ;; - project.version) - version "$gav" - return - ;; - esac - while test -n "$gav" - do - pom="$(read_pom "$gav")" - properties="$(extract_tag properties "$pom")" - property="$(extract_tag "$key" "$properties")" - if test -n "$property" - then - echo "$property" - return - fi - gav="$(parent_gav_from_pom_xml "$pom")" - done - die "Could not resolve \${$2} in $1" -} - -# Given a GAV parameter and a string, expand properties - -expand () { - gav="$1" - string="$2" - result= - while true - do - case "$string" in - *'${'*'}'*) - result="$result${string%%\$\{*}" - string="${string#*\$\{}" - key="${string%\}*}" - result="$result$(get_property "$gav" "$key")" - string="${string#$key\}}" - ;; - *) - echo "$result$string" - break - ;; - esac - done -} - -# Given a GAV parameter, make a list of its dependencies (as GAV parameters) - -get_dependencies () { - pom="$(read_pom "$1")" - while true - do - case "$pom" in - *''*) - dependency="$(extract_tag dependency "$pom")" - scope="$(extract_tag scope "$dependency")" - case "$scope" in - ''|compile) - groupId="$(expand "$1" "$(extract_tag groupId "$dependency")")" - artifactId="$(extract_tag artifactId "$dependency")" - version="$(expand "$1" "$(extract_tag version "$dependency")")" - echo "$groupId:$artifactId:$version" - ;; - esac - pom="${pom#*}" - ;; - *) - break; - esac - done -} - -# Given a GAV parameter and a space-delimited list of GAV parameters, expand -# the list by the first parameter and its dependencies (unless the list already -# contains said parameter) - -get_all_dependencies () { - case " $2 " in - *" $1 "*) - ;; # list already contains the depdendency - *) - gav="$1" - set "" "$2 $1" - for dependency in $(get_dependencies "$gav") - do - set "" "$(get_all_dependencies "$dependency" "$2")" - done - ;; - esac - echo "$2" -} - -# Given a GAV parameter, download the .jar file - -get_jar () { - url="$(jar_url "$1")" - tmpfile="$(tmpfile .jar)" - curl -s "$url" > "$tmpfile" - test " "$tmpfile" - test PK = "$(head -c 2 "$tmpfile")" - echo "$tmpfile" -} - -# Given a GAV parameter, get the commit from the manifest of the deployed .jar - -commit_from_gav () { - jar="$(get_jar "$1")" - unzip -p "$jar" META-INF/MANIFEST.MF | - sed -n -e 's/^Implementation-Build: *//pi' | - tr -d '\r' - rm "$jar" -} - -# Given a GAV parameter, determine whether the .jar file is already in plugins/ -# or jars/ - -is_jar_installed () { - artifactId="$(artifactId "$1")" - version="$(version "$1")" - file=$artifactId-$version.jar - test -f "$file" || file=../plugins/$file - test -f "$file" || return 1 - case "$version" in - *-SNAPSHOT) - # is the file younger than a day? - mtime="$(get_mtime "$file")" - test "$(($mtime-$(date +%s)))" -gt -86400 - ;; - esac -} - -# Given a .jar file, determine whether it is an ImageJ 1.x plugin - -is_ij1_plugin () { - unzip -l "$1" plugins.config > /dev/null 2>&1 -} - -# Given a GAV parameter, download the .jar file and its dependencies as needed -# and install them into plugins/ or jars/, respectively - -install_jar () { - for gav in $(get_all_dependencies "$1") - do - if ! is_jar_installed "$gav" - then - tmp="$(get_jar "$gav")" - name="$(artifactId "$gav")-$(version "$gav").jar" - if test -d ../plugins && is_ij1_plugin "$tmp" - then - mv "$tmp" "../plugins/$name" - else - mv "$tmp" "$name" - fi - fi - done -} - -# Determine whether a local project (specified as pom.xml) needs to be deployed - -is_deployed () { - gav="$(gav_from_pom "$1")" && - commit="$(commit_from_gav "$gav")" && - test -n "$commit" && - dir="$(dirname "$1")" && - (cd "$dir" && - git diff --quiet "$commit".. -- .) -} - -# The main part - -case "$1" in -commit) - commit_from_gav "$2" - ;; -deps|dependencies) - get_dependencies "$2" - ;; -all-deps|all-dependencies) - get_all_dependencies "$2" | - tr ' ' '\n' | - grep -v '^$' - ;; -latest-version) - latest_version "$2" - ;; -gav-from-pom) - gav_from_pom "$2" - ;; -parent-gav) - parent_gav "$2" - ;; -pom-url) - pom_url "$2" - ;; -parent-gav-from-pom) - parent_gav_from_pom "$2" - ;; -packaging-from-pom) - packaging_from_pom "$2" - ;; -property-from-pom|get-property|property) - if test $# -lt 3 - then - get_property pom.xml "$2" - else - get_property "$2" "$3" - fi - ;; -install) - install_jar "$2" - ;; -is-deployed) - is_deployed "$2" - ;; -*) - test $# -eq 0 || echo "Unknown command: $1" >&2 - die "Usage: $0 [command] [argument...]"' - -Commands: - -commit :: - Gets the commit from which the given artifact was built. - -dependencies :: - Lists the direct dependencies of the given artifact. - -all-dependencies :: - Lists all dependencies of the given artifact, including itself and - transitive dependencies. - -latest-version :[:] - Prints the current version of the given artifact (if "SNAPSHOT" is - passed as version, it prints the current snapshot version rather - than the release one). - -parent-gav :[:] - Prints the GAV parameter of the parent project of the given artifact. - -pom-url :: - Gets the URL of the POM describing the given artifact. - -gav-from-pom - Prints the GAV parameter described in the given pom.xml file. - -parent-gav-from-pom - Prints the GAV parameter of the parent project of the pom.xml file. - -packaging-from-pom - Prints the packaging type of the given project. - -property-from-pom - Prints the property specified in the pom.xml file (or in its parents). - -install :: - Installs the given artifact and all its dependencies; if the artifact - or dependency to install is an ImageJ 1.x plugin and the parent - directory contains a subdirectory called "plugins", it will be - installed there, otherwise into the current directory. - -is-deployed - Tests whether the specified project is deployed alright. Fails - with exit code 1 if not. -' - ;; -esac From 9848f55649a1691df6bd9395eb6b54b7e88e2ae6 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 25 Nov 2025 15:58:03 -0600 Subject: [PATCH 13/16] Update github-actionification * actions/checkout: v2 -> v4 * actions/setup-java: v3 -> v4 * ensure setup and build scripts run with bash (hard stare at Windows) --- github-actionify.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/github-actionify.sh b/github-actionify.sh index a88d24f..f6c5a56 100755 --- a/github-actionify.sh +++ b/github-actionify.sh @@ -109,9 +109,9 @@ process() { # -- GitHub Action steps -- - actionCheckout="uses: actions/checkout@v2" + actionCheckout="uses: actions/checkout@v4" actionSetupJava="name: Set up Java - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '8' distribution: 'zulu' @@ -121,9 +121,11 @@ process() { - name: Install conda packages run: conda env update -f environment.yml -n base" actionSetupCI="name: Set up CI environment - run: $ciSetupScript" + run: $ciSetupScript + shell: bash" actionExecuteBuild="name: Execute the build - run: $ciBuildScript" + run: $ciBuildScript + shell: bash" actionSecrets="env: GPG_KEY_NAME: \${{ secrets.GPG_KEY_NAME }} GPG_PASSPHRASE: \${{ secrets.GPG_PASSPHRASE }} From 2e4bc1b99ac3edf8bd6cce119c2ca75792f1143c Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 25 Nov 2025 16:19:46 -0600 Subject: [PATCH 14/16] ci-build.sh: use single quotes for string literals --- ci-build.sh | 56 ++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/ci-build.sh b/ci-build.sh index d9ab7bf..caa05de 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -65,7 +65,7 @@ if [ -f pom.xml ]; then # --== MAVEN SETUP ==-- echo - echo "== Configuring Maven ==" + echo '== Configuring Maven ==' # NB: Suppress "Downloading/Downloaded" messages. # See: https://stackoverflow.com/a/35653426/1207769 @@ -76,12 +76,12 @@ if [ -f pom.xml ]; then settingsFile="$HOME/.m2/settings.xml" customSettings=.ci/settings.xml if [ "$OSSRH_USER" -o "$OSSRH_PASS" ]; then - echo "[WARNING] Obsolete OSSRH vars detected. Secrets may need updating to deploy to Maven Central." + echo '[WARNING] Obsolete OSSRH vars detected. Secrets may need updating to deploy to Maven Central.' fi if [ -f "$customSettings" ]; then cp "$customSettings" "$settingsFile" elif [ -z "$BUILD_REPOSITORY" ]; then - echo "Skipping settings.xml generation (no BUILD_REPOSITORY; assuming we are running locally)" + echo 'Skipping settings.xml generation (no BUILD_REPOSITORY; assuming we are running locally)' else # settings.xml header cat >"$settingsFile" < EOL else - echo "[WARNING] Skipping settings.xml scijava servers (no MAVEN deployment credentials)." + echo '[WARNING] Skipping settings.xml scijava servers (no MAVEN deployment credentials).' fi # settings.xml central server if [ "$CENTRAL_USER" -a "$CENTRAL_PASS" ]; then @@ -115,7 +115,7 @@ EOL EOL else - echo "[WARNING] Skipping settings.xml central server (no CENTRAL deployment credentials)." + echo '[WARNING] Skipping settings.xml central server (no CENTRAL deployment credentials).' fi cat >>"$settingsFile" < @@ -139,7 +139,7 @@ EOL EOL else - echo "[WARNING] Skipping settings.xml gpg profile (no GPG credentials)." + echo '[WARNING] Skipping settings.xml gpg profile (no GPG credentials).' fi # settings.xml footer cat >>"$settingsFile" < "$keyFile" ls -la "$keyFile" @@ -297,7 +297,7 @@ EOL fi fi else - echo "[WARNING] Skipping gpg setup (no GPG credentials)." + echo '[WARNING] Skipping gpg setup (no GPG credentials).' fi # --== BUILD EXECUTION ==-- @@ -305,15 +305,15 @@ EOL # Run the build. if [ "$deployOK" -a -f release.properties ]; then echo - echo "== Cutting and deploying release version ==" + echo '== Cutting and deploying release version ==' BUILD_ARGS="$BUILD_ARGS release:perform" elif [ "$deployOK" ]; then echo - echo "== Building and deploying main branch SNAPSHOT ==" + echo '== Building and deploying main branch SNAPSHOT ==' BUILD_ARGS="-Pdeploy-to-scijava $BUILD_ARGS deploy" else echo - echo "== Building the artifact locally only ==" + echo '== Building the artifact locally only ==' BUILD_ARGS="$BUILD_ARGS install javadoc:javadoc" fi # Check the build result. From 54c788f390e1d46b64ec29104d23778f900cce83 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 25 Nov 2025 16:24:33 -0600 Subject: [PATCH 15/16] ci-build.sh: analyze workflow if vars are missing --- ci-build.sh | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/ci-build.sh b/ci-build.sh index caa05de..8d68269 100755 --- a/ci-build.sh +++ b/ci-build.sh @@ -58,6 +58,66 @@ mavenEvaluate() { mvn -B -U -q -Denforcer.skip=true -Dexec.executable=echo -Dexec.args="$1" --non-recursive validate exec:exec 2>&1 } +# Output debugging info, for troubleshooting builds. +dump() { + if env | grep -q ^$1= + then + # Environment variable is set. + line=$(env | grep ^$1=) + if [ "$line" ] + then + # And it's non-empty. + if [ "$2" ] + then + # Secret value: emit only that it is present. + echo "$1=" + else + # Not a secret: emit in plaintext. + echo "$line" + fi + else + # But it is empty! + echo "$1=" + fi + else + # Environment variable is not set. + echo "$1=" + fi +} + +analyzeGitHubWorkflow() { + test -d .github/workflows || return + echo + echo '/--------------------------------------------------\' + echo '| ci-build.sh analysis: env vars + GitHub workflow |' + echo '\--------------------------------------------------/' + dump dir + dump platform + dump BUILD_REPOSITORY + dump NO_DEPLOY + echo '----------------------------------------------------' + dump GPG_KEY_NAME secret + dump GPG_PASSPHRASE secret + dump MAVEN_USER secret + dump MAVEN_PASS secret + dump CENTRAL_USER secret + dump CENTRAL_PASS secret + dump SIGNING_ASC secret + echo '----------------------------------------------------' + for var in \ + GPG_KEY_NAME \ + GPG_PASSPHRASE \ + MAVEN_USER \ + MAVEN_PASS \ + CENTRAL_USER \ + CENTRAL_PASS \ + SIGNING_ASC + do + grep -q "secrets.$var" .github/workflows/*.yml || + echo "Add \`$var: \${{ secrets.$var }}\` to GitHub workflow env section!" + done +} + # Build Maven projects. if [ -f pom.xml ]; then echo ::group::"= Maven build =" @@ -193,6 +253,7 @@ EOL deployOK=1 else echo 'No deploy -- MAVEN environment variables not available' + analyzeGitHubWorkflow fi ;; *) @@ -219,6 +280,7 @@ EOL deployOK=1 else echo '[ERROR] Cannot deploy: MAVEN environment variables not available' + analyzeGitHubWorkflow exit 1 fi ;; @@ -229,6 +291,7 @@ EOL deployOK=1 else echo '[ERROR] Cannot deploy: CENTRAL environment variables not available' + analyzeGitHubWorkflow exit 1 fi ;; From 8b1eabf060daa50562c80a0606ba6554f1f1d3ed Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 26 Nov 2025 10:25:31 -0600 Subject: [PATCH 16/16] release-version.sh: detect external auto-staging See mobie/mobie-viewer-fiji#1104. --- release-version.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/release-version.sh b/release-version.sh index 8f95226..4505de4 100755 --- a/release-version.sh +++ b/release-version.sh @@ -352,6 +352,25 @@ then $DRY_RUN git commit -s -m "Bump to next development cycle" fi && +# Check that release-only files were not erroneously committed. +if test -z "$DRY_RUN" +then + debug "Verifying release-only files were not committed" + for release_file in release.properties pom.xml.releaseBackup + do + if git diff --name-only HEAD~1 HEAD | grep -qF "$release_file" + then + die "FATAL: $release_file was committed to the branch! +This likely means your IDE automatically staged these files. +Please configure your IDE to NOT auto-stage files during the release process. +You can undo this failed release with: + git reset --hard HEAD~1 + git tag -d \$(sed -n 's/^scm.tag=//p' < release.properties) +Then try the release again after disabling IDE auto-staging." + fi + done +fi && + # Extract the name of the new tag. debug "Extracting new tag name" if test -z "$DRY_RUN"