diff --git a/.github/actions/setup-wheels-test-env/action.yml b/.github/actions/setup-wheels-test-env/action.yml index 10102f69bd..4fe3ae59a7 100644 --- a/.github/actions/setup-wheels-test-env/action.yml +++ b/.github/actions/setup-wheels-test-env/action.yml @@ -81,8 +81,7 @@ runs: - name: Download SQLite JDBC driver shell: bash run: | - curl -sL --retry 3 --retry-delay 2 --retry-all-errors "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.50.3.0/sqlite-jdbc-3.50.3.0.jar" \ - -o /tmp/sqlite-jdbc.jar + bash tools/ci/fetch-sqlite-jdbc.sh /tmp/sqlite-jdbc.jar - name: Start Lucee server shell: bash diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 314ff263fd..5a71a8e487 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -92,8 +92,7 @@ jobs: - name: Download SQLite JDBC driver run: | - curl -sL --retry 3 --retry-delay 2 --retry-all-errors "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.50.3.0/sqlite-jdbc-3.50.3.0.jar" \ - -o /tmp/sqlite-jdbc.jar + bash tools/ci/fetch-sqlite-jdbc.sh /tmp/sqlite-jdbc.jar - name: Start Lucee server run: | diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 4a3c411aaf..7ae3fcff0b 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -81,8 +81,7 @@ jobs: - name: Download SQLite JDBC driver run: | - curl -sL --retry 3 --retry-delay 2 --retry-all-errors "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.50.3.0/sqlite-jdbc-3.50.3.0.jar" \ - -o /tmp/sqlite-jdbc.jar + bash tools/ci/fetch-sqlite-jdbc.sh /tmp/sqlite-jdbc.jar - name: Start Lucee server run: | diff --git a/cli/lucli/tests/specs/commands/CliHardenerS1S10Spec.cfc b/cli/lucli/tests/specs/commands/CliHardenerS1S10Spec.cfc index 2ae3c874e8..8fda00faed 100644 --- a/cli/lucli/tests/specs/commands/CliHardenerS1S10Spec.cfc +++ b/cli/lucli/tests/specs/commands/CliHardenerS1S10Spec.cfc @@ -145,11 +145,18 @@ component extends="wheels.wheelstest.system.BaseSpec" { it("wheels start stages 3.49.1.0; test-cli-local.sh downloads 3.49.1.0; CI pr.yml uses 3.50.3.0", () => { expect(moduleSrc).toInclude("sqlite-jdbc-3.49.1.0"); expect(find("3.50.3.0", moduleSrc)).toBe(0); + // Both download through tools/ci/fetch-sqlite-jdbc.sh, which defaults to the CI + // version; test-cli-local.sh passes 3.49.1.0 and its SHA-256 explicitly. + var fetcher = fileRead(variables.repoRoot & "tools/ci/fetch-sqlite-jdbc.sh"); + expect(fetcher).toInclude('VERSION="3.50.3.0"'); + expect(find("3.49.1.0", fetcher)).toBe(0); var sh = fileRead(cliLocalScript); - expect(sh).toInclude("sqlite-jdbc/3.49.1.0/sqlite-jdbc-3.49.1.0.jar"); + expect(sh).toInclude("tools/ci/fetch-sqlite-jdbc.sh"); + expect(sh).toInclude("sqlite-jdbc-3.49.1.0.jar"); + expect(reFind("fetch-sqlite-jdbc\.sh""[^\n]*\\\n\s*3\.49\.1\.0 [0-9a-f]{64}", sh)).toBeGT(0); expect(find("3.50.3.0", sh)).toBe(0); var pr = fileRead(prYml); - expect(pr).toInclude("sqlite-jdbc/3.50.3.0/sqlite-jdbc-3.50.3.0.jar"); + expect(reFind("bash tools/ci/fetch-sqlite-jdbc\.sh /tmp/sqlite-jdbc\.jar\s*\n", pr)).toBeGT(0); expect(find("3.49.1.0", pr)).toBe(0); }); diff --git a/tools/ci/fetch-sqlite-jdbc.sh b/tools/ci/fetch-sqlite-jdbc.sh new file mode 100755 index 0000000000..7584ff3114 --- /dev/null +++ b/tools/ci/fetch-sqlite-jdbc.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +# Download the SQLite JDBC driver that CI installs into Lucee Express, and fail +# loudly unless the file is exactly the pinned jar. +# +# A plain `curl -sL` exits 0 on an HTTP error page or a truncated transfer, and +# the damaged jar only surfaced later as Tomcat's "zip END header not found" +# and `org.sqlite.JDBC` missing at test time. Each attempt here must pass +# `curl --fail` and the SHA-256 check; a mismatch is downloaded again, up to +# three attempts. +# +# Usage: bash tools/ci/fetch-sqlite-jdbc.sh [output-path [version sha256]] +# output-path defaults to /tmp/sqlite-jdbc.jar. Without a version, it fetches the +# 3.50.3.0 jar CI installs. A different version must come with its SHA-256. +set -euo pipefail + +OUT="${1:-/tmp/sqlite-jdbc.jar}" +if [ "$#" -ge 2 ]; then + if [ "$#" -ne 3 ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "::error::Usage: $0 [output-path [version sha256]]" >&2 + exit 2 + fi + VERSION="$2" + SHA256="$3" +else + VERSION="3.50.3.0" + # Maven Central's published sqlite-jdbc-3.50.3.0.jar.sha256. + SHA256="a3f53a2aa15ae9425a9e793bbe9c8e5288febeb4b65ef5c1a4e80d4c2045cf08" +fi +URL="https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/${VERSION}/sqlite-jdbc-${VERSION}.jar" + +sha256_of() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | cut -d' ' -f1 + else + shasum -a 256 "$1" | cut -d' ' -f1 + fi +} + +tmp="${OUT}.download" +for attempt in 1 2 3; do + rm -f "$tmp" + if ! curl -fsSL --retry 3 --retry-delay 2 --retry-all-errors -o "$tmp" "$URL"; then + echo "Attempt ${attempt}: could not download ${URL}" >&2 + else + actual="$(sha256_of "$tmp")" + if [ "$actual" = "$SHA256" ]; then + mv "$tmp" "$OUT" + echo "sqlite-jdbc ${VERSION} downloaded and verified (sha256 ${SHA256}): ${OUT}" + exit 0 + fi + echo "Attempt ${attempt}: sqlite-jdbc ${VERSION} has sha256 ${actual} ($(wc -c <"$tmp" | tr -d ' ') bytes), expected ${SHA256}" >&2 + fi + [ "$attempt" -lt 3 ] && sleep 5 +done + +rm -f "$tmp" +echo "::error::Could not download a verified sqlite-jdbc ${VERSION} from ${URL}" >&2 +exit 1 diff --git a/tools/test-cli-e2e.sh b/tools/test-cli-e2e.sh index 41af4919ab..0e3708b324 100755 --- a/tools/test-cli-e2e.sh +++ b/tools/test-cli-e2e.sh @@ -508,8 +508,8 @@ sleep 1 LUCEE_LIB=$(find ~/.lucli/express -path "*/lib/ext" -type d 2>/dev/null | head -1) if [ -n "$LUCEE_LIB" ] && ! ls "$LUCEE_LIB"/sqlite-jdbc*.jar 1>/dev/null 2>&1; then echo " Downloading SQLite JDBC driver..." - curl -sL "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.49.1.0/sqlite-jdbc-3.49.1.0.jar" \ - -o "$LUCEE_LIB/sqlite-jdbc-3.49.1.0.jar" + bash "$PROJECT_ROOT/tools/ci/fetch-sqlite-jdbc.sh" "$LUCEE_LIB/sqlite-jdbc-3.49.1.0.jar" \ + 3.49.1.0 5c8609d2ca341deb8c6f71778974b5ba4995c7d32d7c7c89d9392a3e72c39291 fi echo " Starting LuCLI server on port $PORT..." diff --git a/tools/test-cli-local.sh b/tools/test-cli-local.sh index 2b69c29a8b..20a813e414 100755 --- a/tools/test-cli-local.sh +++ b/tools/test-cli-local.sh @@ -271,8 +271,9 @@ else fi if [ -n "$LUCEE_LIB" ] && ! ls "$LUCEE_LIB"/sqlite-jdbc*.jar 1>/dev/null 2>&1; then echo "Downloading SQLite JDBC driver to $LUCEE_LIB..." - curl -sL "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.49.1.0/sqlite-jdbc-3.49.1.0.jar" \ - -o "$LUCEE_LIB/sqlite-jdbc-3.49.1.0.jar" + # The CLI stages 3.49.1.0 (`wheels start`); pinned by SHA-256 like the release packages. + bash "$PROJECT_ROOT/tools/ci/fetch-sqlite-jdbc.sh" "$LUCEE_LIB/sqlite-jdbc-3.49.1.0.jar" \ + 3.49.1.0 5c8609d2ca341deb8c6f71778974b5ba4995c7d32d7c7c89d9392a3e72c39291 echo "Restarting ${CLI_BIN} server to pick up new JAR..." kill "$SERVER_PID" 2>/dev/null || true wait "$SERVER_PID" 2>/dev/null || true diff --git a/tools/test-local.sh b/tools/test-local.sh index 5ccc5a55ea..b86c4ed147 100755 --- a/tools/test-local.sh +++ b/tools/test-local.sh @@ -381,6 +381,7 @@ stop_test_server() { # pins, in the CLI home, not whichever install `find` lists first. EXPRESS_ROOT="$CLI_HOME/express" SQLITE_JDBC_VERSION="3.49.1.0" +SQLITE_JDBC_SHA256="5c8609d2ca341deb8c6f71778974b5ba4995c7d32d7c7c89d9392a3e72c39291" # The Lucee version a lucee.json pins: the first "version" inside its "lucee" block. pinned_lucee_version() { @@ -398,10 +399,8 @@ stage_sqlite_driver() { [ -n "$1" ] && [ -d "$lib" ] || return 1 ls "$lib"/sqlite-jdbc*.jar 1>/dev/null 2>&1 && return 1 echo "Downloading SQLite JDBC driver into Lucee Express $1..." - if ! curl -fsSL --retry 3 --retry-delay 2 \ - "https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/${SQLITE_JDBC_VERSION}/sqlite-jdbc-${SQLITE_JDBC_VERSION}.jar" \ - -o "$lib/sqlite-jdbc-${SQLITE_JDBC_VERSION}.jar"; then - rm -f "$lib/sqlite-jdbc-${SQLITE_JDBC_VERSION}.jar" + if ! bash "$PROJECT_ROOT/tools/ci/fetch-sqlite-jdbc.sh" "$lib/sqlite-jdbc-${SQLITE_JDBC_VERSION}.jar" \ + "$SQLITE_JDBC_VERSION" "$SQLITE_JDBC_SHA256"; then echo "::warning::Could not download the SQLite JDBC driver into $lib" >&2 return 2 fi