diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f61f625..ac0b2ec 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -45,6 +45,19 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Determine channel + id: channel + run: | + if [[ "${{ github.ref }}" == "refs/heads/v2" ]]; then + echo "value=develop" >> $GITHUB_OUTPUT + elif [[ "${{ github.ref }}" == refs/tags/v*-beta* ]]; then + echo "value=beta" >> $GITHUB_OUTPUT + elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then + echo "value=stable" >> $GITHUB_OUTPUT + else + echo "value=develop" >> $GITHUB_OUTPUT + fi + - name: Extract metadata id: meta uses: docker/metadata-action@v5 @@ -70,6 +83,8 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + VITE_CHANNEL=${{ steps.channel.outputs.value }} cache-from: type=registry,ref=${{ env.IMAGE_BASE }}/${{ matrix.image }}:buildcache cache-to: type=registry,ref=${{ env.IMAGE_BASE }}/${{ matrix.image }}:buildcache,mode=max diff --git a/Dockerfile b/Dockerfile index 8527368..bf02081 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,14 @@ RUN deno install --node-modules-dir # Build the application # 1. Vite builds SvelteKit to dist/build/ # 2. Deno compiles to standalone binary + +# Build-time variables for version card +# TARGETARCH is automatically set by Docker buildx (amd64 or arm64) +ARG TARGETARCH +ARG VITE_CHANNEL=stable +ENV VITE_PLATFORM=docker-${TARGETARCH} +ENV VITE_CHANNEL=${VITE_CHANNEL} + ENV APP_BASE_PATH=/build/dist/build RUN deno run -A npm:vite build RUN deno compile \ diff --git a/deno.json b/deno.json index ee95cbb..712bac7 100644 --- a/deno.json +++ b/deno.json @@ -28,7 +28,7 @@ }, "tasks": { "dev": "deno run -A scripts/dev.ts", - "dev:server": "DENO_ENV=development PORT=6969 HOST=0.0.0.0 APP_BASE_PATH=./dist/dev PARSER_HOST=localhost PARSER_PORT=5000 deno run -A npm:vite dev", + "dev:server": "DENO_ENV=development PORT=6969 HOST=0.0.0.0 APP_BASE_PATH=./dist/dev PARSER_HOST=localhost PARSER_PORT=5000 VITE_PLATFORM=linux-amd64 VITE_CHANNEL=dev deno run -A npm:vite dev", "dev:parser": "cd src/services/parser && dotnet watch run --urls http://localhost:5000", "build": "APP_BASE_PATH=./dist/build deno run -A npm:vite build && deno compile --no-check --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run --allow-sys --target x86_64-unknown-linux-gnu --output dist/build/profilarr dist/build/mod.ts", "build:windows": "APP_BASE_PATH=./dist/build deno run -A npm:vite build && deno compile --no-check --allow-net --allow-read --allow-write --allow-env --allow-ffi --allow-run --allow-sys --target x86_64-pc-windows-msvc --output dist/windows/profilarr.exe dist/build/mod.ts", diff --git a/docs/todo/5.dirty-handling-upgrades-renames.md b/docs/todo/5.dirty-handling-upgrades-renames.md deleted file mode 100644 index 6abeff9..0000000 --- a/docs/todo/5.dirty-handling-upgrades-renames.md +++ /dev/null @@ -1,42 +0,0 @@ -# Dirty Handling for Upgrades & Renames - -**Status: Planning** - -## Summary - -Both the Upgrades and Rename configuration pages have issues with form state management and dirty tracking. This task covers fixing save errors and implementing proper dirty state handling. - -## Problems - -### Upgrades Page - -- Save errors occurring (need to investigate root cause) -- Dirty tracking not properly implemented -- Form state management inconsistent - -### Rename Page - -- Needs dirty tracking implementation -- Should follow same pattern as upgrades (once fixed) - -## Requirements - -1. Fix save errors in upgrades page -2. Implement proper dirty tracking for both pages: - - Track when form values differ from saved values - - Show unsaved changes indicator - - Warn before navigating away with unsaved changes - - Reset dirty state after successful save - -## Implementation Notes - -TBD - needs investigation of current issues first. - ---- - -## Related Files - -- `src/routes/arr/[id]/upgrades/+page.svelte` -- `src/routes/arr/[id]/upgrades/+page.server.ts` -- `src/routes/arr/[id]/rename/+page.svelte` -- `src/routes/arr/[id]/rename/+page.server.ts` diff --git a/src/lib/client/ui/navigation/pageNav/pageNav.svelte b/src/lib/client/ui/navigation/pageNav/pageNav.svelte index c3c16d6..cf38b16 100644 --- a/src/lib/client/ui/navigation/pageNav/pageNav.svelte +++ b/src/lib/client/ui/navigation/pageNav/pageNav.svelte @@ -6,6 +6,7 @@ import { navIconStore } from '$stores/navIcons'; export let collapsed: boolean = false; + export let version: string = ''; $: useEmoji = $navIconStore === 'emoji'; @@ -79,5 +80,5 @@ - + diff --git a/src/lib/client/ui/navigation/pageNav/version.svelte b/src/lib/client/ui/navigation/pageNav/version.svelte index 4e4bf12..66d4d96 100644 --- a/src/lib/client/ui/navigation/pageNav/version.svelte +++ b/src/lib/client/ui/navigation/pageNav/version.svelte @@ -1,26 +1,26 @@
-
- -
+ Profilarr logo
-
+
profilarr
- {buildLabel} · v{VERSION} + {platform} · {channel}{#if showVersion && version} · {version}{/if}
diff --git a/src/lib/shared/version.ts b/src/lib/shared/version.ts index 55eca26..5e70d74 100644 --- a/src/lib/shared/version.ts +++ b/src/lib/shared/version.ts @@ -1,31 +1,72 @@ -// Version is injected at build time from package.json -declare const __APP_VERSION__: string; +// Platform and channel are injected at build time +// Version comes from the database (fetched via API) -export const VERSION = __APP_VERSION__; -export const BUILD_TYPE = import.meta.env.MODE === 'development' ? 'dev' : 'stable'; +type Platform = + | 'docker-amd64' + | 'docker-arm64' + | 'windows-amd64' + | 'linux-amd64' + | 'linux-arm64' + | 'macos-amd64' + | 'macos-arm64'; -export function getBuildLabel(): string { - // Check for custom build type from environment - const customBuildType = import.meta.env.VITE_BUILD_TYPE as string | undefined; +type Channel = 'stable' | 'beta' | 'develop' | 'dev'; - if (customBuildType) { - switch (customBuildType) { - case 'beta': - return 'Beta'; - case 'docker': - return 'Docker'; - case 'dev': - return 'Develop'; - case 'stable': - default: - return 'Stable'; +const PLATFORM_LABELS: Record = { + 'docker-amd64': 'docker/amd64', + 'docker-arm64': 'docker/arm64', + 'windows-amd64': 'windows/amd64', + 'linux-amd64': 'linux/amd64', + 'linux-arm64': 'linux/arm64', + 'macos-amd64': 'macos/amd64', + 'macos-arm64': 'macos/arm64' +}; + +const CHANNEL_LABELS: Record = { + stable: 'Stable', + beta: 'Beta', + develop: 'Develop', + dev: 'Dev' +}; + +function detectPlatform(): Platform { + // Try to detect from navigator in browser + if (typeof navigator !== 'undefined' && navigator.platform) { + const platform = navigator.platform.toLowerCase(); + if (platform.includes('win')) return 'windows-amd64'; + if (platform.includes('mac')) { + // Check for Apple Silicon - this is a heuristic + return 'macos-arm64'; } + if (platform.includes('linux')) return 'linux-amd64'; } - - // Fallback based on Vite mode - return import.meta.env.MODE === 'development' ? 'Developer Build' : 'Stable'; + return 'linux-amd64'; } -export function getFullVersionString(): string { - return `Profilarr ${getBuildLabel()} v${VERSION}`; +export function getPlatform(): Platform { + const envPlatform = import.meta.env.VITE_PLATFORM as Platform | undefined; + return envPlatform || detectPlatform(); +} + +export function getChannel(): Channel { + const envChannel = import.meta.env.VITE_CHANNEL as Channel | undefined; + if (envChannel) return envChannel; + + // Default to dev for development mode, stable otherwise + return import.meta.env.MODE === 'development' ? 'dev' : 'stable'; +} + +export function getPlatformLabel(): string { + const platform = getPlatform(); + return PLATFORM_LABELS[platform] || platform; +} + +export function getChannelLabel(): string { + const channel = getChannel(); + return CHANNEL_LABELS[channel] || channel; +} + +export function shouldShowVersion(): boolean { + const channel = getChannel(); + return channel === 'stable' || channel === 'beta'; } diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts new file mode 100644 index 0000000..954cbe7 --- /dev/null +++ b/src/routes/+layout.server.ts @@ -0,0 +1,8 @@ +import type { LayoutServerLoad } from './$types'; +import { appInfoQueries } from '$db/queries/appInfo.ts'; + +export const load: LayoutServerLoad = async () => { + return { + version: appInfoQueries.getVersion() + }; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 70f05c7..632a872 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -5,6 +5,8 @@ import PageNav from '$ui/navigation/pageNav/pageNav.svelte'; import AlertContainer from '$alerts/AlertContainer.svelte'; import { sidebarCollapsed } from '$lib/client/stores/sidebar'; + + export let data; @@ -13,7 +15,7 @@ - +