Compare commits
No commits in common. "main" and "Maintenance/June2026" have entirely different histories.
main
...
Maintenanc
@ -1,5 +1,4 @@
|
||||
name: Build and Deploy CPRNIMS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
@ -7,205 +6,34 @@ on:
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: windows
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clean previous publish output
|
||||
shell: pwsh
|
||||
run: |
|
||||
Remove-Item -Recurse -Force "C:\ci-output\webapi" -ErrorAction SilentlyContinue
|
||||
Remove-Item -Recurse -Force "C:\ci-output\webapps" -ErrorAction SilentlyContinue
|
||||
|
||||
# ---- Build both .NET projects ----
|
||||
- name: Publish WebApi
|
||||
run: dotnet publish .\CPRNIMS.WebApi\CPRNIMS.WebApi.csproj -c Release -o D:\ci-output\webapi
|
||||
shell: pwsh
|
||||
run: dotnet publish .\CPRNIMS.WebApi\CPRNIMS.WebApi.csproj -c Release -o C:\ci-output\webapi
|
||||
|
||||
- name: Publish WebApps
|
||||
run: dotnet publish .\CPRNIMS.WebApps\CPRNIMS.WebApps.csproj -c Release -o D:\ci-output\webapps
|
||||
shell: pwsh
|
||||
run: dotnet publish .\CPRNIMS.WebApps\CPRNIMS.WebApps.csproj -c Release -o C:\ci-output\webapps
|
||||
|
||||
# ---- Generate production config from Gitea Actions secrets (never committed to git) ----
|
||||
- name: Write production appsettings - WebApi
|
||||
shell: pwsh
|
||||
env:
|
||||
TAVILY_KEY: ${{ secrets.LLI_NON_INVENTORY_PROD_TAVILY_API_KEY }}
|
||||
GROQ_KEY: ${{ secrets.LLI_NON_INVENTORY_PROD_GROQ_API_KEY }}
|
||||
JWT_SECRET: ${{ secrets.LLI_NON_INVENTORY_PROD_JWT_SECRET }}
|
||||
DB_CONN: ${{ secrets.LLI_NON_INVENTORY_PROD_DB_CONNECTION }}
|
||||
LOCALPURCH_CONN: ${{ secrets.LLI_NON_INVENTORY_PROD_DB_LOCALPURCH_CONNECTION }}
|
||||
run: |
|
||||
$config = @{
|
||||
Tavily = @{
|
||||
ApiKey = $env:TAVILY_KEY
|
||||
SearchUrl = "https://api.tavily.com/search"
|
||||
}
|
||||
Groq = @{
|
||||
ApiKey = $env:GROQ_KEY
|
||||
ApiUrl = "https://api.groq.com/openai/v1/chat/completions"
|
||||
Model = "llama-3.1-8b-instant"
|
||||
}
|
||||
JWT = @{
|
||||
ValidAudience = "https://lloydwebapi.lloydlab.com:2021"
|
||||
ValidIssuer = "https://lloydwebapi.lloydlab.com:2021"
|
||||
Secret = $env:JWT_SECRET
|
||||
}
|
||||
WebEndPoint = @{
|
||||
ForgotPassword = "https://llipurchasingnoninventory.com:8080/"
|
||||
SupplierForm = "https://llipurchasingnoninventory.com:8083/"
|
||||
}
|
||||
ConnectionStrings = @{
|
||||
DefaultConnection = $env:DB_CONN
|
||||
LocalPurchConn = $env:LOCALPURCH_CONN
|
||||
}
|
||||
}
|
||||
|
||||
$json = $config | ConvertTo-Json -Depth 5
|
||||
$json | Out-File -FilePath "C:\ci-output\webapi\appsettings.Production.json" -Encoding utf8
|
||||
Write-Host "Wrote appsettings.Production.json to webapi output (values masked in this log automatically)"
|
||||
exit 0
|
||||
|
||||
# ---- Generate production config for WebApps (uses Variables, not Secrets, since BaseUrl isn't sensitive) ----
|
||||
- name: Write production appsettings - WebApps
|
||||
shell: pwsh
|
||||
env:
|
||||
API_BASE_URL: ${{ vars.LLI_NON_INVENTORY_PROD_API_BASE_URL }}
|
||||
run: |
|
||||
$config = @{
|
||||
CommonEndpoints = @{
|
||||
ApiDefaultHeaders = @{
|
||||
BaseUrl = $env:API_BASE_URL
|
||||
ESignaturePath = "https://llipurchasingnoninventory.com:8080/Content/Images/Signatures/"
|
||||
ItemImages = "https://llipurchasingnoninventory.com:8080/content/images/"
|
||||
ContentTypeMedia = "application/json"
|
||||
Authorization = "token"
|
||||
ErrorMessage = "api/ErrorLogs/ErrorMessage/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$json = $config | ConvertTo-Json -Depth 5
|
||||
$json | Out-File -FilePath "C:\ci-output\webapps\appsettings.Production.json" -Encoding utf8
|
||||
Write-Host "Wrote appsettings.Production.json to webapps output"
|
||||
exit 0
|
||||
|
||||
# ---- Backup current live deployment before touching anything ----
|
||||
- name: Backup current live files
|
||||
shell: pwsh
|
||||
run: |
|
||||
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
|
||||
New-Item -ItemType Directory -Force -Path "C:\backups\$stamp" | Out-Null
|
||||
|
||||
# Mirror current live folders into the backup location (only if they exist / aren't empty)
|
||||
if (Test-Path "C:\inetpub\cprnims-api") {
|
||||
robocopy "C:\inetpub\cprnims-api" "C:\backups\$stamp\webapi" /MIR /R:2 /W:3 | Out-Null
|
||||
}
|
||||
if (Test-Path "C:\inetpub\cprnims-web") {
|
||||
robocopy "C:\inetpub\cprnims-web" "C:\backups\$stamp\webapps" /MIR /R:2 /W:3 | Out-Null
|
||||
}
|
||||
|
||||
# Record this backup's timestamp so later steps know where it lives
|
||||
$stamp | Out-File -FilePath "C:\backups\latest.txt" -Encoding ascii -NoNewline
|
||||
|
||||
# Keep only the last 5 backups to avoid filling the disk
|
||||
$all = Get-ChildItem "C:\backups" -Directory | Sort-Object Name -Descending
|
||||
if ($all.Count -gt 5) {
|
||||
$all | Select-Object -Skip 5 | Remove-Item -Recurse -Force
|
||||
}
|
||||
|
||||
Write-Host "Backed up current deployment to C:\backups\$stamp"
|
||||
exit 0
|
||||
|
||||
# ---- Deploy to IIS server over SSH ----
|
||||
- name: Stop app pools
|
||||
shell: pwsh
|
||||
run: |
|
||||
Import-Module WebAdministration
|
||||
Stop-WebAppPool -Name "CPRNIMS-Api" -ErrorAction SilentlyContinue
|
||||
Stop-WebAppPool -Name "CPRNIMS-Web" -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
ssh -i D:\gitea-runner\deploy_key lliadmin@212.47.72.54 "Import-Module WebAdministration; Stop-WebAppPool -Name 'CPRNIMS-Api'; Stop-WebAppPool -Name 'CPRNIMS-Web'; Start-Sleep -Seconds 3"
|
||||
shell: pwsh
|
||||
|
||||
- name: Deploy WebApi files
|
||||
id: deploy_api
|
||||
- name: Copy WebApi
|
||||
run: scp -i D:\gitea-runner\deploy_key -r D:\ci-output\webapi\* lliadmin@212.47.72.54:C:/inetpub/cprnims-api/
|
||||
shell: pwsh
|
||||
run: |
|
||||
robocopy "C:\ci-output\webapi" "C:\inetpub\cprnims-api" /MIR /R:3 /W:5
|
||||
$rc = $LASTEXITCODE
|
||||
Write-Host "ROBOCOPY EXIT CODE: $rc"
|
||||
if ($rc -ge 8) {
|
||||
throw "robocopy failed for WebApi with exit code $rc"
|
||||
}
|
||||
exit 0
|
||||
|
||||
- name: Deploy WebApps files
|
||||
id: deploy_web
|
||||
- name: Copy WebApps
|
||||
run: scp -i D:\gitea-runner\deploy_key -r D:\ci-output\webapps\* lliadmin@212.47.72.54:C:/inetpub/cprnims-web/
|
||||
shell: pwsh
|
||||
run: |
|
||||
robocopy "C:\ci-output\webapps" "C:\inetpub\cprnims-web" /MIR /R:3 /W:5
|
||||
$rc = $LASTEXITCODE
|
||||
Write-Host "ROBOCOPY EXIT CODE: $rc"
|
||||
if ($rc -ge 8) {
|
||||
throw "robocopy failed for WebApps with exit code $rc"
|
||||
}
|
||||
exit 0
|
||||
|
||||
- name: Start app pools
|
||||
shell: pwsh
|
||||
run: |
|
||||
Import-Module WebAdministration
|
||||
Start-WebAppPool -Name "CPRNIMS-Api"
|
||||
Start-WebAppPool -Name "CPRNIMS-Web"
|
||||
|
||||
- name: Verify app pools are running
|
||||
ssh -i D:\gitea-runner\deploy_key lliadmin@212.47.72.54 "Import-Module WebAdministration; Start-WebAppPool -Name 'CPRNIMS-Api'; Start-WebAppPool -Name 'CPRNIMS-Web'"
|
||||
shell: pwsh
|
||||
run: |
|
||||
Start-Sleep -Seconds 3
|
||||
Import-Module WebAdministration
|
||||
$api = Get-WebAppPoolState -Name "CPRNIMS-Api"
|
||||
$web = Get-WebAppPoolState -Name "CPRNIMS-Web"
|
||||
Write-Host "CPRNIMS-Api: $($api.Value)"
|
||||
Write-Host "CPRNIMS-Web: $($web.Value)"
|
||||
if ($api.Value -ne "Started" -or $web.Value -ne "Started") {
|
||||
throw "One or more app pools failed to start"
|
||||
}
|
||||
|
||||
# ---- Rollback path: only runs if any prior step in this job failed ----
|
||||
- name: ROLLBACK - restore previous backup
|
||||
if: failure()
|
||||
shell: pwsh
|
||||
run: |
|
||||
$stamp = Get-Content "C:\backups\latest.txt" -Raw
|
||||
$backupPath = "C:\backups\$stamp"
|
||||
Write-Host "Deployment failed - rolling back to backup: $backupPath"
|
||||
|
||||
Import-Module WebAdministration
|
||||
Stop-WebAppPool -Name "CPRNIMS-Api" -ErrorAction SilentlyContinue
|
||||
Stop-WebAppPool -Name "CPRNIMS-Web" -ErrorAction SilentlyContinue
|
||||
Start-Sleep -Seconds 3
|
||||
|
||||
if (Test-Path "$backupPath\webapi") {
|
||||
robocopy "$backupPath\webapi" "C:\inetpub\cprnims-api" /MIR /R:3 /W:5 | Out-Null
|
||||
}
|
||||
if (Test-Path "$backupPath\webapps") {
|
||||
robocopy "$backupPath\webapps" "C:\inetpub\cprnims-web" /MIR /R:3 /W:5 | Out-Null
|
||||
}
|
||||
|
||||
Start-WebAppPool -Name "CPRNIMS-Api"
|
||||
Start-WebAppPool -Name "CPRNIMS-Web"
|
||||
|
||||
Write-Host "Rollback complete. Restored from $backupPath"
|
||||
exit 0
|
||||
|
||||
- name: ROLLBACK - verify pools after restore
|
||||
if: failure()
|
||||
shell: pwsh
|
||||
run: |
|
||||
Start-Sleep -Seconds 3
|
||||
Import-Module WebAdministration
|
||||
$api = Get-WebAppPoolState -Name "CPRNIMS-Api"
|
||||
$web = Get-WebAppPoolState -Name "CPRNIMS-Web"
|
||||
Write-Host "After rollback - CPRNIMS-Api: $($api.Value)"
|
||||
Write-Host "After rollback - CPRNIMS-Web: $($web.Value)"
|
||||
if ($api.Value -ne "Started" -or $web.Value -ne "Started") {
|
||||
Write-Host "WARNING: app pools still not running after rollback. Manual intervention needed."
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user