diff --git a/build-and-push.ps1 b/build-and-push.ps1 new file mode 100644 index 0000000..c7b48bd --- /dev/null +++ b/build-and-push.ps1 @@ -0,0 +1,96 @@ +#requires -Version 5.1 +<# +.SYNOPSIS + Build the SharepointToolbox.Web Docker image and push it to the Gitea + container registry at git.azuze.fr. + +.DESCRIPTION + Builds the image from the local Dockerfile, tags it for the Gitea registry + (both the given tag and :latest), logs in, and pushes. + + Login uses a Gitea access token, NOT your account password. Create one at: + git.azuze.fr -> Settings -> Applications -> Generate New Token + (scope: write:package — read:package too if you also pull) + + Provide credentials via -Username / -Token, or set env vars + GITEA_USER / GITEA_TOKEN, or you'll be prompted. + +.EXAMPLE + .\build-and-push.ps1 + Builds and pushes :latest (prompts for token if not cached). + +.EXAMPLE + .\build-and-push.ps1 -Tag v1.2.0 + Builds and pushes both :v1.2.0 and :latest. + +.EXAMPLE + $env:GITEA_USER='kawa'; $env:GITEA_TOKEN='xxxx'; .\build-and-push.ps1 -Tag v1.2.0 +#> +[CmdletBinding()] +param( + [string]$Tag = 'latest', + [string]$Registry = 'git.azuze.fr', + [string]$Owner = 'kawa', + [string]$Image = 'sptb-web', + [string]$Username = $env:GITEA_USER, + [string]$Token = $env:GITEA_TOKEN, + [switch]$SkipLatest, # don't also tag/push :latest when -Tag is something else + [switch]$NoCache # build with --no-cache +) + +$ErrorActionPreference = 'Stop' +Set-Location -LiteralPath $PSScriptRoot + +function Fail($msg) { Write-Host "ERROR: $msg" -ForegroundColor Red; exit 1 } +function Step($msg) { Write-Host "==> $msg" -ForegroundColor Cyan } + +# --- preflight --------------------------------------------------------------- +if (-not (Get-Command docker -ErrorAction SilentlyContinue)) { + Fail 'docker not on PATH. Start Docker Desktop / install docker CLI.' +} +try { docker info *> $null } catch { Fail 'docker daemon not reachable. Is Docker Desktop running?' } +if (-not (Test-Path .\Dockerfile)) { Fail "Dockerfile not found in $PSScriptRoot" } + +$repo = "$Registry/$Owner/$Image" +$primary = "${repo}:$Tag" +$pushLatest = (-not $SkipLatest) -and ($Tag -ne 'latest') + +# --- build ------------------------------------------------------------------- +Step "Building $primary" +$buildArgs = @('build', '-t', $primary) +if ($pushLatest) { $buildArgs += @('-t', "${repo}:latest") } +if ($NoCache) { $buildArgs += '--no-cache' } +$buildArgs += '.' +docker @buildArgs +if ($LASTEXITCODE -ne 0) { Fail 'docker build failed.' } + +# --- login ------------------------------------------------------------------- +if (-not $Username) { $Username = Read-Host "Gitea username for $Registry" } +if (-not $Token) { + $sec = Read-Host "Gitea access token for $Registry (input hidden)" -AsSecureString + $Token = [Runtime.InteropServices.Marshal]::PtrToStringAuto( + [Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec)) +} +if (-not $Username -or -not $Token) { Fail 'Username/token required to push.' } + +Step "Logging in to $Registry as $Username" +$Token | docker login $Registry --username $Username --password-stdin +if ($LASTEXITCODE -ne 0) { Fail 'docker login failed (bad token? wrong scope?).' } + +# --- push -------------------------------------------------------------------- +Step "Pushing $primary" +docker push $primary +if ($LASTEXITCODE -ne 0) { Fail "docker push failed for $primary" } + +if ($pushLatest) { + Step "Pushing ${repo}:latest" + docker push "${repo}:latest" + if ($LASTEXITCODE -ne 0) { Fail "docker push failed for ${repo}:latest" } +} + +Write-Host "" +Write-Host "Done. Pushed:" -ForegroundColor Green +Write-Host " $primary" +if ($pushLatest) { Write-Host " ${repo}:latest" } +Write-Host "" +Write-Host "Pull with: docker pull $primary"