DslrDirector/scripts/backup_to_gitea.ps1
2025-09-29 00:46:38 -07:00

102 lines
3.8 KiB
PowerShell

<#
Backup the repository to a Gitea backup repository.
Usage (PowerShell):
# one-time: create a Gitea backup repo and get a personal access token
$GITEA_URL = 'https://gitea.example.com'
$GITEA_USER = 'username'
$GITEA_TOKEN = 'PERSONAL_ACCESS_TOKEN'
.\scripts\backup_to_gitea.ps1 -GiteaUrl $GITEA_URL -GiteaUser $GITEA_USER -GiteaToken $GITEA_TOKEN -BackupRepo "username/dslr-director-backups"
What it does:
- Creates a timestamped snapshot directory under a local temporary clone of the backup repo
- Copies the current project files into that snapshot (excluding .venv and .git)
- Commits and pushes the snapshot to the remote Gitea backup repository
Notes:
- The backup repo must already exist on your Gitea server (or create it via the web UI/API).
- Your Gitea token should have repo:push permissions. For HTTPS push the token is used as password.
- This script is idempotent for the same timestamp but you will normally run it manually or from a scheduled task.
#>
param(
[Parameter(Mandatory=$true)] [string] $GiteaUrl,
[Parameter(Mandatory=$true)] [string] $GiteaUser,
[Parameter(Mandatory=$true)] [string] $GiteaToken,
[Parameter(Mandatory=$true)] [string] $BackupRepo, # e.g. "username/dslr-director-backups"
[string] $TempDir = "$env:TEMP\dslr_backups",
[string] $RepoRoot = "$(Resolve-Path ..)"
)
# Ensure Git is available
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
Write-Error "git not found in PATH. Install git first."
exit 1
}
# Normalize paths
$RepoRoot = Resolve-Path -Path $RepoRoot | Select-Object -ExpandProperty Path
$TempDir = Resolve-Path -Path $TempDir -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path -ErrorAction SilentlyContinue
if (-not $TempDir) { New-Item -ItemType Directory -Path "$env:TEMP\dslr_backups" -Force | Out-Null; $TempDir = "$env:TEMP\dslr_backups" }
# Make clone path
$repoName = $BackupRepo.Split('/')[-1]
$clonePath = Join-Path $TempDir $repoName
# Build remote URL with token for HTTPS push
# Format: https://<user>:<token>@gitea.example.com/<owner>/<repo>.git
$remoteUrl = $GiteaUrl.TrimEnd('/') + "/" + $BackupRepo + ".git"
$remoteUrlAuth = $remoteUrl -replace '^(https?://)', "`$1$($GiteaUser):$($GiteaToken)@"
Write-Host "Using repo root: $RepoRoot"
Write-Host "Cloning backup repo into: $clonePath"
if (-not (Test-Path $clonePath)) {
git clone $remoteUrl $clonePath 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to clone backup repo. Check credentials and repo existence."
exit 1
}
} else {
Push-Location $clonePath
git pull 2>&1 | Write-Host
Pop-Location
}
# Create timestamped snapshot folder
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$snapshotDir = Join-Path $clonePath "snapshots\$ts"
New-Item -ItemType Directory -Path $snapshotDir -Force | Out-Null
# Rsync-like copy: use robocopy to preserve structure and skip .git and venv
$exclude = @('.git', '.venv', 'venv', 'node_modules')
$copyOptions = @('/E','/COPY:DAT','/R:2','/W:1')
foreach ($entry in Get-ChildItem -Path $RepoRoot -Force) {
if ($exclude -contains $entry.Name) { continue }
$dest = Join-Path $snapshotDir $entry.Name
if ($entry.PSIsContainer) {
robocopy $entry.FullName $dest @copyOptions | Out-Null
} else {
Copy-Item -Path $entry.FullName -Destination $dest -Force
}
}
# Commit and push
Push-Location $clonePath
try {
git add . 2>&1 | Write-Host
git commit -m "Backup snapshot: $ts" 2>&1 | Write-Host
# push using auth in URL
git push $remoteUrlAuth HEAD:main 2>&1 | Write-Host
if ($LASTEXITCODE -ne 0) {
Write-Error "Push failed. You may need to set the remote or use a different branch."
exit 1
}
Write-Host "Backup pushed to $BackupRepo as snapshot $ts"
} catch {
Write-Error "Backup commit/push failed: $_"
exit 1
} finally {
Pop-Location
}