<# 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://:@gitea.example.com//.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 }