Skip to content

Commit e4cfebe

Browse files
committed
feat: enable post-checkout scripts at root level (depth 0) - fixes #9
Add support for executing post-checkout scripts at depth 0 when configured in the input dependency file, removing the previous limitation that restricted script execution to nested repositories only. Key changes: - Post-checkout scripts now execute at depth 0 before repository processing - Script path construction uses input dependency file directory as base path - Environment variables provided as empty strings (except LSIGIT_SCRIPT_VERSION) - Enhanced logging for depth 0 script execution with clear context indication - Complete backward compatibility maintained for all existing functionality Implementation details: - Modified Process-DependencyFile to handle depth 0 script execution - Added specific logic for root-level script path resolution - Enhanced debug logging to distinguish depth 0 execution context - Updated documentation with root-level script configuration examples Environment variables at depth 0: - LSIGIT_REPOSITORY_URL: "" (empty string) - LSIGIT_REPOSITORY_PATH: input dependency file directory - LSIGIT_TAG: "" (empty string) - LSIGIT_SCRIPT_VERSION: current script version Use cases enabled: - Global environment setup before repository processing - System validation and pre-flight checks - Workspace preparation and directory structure creation - Centralized logging initialization - Tool and dependency verification Files modified: - LsiGitCheckout.ps1: core script logic enhanced for depth 0 support - CHANGELOG.md: v6.2.1 release notes with detailed feature description - README.md: updated documentation with root-level script examples Version: 6.2.1 Breaking changes: None Backward compatibility: Full
1 parent 4198c3c commit e4cfebe

File tree

6 files changed

+445
-218
lines changed

6 files changed

+445
-218
lines changed

CHANGELOG.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,79 @@ All notable changes to LsiGitCheckout will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [6.2.1] - 2025-01-27
9+
10+
### Added
11+
- **Root-Level Post-Checkout Scripts**: Added support for executing post-checkout scripts at depth 0 (root level) when configured in the input dependency file
12+
- **Enhanced Script Path Construction**: Post-checkout scripts at depth 0 use the input dependency file location as the base path for script resolution
13+
- **Depth 0 Environment Variables**: Environment variables at depth 0 are provided as empty strings (except `LSIGIT_SCRIPT_VERSION`) for consistent script interface
14+
15+
### Changed
16+
- **Post-Checkout Script Execution**: Scripts can now execute before processing repositories when configured in the main input dependency file
17+
- **Improved Depth Handling**: Post-checkout scripts execute at any depth level, including depth 0 (root level)
18+
- **Enhanced Logging**: Added specific logging for depth 0 post-checkout script execution with base path information
19+
20+
### Fixed
21+
- **Root-Level Limitation Removed**: Previously post-checkout scripts could only be configured for depths > 0; now supports depth 0 execution
22+
- **Environment Variable Consistency**: Provides consistent environment variable interface across all depth levels
23+
24+
### Benefits
25+
- **Complete Coverage**: Post-checkout scripts can now be executed at every level of dependency processing
26+
- **Enhanced Integration**: Root-level scripts enable pre-repository setup tasks and global configuration
27+
- **Consistent Interface**: Uniform environment variable handling across all depth levels
28+
- **Flexible Setup**: Scripts can perform root-level initialization before any repository processing begins
29+
30+
### Configuration Examples
31+
32+
#### Root-Level Post-Checkout Script Configuration
33+
```json
34+
{
35+
"Post-Checkout Script File Name": "root-setup.ps1",
36+
"Post-Checkout Script File Path": "scripts",
37+
"Repositories": [
38+
{
39+
"Repository URL": "https://github.com/myorg/project.git",
40+
"Base Path": "repos/project",
41+
"Tag": "v1.0.0"
42+
}
43+
]
44+
}
45+
```
46+
47+
#### Script Execution at Depth 0
48+
49+
**Environment Variables Provided:**
50+
- `LSIGIT_REPOSITORY_URL`: Empty string
51+
- `LSIGIT_REPOSITORY_PATH`: Input dependency file directory path
52+
- `LSIGIT_TAG`: Empty string
53+
- `LSIGIT_SCRIPT_VERSION`: Current LsiGitCheckout version
54+
55+
**Working Directory:** Input dependency file directory
56+
57+
**Script Path Resolution:**
58+
- Base path: Directory containing the input dependency file
59+
- Script location: `<input_file_directory>/<Post-Checkout Script File Path>/<Post-Checkout Script File Name>`
60+
61+
### Use Cases for Root-Level Scripts
62+
- **Global Environment Setup**: Configure development environment before any repository checkout
63+
- **Credential Validation**: Verify SSH keys and authentication before processing
64+
- **Workspace Preparation**: Create directory structures and set permissions
65+
- **Pre-Flight Checks**: Validate system requirements and dependencies
66+
- **Logging Initialization**: Set up centralized logging for the entire checkout process
67+
68+
### Migration Notes
69+
- **Zero Breaking Changes**: All existing v6.2.0 configurations work without modification
70+
- **Optional Enhancement**: Root-level scripts are completely optional
71+
- **Backward Compatibility**: Maintains full compatibility with nested post-checkout scripts
72+
- **Enhanced Capability**: Extends post-checkout script functionality to cover all depth levels
73+
74+
### Technical Implementation
75+
- Post-checkout scripts at depth 0 execute before processing the repositories listed in the input dependency file
76+
- Script path resolution uses the input dependency file directory as the base path
77+
- Environment variables follow the same pattern as nested scripts but with empty strings for repository-specific values
78+
- Logging clearly indicates depth 0 execution context for debugging and monitoring
79+
- Error handling ensures root-level script failures don't prevent repository processing
80+
881
## [6.2.0] - 2025-01-24
982

1083
### Added

LsiGitCheckout.ps1

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
eliminating the need for manual temporal ordering in "API Compatible Tags".
1616
1717
Post-checkout PowerShell scripts can be executed after successful repository
18-
checkouts to integrate with external dependency management systems.
18+
checkouts to integrate with external dependency management systems. Scripts
19+
can be configured at any depth level, including depth 0 (root level).
1920
.PARAMETER InputFile
2021
Path to the JSON configuration file. Defaults to 'dependencies.json' in the script directory.
2122
.PARAMETER CredentialsFile
@@ -41,12 +42,18 @@
4142
.\LsiGitCheckout.ps1 -InputFile "repos.json" -EnableDebug -ApiCompatibility Strict
4243
.\LsiGitCheckout.ps1 -Verbose -DisablePostCheckoutScripts
4344
.NOTES
44-
Version: 6.2.0
45-
Last Modified: 2025-01-24
45+
Version: 6.2.1
46+
Last Modified: 2025-01-27
4647
4748
This script uses PuTTY/plink for SSH authentication. SSH keys must be in PuTTY format (.ppk).
4849
Use PuTTYgen to convert OpenSSH keys to PuTTY format if needed.
4950
51+
Changes in 6.2.1:
52+
- Added support for post-checkout scripts at depth 0 (root level) when configured in the input dependency file
53+
- Post-checkout scripts can now be configured in the main input dependency file and execute before processing repositories
54+
- At depth 0, environment variables are provided as empty strings (except LSIGIT_SCRIPT_VERSION)
55+
- Script path construction at depth 0 uses the input dependency file location as the base path
56+
5057
Changes in 6.2.0:
5158
- Added support for post-checkout PowerShell script execution
5259
- New "Post-Checkout Script File Name" and "Post-Checkout Script File Path" configuration options
@@ -130,7 +137,7 @@ param(
130137
)
131138

132139
# Script configuration
133-
$script:Version = "6.2.0"
140+
$script:Version = "6.2.1"
134141
$script:ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
135142
$script:ErrorFile = Join-Path $ScriptPath "LsiGitCheckout_Errors.txt"
136143
$script:DebugLogFile = Join-Path $ScriptPath ("debug_log_{0}.txt" -f (Get-Date -Format "yyyyMMddHHmm"))
@@ -1662,33 +1669,47 @@ function Process-DependencyFile {
16621669
Write-Log "Post-checkout script configured: $postCheckoutScriptFileName" -Level Info
16631670
}
16641671

1665-
# Execute post-checkout script for the repository that contains this dependency file
1666-
# This should happen BEFORE processing the repositories listed in the dependency file
1667-
if (-not [string]::IsNullOrWhiteSpace($postCheckoutScriptFileName) -and
1668-
-not [string]::IsNullOrWhiteSpace($CallingRepositoryRootPath) -and
1669-
$Depth -gt 0) {
1670-
1671-
# Get the repository URL for the calling repository (the one containing the dependency file)
1672-
$callingRepositoryUrl = ""
1673-
$callingRepositoryTag = ""
1674-
1675-
# Find the calling repository in our dictionary by matching the path
1676-
foreach ($repoEntry in $script:RepositoryDictionary.GetEnumerator()) {
1677-
if ($repoEntry.Value.AbsolutePath -eq $CallingRepositoryRootPath) {
1678-
$callingRepositoryUrl = $repoEntry.Key
1679-
$callingRepositoryTag = $repoEntry.Value.Tag
1680-
break
1681-
}
1682-
}
1683-
1684-
if (-not [string]::IsNullOrWhiteSpace($callingRepositoryUrl)) {
1685-
Write-Log "Executing post-checkout script for repository containing dependency file: $callingRepositoryUrl" -Level Info
1686-
$scriptResult = Invoke-PostCheckoutScript -RepoAbsolutePath $CallingRepositoryRootPath -ScriptFileName $postCheckoutScriptFileName -ScriptFilePath $postCheckoutScriptFilePath -RepositoryUrl $callingRepositoryUrl -Tag $callingRepositoryTag
1672+
# Execute post-checkout script for depth 0 (root level) or when processing nested dependencies
1673+
if (-not [string]::IsNullOrWhiteSpace($postCheckoutScriptFileName)) {
1674+
if ($Depth -eq 0) {
1675+
# Depth 0: Execute from input dependency file location with empty environment variables
1676+
Write-Log "Executing post-checkout script at depth 0 (root level)" -Level Info
1677+
1678+
# For depth 0, use the directory containing the input dependency file as the base path
1679+
$inputFileDirectory = Split-Path -Parent (Resolve-Path $DependencyFilePath)
1680+
Write-Log "Using input dependency file directory as base path for depth 0: $inputFileDirectory" -Level Debug
1681+
1682+
# Execute script with empty environment variables (except LSIGIT_SCRIPT_VERSION)
1683+
$scriptResult = Invoke-PostCheckoutScript -RepoAbsolutePath $inputFileDirectory -ScriptFileName $postCheckoutScriptFileName -ScriptFilePath $postCheckoutScriptFilePath -RepositoryUrl "" -Tag ""
16871684
if (-not $scriptResult) {
1688-
Write-Log "Post-checkout script failed for repository '$callingRepositoryUrl', but continuing with dependency processing" -Level Warning
1685+
Write-Log "Post-checkout script failed at depth 0, but continuing with repository processing" -Level Warning
1686+
}
1687+
} elseif ($Depth -gt 0 -and -not [string]::IsNullOrWhiteSpace($CallingRepositoryRootPath)) {
1688+
# Depth > 0: Execute for the repository containing the dependency file
1689+
Write-Log "Executing post-checkout script for repository containing dependency file at depth $Depth" -Level Info
1690+
1691+
# Get the repository URL for the calling repository (the one containing the dependency file)
1692+
$callingRepositoryUrl = ""
1693+
$callingRepositoryTag = ""
1694+
1695+
# Find the calling repository in our dictionary by matching the path
1696+
foreach ($repoEntry in $script:RepositoryDictionary.GetEnumerator()) {
1697+
if ($repoEntry.Value.AbsolutePath -eq $CallingRepositoryRootPath) {
1698+
$callingRepositoryUrl = $repoEntry.Key
1699+
$callingRepositoryTag = $repoEntry.Value.Tag
1700+
break
1701+
}
1702+
}
1703+
1704+
if (-not [string]::IsNullOrWhiteSpace($callingRepositoryUrl)) {
1705+
Write-Log "Executing post-checkout script for repository containing dependency file: $callingRepositoryUrl" -Level Info
1706+
$scriptResult = Invoke-PostCheckoutScript -RepoAbsolutePath $CallingRepositoryRootPath -ScriptFileName $postCheckoutScriptFileName -ScriptFilePath $postCheckoutScriptFilePath -RepositoryUrl $callingRepositoryUrl -Tag $callingRepositoryTag
1707+
if (-not $scriptResult) {
1708+
Write-Log "Post-checkout script failed for repository '$callingRepositoryUrl', but continuing with dependency processing" -Level Warning
1709+
}
1710+
} else {
1711+
Write-Log "Could not determine repository URL for calling repository at path: $CallingRepositoryRootPath" -Level Warning
16891712
}
1690-
} else {
1691-
Write-Log "Could not determine repository URL for calling repository at path: $CallingRepositoryRootPath" -Level Warning
16921713
}
16931714
}
16941715

@@ -1885,8 +1906,6 @@ Failed: $($script:FailureCount)
18851906
}
18861907
}
18871908

1888-
$summary += "`nTag Temporal Sorting: Always Enabled"
1889-
18901909
# Show post-checkout script statistics
18911910
if ($script:PostCheckoutScriptsEnabled) {
18921911
$summary += "`nPost-Checkout Scripts: Enabled"

0 commit comments

Comments
 (0)