diff --git a/scripts/docker-push.ps1 b/scripts/docker-push.ps1 new file mode 100644 index 0000000..919aa88 --- /dev/null +++ b/scripts/docker-push.ps1 @@ -0,0 +1,142 @@ +<# +.SYNOPSIS + Buduje i publikuje obraz aplikacji w rejestrze kontenerów Gitea. + +.DESCRIPTION + Wersja czytana jest z backend/TarninaHub.csproj (). + Krok 0 sprawdza połączenie z demonem Docker i dostępność rejestru Gitea. + Jeżeli obraz w tej wersji jest już wypchnięty do rejestru, skrypt wypisuje + czerwony komunikat i kończy pracę. W przeciwnym razie wykonuje po kolei: + 0. sprawdzenie połączenia (demon Docker + rejestr), + 1. odczyt wersji z backendu, + 2. logowanie do rejestru, + 3. sprawdzenie, czy wersja już istnieje, + 4. build frontendu, kopiowanie i build backendu, + 5. build obrazu Docker, + 6. push obrazu jako oraz :latest. + + Dane logowania pobierane są ze zmiennych środowiskowych GITEA_USER oraz + GITEA_TOKEN (preferowany) lub GITEA_PASSWORD; jeśli ich brak, używany jest + `docker login` (interaktywnie). Token utworzysz na stronie: + https:///user/settings/applications (zakres: write:package) + +.EXAMPLE + pwsh ./scripts/docker-push.ps1 + +.EXAMPLE + $env:GITEA_USER = "rtynski"; $env:GITEA_TOKEN = "xxx" + pwsh ./scripts/docker-push.ps1 -Force +#> +param( + [string]$Registry = "git.rtynski.pl", + [string]$Owner = "rtynski", + [string]$Repo = "hy2026", + [string]$ProjectFile = "backend/TarninaHub.csproj", + [string]$SolutionFile = "TarninaHub.slnx", + [string]$Username = $env:GITEA_USER, + [string]$Token = $env:GITEA_TOKEN, + [string]$Password = $env:GITEA_PASSWORD, + [switch]$Force +) + +$ErrorActionPreference = "Stop" + +$root = Split-Path -Parent $PSScriptRoot +$image = "$Registry/$Owner/$Repo" + +function Invoke-Step { + param([string]$Label, [scriptblock]$Action) + Write-Host "`n> $Label" -ForegroundColor Cyan + Push-Location $root + try { & $Action } finally { Pop-Location } + if ($LASTEXITCODE -ne 0) { throw "Krok nie powiódł się: $Label" } +} + +function Test-TcpConnection { + param([string]$HostName, [int]$Port, [int]$TimeoutMs = 5000) + $client = [System.Net.Sockets.TcpClient]::new() + try { + $task = $client.ConnectAsync($HostName, $Port) + return $task.Wait($TimeoutMs) -and $client.Connected + } catch { + return $false + } finally { + $client.Dispose() + } +} + +# 0. Sprawdzenie połączenia (demon Docker + dostępność rejestru) +Write-Host "Krok 0: sprawdzanie połączenia..." -ForegroundColor Cyan + +if (-not (Get-Command docker -ErrorAction SilentlyContinue)) { + throw "Nie znaleziono 'docker' w PATH." +} + +docker info *> $null +if ($LASTEXITCODE -ne 0) { + throw "Brak połączenia z demonem Docker. Uruchom Docker Desktop." +} + +if (-not (Test-TcpConnection -HostName $Registry -Port 443)) { + throw "Nie mogę połączyć się z rejestrem ${Registry}:443. Sprawdź sieć/adres." +} + +Write-Host "Połączenie OK (Docker + ${Registry}:443)." -ForegroundColor Green + +# 1. Wersja z backendu +$projectPath = Join-Path $root $ProjectFile +if (-not (Test-Path -LiteralPath $projectPath)) { + throw "Nie znaleziono pliku projektu: $projectPath" +} +$xml = [xml](Get-Content -LiteralPath $projectPath -Raw) +$versionNode = $xml.SelectSingleNode('/Project/PropertyGroup/Version') +if (-not $versionNode -or [string]::IsNullOrWhiteSpace($versionNode.InnerText)) { + throw "Brak w $ProjectFile." +} +$version = $versionNode.InnerText.Trim() +$versionTag = "${image}:$version" +$latestTag = "${image}:latest" + +Write-Host "Wersja backendu: $version" + +# 2. Logowanie do rejestru (potrzebne do sprawdzenia i push) +$secret = if ($Token) { $Token } elseif ($Password) { $Password } else { $null } + +if ($Username -and $secret) { + Write-Host "Loguję do $Registry jako $Username..." + $secret | docker login $Registry --username $Username --password-stdin +} else { + Write-Host "Loguję do $Registry (interaktywnie)..." + Write-Host "Jeśli nie widzisz promptu, wpisz nazwę użytkownika i naciśnij Enter." -ForegroundColor Yellow + docker login $Registry +} +if ($LASTEXITCODE -ne 0) { throw "docker login nie powiodło się." } + +# 3. Sprawdzenie, czy wersja została już wypchnięta +docker manifest inspect $versionTag *> $null +$alreadyPushed = ($LASTEXITCODE -eq 0) + +if ($alreadyPushed -and -not $Force) { + Write-Host "`nObraz $versionTag jest już wypchnięty do rejestru." -ForegroundColor Red + Write-Host "Zmien w $ProjectFile lub użyj -Force." -ForegroundColor Red + exit 1 +} +if ($alreadyPushed) { + Write-Host "Obraz $versionTag już istnieje, ale -Force pomija sprawdzenie." -ForegroundColor Yellow +} + +# 4. Build frontendu, kopiowanie i build backendu +Invoke-Step "Build frontendu (Vite)" { npm --prefix client run build } +Invoke-Step "Kopiowanie client/dist -> backend/wwwroot" { node scripts/copy-client.mjs } +Invoke-Step "Build backendu (.NET)" { dotnet build $SolutionFile --configuration Release } + +# 5. Build obrazu Docker +Invoke-Step "Build obrazu Docker ($versionTag)" { + docker build --build-arg "APP_VERSION=$version" -f Dockerfile -t $versionTag -t $latestTag . +} + +# 6. Push wersji oraz latest +Invoke-Step "Push $versionTag" { docker push $versionTag } +Invoke-Step "Push $latestTag" { docker push $latestTag } + +Write-Host "`nGotowe: $versionTag oraz $latestTag" -ForegroundColor Green