|
<# |
|
.SYNOPSIS |
|
Creates snapshots of a Git repository at specified tags, branches, or commits. |
|
|
|
.DESCRIPTION |
|
This script generates snapshots of a Git repository based on user-defined labels, branches, tags, or specific commits. |
|
The snapshots are saved as separate folders and then compressed into a timestamped ZIP file. The script can |
|
optionally force delete existing snapshot folders without user confirmation. |
|
|
|
NOTE: This script must be placed and run from the root of the Git repository for the `git archive` commands to work correctly. |
|
|
|
.PARAMETER Force |
|
If specified, forces deletion of existing snapshot folders without prompting the user. |
|
|
|
.PARAMETER ZipName |
|
Specifies the base name of the resulting ZIP file. The file will be named as |
|
'ZipName_YYYYMMDD-HHMMSS.zip', where 'YYYYMMDD-HHMMSS' is the current timestamp. |
|
|
|
.EXAMPLE |
|
pwsh ./Create-Snapshots.ps1 -Force -ZipName "ChapterEventRefactoring" |
|
|
|
Forces deletion of existing snapshot folders and creates a ZIP file named 'ChapterEventRefactoring_YYYYMMDD-HHMMSS.zip'. |
|
|
|
.EXAMPLE |
|
pwsh ./Create-Snapshots.ps1 |
|
|
|
Runs the script without force deletion, prompting the user if any existing folders are present, and uses the default ZIP file name 'snapshots_YYYYMMDD-HHMMSS.zip'. |
|
|
|
.NOTES |
|
Ensure that Git and an archive tool (tar) are installed and accessible in your system's PATH for the script to work. |
|
The script should be placed in the root of the repository to work correctly. |
|
|
|
.AUTHOR |
|
Christian Prior-Mamulyan, [email protected] |
|
|
|
.LICENSE |
|
Licensed under CC-BY (Creative Commons Attribution License). |
|
#> |
|
|
|
param ( |
|
[switch]$Force, # Argument to force deletion without prompt |
|
[string]$ZipName = "snapshots" # Argument to specify the ZIP file name prefix |
|
) |
|
|
|
# Define snapshots with labels, identifiers (branches, tags, commits), and types |
|
$snapshots = @( |
|
@{ label = "01_foo"; identifier = "v0.1.0"; type = "tag" }, |
|
@{ label = "10_bar"; identifier = "legacy/REFramework2016"; type = "branch" }, |
|
@{ label = "20_baz"; identifier = "be87405fa7c8f1bbbda1dc95703750182adaccdd"; type = "commit" } |
|
) |
|
|
|
# Define directories: repository and snapshots directory paths |
|
$repoDir = (Get-Location).Path |
|
$snapshotsDir = Join-Path -Path $repoDir -ChildPath "../snapshots" |
|
|
|
# Check if any existing snapshot folders are present in the snapshots directory |
|
$existingFolders = Get-ChildItem -Path $snapshotsDir -Directory -ErrorAction SilentlyContinue |
|
|
|
if ($existingFolders) { |
|
# If -Force parameter is specified, delete all existing folders without prompting |
|
if ($Force) { |
|
$existingFolders | ForEach-Object { Remove-Item -Recurse -Force -Path $_.FullName } |
|
Write-Output "Existing snapshot folders deleted (force mode)." |
|
} else { |
|
# Prompt the user if -Force is not specified and existing folders are found |
|
Write-Output "Snapshot folders already exist in $snapshotsDir." |
|
$response = Read-Host "Do you want to delete all existing snapshot folders and continue? (y/n)" |
|
|
|
if ($response -eq 'y') { |
|
# Delete existing folders if the user confirms |
|
$existingFolders | ForEach-Object { Remove-Item -Recurse -Force -Path $_.FullName } |
|
Write-Output "Existing snapshot folders deleted." |
|
} else { |
|
# Exit if the user chooses not to delete existing folders |
|
Write-Output "Exiting without making any changes." |
|
exit |
|
} |
|
} |
|
} else { |
|
Write-Output "No existing snapshot folders found. Proceeding with snapshot creation." |
|
} |
|
|
|
# Ensure snapshots directory exists |
|
if (!(Test-Path -Path $snapshotsDir)) { |
|
New-Item -ItemType Directory -Path $snapshotsDir | Out-Null |
|
} |
|
|
|
# Function to create individual snapshots |
|
function Create-Snapshot { |
|
<# |
|
.SYNOPSIS |
|
Creates a snapshot of the Git repository at the specified identifier. |
|
|
|
.DESCRIPTION |
|
This function uses Git to create a snapshot of the repository at a specified branch, tag, or commit. |
|
The snapshot is saved in a uniquely labeled folder within the snapshots directory. |
|
|
|
.PARAMETER Label |
|
The label used as a prefix in the snapshot folder name. |
|
|
|
.PARAMETER Identifier |
|
The Git identifier for the snapshot (e.g., branch name, tag name, or commit hash). |
|
|
|
.PARAMETER Type |
|
The type of the identifier (e.g., "branch", "tag", or "commit"). |
|
#> |
|
|
|
param ( |
|
[string]$Label, |
|
[string]$Identifier, |
|
[string]$Type |
|
) |
|
|
|
# Construct folder name by combining label and identifier, replacing '/' with '-' |
|
$folderName = "$Label-$($Identifier -replace '/', '-')" |
|
$snapshotPath = Join-Path -Path $snapshotsDir -ChildPath $folderName |
|
|
|
Write-Output "Creating snapshot for '$Identifier' with label '$Label'..." |
|
New-Item -ItemType Directory -Path $snapshotPath | Out-Null |
|
|
|
# Use git archive to export the snapshot; assumes script is in the repo root |
|
& git archive --format=tar --prefix="$Identifier/" $Identifier | tar -xf - -C $snapshotPath |
|
|
|
# Check for successful snapshot creation |
|
if ($LASTEXITCODE -eq 0) { |
|
Write-Output "Snapshot created: $snapshotPath" |
|
} else { |
|
Write-Output "Error creating snapshot for $Identifier" |
|
} |
|
} |
|
|
|
# Iterate through each defined snapshot and create it |
|
foreach ($snapshot in $snapshots) { |
|
Create-Snapshot -Label $snapshot.label -Identifier $snapshot.identifier -Type $snapshot.type |
|
} |
|
|
|
# Generate a timestamp in the format YYYYMMDD-HHMMSS for the ZIP file name |
|
$timestamp = (Get-Date -Format "yyyyMMdd-HHmmss") |
|
$zipPath = Join-Path -Path $snapshotsDir -ChildPath "$ZipName`_$timestamp.zip" |
|
|
|
# Delete any existing ZIP file with the same name |
|
if (Test-Path -Path $zipPath) { Remove-Item -Path $zipPath } |
|
|
|
Write-Output "Zipping all snapshots into $zipPath..." |
|
|
|
# Compress all folders in the snapshots directory into a single ZIP archive |
|
Compress-Archive -Path (Get-ChildItem -Path $snapshotsDir -Directory).FullName -DestinationPath $zipPath |
|
|
|
# Verify that the ZIP file was created successfully |
|
if (Test-Path -Path $zipPath) { |
|
Write-Output "All snapshots have been zipped into $zipPath" |
|
} else { |
|
Write-Output "Error creating ZIP archive" |
|
} |