diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..64ac0bb --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,101 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + windows-portable: + runs-on: windows-latest + timeout-minutes: 25 + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Setup Node + uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Verify project + run: npm run check + + - name: Verify tag matches package version + shell: pwsh + run: | + $package = Get-Content package.json -Raw | ConvertFrom-Json + $expectedTag = "v$($package.version)" + if ($env:GITHUB_REF_NAME -ne $expectedTag) { + throw "Release tag $env:GITHUB_REF_NAME does not match package.json version $expectedTag" + } + + - name: Assemble portable Windows package + shell: pwsh + run: | + $packageName = "OpenMockup-Studio-Windows-x64" + $stageRoot = Join-Path $env:RUNNER_TEMP $packageName + Remove-Item $stageRoot -Recurse -Force -ErrorAction SilentlyContinue + New-Item -ItemType Directory -Path $stageRoot | Out-Null + New-Item -ItemType Directory -Path (Join-Path $stageRoot "runtime") | Out-Null + New-Item -ItemType Directory -Path (Join-Path $stageRoot "tools") | Out-Null + + foreach ($directory in @("src", "public", "scripts")) { + Copy-Item $directory (Join-Path $stageRoot $directory) -Recurse + } + + robocopy node_modules (Join-Path $stageRoot "node_modules") /E /NFL /NDL /NJH /NJS /NP + if ($LASTEXITCODE -gt 7) { throw "robocopy node_modules failed with exit code $LASTEXITCODE" } + $global:LASTEXITCODE = 0 + + foreach ($file in @( + "index.html", + "package.json", + "package-lock.json", + "tsconfig.json", + "vite.config.ts", + ".env.example", + "README.md", + "LICENSE", + "stop.bat" + )) { + Copy-Item $file (Join-Path $stageRoot $file) + } + + Copy-Item (Get-Command node).Source (Join-Path $stageRoot "runtime\node.exe") + Copy-Item "packaging\windows\start-openmockup.bat" (Join-Path $stageRoot "start-openmockup.bat") + Copy-Item "packaging\windows\start-openmockup-psd.bat" (Join-Path $stageRoot "start-openmockup-psd.bat") + Copy-Item "packaging\windows\README.txt" (Join-Path $stageRoot "README-PORTABLE.txt") + + Invoke-WebRequest ` + -Uri "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe" ` + -OutFile (Join-Path $stageRoot "tools\cloudflared.exe") + + $zipPath = Join-Path $env:GITHUB_WORKSPACE "$packageName.zip" + Remove-Item $zipPath -Force -ErrorAction SilentlyContinue + tar.exe -a -c -f $zipPath -C $env:RUNNER_TEMP $packageName + if ($LASTEXITCODE -ne 0) { throw "Creating release ZIP failed with exit code $LASTEXITCODE" } + + $hash = (Get-FileHash $zipPath -Algorithm SHA256).Hash.ToLowerInvariant() + $checksumPath = Join-Path $env:GITHUB_WORKSPACE "$packageName.zip.sha256" + "$hash $packageName.zip" | Set-Content $checksumPath -Encoding ascii + + - name: Publish GitHub Release + shell: pwsh + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create $env:GITHUB_REF_NAME ` + "OpenMockup-Studio-Windows-x64.zip" ` + "OpenMockup-Studio-Windows-x64.zip.sha256" ` + --repo $env:GITHUB_REPOSITORY ` + --title "OpenMockup Studio $env:GITHUB_REF_NAME" ` + --generate-notes ` + --verify-tag diff --git a/packaging/windows/README.txt b/packaging/windows/README.txt new file mode 100644 index 0000000..1cfdd36 --- /dev/null +++ b/packaging/windows/README.txt @@ -0,0 +1,33 @@ +OpenMockup Studio - Portable Windows package +============================================ + +This package is self-contained. You do NOT need to install Node.js, npm, or cloudflared. + +Start image mockup mode +----------------------- +Double-click: + start-openmockup.bat + +Use this for PNG, JPG, and WebP mockups. Rendering stays local in your browser. + +Start PSD / Photopea mode +------------------------- +Double-click: + start-openmockup-psd.bat + +The package includes cloudflared. PSD mode creates a temporary trycloudflare.com tunnel so Photopea can fetch the selected design asset. The OpenMockup UI stays on http://127.0.0.1:5173. + +Do not use PSD mode for confidential artwork unless you understand and accept this data flow. + +Stop +---- +Close the launcher window. For PSD mode you can also run stop.bat if a previous process remains. + +Security / integrity +-------------------- +GitHub Releases also publishes a SHA-256 checksum file for the ZIP. You can verify it in PowerShell with: + + Get-FileHash .\OpenMockup-Studio-Windows-x64.zip -Algorithm SHA256 + +Project: + https://github.com/SLP-DEV1/OpenMockup-Studio diff --git a/packaging/windows/start-openmockup-psd.bat b/packaging/windows/start-openmockup-psd.bat new file mode 100644 index 0000000..0bc188c --- /dev/null +++ b/packaging/windows/start-openmockup-psd.bat @@ -0,0 +1,40 @@ +@echo off +setlocal EnableExtensions +cd /d "%~dp0" +title OpenMockup Studio - Portable PSD Mode + +set "NODE_EXE=%CD%\runtime\node.exe" +set "CLOUDFLARED_BIN=%CD%\tools\cloudflared.exe" +set "PATH=%CD%\runtime;%CD%\tools;%PATH%" + +if not exist "%NODE_EXE%" ( + echo [ERROR] Portable Node runtime is missing. + pause + exit /b 1 +) +if not exist "%CLOUDFLARED_BIN%" ( + echo [ERROR] Bundled cloudflared is missing. + pause + exit /b 1 +) +if not exist "%CD%\node_modules\vite\bin\vite.js" ( + echo [ERROR] Portable app dependencies are missing. + pause + exit /b 1 +) + +echo. +echo ========================================== +echo OpenMockup Studio - Portable PSD Mode +echo ========================================== +echo. +echo No Node.js or cloudflared installation is required. +echo A temporary trycloudflare.com URL is created only so Photopea can fetch the selected design asset. +echo The OpenMockup UI itself stays on 127.0.0.1. +echo Keep this window open while using PSD mode. +echo. + +"%NODE_EXE%" "%CD%\scripts\dev-public.mjs" + +echo. +pause diff --git a/packaging/windows/start-openmockup.bat b/packaging/windows/start-openmockup.bat new file mode 100644 index 0000000..e2033dd --- /dev/null +++ b/packaging/windows/start-openmockup.bat @@ -0,0 +1,37 @@ +@echo off +setlocal EnableExtensions +cd /d "%~dp0" +title OpenMockup Studio - Portable Image Mode + +set "APP_PORT=5173" +if not "%OPENMOCKUP_PORT%"=="" set "APP_PORT=%OPENMOCKUP_PORT%" +set "APP_URL=http://127.0.0.1:%APP_PORT%/" +set "NODE_EXE=%CD%\runtime\node.exe" +set "VITE_BIN=%CD%\node_modules\vite\bin\vite.js" + +if not exist "%NODE_EXE%" ( + echo [ERROR] Portable Node runtime is missing. + pause + exit /b 1 +) +if not exist "%VITE_BIN%" ( + echo [ERROR] Portable app dependencies are missing. + pause + exit /b 1 +) + +echo. +echo ========================================== +echo OpenMockup Studio - Portable Image Mode +echo ========================================== +echo. +echo No Node.js installation is required. +echo Open: %APP_URL% +echo Keep this window open while using the app. +echo. + +start "" "%APP_URL%" +"%NODE_EXE%" "%VITE_BIN%" --host 127.0.0.1 --port %APP_PORT% --strictPort + +echo. +pause