deploy CI

This commit is contained in:
Fran Jurmanović
2025-07-04 19:25:34 +02:00
parent 12e259270d
commit b1792e1c71
8 changed files with 994 additions and 7665 deletions

233
.github/workflows/deploy.yml vendored Normal file
View File

@@ -0,0 +1,233 @@
name: Deploy to Windows Server
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
workflow_dispatch:
env:
GO_VERSION: '1.23'
SERVICE_NAME: 'ACC Server Manager'
BINARY_NAME: 'acc-server-manager'
MIGRATE_BINARY_NAME: 'acc-migrate'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go modules
uses: actions/cache@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Run tests
run: go test -v ./...
- name: Build API for Windows
env:
GOOS: windows
GOARCH: amd64
run: |
go build -o ${{ env.BINARY_NAME }}.exe ./cmd/api
- name: Build Migration tool for Windows
env:
GOOS: windows
GOARCH: amd64
run: |
go build -o ${{ env.MIGRATE_BINARY_NAME }}.exe ./cmd/migrate
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: windows-binaries
path: |
${{ env.BINARY_NAME }}.exe
${{ env.MIGRATE_BINARY_NAME }}.exe
retention-days: 5
deploy:
needs: build
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: windows-binaries
path: ./build
- name: Setup SSH key
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.WINDOWS_SERVER_SSH_KEY }}
- name: Deploy to Windows Server
env:
SERVER_HOST: ${{ secrets.WINDOWS_SERVER_HOST }}
SERVER_USER: ${{ secrets.WINDOWS_SERVER_USER }}
SERVER_PASSWORD: ${{ secrets.WINDOWS_SERVER_PASSWORD }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
run: |
# Install PowerShell Core if not available
if ! command -v pwsh &> /dev/null; then
echo "Installing PowerShell Core..."
wget -q https://github.com/PowerShell/PowerShell/releases/download/v7.4.0/powershell_7.4.0-1.deb_amd64.deb
sudo dpkg -i powershell_7.4.0-1.deb_amd64.deb
sudo apt-get install -f
fi
# Create deployment script
cat > deploy_script.ps1 << 'EOF'
param(
[string]$ServiceName = "${{ env.SERVICE_NAME }}",
[string]$BinaryName = "${{ env.BINARY_NAME }}",
[string]$MigrateBinaryName = "${{ env.MIGRATE_BINARY_NAME }}",
[string]$DeployPath = "$env:DEPLOY_PATH"
)
Write-Host "Starting deployment process..." -ForegroundColor Green
# Check if service exists and stop it
$service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($service) {
Write-Host "Stopping service: $ServiceName" -ForegroundColor Yellow
Stop-Service -Name $ServiceName -Force
# Wait for service to stop
$timeout = 30
$elapsed = 0
while ($service.Status -ne 'Stopped' -and $elapsed -lt $timeout) {
Start-Sleep -Seconds 1
$elapsed++
$service.Refresh()
}
if ($service.Status -ne 'Stopped') {
Write-Error "Failed to stop service within timeout"
exit 1
}
Write-Host "Service stopped successfully" -ForegroundColor Green
} else {
Write-Host "Service not found: $ServiceName" -ForegroundColor Yellow
}
# Create backup of current deployment
$backupPath = "$DeployPath\backup_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
if (Test-Path "$DeployPath\$BinaryName.exe") {
Write-Host "Creating backup at: $backupPath" -ForegroundColor Yellow
New-Item -ItemType Directory -Path $backupPath -Force | Out-Null
Copy-Item "$DeployPath\*" -Destination $backupPath -Recurse -Force
}
# Copy new binaries
Write-Host "Copying new binaries to: $DeployPath" -ForegroundColor Yellow
Copy-Item "C:\temp\$BinaryName.exe" -Destination "$DeployPath\$BinaryName.exe" -Force
Copy-Item "C:\temp\$MigrateBinaryName.exe" -Destination "$DeployPath\$MigrateBinaryName.exe" -Force
# Run migrations
Write-Host "Running database migrations..." -ForegroundColor Yellow
$migrateResult = & "$DeployPath\$MigrateBinaryName.exe" 2>&1
Write-Host "Migration output: $migrateResult" -ForegroundColor Cyan
# Start service
if ($service) {
Write-Host "Starting service: $ServiceName" -ForegroundColor Yellow
Start-Service -Name $ServiceName
# Wait for service to start
$timeout = 30
$elapsed = 0
while ($service.Status -ne 'Running' -and $elapsed -lt $timeout) {
Start-Sleep -Seconds 1
$elapsed++
$service.Refresh()
}
if ($service.Status -ne 'Running') {
Write-Error "Failed to start service within timeout"
# Rollback
Write-Host "Rolling back deployment..." -ForegroundColor Red
if (Test-Path $backupPath) {
Copy-Item "$backupPath\*" -Destination $DeployPath -Recurse -Force
Start-Service -Name $ServiceName
}
exit 1
}
Write-Host "Service started successfully" -ForegroundColor Green
} else {
Write-Host "Service not configured. Manual start required." -ForegroundColor Yellow
}
# Cleanup old backups (keep last 5)
$backupDir = Split-Path $DeployPath -Parent
Get-ChildItem -Path $backupDir -Directory -Name "backup_*" |
Sort-Object -Descending |
Select-Object -Skip 5 |
ForEach-Object { Remove-Item -Path "$backupDir\$_" -Recurse -Force }
Write-Host "Deployment completed successfully!" -ForegroundColor Green
EOF
# Copy files to Windows server using SCP
echo "Copying files to Windows server..."
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
./build/${{ env.BINARY_NAME }}.exe \
./build/${{ env.MIGRATE_BINARY_NAME }}.exe \
deploy_script.ps1 \
${{ env.SERVER_USER }}@${{ env.SERVER_HOST }}:C:/temp/
# Execute deployment script on Windows server
echo "Executing deployment script on Windows server..."
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
${{ env.SERVER_USER }}@${{ env.SERVER_HOST }} \
"powershell.exe -ExecutionPolicy Bypass -File C:/temp/deploy_script.ps1"
# Cleanup temp files
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
${{ env.SERVER_USER }}@${{ env.SERVER_HOST }} \
"del C:/temp/${{ env.BINARY_NAME }}.exe C:/temp/${{ env.MIGRATE_BINARY_NAME }}.exe C:/temp/deploy_script.ps1"
echo "Deployment completed successfully!"
notify:
needs: [build, deploy]
runs-on: ubuntu-latest
if: always()
steps:
- name: Notify deployment status
env:
WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
run: |
if [ "${{ needs.deploy.result }}" == "success" ]; then
STATUS="✅ SUCCESS"
COLOR="good"
else
STATUS="❌ FAILED"
COLOR="danger"
fi
if [ -n "$WEBHOOK_URL" ]; then
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"ACC Server Manager Deployment $STATUS\",\"attachments\":[{\"color\":\"$COLOR\",\"fields\":[{\"title\":\"Branch\",\"value\":\"${{ github.ref_name }}\",\"short\":true},{\"title\":\"Commit\",\"value\":\"${{ github.sha }}\",\"short\":true}]}]}" \
$WEBHOOK_URL
fi