diff --git a/README.md b/README.md index 21db19c..6a59a52 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,9 @@ See [release notes](https://github.com/ZimengXiong/ExcaliDash/releases) for a sp > [!CAUTION] > NOT for production use. While attempts have been made at hardening (XSS/dompurify, CORS, rate-limiting, sanitization) have been made, they are inadequate for public deployment. Do not expose any ports. Currently lacking CSRF. +> [!CAUTION] +> ExcaliDash is in BETA. Please backup your data regularly (e.g. with cron). + ## Docker Hub (Recommended) [Install Docker](https://docs.docker.com/desktop/) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..7693c96 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.3 \ No newline at end of file diff --git a/backend/package.json b/backend/package.json index 2594ba9..56d0af9 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "backend", - "version": "1.0.0", + "version": "0.1.3", "description": "", "main": "index.js", "scripts": { diff --git a/frontend/package.json b/frontend/package.json index bb09658..17772c4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "frontend", "private": true, - "version": "0.0.0", + "version": "0.1.3", "type": "module", "scripts": { "dev": "vite", diff --git a/publish-docker-prerelease.sh b/publish-docker-prerelease.sh index 5cc2a6b..000ab00 100755 --- a/publish-docker-prerelease.sh +++ b/publish-docker-prerelease.sh @@ -4,7 +4,7 @@ set -e # Configuration DOCKER_USERNAME="zimengxiong" IMAGE_NAME="excalidash" -VERSION=${1:-pre-release} +VERSION=${1:-$(node -e "try { console.log(require('fs').readFileSync('VERSION', 'utf8').trim() + '-dev') } catch { console.log('pre-release') }")} # Colors for output RED='\033[0;31m' @@ -17,8 +17,8 @@ echo -e "${BLUE}===========================================${NC}" echo -e "${BLUE}ExcaliDash Pre-Release Docker Builder${NC}" echo -e "${BLUE}===========================================${NC}" echo "" -echo -e "${YELLOW}⚠️ This will publish images with tag: ${VERSION}${NC}" -echo -e "${YELLOW}⚠️ Pre-release images will NOT update 'latest' tag${NC}" +echo -e "${YELLOW}This will publish images with tag: ${VERSION}${NC}" +echo -e "${YELLOW}Pre-release images will NOT update 'latest' tag${NC}" echo "" # Confirm before proceeding diff --git a/publish-docker.sh b/publish-docker.sh index 2ada6ef..8551dd8 100755 --- a/publish-docker.sh +++ b/publish-docker.sh @@ -4,7 +4,7 @@ set -e # Configuration DOCKER_USERNAME="zimengxiong" IMAGE_NAME="excalidash" -VERSION=${1:-latest} +VERSION=${1:-$(node -e "try { console.log(require('fs').readFileSync('VERSION', 'utf8').trim()) } catch { console.log('latest') }")} # Colors for output RED='\033[0;31m' diff --git a/version-manager.js b/version-manager.js new file mode 100644 index 0000000..3f1e912 --- /dev/null +++ b/version-manager.js @@ -0,0 +1,159 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const VERSION_FILE = 'VERSION'; +const BACKEND_PACKAGE = 'backend/package.json'; +const FRONTEND_PACKAGE = 'frontend/package.json'; + +const colors = { + red: '\x1b[31m', + green: '\x1b[32m', + yellow: '\x1b[33m', + blue: '\x1b[34m', + reset: '\x1b[0m', + bright: '\x1b[1m', +}; + +function log(message, color = 'reset') { + console.log(`${colors[color]}${message}${colors.reset}`); +} + +function showHelp() { + log('ExcaliDash Version Manager', 'blue'); + log(''); + log('Usage: node version-manager.js [COMMAND] [VERSION_TYPE]'); + log(''); + log('Commands:'); + log(' get Get current version'); + log(' set VERSION Set specific version (e.g., 1.2.3)'); + log(' patch Bump patch version (1.0.0 → 1.0.1)'); + log(' minor Bump minor version (1.0.0 → 1.1.0)'); + log(' major Bump major version (1.0.0 → 2.0.0)'); + log(' sync Sync version to all package.json files'); + log(' help Show this help message'); + log(''); + log('Examples:'); + log(' node version-manager.js get'); + log(' node version-manager.js set 1.2.3'); + log(' node version-manager.js patch'); + log(' node version-manager.js minor'); +} + +function getCurrentVersion() { + try { + if (fs.existsSync(VERSION_FILE)) { + return fs.readFileSync(VERSION_FILE, 'utf8').trim(); + } + } catch (error) { + // Continue to default version + } + return '0.1.0'; // Default version if VERSION file doesn't exist +} + +function setVersion(newVersion) { + // Validate version format (semantic versioning) + if (!/^\d+\.\d+\.\d+$/.test(newVersion)) { + log(`Error: Version must be in format X.Y.Z (e.g., 1.2.3)`, 'red'); + process.exit(1); + } + + // Update VERSION file + try { + fs.writeFileSync(VERSION_FILE, newVersion); + log(`✓ Updated VERSION file to ${newVersion}`, 'green'); + } catch (error) { + log(`Error writing VERSION file: ${error.message}`, 'red'); + process.exit(1); + } + + // Update package.json files + syncVersionToPackages(newVersion); +} + +function bumpVersion(bumpType) { + const currentVersion = getCurrentVersion(); + const [major, minor, patch] = currentVersion.split('.').map(Number); + + let newMajor = major; + let newMinor = minor; + let newPatch = patch; + + switch (bumpType) { + case 'patch': + newPatch = patch + 1; + break; + case 'minor': + newMinor = minor + 1; + newPatch = 0; + break; + case 'major': + newMajor = major + 1; + newMinor = 0; + newPatch = 0; + break; + default: + log(`Error: Invalid bump type. Use 'patch', 'minor', or 'major'`, 'red'); + process.exit(1); + } + + const newVersion = `${newMajor}.${newMinor}.${newPatch}`; + setVersion(newVersion); +} + +function updatePackageJson(packagePath, version) { + try { + const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')); + packageJson.version = version; + fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + '\n'); + log(`✓ Updated ${packagePath} to version ${version}`, 'green'); + } catch (error) { + if (error.code === 'ENOENT') { + log(`⚠️ ${packagePath} not found`, 'yellow'); + } else { + log(`Error updating ${packagePath}: ${error.message}`, 'red'); + } + } +} + +function syncVersionToPackages(version) { + updatePackageJson(BACKEND_PACKAGE, version); + updatePackageJson(FRONTEND_PACKAGE, version); +} + +// Main command handling +const args = process.argv.slice(2); +const command = args[0]; +const arg = args[1]; + +switch (command) { + case 'get': + console.log(getCurrentVersion()); + break; + case 'set': + if (!arg) { + log('Error: Version required for "set" command', 'red'); + showHelp(); + process.exit(1); + } + setVersion(arg); + break; + case 'patch': + case 'minor': + case 'major': + bumpVersion(command); + break; + case 'sync': + const version = getCurrentVersion(); + syncVersionToPackages(version); + break; + case 'help': + case undefined: + showHelp(); + break; + default: + log(`Error: Unknown command '${command}'`, 'red'); + showHelp(); + process.exit(1); +} \ No newline at end of file