0476315322
* feat(security): implement CSRF protection * chore: clean up CSRF implementation - Remove unused generateCsrfToken export from security.ts - Remove redundant /csrf-token path check (GET already exempt) - Restore defineConfig wrapper in vitest.config.ts for type safety * add K8S note in README, fix broken e2e * feat/upload-bar (#30) * feat/upload-bar: add a upload bar when user upload file, indicate the upload process * feat/save-loading-status: add save status when click back button from editor * fix: address PR review issues in upload and save features - Replace deprecated substr() with substring() in UploadContext - Fix broken error handling that checked stale task status - Fix missing useEffect dependency in UploadStatus - Fix CSS class conflict in progress bar styling - Add error recovery for save state in Editor (reset on failure) - Use .finally() instead of .then() to ensure refresh on upload failure - Fix inconsistent indentation in UploadContext * fix e2e tests --------- Co-authored-by: Zimeng Xiong <zxzimeng@gmail.com> * chore: pre-release v0.2.1-dev * Update backend/src/security.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix filename/math random UUID generation --------- Co-authored-by: AdrianAcala <adrianacala017@gmail.com> Co-authored-by: adamant368 <60790941+Yiheng-Liu@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
551 lines
20 KiB
Makefile
551 lines
20 KiB
Makefile
# ExcaliDash Makefile
|
|
# Comprehensive development, testing, and release automation
|
|
|
|
.PHONY: help install dev build test test-frontend test-backend test-e2e test-e2e-docker \
|
|
lint lint-frontend lint-backend clean docker-build docker-run docker-down docker-logs \
|
|
release pre-release version-bump changelog db-migrate db-reset
|
|
|
|
# Colors
|
|
GREEN := \033[0;32m
|
|
YELLOW := \033[1;33m
|
|
BLUE := \033[0;34m
|
|
RED := \033[0;31m
|
|
NC := \033[0m
|
|
|
|
# Configuration
|
|
DOCKER_USERNAME := zimengxiong
|
|
IMAGE_NAME := excalidash
|
|
VERSION := $(shell cat VERSION 2>/dev/null || echo "0.0.0")
|
|
|
|
# Default target
|
|
.DEFAULT_GOAL := help
|
|
|
|
#===============================================================================
|
|
# HELP
|
|
#===============================================================================
|
|
|
|
help: ## Show this help message
|
|
@echo ""
|
|
@echo "$(GREEN)ExcaliDash Makefile$(NC)"
|
|
@echo "$(GREEN)==================$(NC)"
|
|
@echo ""
|
|
@echo "$(YELLOW)Usage:$(NC) make [target]"
|
|
@echo ""
|
|
@echo "$(BLUE)Development:$(NC)"
|
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -E '(install|dev|build|lint|clean)' | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo "$(BLUE)Testing:$(NC)"
|
|
@grep -E '^test[-a-zA-Z0-9_]*:.*## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo "$(BLUE)Docker:$(NC)"
|
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -E '(docker)' | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo "$(BLUE)Release:$(NC)"
|
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -E '(release|version|changelog)' | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo "$(BLUE)Database:$(NC)"
|
|
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | grep -E '(db-)' | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
|
|
@echo ""
|
|
@echo "$(YELLOW)Current version:$(NC) $(VERSION)"
|
|
@echo ""
|
|
|
|
#===============================================================================
|
|
# DEVELOPMENT
|
|
#===============================================================================
|
|
|
|
install: ## Install all dependencies (frontend, backend, e2e)
|
|
@echo "$(YELLOW)Installing frontend dependencies...$(NC)"
|
|
cd frontend && npm install
|
|
@echo "$(YELLOW)Installing backend dependencies...$(NC)"
|
|
cd backend && npm install
|
|
@echo "$(YELLOW)Installing e2e dependencies...$(NC)"
|
|
cd e2e && npm install
|
|
@echo "$(GREEN)All dependencies installed!$(NC)"
|
|
|
|
dev: ## Start development servers (frontend + backend)
|
|
@echo "$(YELLOW)Starting development servers...$(NC)"
|
|
@echo "$(BLUE)Backend will run on port 8000, Frontend on port 5173$(NC)"
|
|
@trap 'kill 0' INT; \
|
|
(cd backend && npm run dev) & \
|
|
(cd frontend && npm run dev) & \
|
|
wait
|
|
|
|
dev-frontend: ## Start frontend dev server only
|
|
cd frontend && npm run dev
|
|
|
|
dev-backend: ## Start backend dev server only
|
|
cd backend && npm run dev
|
|
|
|
build: ## Build frontend and backend for production
|
|
@echo "$(YELLOW)Building frontend...$(NC)"
|
|
cd frontend && npm run build
|
|
@echo "$(GREEN)Build complete!$(NC)"
|
|
|
|
lint: lint-frontend lint-backend ## Run linters for frontend and backend
|
|
|
|
lint-frontend: ## Run frontend linter
|
|
@echo "$(YELLOW)Linting frontend...$(NC)"
|
|
cd frontend && npm run lint
|
|
|
|
lint-backend: ## Run backend linter (if available)
|
|
@echo "$(YELLOW)Backend linting not configured$(NC)"
|
|
|
|
clean: ## Clean build artifacts and node_modules
|
|
@echo "$(YELLOW)Cleaning build artifacts...$(NC)"
|
|
rm -rf frontend/dist
|
|
rm -rf frontend/node_modules/.vite
|
|
@echo "$(GREEN)Clean complete!$(NC)"
|
|
|
|
clean-all: clean ## Clean everything including node_modules
|
|
@echo "$(RED)Removing all node_modules...$(NC)"
|
|
rm -rf frontend/node_modules
|
|
rm -rf backend/node_modules
|
|
rm -rf e2e/node_modules
|
|
@echo "$(GREEN)Full clean complete!$(NC)"
|
|
|
|
#===============================================================================
|
|
# TESTING
|
|
#===============================================================================
|
|
|
|
test: test-frontend test-backend ## Run all tests (frontend + backend unit tests)
|
|
@echo "$(GREEN)All unit tests passed!$(NC)"
|
|
|
|
test-all: test test-e2e ## Run ALL tests (unit + e2e)
|
|
@echo "$(GREEN)All tests passed!$(NC)"
|
|
|
|
test-frontend: ## Run frontend unit tests
|
|
@echo "$(YELLOW)Running frontend tests...$(NC)"
|
|
cd frontend && npm test
|
|
|
|
test-backend: ## Run backend unit tests
|
|
@echo "$(YELLOW)Running backend tests...$(NC)"
|
|
cd backend && npm test
|
|
|
|
test-coverage: ## Run all unit tests with coverage
|
|
@echo "$(YELLOW)Running tests with coverage...$(NC)"
|
|
cd frontend && npm run test:coverage
|
|
cd backend && npm run test:coverage
|
|
|
|
test-e2e: ## Run e2e tests (starts servers automatically)
|
|
@echo "$(YELLOW)Running e2e tests...$(NC)"
|
|
cd e2e && ./run-e2e.sh
|
|
|
|
test-e2e-headed: ## Run e2e tests with visible browser
|
|
@echo "$(YELLOW)Running e2e tests (headed)...$(NC)"
|
|
cd e2e && ./run-e2e.sh --headed
|
|
|
|
test-e2e-docker: ## Run e2e tests in Docker containers
|
|
@echo "$(YELLOW)Running e2e tests in Docker...$(NC)"
|
|
cd e2e && ./run-e2e.sh --docker
|
|
|
|
test-watch: ## Run tests in watch mode
|
|
@trap 'kill 0' INT; \
|
|
(cd frontend && npm run test:watch) & \
|
|
(cd backend && npm run test:watch) & \
|
|
wait
|
|
|
|
#===============================================================================
|
|
# DOCKER
|
|
#===============================================================================
|
|
|
|
docker-build: ## Build Docker images locally
|
|
@echo "$(YELLOW)Building Docker images...$(NC)"
|
|
docker-compose build
|
|
@echo "$(GREEN)Docker images built!$(NC)"
|
|
|
|
docker-run: ## Start Docker containers (docker-compose up)
|
|
@echo "$(YELLOW)Starting Docker containers...$(NC)"
|
|
docker-compose up
|
|
|
|
docker-up: docker-run ## Alias for docker-run
|
|
|
|
docker-run-detached: ## Start Docker containers in background
|
|
@echo "$(YELLOW)Starting Docker containers (detached)...$(NC)"
|
|
docker-compose up -d
|
|
@echo "$(GREEN)Containers started! Access at http://localhost:6767$(NC)"
|
|
|
|
docker-down: ## Stop and remove Docker containers
|
|
@echo "$(YELLOW)Stopping Docker containers...$(NC)"
|
|
docker-compose down
|
|
@echo "$(GREEN)Containers stopped!$(NC)"
|
|
|
|
docker-down-volumes: ## Stop containers and remove volumes
|
|
@echo "$(RED)Stopping containers and removing volumes...$(NC)"
|
|
docker-compose down -v
|
|
|
|
docker-logs: ## Show Docker container logs
|
|
docker-compose logs -f
|
|
|
|
docker-ps: ## Show running Docker containers
|
|
docker-compose ps
|
|
|
|
docker-restart: docker-down docker-run ## Restart Docker containers
|
|
|
|
docker-rebuild: docker-down docker-build docker-run ## Rebuild and restart containers
|
|
|
|
#===============================================================================
|
|
# VERSION MANAGEMENT
|
|
#===============================================================================
|
|
|
|
version: ## Show current version
|
|
@echo "$(YELLOW)Current version:$(NC) $(VERSION)"
|
|
|
|
version-bump: ## Interactive version bump
|
|
@echo "$(YELLOW)Current version:$(NC) $(VERSION)"
|
|
@echo ""
|
|
@echo "$(BLUE)Select version bump type:$(NC)"
|
|
@echo " 1) patch ($(VERSION) -> $$(echo $(VERSION) | awk -F. '{print $$1"."$$2"."$$3+1}'))"
|
|
@echo " 2) minor ($(VERSION) -> $$(echo $(VERSION) | awk -F. '{print $$1"."$$2+1".0"}'))"
|
|
@echo " 3) major ($(VERSION) -> $$(echo $(VERSION) | awk -F. '{print $$1+1".0.0"}'))"
|
|
@echo " 4) custom"
|
|
@echo ""
|
|
@read -p "Enter choice [1-4]: " choice; \
|
|
case $$choice in \
|
|
1) NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1"."$$2"."$$3+1}') ;; \
|
|
2) NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1"."$$2+1".0"}') ;; \
|
|
3) NEW_VERSION=$$(echo $(VERSION) | awk -F. '{print $$1+1".0.0"}') ;; \
|
|
4) read -p "Enter new version: " NEW_VERSION ;; \
|
|
*) echo "$(RED)Invalid choice$(NC)"; exit 1 ;; \
|
|
esac; \
|
|
echo "$(YELLOW)Bumping version to $$NEW_VERSION...$(NC)"; \
|
|
echo "$$NEW_VERSION" > VERSION; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json; \
|
|
echo "$(GREEN)Version bumped to $$NEW_VERSION$(NC)"
|
|
|
|
#===============================================================================
|
|
# RELEASE
|
|
#===============================================================================
|
|
|
|
changelog: ## Edit release notes (RELEASE.md)
|
|
@echo "$(YELLOW)Opening RELEASE.md for editing...$(NC)"
|
|
@if [ -z "$$EDITOR" ]; then \
|
|
echo "$(RED)No EDITOR set. Using vim.$(NC)"; \
|
|
vim RELEASE.md; \
|
|
else \
|
|
$$EDITOR RELEASE.md; \
|
|
fi
|
|
|
|
release: ## Full release workflow (main branch only)
|
|
@echo "$(GREEN)===========================================$(NC)"
|
|
@echo "$(GREEN) ExcaliDash Release Workflow$(NC)"
|
|
@echo "$(GREEN)===========================================$(NC)"
|
|
@echo ""
|
|
@# Branch check
|
|
@CURRENT_BRANCH=$$(git rev-parse --abbrev-ref HEAD); \
|
|
if [ "$$CURRENT_BRANCH" != "main" ]; then \
|
|
echo "$(RED)ERROR: Releases must be made from 'main' branch!$(NC)"; \
|
|
echo "$(RED)Current branch: $$CURRENT_BRANCH$(NC)"; \
|
|
echo "$(YELLOW)Please switch to main and try again.$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo "$(GREEN)✓ On main branch$(NC)"
|
|
@echo ""
|
|
@# Pull latest
|
|
@echo "$(YELLOW)Pulling latest changes...$(NC)"
|
|
@git pull origin main
|
|
@echo "$(GREEN)✓ Up to date with remote$(NC)"
|
|
@echo ""
|
|
@# Show current status
|
|
@echo "$(YELLOW)Current status:$(NC)"
|
|
@git status --short || true
|
|
@echo ""
|
|
@# Run tests
|
|
@echo "$(YELLOW)Running tests...$(NC)"
|
|
@$(MAKE) test
|
|
@echo "$(GREEN)✓ All tests passed$(NC)"
|
|
@echo ""
|
|
@# Version bump - inline with clear options
|
|
@CURRENT=$$(cat VERSION); \
|
|
PATCH=$$(echo $$CURRENT | awk -F. '{print $$1"."$$2"."$$3+1}'); \
|
|
MINOR=$$(echo $$CURRENT | awk -F. '{print $$1"."$$2+1".0"}'); \
|
|
MAJOR=$$(echo $$CURRENT | awk -F. '{print $$1+1".0.0"}'); \
|
|
echo "$(YELLOW)Current version: $$CURRENT$(NC)"; \
|
|
echo ""; \
|
|
echo "$(BLUE)Select version bump:$(NC)"; \
|
|
echo " 1) patch → $$PATCH"; \
|
|
echo " 2) minor → $$MINOR"; \
|
|
echo " 3) major → $$MAJOR"; \
|
|
echo " 4) custom"; \
|
|
echo " 5) skip (keep $$CURRENT)"; \
|
|
echo ""; \
|
|
read -p "Enter choice [1-5]: " choice; \
|
|
case $$choice in \
|
|
1) NEW_VERSION=$$PATCH ;; \
|
|
2) NEW_VERSION=$$MINOR ;; \
|
|
3) NEW_VERSION=$$MAJOR ;; \
|
|
4) read -p "Enter new version: " NEW_VERSION ;; \
|
|
5) NEW_VERSION=$$CURRENT ;; \
|
|
*) echo "$(RED)Invalid choice, using current$(NC)"; NEW_VERSION=$$CURRENT ;; \
|
|
esac; \
|
|
if [ "$$NEW_VERSION" != "$$CURRENT" ]; then \
|
|
echo "$(YELLOW)Bumping version to $$NEW_VERSION...$(NC)"; \
|
|
echo "$$NEW_VERSION" > VERSION; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json; \
|
|
echo "$(GREEN)✓ Version bumped to $$NEW_VERSION$(NC)"; \
|
|
else \
|
|
echo "$(YELLOW)Keeping version $$CURRENT$(NC)"; \
|
|
fi
|
|
@echo ""
|
|
@# Release notes
|
|
@echo "$(YELLOW)Release notes (RELEASE.md):$(NC)"
|
|
@read -p "Edit RELEASE.md now? [Y/n]: " edit; \
|
|
if [ "$$edit" != "n" ] && [ "$$edit" != "N" ]; then \
|
|
$(MAKE) changelog; \
|
|
fi
|
|
@echo ""
|
|
@# Show summary before commit
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(BLUE)===========================================$(NC)"; \
|
|
echo "$(BLUE)Release Summary$(NC)"; \
|
|
echo "$(BLUE)===========================================$(NC)"; \
|
|
echo " Version: v$$NEW_VERSION"; \
|
|
echo " Branch: main"; \
|
|
echo " Tag: v$$NEW_VERSION"; \
|
|
echo ""; \
|
|
echo "$(YELLOW)Changes to be committed:$(NC)"; \
|
|
git status --short; \
|
|
echo ""
|
|
@read -p "$(YELLOW)Proceed with release? [y/N]: $(NC)" confirm; \
|
|
if [ "$$confirm" != "y" ] && [ "$$confirm" != "Y" ]; then \
|
|
echo "$(RED)Release aborted.$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo ""
|
|
@# Commit changes
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(YELLOW)Committing release...$(NC)"; \
|
|
git add -A; \
|
|
git commit -m "chore: release v$$NEW_VERSION" || echo "$(YELLOW)Nothing to commit$(NC)"
|
|
@echo "$(GREEN)✓ Changes committed$(NC)"
|
|
@echo ""
|
|
@# Push to remote
|
|
@echo "$(YELLOW)Pushing to remote...$(NC)"
|
|
@git push origin main
|
|
@echo "$(GREEN)✓ Pushed to origin/main$(NC)"
|
|
@echo ""
|
|
@# Create git tag
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(YELLOW)Creating tag v$$NEW_VERSION...$(NC)"; \
|
|
git tag -a "v$$NEW_VERSION" -m "Release v$$NEW_VERSION"; \
|
|
git push origin "v$$NEW_VERSION"
|
|
@echo "$(GREEN)✓ Tag v$$NEW_VERSION created and pushed$(NC)"
|
|
@echo ""
|
|
@# Create GitHub release
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(YELLOW)Creating GitHub release...$(NC)"; \
|
|
if command -v gh &> /dev/null; then \
|
|
gh release create "v$$NEW_VERSION" \
|
|
--title "ExcaliDash v$$NEW_VERSION" \
|
|
--notes-file RELEASE.md; \
|
|
echo "$(GREEN)✓ GitHub release created$(NC)"; \
|
|
else \
|
|
echo "$(RED)gh CLI not installed!$(NC)"; \
|
|
echo "$(YELLOW)Install with: brew install gh$(NC)"; \
|
|
echo "$(YELLOW)Then run: gh auth login$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo ""
|
|
@# Build and push Docker images
|
|
@echo "$(YELLOW)Building and pushing Docker images...$(NC)"
|
|
@./publish-docker.sh
|
|
@echo ""
|
|
@echo "$(GREEN)===========================================$(NC)"
|
|
@echo "$(GREEN) Release Complete!$(NC)"
|
|
@echo "$(GREEN)===========================================$(NC)"
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo ""; \
|
|
echo "$(GREEN)✓ Version: v$$NEW_VERSION$(NC)"; \
|
|
echo "$(GREEN)✓ Git tag pushed$(NC)"; \
|
|
echo "$(GREEN)✓ GitHub release created$(NC)"; \
|
|
echo "$(GREEN)✓ Docker images published$(NC)"
|
|
|
|
pre-release: ## Pre-release workflow (pre-release branch only)
|
|
@echo "$(BLUE)===========================================$(NC)"
|
|
@echo "$(BLUE) ExcaliDash Pre-Release Workflow$(NC)"
|
|
@echo "$(BLUE)===========================================$(NC)"
|
|
@echo ""
|
|
@# Branch check
|
|
@CURRENT_BRANCH=$$(git rev-parse --abbrev-ref HEAD); \
|
|
if [ "$$CURRENT_BRANCH" != "pre-release" ]; then \
|
|
echo "$(RED)ERROR: Pre-releases must be made from 'pre-release' branch!$(NC)"; \
|
|
echo "$(RED)Current branch: $$CURRENT_BRANCH$(NC)"; \
|
|
echo "$(YELLOW)Please switch to pre-release and try again.$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo "$(GREEN)✓ On pre-release branch$(NC)"
|
|
@echo ""
|
|
@# Pull latest
|
|
@echo "$(YELLOW)Pulling latest changes...$(NC)"
|
|
@git pull origin pre-release
|
|
@echo "$(GREEN)✓ Up to date with remote$(NC)"
|
|
@echo ""
|
|
@# Show current status
|
|
@echo "$(YELLOW)Current status:$(NC)"
|
|
@git status --short || true
|
|
@echo ""
|
|
@# Run tests
|
|
@echo "$(YELLOW)Running tests...$(NC)"
|
|
@$(MAKE) test
|
|
@echo "$(GREEN)✓ All tests passed$(NC)"
|
|
@echo ""
|
|
@# Version bump - inline with clear options
|
|
@CURRENT=$$(cat VERSION); \
|
|
PATCH=$$(echo $$CURRENT | awk -F. '{print $$1"."$$2"."$$3+1}'); \
|
|
MINOR=$$(echo $$CURRENT | awk -F. '{print $$1"."$$2+1".0"}'); \
|
|
MAJOR=$$(echo $$CURRENT | awk -F. '{print $$1+1".0.0"}'); \
|
|
echo "$(YELLOW)Current version: $$CURRENT$(NC)"; \
|
|
echo ""; \
|
|
echo "$(BLUE)Select version bump:$(NC)"; \
|
|
echo " 1) patch → $$PATCH-dev"; \
|
|
echo " 2) minor → $$MINOR-dev"; \
|
|
echo " 3) major → $$MAJOR-dev"; \
|
|
echo " 4) custom"; \
|
|
echo " 5) skip (keep $$CURRENT-dev)"; \
|
|
echo ""; \
|
|
read -p "Enter choice [1-5]: " choice; \
|
|
case $$choice in \
|
|
1) NEW_VERSION=$$PATCH ;; \
|
|
2) NEW_VERSION=$$MINOR ;; \
|
|
3) NEW_VERSION=$$MAJOR ;; \
|
|
4) read -p "Enter new version (without -dev suffix): " NEW_VERSION ;; \
|
|
5) NEW_VERSION=$$CURRENT ;; \
|
|
*) echo "$(RED)Invalid choice, using current$(NC)"; NEW_VERSION=$$CURRENT ;; \
|
|
esac; \
|
|
if [ "$$NEW_VERSION" != "$$CURRENT" ]; then \
|
|
echo "$(YELLOW)Bumping version to $$NEW_VERSION...$(NC)"; \
|
|
echo "$$NEW_VERSION" > VERSION; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" frontend/package.json; \
|
|
sed -i '' "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json 2>/dev/null || \
|
|
sed -i "s/\"version\": \".*\"/\"version\": \"$$NEW_VERSION\"/" backend/package.json; \
|
|
echo "$(GREEN)✓ Version bumped to $$NEW_VERSION$(NC)"; \
|
|
else \
|
|
echo "$(YELLOW)Keeping version $$CURRENT$(NC)"; \
|
|
fi
|
|
@echo ""
|
|
@# Release notes
|
|
@echo "$(YELLOW)Release notes (RELEASE.md):$(NC)"
|
|
@read -p "Edit RELEASE.md now? [Y/n]: " edit; \
|
|
if [ "$$edit" != "n" ] && [ "$$edit" != "N" ]; then \
|
|
$(MAKE) changelog; \
|
|
fi
|
|
@echo ""
|
|
@# Show summary before commit
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(BLUE)===========================================$(NC)"; \
|
|
echo "$(BLUE)Pre-Release Summary$(NC)"; \
|
|
echo "$(BLUE)===========================================$(NC)"; \
|
|
echo " Version: v$$NEW_VERSION-dev"; \
|
|
echo " Branch: pre-release"; \
|
|
echo " Tag: v$$NEW_VERSION-dev (pre-release)"; \
|
|
echo ""; \
|
|
echo "$(YELLOW)Changes to be committed:$(NC)"; \
|
|
git status --short; \
|
|
echo ""
|
|
@read -p "$(YELLOW)Proceed with pre-release? [y/N]: $(NC)" confirm; \
|
|
if [ "$$confirm" != "y" ] && [ "$$confirm" != "Y" ]; then \
|
|
echo "$(RED)Pre-release aborted.$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo ""
|
|
@# Commit changes
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo "$(YELLOW)Committing pre-release...$(NC)"; \
|
|
git add -A; \
|
|
git commit -m "chore: pre-release v$$NEW_VERSION-dev" || echo "$(YELLOW)Nothing to commit$(NC)"
|
|
@echo "$(GREEN)✓ Changes committed$(NC)"
|
|
@echo ""
|
|
@# Push to remote
|
|
@echo "$(YELLOW)Pushing to remote...$(NC)"
|
|
@git push origin pre-release
|
|
@echo "$(GREEN)✓ Pushed to origin/pre-release$(NC)"
|
|
@echo ""
|
|
@# Create git tag
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
PRE_TAG="v$$NEW_VERSION-dev"; \
|
|
echo "$(YELLOW)Creating tag $$PRE_TAG...$(NC)"; \
|
|
git tag -a "$$PRE_TAG" -m "Pre-release $$PRE_TAG"; \
|
|
git push origin "$$PRE_TAG"
|
|
@echo "$(GREEN)✓ Tag $$PRE_TAG created and pushed$(NC)"
|
|
@echo ""
|
|
@# Create GitHub pre-release
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
PRE_TAG="v$$NEW_VERSION-dev"; \
|
|
echo "$(YELLOW)Creating GitHub pre-release...$(NC)"; \
|
|
if command -v gh &> /dev/null; then \
|
|
gh release create "$$PRE_TAG" \
|
|
--title "ExcaliDash $$PRE_TAG (Pre-release)" \
|
|
--notes-file RELEASE.md \
|
|
--prerelease; \
|
|
echo "$(GREEN)✓ GitHub pre-release created$(NC)"; \
|
|
else \
|
|
echo "$(RED)gh CLI not installed!$(NC)"; \
|
|
echo "$(YELLOW)Install with: brew install gh$(NC)"; \
|
|
echo "$(YELLOW)Then run: gh auth login$(NC)"; \
|
|
exit 1; \
|
|
fi
|
|
@echo ""
|
|
@# Build and push Docker images
|
|
@echo "$(YELLOW)Building and pushing Docker images...$(NC)"
|
|
@./publish-docker-prerelease.sh
|
|
@echo ""
|
|
@echo "$(BLUE)===========================================$(NC)"
|
|
@echo "$(GREEN) Pre-Release Complete!$(NC)"
|
|
@echo "$(BLUE)===========================================$(NC)"
|
|
@NEW_VERSION=$$(cat VERSION); \
|
|
echo ""; \
|
|
echo "$(GREEN)✓ Version: v$$NEW_VERSION-dev$(NC)"; \
|
|
echo "$(GREEN)✓ Git tag pushed$(NC)"; \
|
|
echo "$(GREEN)✓ GitHub pre-release created$(NC)"; \
|
|
echo "$(GREEN)✓ Docker images published$(NC)"
|
|
|
|
release-docker: ## Build and push release Docker images
|
|
./publish-docker.sh
|
|
|
|
pre-release-docker: ## Build and push pre-release Docker images
|
|
./publish-docker-prerelease.sh
|
|
|
|
#===============================================================================
|
|
# DATABASE
|
|
#===============================================================================
|
|
|
|
db-migrate: ## Run database migrations
|
|
@echo "$(YELLOW)Running database migrations...$(NC)"
|
|
cd backend && npx prisma migrate dev
|
|
@echo "$(GREEN)Migrations complete!$(NC)"
|
|
|
|
db-generate: ## Generate Prisma client
|
|
@echo "$(YELLOW)Generating Prisma client...$(NC)"
|
|
cd backend && npx prisma generate
|
|
@echo "$(GREEN)Client generated!$(NC)"
|
|
|
|
db-reset: ## Reset database (WARNING: destroys all data)
|
|
@echo "$(RED)WARNING: This will destroy all data!$(NC)"
|
|
@read -p "Are you sure? [y/N]: " confirm; \
|
|
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
|
|
cd backend && npx prisma migrate reset --force; \
|
|
echo "$(GREEN)Database reset complete!$(NC)"; \
|
|
else \
|
|
echo "$(YELLOW)Cancelled$(NC)"; \
|
|
fi
|
|
|
|
db-studio: ## Open Prisma Studio (database GUI)
|
|
@echo "$(YELLOW)Opening Prisma Studio...$(NC)"
|
|
cd backend && npx prisma studio
|
|
|
|
#===============================================================================
|
|
# QUICK ALIASES
|
|
#===============================================================================
|
|
|
|
up: docker-run ## Alias: Start Docker containers
|
|
down: docker-down ## Alias: Stop Docker containers
|
|
logs: docker-logs ## Alias: Show Docker logs
|
|
t: test ## Alias: Run unit tests
|
|
ta: test-all ## Alias: Run all tests
|