Files
ERP/scripts/package-release.sh
T

95 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
BACKEND_DIR="$ROOT_DIR/oa-backend"
FRONTEND_DIR="$ROOT_DIR/ofbiz-framework/plugins/modern-ui/app"
DIST_DIR="${ERP_RELEASE_DIST_DIR:-$ROOT_DIR/dist}"
VERSION="${1:-${ERP_RELEASE_VERSION:-}}"
PRIVATE_KEY="${ERP_RELEASE_PRIVATE_KEY_FILE:-}"
REQUIRE_SIGNATURE="${ERP_REQUIRE_RELEASE_SIGNATURE:-1}"
if [[ "$VERSION" == v* ]]; then VERSION="${VERSION#v}"; fi
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?(\+[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then
printf 'usage: %s <semver>\n' "$0" >&2
exit 2
fi
for command in java jar npm tar openssl cmp; do
command -v "$command" >/dev/null 2>&1 || { printf 'missing command: %s\n' "$command" >&2; exit 1; }
done
JAVA_MAJOR="$(java -version 2>&1 | awk -F'[".]' '/version/ {print $2; exit}')"
[[ "$JAVA_MAJOR" =~ ^[0-9]+$ && "$JAVA_MAJOR" -ge 17 ]] \
|| { printf 'Java 17 or newer is required\n' >&2; exit 1; }
OPENSSL_VERSION="$(openssl version 2>/dev/null || true)"
[[ "$OPENSSL_VERSION" =~ ^OpenSSL[[:space:]]3\. ]] \
|| { printf 'OpenSSL 3 with Ed25519 support is required\n' >&2; exit 1; }
OPENSSL_ALGORITHMS="$(openssl list -public-key-algorithms 2>/dev/null || true)"
grep -qi ED25519 <<< "$OPENSSL_ALGORITHMS" \
|| { printf 'OpenSSL 3 with Ed25519 support is required\n' >&2; exit 1; }
if [[ "${ERP_SKIP_FRONTEND_BUILD:-0}" != "1" ]]; then
(
cd "$FRONTEND_DIR"
npm ci
NODE_OPTIONS="${NODE_OPTIONS:---max-old-space-size=8192}" npm run build
)
fi
(
cd "$BACKEND_DIR"
./gradlew clean bootJar -PreleaseVersion="$VERSION" -PproductionBuild=true
)
JAR="$BACKEND_DIR/build/libs/oa-backend-${VERSION}.jar"
[[ -r "$JAR" ]] || { printf 'bootJar not found: %s\n' "$JAR" >&2; exit 1; }
JAR_ENTRIES="$(jar tf "$JAR")"
grep -Eq '^BOOT-INF/lib/postgresql-[^/]+\.jar$' <<< "$JAR_ENTRIES" \
|| { printf 'production JAR is missing the PostgreSQL driver\n' >&2; exit 1; }
if grep -Eq '^BOOT-INF/lib/(sqlite-jdbc|hibernate-community-dialects)-[^/]+\.jar$' <<< "$JAR_ENTRIES"; then
printf 'production JAR must not contain SQLite runtime libraries\n' >&2
exit 1
fi
mkdir -p "$DIST_DIR"
STAGE="$(mktemp -d "${TMPDIR:-/tmp}/kaidi-erp-package.XXXXXX")"
trap 'rm -rf "$STAGE"' EXIT
PACKAGE_ROOT="$STAGE/kaidi-erp-${VERSION}"
mkdir -p "$PACKAGE_ROOT/app" "$PACKAGE_ROOT/bin" "$PACKAGE_ROOT/config"
cp "$JAR" "$PACKAGE_ROOT/app/kaidi-erp.jar"
cp "$ROOT_DIR/distribution/bin/erp-run" "$PACKAGE_ROOT/bin/erp-run"
cp "$ROOT_DIR/distribution/bin/erp-update" "$PACKAGE_ROOT/bin/erp-update"
cp "$ROOT_DIR/distribution/release-public-key.pem" "$PACKAGE_ROOT/config/release-public-key.pem"
chmod 755 "$PACKAGE_ROOT/bin/erp-run" "$PACKAGE_ROOT/bin/erp-update"
printf '%s\n' "$VERSION" > "$PACKAGE_ROOT/VERSION"
printf '{"version":"%s","database":"postgresql","minimumPostgres":15,"rollbackCompatible":true}\n' \
"$VERSION" > "$PACKAGE_ROOT/manifest.json"
ARCHIVE="kaidi-erp-${VERSION}.tar.gz"
tar -czf "$DIST_DIR/$ARCHIVE" -C "$STAGE" "kaidi-erp-${VERSION}"
if command -v sha256sum >/dev/null 2>&1; then
(cd "$DIST_DIR" && sha256sum "$ARCHIVE" > SHA256SUMS)
else
(cd "$DIST_DIR" && shasum -a 256 "$ARCHIVE" > SHA256SUMS)
fi
if [[ -n "$PRIVATE_KEY" && -r "$PRIVATE_KEY" ]]; then
GENERATED_PUBLIC_KEY="$STAGE/release-public-key.pem"
openssl pkey -in "$PRIVATE_KEY" -pubout -out "$GENERATED_PUBLIC_KEY" >/dev/null 2>&1
cmp -s "$GENERATED_PUBLIC_KEY" "$ROOT_DIR/distribution/release-public-key.pem" \
|| { printf 'release signing key does not match distribution/release-public-key.pem\n' >&2; exit 1; }
openssl pkeyutl -sign -rawin -inkey "$PRIVATE_KEY" \
-in "$DIST_DIR/SHA256SUMS" -out "$DIST_DIR/SHA256SUMS.sig"
elif [[ "$REQUIRE_SIGNATURE" == "1" ]]; then
printf 'ERP_RELEASE_PRIVATE_KEY_FILE is required for signed releases\n' >&2
exit 1
else
: > "$DIST_DIR/SHA256SUMS.sig"
fi
printf 'release assets:\n %s\n %s\n %s\n' \
"$DIST_DIR/$ARCHIVE" "$DIST_DIR/SHA256SUMS" "$DIST_DIR/SHA256SUMS.sig"