버전 불일치 문제
This commit is contained in:
@@ -59,14 +59,17 @@ public class DesktopAppReleaseService {
|
|||||||
String publishedVer = readLatestJsonVersion();
|
String publishedVer = readLatestJsonVersion();
|
||||||
String buildInfoVer = readBuildInfoVersion(releaseDirectory());
|
String buildInfoVer = readBuildInfoVersion(releaseDirectory());
|
||||||
|
|
||||||
// 헤더 버전: 실제 설치 파일 > build-info > 설정값 (latest.json은 업데이터용이라 다운로드와 어긋날 수 있음)
|
// 헤더 = build-info(마지막 성공 Jenkins 빌드) → mac/win 설치 파일 → 설정값
|
||||||
|
// latest.json 은 업데이터용 — 설치 파일보다 높으면 헤더에 쓰지 않음 (UI 불일치 방지)
|
||||||
String installerVer = maxSemver(macVer, winVer);
|
String installerVer = maxSemver(macVer, winVer);
|
||||||
String version = maxSemver(
|
String version = maxSemver(
|
||||||
installerVer,
|
|
||||||
buildInfoVer,
|
buildInfoVer,
|
||||||
nullIfBlank(configuredVersion),
|
installerVer,
|
||||||
publishedVer
|
nullIfBlank(configuredVersion)
|
||||||
);
|
);
|
||||||
|
if (version == null) {
|
||||||
|
version = publishedVer;
|
||||||
|
}
|
||||||
|
|
||||||
Instant latestUpdated = Stream.of(macFile, winFile)
|
Instant latestUpdated = Stream.of(macFile, winFile)
|
||||||
.flatMap(Optional::stream)
|
.flatMap(Optional::stream)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@goldenchart/desktop",
|
"name": "@goldenchart/desktop",
|
||||||
"version": "0.1.4",
|
"version": "0.1.18",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://schema.tauri.app/config/2",
|
"$schema": "https://schema.tauri.app/config/2",
|
||||||
"productName": "GoldenChart",
|
"productName": "GoldenChart",
|
||||||
"version": "0.1.4",
|
"version": "0.1.18",
|
||||||
"identifier": "com.goldenchart.desktop",
|
"identifier": "com.goldenchart.desktop",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "npm run dev",
|
"beforeDevCommand": "npm run dev",
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ const PlatformCard: React.FC<{
|
|||||||
const configs = {
|
const configs = {
|
||||||
mac: { label: 'macOS (Apple Silicon · Intel)', icon: '🍎', ext: '.dmg', isLink: false },
|
mac: { label: 'macOS (Apple Silicon · Intel)', icon: '🍎', ext: '.dmg', isLink: false },
|
||||||
windows: { label: 'Windows (64-bit)', icon: '🪟', ext: '.exe', isLink: false },
|
windows: { label: 'Windows (64-bit)', icon: '🪟', ext: '.exe', isLink: false },
|
||||||
android: { label: 'Android (패드 · 폰)', icon: '🤖', ext: '.apk', isLink: false },
|
android: { label: 'Android (패드 · 폰 · 별도 버전)', icon: '🤖', ext: '.apk', isLink: false },
|
||||||
} as const;
|
} as const;
|
||||||
const { label, icon, ext } = configs[platform];
|
const { label, icon, ext } = configs[platform];
|
||||||
|
|
||||||
@@ -435,6 +435,14 @@ const DesktopTab: React.FC<{ canBuildDesktop: boolean }> = ({ canBuildDesktop })
|
|||||||
|
|
||||||
const hasAny = info?.mac?.available || info?.windows?.available || mobileInfo?.available;
|
const hasAny = info?.mac?.available || info?.windows?.available || mobileInfo?.available;
|
||||||
|
|
||||||
|
const desktopVersionMismatch = Boolean(
|
||||||
|
info?.version
|
||||||
|
&& (
|
||||||
|
(info.mac?.available && info.mac.version && info.mac.version !== info.version)
|
||||||
|
|| (info.windows?.available && info.windows.version && info.windows.version !== info.version)
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
if (loading) return <p className="app-download-muted">PC 프로그램 정보 불러오는 중…</p>;
|
if (loading) return <p className="app-download-muted">PC 프로그램 정보 불러오는 중…</p>;
|
||||||
if (error) return <p className="app-download-error">{error}</p>;
|
if (error) return <p className="app-download-error">{error}</p>;
|
||||||
|
|
||||||
@@ -468,6 +476,12 @@ const DesktopTab: React.FC<{ canBuildDesktop: boolean }> = ({ canBuildDesktop })
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{desktopVersionMismatch && (
|
||||||
|
<p className="app-download-error" style={{ marginBottom: 8 }}>
|
||||||
|
macOS·Windows 설치 파일 버전이 최신 빌드(v{info?.version})와 다릅니다. 「앱 빌드」를 다시 실행하세요.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
|
||||||
{showBuildProgress && (
|
{showBuildProgress && (
|
||||||
<DesktopBuildProgressPanel
|
<DesktopBuildProgressPanel
|
||||||
status={buildStatus}
|
status={buildStatus}
|
||||||
|
|||||||
+49
-20
@@ -2,11 +2,14 @@
|
|||||||
# GoldenChart Desktop — macOS Jenkins 빌드 (macOS dmg + Windows NSIS cross-build)
|
# GoldenChart Desktop — macOS Jenkins 빌드 (macOS dmg + Windows NSIS cross-build)
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
SCRIPT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
cd "$ROOT"
|
WORK_TREE="${WORK_TREE:-$SCRIPT_ROOT}"
|
||||||
|
cd "$WORK_TREE"
|
||||||
|
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source "$ROOT/scripts/desktop-dev-path.sh"
|
source "$WORK_TREE/scripts/desktop-dev-path.sh"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$WORK_TREE/scripts/desktop-installer-version.sh"
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
[[ -f "$HOME/.cargo/env" ]] && source "$HOME/.cargo/env"
|
[[ -f "$HOME/.cargo/env" ]] && source "$HOME/.cargo/env"
|
||||||
|
|
||||||
@@ -25,8 +28,8 @@ while [[ $# -gt 0 ]]; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo "=== GoldenChart Desktop Build ==="
|
echo "=== GoldenChart Desktop Build ==="
|
||||||
echo "Root: $ROOT"
|
echo "Work tree: $WORK_TREE"
|
||||||
echo "Git: $(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo 'n/a')"
|
echo "Git: $(git -C "$WORK_TREE" rev-parse --short HEAD 2>/dev/null || echo 'n/a')"
|
||||||
|
|
||||||
need_cmd() {
|
need_cmd() {
|
||||||
if ! command -v "$1" >/dev/null 2>&1; then
|
if ! command -v "$1" >/dev/null 2>&1; then
|
||||||
@@ -45,14 +48,16 @@ if [[ "$BUILD_WIN" -eq 1 ]]; then
|
|||||||
rustup target add x86_64-pc-windows-msvc 2>/dev/null || true
|
rustup target add x86_64-pc-windows-msvc 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CONF="$ROOT/desktop/src-tauri/tauri.conf.json"
|
CONF="$WORK_TREE/desktop/src-tauri/tauri.conf.json"
|
||||||
|
|
||||||
# CI: 매 Jenkins 빌드마다 patch 버전 bump (git tauri.conf 0.1.4 고정이어도 산출물 버전 증가)
|
# CI patch bump (jenkins-desktop-pipeline 에서 선행 bump 시 DESKTOP_SKIP_VERSION_BUMP=1)
|
||||||
if [[ -z "${BUMP_VERSION:-}" ]] && [[ "${DESKTOP_BUMP_ON_CI:-1}" == "1" ]] \
|
if [[ "${DESKTOP_SKIP_VERSION_BUMP:-}" != "1" ]] \
|
||||||
|
&& [[ -z "${BUMP_VERSION:-}" ]] \
|
||||||
|
&& [[ "${DESKTOP_BUMP_ON_CI:-1}" == "1" ]] \
|
||||||
&& [[ -n "${BUILD_NUMBER:-}${DESKTOP_AUTO_BUMP:-}" ]]; then
|
&& [[ -n "${BUILD_NUMBER:-}${DESKTOP_AUTO_BUMP:-}" ]]; then
|
||||||
chmod +x "$ROOT/scripts/bump-desktop-version-from-release.sh"
|
chmod +x "$WORK_TREE/scripts/bump-desktop-version-from-release.sh"
|
||||||
export WORK_TREE="$ROOT"
|
export WORK_TREE
|
||||||
BUMPED="$("$ROOT/scripts/bump-desktop-version-from-release.sh")"
|
BUMPED="$("$WORK_TREE/scripts/bump-desktop-version-from-release.sh")"
|
||||||
echo "Desktop CI version bump → $BUMPED"
|
echo "Desktop CI version bump → $BUMPED"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -85,12 +90,12 @@ fs.writeFileSync(confPath, JSON.stringify(conf, null, 2) + '\n');
|
|||||||
console.log('window title →', title);
|
console.log('window title →', title);
|
||||||
" "$CONF" "$VERSION"
|
" "$CONF" "$VERSION"
|
||||||
|
|
||||||
if [[ -f "$ROOT/scripts/patch-tauri-updater-pubkey.sh" ]]; then
|
if [[ -f "$WORK_TREE/scripts/patch-tauri-updater-pubkey.sh" ]]; then
|
||||||
chmod +x "$ROOT/scripts/patch-tauri-updater-pubkey.sh"
|
chmod +x "$WORK_TREE/scripts/patch-tauri-updater-pubkey.sh"
|
||||||
fi
|
fi
|
||||||
chmod +x "$ROOT/scripts/prepare-tauri-build.sh" 2>/dev/null || true
|
chmod +x "$WORK_TREE/scripts/prepare-tauri-build.sh" 2>/dev/null || true
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
source "$ROOT/scripts/prepare-tauri-build.sh"
|
source "$WORK_TREE/scripts/prepare-tauri-build.sh"
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
@@ -98,9 +103,9 @@ echo "--- Vite build (desktop) ---"
|
|||||||
export DESKTOP_APP_VERSION="$VERSION"
|
export DESKTOP_APP_VERSION="$VERSION"
|
||||||
npm run build -w @goldenchart/desktop
|
npm run build -w @goldenchart/desktop
|
||||||
|
|
||||||
DESKTOP_DIR="$ROOT/desktop"
|
DESKTOP_DIR="$WORK_TREE/desktop"
|
||||||
TAURI_TARGET="$DESKTOP_DIR/src-tauri/target"
|
TAURI_TARGET="$DESKTOP_DIR/src-tauri/target"
|
||||||
ARTIFACT_DIR="$ROOT/dist-desktop"
|
ARTIFACT_DIR="${ARTIFACT_DIR:-$WORK_TREE/dist-desktop}"
|
||||||
UPDATES_DIR="$ARTIFACT_DIR/updates"
|
UPDATES_DIR="$ARTIFACT_DIR/updates"
|
||||||
rm -rf "$ARTIFACT_DIR"
|
rm -rf "$ARTIFACT_DIR"
|
||||||
mkdir -p "$ARTIFACT_DIR" "$UPDATES_DIR"
|
mkdir -p "$ARTIFACT_DIR" "$UPDATES_DIR"
|
||||||
@@ -125,7 +130,7 @@ copy_installer_matching_version() {
|
|||||||
local found=""
|
local found=""
|
||||||
while IFS= read -r f; do
|
while IFS= read -r f; do
|
||||||
[[ -z "$f" ]] && continue
|
[[ -z "$f" ]] && continue
|
||||||
if [[ "$f" == *"${VERSION}"* ]]; then
|
if desktop_installer_matches_version "$(basename "$f")" "$VERSION"; then
|
||||||
found="$f"
|
found="$f"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
@@ -157,8 +162,32 @@ if [[ "$BUILD_WIN" -eq 1 ]]; then
|
|||||||
collect_updater_artifacts
|
collect_updater_artifacts
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GIT_SHA="$(git -C "$ROOT" rev-parse HEAD 2>/dev/null || echo '')"
|
# mac·win 설치 파일 semver 일치 검증
|
||||||
GIT_SHORT="$(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo '')"
|
MAC_VER="" WIN_VER=""
|
||||||
|
shopt -s nullglob
|
||||||
|
for f in "$ARTIFACT_DIR"/*.dmg; do
|
||||||
|
MAC_VER="$(desktop_extract_version_from_name "$(basename "$f")")"
|
||||||
|
done
|
||||||
|
for f in "$ARTIFACT_DIR"/*setup.exe; do
|
||||||
|
WIN_VER="$(desktop_extract_version_from_name "$(basename "$f")")"
|
||||||
|
done
|
||||||
|
shopt -u nullglob
|
||||||
|
|
||||||
|
if [[ "$BUILD_MAC" -eq 1 && -n "$MAC_VER" && "$MAC_VER" != "$VERSION" ]]; then
|
||||||
|
echo "ERROR: macOS installer v${MAC_VER} != build v${VERSION}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "$BUILD_WIN" -eq 1 && -n "$WIN_VER" && "$WIN_VER" != "$VERSION" ]]; then
|
||||||
|
echo "ERROR: Windows installer v${WIN_VER} != build v${VERSION}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ "$BUILD_MAC" -eq 1 && "$BUILD_WIN" -eq 1 && -n "$MAC_VER" && -n "$WIN_VER" && "$MAC_VER" != "$WIN_VER" ]]; then
|
||||||
|
echo "ERROR: macOS v${MAC_VER} != Windows v${WIN_VER}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
GIT_SHA="$(git -C "$WORK_TREE" rev-parse HEAD 2>/dev/null || echo '')"
|
||||||
|
GIT_SHORT="$(git -C "$WORK_TREE" rev-parse --short HEAD 2>/dev/null || echo '')"
|
||||||
cat > "$ARTIFACT_DIR/build-info.json" <<EOF
|
cat > "$ARTIFACT_DIR/build-info.json" <<EOF
|
||||||
{
|
{
|
||||||
"version": "$VERSION",
|
"version": "$VERSION",
|
||||||
|
|||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# GoldenChart Desktop 설치 파일명 ↔ semver 일치 검사 (부분 문자열 오매칭 방지)
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
desktop_installer_matches_version() {
|
||||||
|
local file_name="$1"
|
||||||
|
local version="$2"
|
||||||
|
[[ -n "$file_name" && -n "$version" ]] || return 1
|
||||||
|
local escaped="${version//./\\.}"
|
||||||
|
[[ "$file_name" =~ GoldenChart[_-]${escaped}([_.-]|\.(dmg|exe)$) ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
desktop_extract_version_from_name() {
|
||||||
|
local file_name="$1"
|
||||||
|
if [[ "$file_name" =~ GoldenChart[_-]([0-9]+\.[0-9]+\.[0-9]+) ]]; then
|
||||||
|
echo "${BASH_REMATCH[1]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "${BASH_SOURCE[0]:-}" == "${0:-}" ]]; then
|
||||||
|
case "${1:-}" in
|
||||||
|
match)
|
||||||
|
desktop_installer_matches_version "${2:-}" "${3:-}"
|
||||||
|
;;
|
||||||
|
extract)
|
||||||
|
desktop_extract_version_from_name "${2:-}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 match <file> <version> | extract <file>" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
# Jenkins goldenChart-Desktop-Pipeline — 전체 빌드·배포 진입점
|
# Jenkins goldenChart-Desktop-Pipeline — 전체 빌드·배포 진입점
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
||||||
WORK_TREE="${WORK_TREE:-/Users/aidev/apps/goldenChart}"
|
WORK_TREE="${WORK_TREE:-/Users/aidev/apps/goldenChart}"
|
||||||
|
ROOT="$WORK_TREE"
|
||||||
export PATH="/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:${PATH:-/usr/bin:/bin}"
|
export PATH="/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:${PATH:-/usr/bin:/bin}"
|
||||||
for prefix in "$HOME/homebrew" /opt/homebrew; do
|
for prefix in "$HOME/homebrew" /opt/homebrew; do
|
||||||
[[ -x "$prefix/bin/brew" ]] && eval "$("$prefix/bin/brew" shellenv)"
|
[[ -x "$prefix/bin/brew" ]] && eval "$("$prefix/bin/brew" shellenv)"
|
||||||
@@ -18,25 +18,25 @@ log "WORK_TREE=$WORK_TREE"
|
|||||||
|
|
||||||
cd "$WORK_TREE"
|
cd "$WORK_TREE"
|
||||||
|
|
||||||
# Git 동기화 (Jenkins SCM checkout 후에도 file:// bare 와 맞춤)
|
# Git 동기화 (checkout 후 tauri.conf 가 git 버전으로 리셋됨 → bump 필수)
|
||||||
if [[ -d "${GIT_DIR:-/Volumes/ADATA/git/goldenChart.git}" ]]; then
|
if [[ -d "${GIT_DIR:-/Volumes/ADATA/git/goldenChart.git}" ]]; then
|
||||||
git --git-dir="${GIT_DIR:-/Volumes/ADATA/git/goldenChart.git}" \
|
git --git-dir="${GIT_DIR:-/Volumes/ADATA/git/goldenChart.git}" \
|
||||||
--work-tree="$WORK_TREE" checkout -f main 2>/dev/null || true
|
--work-tree="$WORK_TREE" checkout -f main 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
chmod +x "$ROOT/scripts/"*.sh 2>/dev/null || true
|
chmod +x "$WORK_TREE/scripts/"*.sh 2>/dev/null || true
|
||||||
|
|
||||||
# 의존성 (최초 1회 — 이미 있으면 빠르게 통과)
|
# 의존성 (최초 1회 — 이미 있으면 빠르게 통과)
|
||||||
if ! command -v cargo-xwin >/dev/null 2>&1 || ! command -v rustc >/dev/null 2>&1; then
|
if ! command -v cargo-xwin >/dev/null 2>&1 || ! command -v rustc >/dev/null 2>&1; then
|
||||||
log "Desktop build deps 설치..."
|
log "Desktop build deps 설치..."
|
||||||
"$ROOT/scripts/install-desktop-build-deps.sh"
|
"$WORK_TREE/scripts/install-desktop-build-deps.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# updater pubkey (repo에 desktop/updater.pub 있으면 patch만)
|
# updater pubkey (repo에 desktop/updater.pub 있으면 patch만)
|
||||||
if [[ -f "$ROOT/desktop/updater.pub" ]]; then
|
if [[ -f "$WORK_TREE/desktop/updater.pub" ]]; then
|
||||||
"$ROOT/scripts/patch-tauri-updater-pubkey.sh"
|
"$WORK_TREE/scripts/patch-tauri-updater-pubkey.sh"
|
||||||
elif [[ -f "${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}" ]]; then
|
elif [[ -f "${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}" ]]; then
|
||||||
"$ROOT/scripts/setup-desktop-updater-keys.sh"
|
"$WORK_TREE/scripts/setup-desktop-updater-keys.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
BUILD_ARGS=(--all)
|
BUILD_ARGS=(--all)
|
||||||
@@ -45,25 +45,36 @@ if [[ -n "${DESKTOP_BUILD_WIN_ONLY:-}" ]]; then BUILD_ARGS=(--win); fi
|
|||||||
if [[ -n "${BUMP_VERSION:-}" ]]; then
|
if [[ -n "${BUMP_VERSION:-}" ]]; then
|
||||||
BUILD_ARGS+=(--bump-version "$BUMP_VERSION")
|
BUILD_ARGS+=(--bump-version "$BUMP_VERSION")
|
||||||
fi
|
fi
|
||||||
# 버전 bump 는 scripts/build-desktop.sh (CI BUILD_NUMBER) 에서 처리
|
|
||||||
|
|
||||||
"$ROOT/scripts/build-desktop.sh" "${BUILD_ARGS[@]}"
|
export WORK_TREE
|
||||||
|
export BUILD_NUMBER="${BUILD_NUMBER:-}"
|
||||||
|
export DESKTOP_BUMP_ON_CI="${DESKTOP_BUMP_ON_CI:-1}"
|
||||||
|
|
||||||
|
# mobile pipeline 과 동일: git checkout 직후 semver bump (0.1.4 고정 tauri.conf 방지)
|
||||||
|
if [[ -z "${BUMP_VERSION:-}" ]] && [[ -n "${BUILD_NUMBER:-}" ]] && [[ "${DESKTOP_BUMP_ON_CI:-1}" == "1" ]]; then
|
||||||
|
log "CI Desktop version bump..."
|
||||||
|
BUMPED="$("$WORK_TREE/scripts/bump-desktop-version-from-release.sh")"
|
||||||
|
export DESKTOP_SKIP_VERSION_BUMP=1
|
||||||
|
log "Desktop version → $BUMPED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$WORK_TREE/scripts/build-desktop.sh" "${BUILD_ARGS[@]}"
|
||||||
|
|
||||||
WORK_TREE="$WORK_TREE" \
|
WORK_TREE="$WORK_TREE" \
|
||||||
ARTIFACT_DIR="$ROOT/dist-desktop" \
|
ARTIFACT_DIR="$WORK_TREE/dist-desktop" \
|
||||||
DESKTOP_UPDATE_BASE_URL="${DESKTOP_UPDATE_BASE_URL:-https://exdev.co.kr/desktop/updates}" \
|
DESKTOP_UPDATE_BASE_URL="${DESKTOP_UPDATE_BASE_URL:-https://exdev.co.kr/desktop/updates}" \
|
||||||
TAURI_SIGNER_KEY="${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}" \
|
TAURI_SIGNER_KEY="${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}" \
|
||||||
DESKTOP_RELEASE_NOTES="${DESKTOP_RELEASE_NOTES:-Build ${BUILD_NUMBER:-local}}" \
|
DESKTOP_RELEASE_NOTES="${DESKTOP_RELEASE_NOTES:-Build ${BUILD_NUMBER:-local}}" \
|
||||||
"$ROOT/scripts/publish-desktop-update.sh"
|
"$WORK_TREE/scripts/publish-desktop-update.sh"
|
||||||
|
|
||||||
# latest.json·설치 파일 nginx 즉시 반영 (볼륨 마운트)
|
# latest.json·설치 파일 nginx 즉시 반영 (볼륨 마운트)
|
||||||
if [[ -x "$ROOT/scripts/reload-frontend-desktop-static.sh" ]]; then
|
if [[ -x "$WORK_TREE/scripts/reload-frontend-desktop-static.sh" ]]; then
|
||||||
WORK_TREE="$WORK_TREE" "$ROOT/scripts/reload-frontend-desktop-static.sh" || true
|
WORK_TREE="$WORK_TREE" "$WORK_TREE/scripts/reload-frontend-desktop-static.sh" || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Jenkins artifact archive 경로
|
# Jenkins artifact archive 경로
|
||||||
if [[ -d "$ROOT/dist-desktop" ]]; then
|
if [[ -d "$WORK_TREE/dist-desktop" ]]; then
|
||||||
log "Artifacts ready: $ROOT/dist-desktop"
|
log "Artifacts ready: $WORK_TREE/dist-desktop"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 웹 frontend Docker 재배포 (latest.json static 포함) — 선택
|
# 웹 frontend Docker 재배포 (latest.json static 포함) — 선택
|
||||||
|
|||||||
@@ -2,26 +2,29 @@
|
|||||||
# GoldenChart Desktop — updater 서명 + latest.json + 웹 static 배포
|
# GoldenChart Desktop — updater 서명 + latest.json + 웹 static 배포
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
SCRIPT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||||
ARTIFACT_DIR="${ARTIFACT_DIR:-$ROOT/dist-desktop}"
|
WORK_TREE="${WORK_TREE:-$SCRIPT_ROOT}"
|
||||||
|
ARTIFACT_DIR="${ARTIFACT_DIR:-$WORK_TREE/dist-desktop}"
|
||||||
UPDATES_SRC="${UPDATES_SRC:-$ARTIFACT_DIR/updates}"
|
UPDATES_SRC="${UPDATES_SRC:-$ARTIFACT_DIR/updates}"
|
||||||
UPDATES_DIR="${UPDATES_DIR:-${WORK_TREE:-$ROOT}/frontend/public/desktop/updates}"
|
UPDATES_DIR="${UPDATES_DIR:-$WORK_TREE/frontend/public/desktop/updates}"
|
||||||
WEB_STATIC_DIR="${WEB_STATIC_DIR:-$UPDATES_DIR}"
|
WEB_STATIC_DIR="${WEB_STATIC_DIR:-$UPDATES_DIR}"
|
||||||
BASE_URL="${DESKTOP_UPDATE_BASE_URL:-https://exdev.co.kr/desktop/updates}"
|
BASE_URL="${DESKTOP_UPDATE_BASE_URL:-https://exdev.co.kr/desktop/updates}"
|
||||||
BASE_URL="${BASE_URL/http:\/\//https:\/\/}"
|
BASE_URL="${BASE_URL/http:\/\//https:\/\/}"
|
||||||
DESKTOP_RELEASE_DIR="${GC_DESKTOP_APP_RELEASE_DIR:-$ROOT/data/desktop-releases}"
|
DESKTOP_RELEASE_DIR="${GC_DESKTOP_APP_RELEASE_DIR:-$WORK_TREE/data/desktop-releases}"
|
||||||
KEY_PATH="${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}"
|
KEY_PATH="${TAURI_SIGNER_KEY:-$HOME/.tauri/goldenchart.key}"
|
||||||
DESKTOP_DIR="$ROOT/desktop"
|
DESKTOP_DIR="$WORK_TREE/desktop"
|
||||||
CONF="$DESKTOP_DIR/src-tauri/tauri.conf.json"
|
CONF="$DESKTOP_DIR/src-tauri/tauri.conf.json"
|
||||||
BUILD_INFO="$ARTIFACT_DIR/build-info.json"
|
BUILD_INFO="$ARTIFACT_DIR/build-info.json"
|
||||||
|
|
||||||
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:${PATH:-/usr/bin:/bin}"
|
export PATH="/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:${PATH:-/usr/bin:/bin}"
|
||||||
# shellcheck disable=SC1091
|
# shellcheck disable=SC1091
|
||||||
[[ -f "$HOME/.cargo/env" ]] && source "$HOME/.cargo/env"
|
[[ -f "$HOME/.cargo/env" ]] && source "$HOME/.cargo/env"
|
||||||
|
# shellcheck disable=SC1091
|
||||||
|
source "$WORK_TREE/scripts/desktop-installer-version.sh"
|
||||||
|
|
||||||
log() { echo "[publish-desktop] $*"; }
|
log() { echo "[publish-desktop] $*"; }
|
||||||
|
|
||||||
# CI bump 후 deploy checkout 등으로 tauri.conf가 되돌아갈 수 있음 — build-info 우선
|
# build-info 가 단일 버전 소스 (tauri.conf 는 git checkout 으로 구버전일 수 있음)
|
||||||
VERSION="$(node -p "require('$CONF').version" 2>/dev/null || echo '0.1.0')"
|
VERSION="$(node -p "require('$CONF').version" 2>/dev/null || echo '0.1.0')"
|
||||||
if [[ -f "$BUILD_INFO" ]]; then
|
if [[ -f "$BUILD_INFO" ]]; then
|
||||||
VERSION="$(node -e "try{console.log(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).version||'')}catch{}" "$BUILD_INFO" 2>/dev/null || echo "$VERSION")"
|
VERSION="$(node -e "try{console.log(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).version||'')}catch{}" "$BUILD_INFO" 2>/dev/null || echo "$VERSION")"
|
||||||
@@ -30,8 +33,10 @@ fi
|
|||||||
NOTES="${DESKTOP_RELEASE_NOTES:-GoldenChart Desktop $VERSION}"
|
NOTES="${DESKTOP_RELEASE_NOTES:-GoldenChart Desktop $VERSION}"
|
||||||
|
|
||||||
log "=== Publish Desktop v$VERSION ==="
|
log "=== Publish Desktop v$VERSION ==="
|
||||||
|
log "Work tree: $WORK_TREE"
|
||||||
log "Updates src: $UPDATES_SRC"
|
log "Updates src: $UPDATES_SRC"
|
||||||
log "Web static: $WEB_STATIC_DIR"
|
log "Web static: $WEB_STATIC_DIR"
|
||||||
|
log "Release dir: $DESKTOP_RELEASE_DIR"
|
||||||
|
|
||||||
mkdir -p "$WEB_STATIC_DIR"
|
mkdir -p "$WEB_STATIC_DIR"
|
||||||
|
|
||||||
@@ -46,16 +51,18 @@ prune_old_installers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 설치 파일(dist-desktop/*.dmg, *setup.exe) 복사 — nginx static + backend API 디렉터리
|
# 설치 파일(dist-desktop/*.dmg, *setup.exe) 복사 — nginx static + backend API 디렉터리
|
||||||
|
MAC_VER="" WIN_VER=""
|
||||||
|
INSTALLER_COUNT=0
|
||||||
|
|
||||||
if [[ -d "$ARTIFACT_DIR" ]]; then
|
if [[ -d "$ARTIFACT_DIR" ]]; then
|
||||||
mkdir -p "$DESKTOP_RELEASE_DIR"
|
mkdir -p "$DESKTOP_RELEASE_DIR"
|
||||||
prune_old_installers "$DESKTOP_RELEASE_DIR"
|
prune_old_installers "$DESKTOP_RELEASE_DIR"
|
||||||
prune_old_installers "$WEB_STATIC_DIR"
|
prune_old_installers "$WEB_STATIC_DIR"
|
||||||
|
|
||||||
INSTALLER_COUNT=0
|
|
||||||
while IFS= read -r f; do
|
while IFS= read -r f; do
|
||||||
[[ -z "$f" ]] && continue
|
[[ -z "$f" ]] && continue
|
||||||
base="$(basename "$f")"
|
base="$(basename "$f")"
|
||||||
if [[ "$base" != *"${VERSION}"* ]]; then
|
if ! desktop_installer_matches_version "$base" "$VERSION"; then
|
||||||
log "[WARN] skip installer (version mismatch): $base (expected v${VERSION})"
|
log "[WARN] skip installer (version mismatch): $base (expected v${VERSION})"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
@@ -63,10 +70,28 @@ if [[ -d "$ARTIFACT_DIR" ]]; then
|
|||||||
cp -f "$f" "$DESKTOP_RELEASE_DIR/"
|
cp -f "$f" "$DESKTOP_RELEASE_DIR/"
|
||||||
log "Installer: $base"
|
log "Installer: $base"
|
||||||
INSTALLER_COUNT=$((INSTALLER_COUNT + 1))
|
INSTALLER_COUNT=$((INSTALLER_COUNT + 1))
|
||||||
|
case "$base" in
|
||||||
|
*.dmg) MAC_VER="$(desktop_extract_version_from_name "$base")" ;;
|
||||||
|
*setup.exe) WIN_VER="$(desktop_extract_version_from_name "$base")" ;;
|
||||||
|
esac
|
||||||
done < <(find "$ARTIFACT_DIR" -maxdepth 1 -type f \( -name '*.dmg' -o -name '*setup.exe' \) 2>/dev/null)
|
done < <(find "$ARTIFACT_DIR" -maxdepth 1 -type f \( -name '*.dmg' -o -name '*setup.exe' \) 2>/dev/null)
|
||||||
|
|
||||||
if [[ "$INSTALLER_COUNT" -eq 0 ]]; then
|
if [[ "$INSTALLER_COUNT" -eq 0 ]]; then
|
||||||
log "[WARN] v${VERSION} 설치 파일(dmg/exe) 없음 — latest.json 만 갱신될 수 있음"
|
log "ERROR: v${VERSION} 설치 파일(dmg/exe) 없음 — latest.json 만 갱신하면 UI 버전이 어긋납니다." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$MAC_VER" && "$MAC_VER" != "$VERSION" ]]; then
|
||||||
|
log "ERROR: macOS installer v${MAC_VER} != publish v${VERSION}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -n "$WIN_VER" && "$WIN_VER" != "$VERSION" ]]; then
|
||||||
|
log "ERROR: Windows installer v${WIN_VER} != publish v${VERSION}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [[ -n "$MAC_VER" && -n "$WIN_VER" && "$MAC_VER" != "$WIN_VER" ]]; then
|
||||||
|
log "ERROR: macOS v${MAC_VER} != Windows v${WIN_VER}" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "$BUILD_INFO" ]]; then
|
if [[ -f "$BUILD_INFO" ]]; then
|
||||||
@@ -102,9 +127,9 @@ if [[ -f "$BUILD_INFO" ]]; then
|
|||||||
cp -f "$BUILD_INFO" "$PUBLISH_UPDATES/build-info.json"
|
cp -f "$BUILD_INFO" "$PUBLISH_UPDATES/build-info.json"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# latest.json
|
# latest.json — 설치 파일과 동일 semver
|
||||||
set +e
|
set +e
|
||||||
node "$ROOT/scripts/generate-desktop-latest-json.mjs" \
|
node "$WORK_TREE/scripts/generate-desktop-latest-json.mjs" \
|
||||||
--version "$VERSION" \
|
--version "$VERSION" \
|
||||||
--dir "$PUBLISH_UPDATES" \
|
--dir "$PUBLISH_UPDATES" \
|
||||||
--base-url "$BASE_URL" \
|
--base-url "$BASE_URL" \
|
||||||
@@ -113,12 +138,22 @@ GEN_RC=$?
|
|||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [[ "$GEN_RC" -eq 2 ]]; then
|
if [[ "$GEN_RC" -eq 2 ]]; then
|
||||||
log "[WARN] signed updater bundle 없음 — latest.json 유지 (placeholder 덮어쓰기 안 함)"
|
log "[WARN] signed updater bundle 없음 — latest.json 은 v${VERSION} build-info 기준 유지"
|
||||||
|
if [[ -f "$BUILD_INFO" ]]; then
|
||||||
|
node -e "
|
||||||
|
const fs=require('fs'); const p=process.argv[1]; const v=process.argv[2]; const u=process.argv[3]; const n=process.argv[4];
|
||||||
|
const latestPath=p+'/latest.json';
|
||||||
|
let cur={version:v,notes:n,pub_date:new Date().toISOString(),platforms:{}};
|
||||||
|
if(fs.existsSync(latestPath)){try{cur=JSON.parse(fs.readFileSync(latestPath,'utf8'));cur.version=v;cur.notes=n;}catch{}}
|
||||||
|
fs.writeFileSync(latestPath, JSON.stringify(cur,null,2)+'\n');
|
||||||
|
console.log('latest.json version →', v);
|
||||||
|
" "$PUBLISH_UPDATES" "$VERSION" "$BASE_URL" "$NOTES"
|
||||||
|
fi
|
||||||
elif [[ "$GEN_RC" -ne 0 ]]; then
|
elif [[ "$GEN_RC" -ne 0 ]]; then
|
||||||
exit "$GEN_RC"
|
exit "$GEN_RC"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "Published:"
|
log "Published v${VERSION}:"
|
||||||
ls -la "$PUBLISH_UPDATES"
|
ls -la "$PUBLISH_UPDATES"
|
||||||
|
|
||||||
log "nginx: /desktop/updates/ → frontend/public/desktop/updates (Docker rebuild 시 반영)"
|
log "nginx: /desktop/updates/ → frontend/public/desktop/updates (Docker rebuild 시 반영)"
|
||||||
|
|||||||
Reference in New Issue
Block a user