From a99e716ad2793903ffef997ad7ac56d9f06540a7 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Wed, 15 Oct 2025 16:38:33 -0600 Subject: [PATCH] Add windows running --- Makefile.Windows.ps1 | 300 +++++++++++++++++++++++++++++++++++++++++++ api/run.ps1 | 53 ++++++++ web/run.ps1 | 24 ++++ 3 files changed, 377 insertions(+) create mode 100644 Makefile.Windows.ps1 create mode 100644 api/run.ps1 create mode 100644 web/run.ps1 diff --git a/Makefile.Windows.ps1 b/Makefile.Windows.ps1 new file mode 100644 index 000000000..9a3242bfa --- /dev/null +++ b/Makefile.Windows.ps1 @@ -0,0 +1,300 @@ +[CmdletBinding()] +param( + [Parameter(Position = 0)] + [string[]]$Targets = @("help") +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = "Stop" + +$RepositoryRoot = $PSScriptRoot +if (-not $RepositoryRoot) { + $RepositoryRoot = (Get-Location).Path +} + +function Copy-FileIfMissing { + param( + [Parameter(Mandatory = $true)][string]$Source, + [Parameter(Mandatory = $true)][string]$Destination, + [string]$ExistsMessage = "" + ) + + if (-not (Test-Path -LiteralPath $Destination)) { + $destinationDirectory = Split-Path -Parent -Path $Destination + if ($destinationDirectory -and -not (Test-Path -LiteralPath $destinationDirectory)) { + New-Item -ItemType Directory -Path $destinationDirectory | Out-Null + } + + Copy-Item -LiteralPath $Source -Destination $Destination + } + elseif ($ExistsMessage) { + Write-Host $ExistsMessage + } +} + +function Remove-PathIfExists { + param([Parameter(Mandatory = $true)][string]$Target) + + if (Test-Path -LiteralPath $Target) { + Remove-Item -LiteralPath $Target -Recurse -Force + } +} + +function Invoke-InDirectory { + param( + [Parameter(Mandatory = $true)][string]$Path, + [Parameter(Mandatory = $true)][scriptblock]$Script + ) + + Push-Location -LiteralPath $Path + try { + & $Script + } + finally { + Pop-Location + } +} + +function Invoke-PrepareDocker { + Write-Host "🐳 Setting up Docker middleware..." + $dockerDirectory = Join-Path $RepositoryRoot "docker" + + Copy-FileIfMissing ` + -Source (Join-Path $dockerDirectory "middleware.env.example") ` + -Destination (Join-Path $dockerDirectory "middleware.env") ` + -ExistsMessage "Docker middleware.env already exists" + + Invoke-InDirectory -Path $dockerDirectory -Script { + docker compose -f docker-compose.middleware.yaml ` + --env-file middleware.env ` + -p dify-middlewares-dev up -d + } + + Write-Host "✅ Docker middleware started" +} + +function Invoke-PrepareWeb { + Write-Host "🌐 Setting up web environment..." + $webDirectory = Join-Path $RepositoryRoot "web" + + Copy-FileIfMissing ` + -Source (Join-Path $webDirectory ".env.example") ` + -Destination (Join-Path $webDirectory ".env") ` + -ExistsMessage "Web .env already exists" + + Invoke-InDirectory -Path $webDirectory -Script { + pnpm install + } + + Write-Host "✅ Web environment prepared (not started)" +} + +function Invoke-PrepareApi { + Write-Host "🔧 Setting up API environment..." + $apiDirectory = Join-Path $RepositoryRoot "api" + + Copy-FileIfMissing ` + -Source (Join-Path $apiDirectory ".env.example") ` + -Destination (Join-Path $apiDirectory ".env") ` + -ExistsMessage "API .env already exists" + + Invoke-InDirectory -Path $apiDirectory -Script { + uv sync --dev + uv run flask db upgrade + } + + Write-Host "✅ API environment prepared (not started)" +} + +function Invoke-DevClean { + Write-Host "⚠️ Stopping Docker containers..." + $dockerDirectory = Join-Path $RepositoryRoot "docker" + + Invoke-InDirectory -Path $dockerDirectory -Script { + docker compose -f docker-compose.middleware.yaml ` + --env-file middleware.env ` + -p dify-middlewares-dev down + } + + Write-Host "🗑️ Removing volumes..." + Remove-PathIfExists (Join-Path $dockerDirectory "volumes/db") + Remove-PathIfExists (Join-Path $dockerDirectory "volumes/redis") + Remove-PathIfExists (Join-Path $dockerDirectory "volumes/plugin_daemon") + Remove-PathIfExists (Join-Path $dockerDirectory "volumes/weaviate") + Remove-PathIfExists (Join-Path $RepositoryRoot "api/storage") + + Write-Host "✅ Cleanup complete" +} + +function Invoke-Format { + Write-Host "🎨 Running ruff format..." + Invoke-InDirectory -Path $RepositoryRoot -Script { + uv run --project api --dev ruff format ./api + } + Write-Host "✅ Code formatting complete" +} + +function Invoke-Check { + Write-Host "🔍 Running ruff check..." + Invoke-InDirectory -Path $RepositoryRoot -Script { + uv run --project api --dev ruff check ./api + } + Write-Host "✅ Code check complete" +} + +function Invoke-Lint { + Write-Host "🔧 Running ruff format, check with fixes, and import linter..." + Invoke-InDirectory -Path $RepositoryRoot -Script { + uv run --project api --dev ruff format ./api + uv run --project api --dev ruff check --fix ./api + } + + Invoke-InDirectory -Path (Join-Path $RepositoryRoot "api") -Script { + uv run --dev lint-imports + } + + Write-Host "✅ Linting complete" +} + +function Invoke-TypeCheck { + Write-Host "📝 Running type check with basedpyright..." + Invoke-InDirectory -Path (Join-Path $RepositoryRoot "api") -Script { + uv run --dev basedpyright + } + Write-Host "✅ Type check complete" +} + +function Invoke-BuildWeb { + $dockerRegistry = $env:DOCKER_REGISTRY + if (-not $dockerRegistry) { + $dockerRegistry = "langgenius" + } + + $image = "$dockerRegistry/dify-web" + $version = if ($env:VERSION) { $env:VERSION } else { "latest" } + + Write-Host "Building web Docker image: $image:$version..." + Invoke-InDirectory -Path $RepositoryRoot -Script { + docker build -t "$image:$version" ./web + } + Write-Host "Web Docker image built successfully: $image:$version" +} + +function Invoke-BuildApi { + $dockerRegistry = $env:DOCKER_REGISTRY + if (-not $dockerRegistry) { + $dockerRegistry = "langgenius" + } + + $image = "$dockerRegistry/dify-api" + $version = if ($env:VERSION) { $env:VERSION } else { "latest" } + + Write-Host "Building API Docker image: $image:$version..." + Invoke-InDirectory -Path $RepositoryRoot -Script { + docker build -t "$image:$version" ./api + } + Write-Host "API Docker image built successfully: $image:$version" +} + +function Invoke-PushWeb { + $dockerRegistry = $env:DOCKER_REGISTRY + if (-not $dockerRegistry) { + $dockerRegistry = "langgenius" + } + + $image = "$dockerRegistry/dify-web" + $version = if ($env:VERSION) { $env:VERSION } else { "latest" } + + Write-Host "Pushing web Docker image: $image:$version..." + docker push "$image:$version" + Write-Host "Web Docker image pushed successfully: $image:$version" +} + +function Invoke-PushApi { + $dockerRegistry = $env:DOCKER_REGISTRY + if (-not $dockerRegistry) { + $dockerRegistry = "langgenius" + } + + $image = "$dockerRegistry/dify-api" + $version = if ($env:VERSION) { $env:VERSION } else { "latest" } + + Write-Host "Pushing API Docker image: $image:$version..." + docker push "$image:$version" + Write-Host "API Docker image pushed successfully: $image:$version" +} + +function Invoke-BuildAll { + Invoke-BuildWeb + Invoke-BuildApi +} + +function Invoke-PushAll { + Invoke-PushWeb + Invoke-PushApi +} + +function Invoke-BuildPushAll { + Invoke-BuildAll + Invoke-PushAll + Write-Host "All Docker images have been built and pushed." +} + +function Invoke-Help { + Write-Host "Development Setup Targets:" + Write-Host " dev-setup - Run all setup steps for backend dev environment" + Write-Host " prepare-docker - Set up Docker middleware" + Write-Host " prepare-web - Set up web environment" + Write-Host " prepare-api - Set up API environment" + Write-Host " dev-clean - Stop Docker middleware containers" + Write-Host "" + Write-Host "Backend Code Quality:" + Write-Host " format - Format code with ruff" + Write-Host " check - Check code with ruff" + Write-Host " lint - Format and fix code with ruff" + Write-Host " type-check - Run type checking with basedpyright" + Write-Host "" + Write-Host "Docker Build Targets:" + Write-Host " build-web - Build web Docker image" + Write-Host " build-api - Build API Docker image" + Write-Host " build-all - Build all Docker images" + Write-Host " push-all - Push all Docker images" + Write-Host " build-push-all - Build and push all Docker images" +} + +$TargetHandlers = @{ + "prepare-docker" = { Invoke-PrepareDocker } + "prepare-web" = { Invoke-PrepareWeb } + "prepare-api" = { Invoke-PrepareApi } + "dev-setup" = { + Invoke-PrepareDocker + Invoke-PrepareWeb + Invoke-PrepareApi + Write-Host "✅ Backend development environment setup complete!" + } + "dev-clean" = { Invoke-DevClean } + "format" = { Invoke-Format } + "check" = { Invoke-Check } + "lint" = { Invoke-Lint } + "type-check" = { Invoke-TypeCheck } + "build-web" = { Invoke-BuildWeb } + "build-api" = { Invoke-BuildApi } + "push-web" = { Invoke-PushWeb } + "push-api" = { Invoke-PushApi } + "build-all" = { Invoke-BuildAll } + "push-all" = { Invoke-PushAll } + "build-push-all" = { Invoke-BuildPushAll } + "help" = { Invoke-Help } +} + +foreach ($target in $Targets) { + $normalized = $target.ToLowerInvariant() + if (-not $TargetHandlers.ContainsKey($normalized)) { + Write-Error "Unknown target '$target'. Run 'pwsh -File Makefile.Windows.ps1 help' for available targets." + exit 1 + } + + & $TargetHandlers[$normalized] +} + + diff --git a/api/run.ps1 b/api/run.ps1 new file mode 100644 index 000000000..344060c64 --- /dev/null +++ b/api/run.ps1 @@ -0,0 +1,53 @@ +[CmdletBinding()] +param( + [string]$Host = "0.0.0.0", + [int]$Port = 5001, + [switch]$NoDebug +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = "Stop" + +Push-Location -LiteralPath $PSScriptRoot +try { + $venvPath = Join-Path (Get-Location) ".venv" + + if (-not (Test-Path -LiteralPath $venvPath)) { + Write-Host "Creating uv virtual environment at $venvPath..." + uv venv --seed + uv sync --dev + } + + $activateScript = Join-Path $venvPath "Scripts/Activate.ps1" + if (-not (Test-Path -LiteralPath $activateScript)) { + throw "Unable to locate activation script at $activateScript" + } + + $uvArgs = @( + "-m", + "flask", + "--app", "app", + "run", + "--host", $Host, + "--port", $Port.ToString() + ) + + if (-not $NoDebug.IsPresent) { + $uvArgs += "--debug" + } + + . $activateScript + try { + & python @uvArgs + } + finally { + if (Get-Command -Name deactivate -ErrorAction SilentlyContinue) { + deactivate + } + } +} +finally { + Pop-Location +} + + diff --git a/web/run.ps1 b/web/run.ps1 new file mode 100644 index 000000000..3116e3e2a --- /dev/null +++ b/web/run.ps1 @@ -0,0 +1,24 @@ +[CmdletBinding()] +param( + [string]$Script = "dev", + [string[]]$Arguments +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = "Stop" + +Push-Location -LiteralPath $PSScriptRoot +try { + $pnpmArgs = @("run", $Script) + if ($Arguments) { + $pnpmArgs += "--" + $pnpmArgs += $Arguments + } + + pnpm @pnpmArgs +} +finally { + Pop-Location +} + +