name: SAP-ERP Portal CI/CD on: push: branches: - main jobs: build: runs-on: windows-latest steps: - name: Checkout source code uses: actions/checkout@v4 - name: Check Node.js shell: powershell run: node --version - name: Check npm shell: powershell run: npm --version - name: Install dependencies shell: powershell run: npm ci - name: Check application syntax shell: powershell run: node --check server.js - name: Bundle backend (esbuild) shell: powershell run: | if (Test-Path dist) { Remove-Item dist -Recurse -Force } New-Item -ItemType Directory -Path dist | Out-Null npx esbuild server.js --bundle --platform=node --target=node18 --minify --outfile=dist\server.js --log-level=warning if ($LASTEXITCODE -ne 0) { throw "esbuild failed" } - name: Copy frontend + runtime assets shell: powershell run: | Copy-Item -Path public -Destination dist\public -Recurse -Force if (Test-Path logo.png) { Copy-Item logo.png dist\ -Force } New-Item -ItemType Directory -Path dist\data -Force | Out-Null Copy-Item node_modules\@foliojs-fork\fontkit\data.trie dist\ -Force Copy-Item node_modules\@foliojs-fork\fontkit\indic.trie dist\ -Force Copy-Item node_modules\@foliojs-fork\fontkit\use.trie dist\ -Force Copy-Item node_modules\@foliojs-fork\linebreak\src\classes.trie dist\ -Force Copy-Item node_modules\@foliojs-fork\pdfkit\js\data\*.afm dist\data\ -Force Copy-Item node_modules\@foliojs-fork\pdfkit\js\data\sRGB_IEC61966_2_1.icc dist\data\ -Force Copy-Item deploy dist\deploy -Recurse -Force Remove-Item dist\deploy\build-dist.bat -Force -ErrorAction SilentlyContinue if (Test-Path services\sap-di-pr.ps1) { Copy-Item services\sap-di-pr.ps1 dist\ -Force } $diExe = "services\SapDiConsole\bin\Release\net472\SapDiConsole.exe" if (Test-Path $diExe) { New-Item -ItemType Directory -Path dist\SapDiConsole\bin\Release\net472 -Force | Out-Null Copy-Item services\SapDiConsole\bin\Release\net472\* dist\SapDiConsole\bin\Release\net472\ -Recurse -Force } else { Write-Warning "SapDiConsole.exe not found - Purchase Requests will not work until it is built and committed separately." } New-Item -ItemType Directory -Path dist\uploads -Force | Out-Null New-Item -ItemType Directory -Path dist\logs -Force | Out-Null - name: Stop running portal shell: powershell run: | schtasks /End /TN "SAP-ERP-Portal" 2>$null Get-CimInstance Win32_Process | Where-Object { $_.Name -eq 'node.exe' -and $_.CommandLine -match 'server\.js' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force Write-Host "Stopped node PID $($_.ProcessId)" } - name: Deploy to production folder shell: powershell run: | $deployPath = "D:\apps\sap-erp" if (!(Test-Path $deployPath)) { New-Item -ItemType Directory -Path $deployPath -Force | Out-Null } # Copy the fresh build over the live folder, but never touch # .env, uploads\ or logs\ - those belong to the running instance. robocopy dist\ $deployPath /E /XD "$deployPath\uploads" "$deployPath\logs" /XF ".env" /NFL /NDL /NJH /NJS if ($LASTEXITCODE -ge 8) { throw "robocopy failed with exit code $LASTEXITCODE" } Write-Host "Deployment completed successfully." - name: Start portal shell: powershell run: | $started = $false try { schtasks /Run /TN "SAP-ERP-Portal" 2>$null if ($LASTEXITCODE -eq 0) { $started = $true } } catch {} if (-not $started) { Write-Warning "Scheduled task 'SAP-ERP-Portal' not found - starting supervisor directly." Start-Process -FilePath "D:\apps\sap-erp\deploy\start-server.bat" -WorkingDirectory "D:\apps\sap-erp\deploy" } Write-Host "Portal restart triggered."