#!/usr/bin/env bash # deploy.yml › backend — build (or reuse) the self-contained release for BACKEND_HASH into # /opt/erpcore/releases/backend/. Releases are shared by test and release, so a # Dev → production merge that carries the same Backend/ERPCore tree skips the build entirely. # shellcheck source=common.sh source "$(dirname "${BASH_SOURCE[0]}")/common.sh" : "${BACKEND_HASH:?BACKEND_HASH is required}" target="$RELEASES_DIR/$BACKEND_HASH" reuse_if_built() { if [[ -x "$target/ERPCore" ]]; then log "backend $BACKEND_HASH already built → reused ($target)" set_output reused true exit 0 fi } reuse_if_built with_build_lock reuse_if_built # another job may have built it while we waited for the lock # Only the exact tree can be built. A rollback hash whose release was pruned cannot be recreated # from a different checkout — fail instead of deploying something else under that name. [[ "$(tree_hash "$BACKEND_PATH")" == "$BACKEND_HASH" ]] || fail "no release for $BACKEND_HASH, and this checkout's $BACKEND_PATH is a different tree (pruned rollback target?)" mkdir -p "$RELEASES_DIR" tmp="$target.tmp" rm -rf "$tmp" mkdir -p "$tmp" z="$(selinux_mount_suffix)" log "building backend $BACKEND_HASH (capped: 2 CPU / 1500 MB)" docker run --rm --cpus=2 --cpu-shares=512 --memory=1500m \ -e DOTNET_CLI_TELEMETRY_OPTOUT=1 -e DOTNET_NOLOGO=1 \ -v "$PWD/Backend:/src$z" \ -v "$tmp:/out$z" \ -v erp-nuget:/root/.nuget/packages \ -w /src "$DOTNET_SDK_IMAGE" \ dotnet publish ERPCore/ERPCore.csproj -c Release -r linux-x64 --self-contained true -o /out [[ -x "$tmp/ERPCore" ]] || fail "publish finished but $tmp/ERPCore is missing" # Root-owned and read-only for the service user: the app never writes into its own release # (uploads and logs live under /var/lib/erpcore and /var/log/erpcore). chown -R root:root "$tmp" chmod -R u=rwX,go=rX "$tmp" chmod 755 "$tmp/ERPCore" mv "$tmp" "$target" if command -v restorecon >/dev/null 2>&1; then restorecon -R "$target"; fi log "backend release ready: $target" set_output reused false