From 72b4fa8710176ba79510c2ca84b02ce86c1a457a Mon Sep 17 00:00:00 2001 From: Gamosoft Date: Sun, 23 Nov 2025 16:45:47 +0100 Subject: [PATCH 1/3] displaying version number and changed versioning approach --- Dockerfile | 1 + VERSION | 2 ++ backend/main.py | 8 +++++++ config.yaml | 1 - frontend/app.js | 2 ++ frontend/index.html | 2 ++ release.ps1 | 56 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 VERSION create mode 100644 release.ps1 diff --git a/Dockerfile b/Dockerfile index 2d89598..0c49b53 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ COPY --from=builder /install /usr/local COPY backend ./backend COPY frontend ./frontend COPY config.yaml . +COPY VERSION . COPY plugins ./plugins COPY themes ./themes COPY generate_password.py . diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..26b5dec --- /dev/null +++ b/VERSION @@ -0,0 +1,2 @@ +0.4.0 + diff --git a/backend/main.py b/backend/main.py index 17ac833..4b0e2c1 100644 --- a/backend/main.py +++ b/backend/main.py @@ -43,6 +43,14 @@ config_path = Path(__file__).parent.parent / "config.yaml" with open(config_path, 'r', encoding='utf-8') as f: config = yaml.safe_load(f) +# Load version from VERSION file (single source of truth) +version_path = Path(__file__).parent.parent / "VERSION" +if not version_path.exists(): + raise FileNotFoundError("VERSION file not found. Please create it with the current version number.") +with open(version_path, 'r', encoding='utf-8') as f: + version = f.read().strip() + config['app']['version'] = version + # Initialize app app = FastAPI( title=config['app']['name'], diff --git a/config.yaml b/config.yaml index 0b5c941..6d0f215 100644 --- a/config.yaml +++ b/config.yaml @@ -4,7 +4,6 @@ app: name: "NoteDiscovery" tagline: "Your Self-Hosted Knowledge Base" - version: "1.0.0" server: host: "0.0.0.0" diff --git a/frontend/app.js b/frontend/app.js index 028d3ef..10a2f36 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -35,6 +35,7 @@ function noteApp() { // App state appName: 'NoteDiscovery', appTagline: 'Your Self-Hosted Knowledge Base', + appVersion: '0.0.0', notes: [], currentNote: '', currentNoteName: '', @@ -394,6 +395,7 @@ function noteApp() { const config = await response.json(); this.appName = config.name; this.appTagline = config.tagline; + this.appVersion = config.version || '0.0.0'; } catch (error) { console.error('Failed to load config:', error); } diff --git a/frontend/index.html b/frontend/index.html index 49f7bd2..224c607 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -995,6 +995,8 @@
notes + ยท +
diff --git a/release.ps1 b/release.ps1 new file mode 100644 index 0000000..881963d --- /dev/null +++ b/release.ps1 @@ -0,0 +1,56 @@ +param( + [Parameter(Mandatory=$true)] + [string]$Version, + + [Parameter(Mandatory=$false)] + [switch]$SkipCommit = $false +) + +# Validate version format (semantic versioning) +if ($Version -notmatch '^\d+\.\d+\.\d+$') { + Write-Host "Error: Version must be in format X.Y.Z (e.g., 0.4.0)" -ForegroundColor Red + exit 1 +} + +Write-Host "Releasing version $Version..." -ForegroundColor Green + +# Check if working directory is clean (unless skipping commit) +if (-not $SkipCommit) { + $status = git status --porcelain + if ($status) { + Write-Host "Warning: Working directory has uncommitted changes:" -ForegroundColor Yellow + Write-Host $status -ForegroundColor Yellow + $response = Read-Host "Continue anyway? (y/N)" + if ($response -ne 'y' -and $response -ne 'Y') { + Write-Host "Aborted." -ForegroundColor Red + exit 1 + } + } +} + +# Update VERSION file (single source of truth) +Write-Host "Updating VERSION file..." -ForegroundColor Yellow +$Version | Out-File -FilePath "VERSION" -Encoding utf8 -NoNewline + +# Commit changes (unless skipped) +if (-not $SkipCommit) { + Write-Host "Committing version changes..." -ForegroundColor Yellow + git add VERSION + git commit -m "Bump version to $Version" + + # Push commits first + Write-Host "Pushing commits..." -ForegroundColor Yellow + git push +} + +# Create git tag +Write-Host "Creating git tag v$Version..." -ForegroundColor Yellow +git tag -a "v$Version" -m "Release version $Version" + +# Push tag to remote +Write-Host "Pushing tag to remote..." -ForegroundColor Yellow +git push origin "v$Version" + +Write-Host "`nRelease $Version completed successfully!" -ForegroundColor Green +Write-Host "Tag: v$Version" -ForegroundColor Cyan + From b491078dc87ce9f9bfa196b4c125849436fd1cb3 Mon Sep 17 00:00:00 2001 From: Gamosoft Date: Sun, 23 Nov 2025 16:55:05 +0100 Subject: [PATCH 2/3] added some checks to release script --- release.ps1 | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/release.ps1 b/release.ps1 index 881963d..a9ccf2e 100644 --- a/release.ps1 +++ b/release.ps1 @@ -12,7 +12,69 @@ if ($Version -notmatch '^\d+\.\d+\.\d+$') { exit 1 } -Write-Host "Releasing version $Version..." -ForegroundColor Green +# Check if we're on the main branch +$currentBranch = git rev-parse --abbrev-ref HEAD +if ($currentBranch -ne "main" -and $currentBranch -ne "master") { + Write-Host "Error: Releases can only be created from the main branch." -ForegroundColor Red + Write-Host "Current branch: $currentBranch" -ForegroundColor Yellow + Write-Host "Please switch to main branch first: git checkout main" -ForegroundColor Yellow + exit 1 +} + +Write-Host "Releasing version $Version from branch: $currentBranch" -ForegroundColor Green + +# Read current version and validate it's higher +if (Test-Path "VERSION") { + $currentVersion = (Get-Content "VERSION" -Raw).Trim() + + if ($currentVersion -match '^\d+\.\d+\.\d+$') { + # Parse versions into components + $currentParts = $currentVersion -split '\.' + $newParts = $Version -split '\.' + + $currentMajor = [int]$currentParts[0] + $currentMinor = [int]$currentParts[1] + $currentPatch = [int]$currentParts[2] + + $newMajor = [int]$newParts[0] + $newMinor = [int]$newParts[1] + $newPatch = [int]$newParts[2] + + # Compare versions + $isHigher = $false + if ($newMajor -gt $currentMajor) { + $isHigher = $true + } elseif ($newMajor -eq $currentMajor) { + if ($newMinor -gt $currentMinor) { + $isHigher = $true + } elseif ($newMinor -eq $currentMinor) { + if ($newPatch -gt $currentPatch) { + $isHigher = $true + } + } + } + + if (-not $isHigher) { + Write-Host "Error: New version must be higher than current version." -ForegroundColor Red + Write-Host "Current version: $currentVersion" -ForegroundColor Yellow + Write-Host "New version: $Version" -ForegroundColor Yellow + Write-Host "`nVersion comparison:" -ForegroundColor Yellow + Write-Host " Major: $newMajor vs $currentMajor" -ForegroundColor Yellow + Write-Host " Minor: $newMinor vs $currentMinor" -ForegroundColor Yellow + Write-Host " Patch: $newPatch vs $currentPatch" -ForegroundColor Yellow + exit 1 + } + + Write-Host "Version check passed: $currentVersion -> $Version" -ForegroundColor Green + } else { + Write-Host "Error: Current VERSION file has invalid format. Must be in X.Y.Z format (e.g., 0.4.0)" -ForegroundColor Red + Write-Host "Current VERSION file contains: '$currentVersion'" -ForegroundColor Yellow + Write-Host "Please fix the VERSION file before creating a release." -ForegroundColor Yellow + exit 1 + } +} else { + Write-Host "No existing VERSION file found. Creating new one..." -ForegroundColor Yellow +} # Check if working directory is clean (unless skipping commit) if (-not $SkipCommit) { From f6c422516606136e326ef5895efcc00a58bde88a Mon Sep 17 00:00:00 2001 From: Gamosoft Date: Sun, 23 Nov 2025 16:59:57 +0100 Subject: [PATCH 3/3] fixed image paste issue with double timestamp, added alt text on mouseover --- frontend/app.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/frontend/app.js b/frontend/app.js index 10a2f36..7041c09 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -1069,16 +1069,9 @@ function noteApp() { const textarea = event.target; const cursorPos = textarea.selectionStart || 0; - // Create a filename based on timestamp (format: YYYYMMDDHHMMSS) - const now = new Date(); - const timestamp = now.getFullYear() + - String(now.getMonth() + 1).padStart(2, '0') + - String(now.getDate()).padStart(2, '0') + - String(now.getHours()).padStart(2, '0') + - String(now.getMinutes()).padStart(2, '0') + - String(now.getSeconds()).padStart(2, '0'); + // Create a simple filename - backend will add timestamp to prevent collisions const ext = item.type.split('/')[1] || 'png'; - const filename = `pasted-image-${timestamp}.${ext}`; + const filename = `pasted-image.${ext}`; // Create a File from the blob const file = new File([blob], filename, { type: item.type }); @@ -2217,7 +2210,7 @@ function noteApp() { // Parse markdown let html = marked.parse(content); - // Post-process: Add target="_blank" to external links + // Post-process: Add target="_blank" to external links and title attributes to images // Parse as DOM to safely manipulate const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; @@ -2239,6 +2232,16 @@ function noteApp() { } }); + // Find all images and add title attribute from alt text for hover tooltips + const images = tempDiv.querySelectorAll('img'); + images.forEach(img => { + const altText = img.getAttribute('alt'); + if (altText) { + // Set title attribute to show alt text on hover + img.setAttribute('title', altText); + } + }); + html = tempDiv.innerHTML; // Trigger MathJax rendering after DOM updates