Skip to content
Merged
110 changes: 110 additions & 0 deletions .github/prompts/save-branch-to-PR.prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
agent: agent
---

# Save Branch to PR Workflow

This prompt guides through the complete workflow of saving a feature branch by creating a PR, waiting for checks, merging, and cleaning up.

## Prerequisites
- Git repository with GitHub remote
- GitHub CLI (`gh`) installed and authenticated
- Current branch should be a feature branch (not `main`)

## Workflow Steps

### Step 1: Verify Current Branch
Check that we are NOT on the `main` branch. If on `main`, stop and inform the user.

```powershell
$currentBranch = git branch --show-current
if ($currentBranch -eq "main") {
Write-Error "Cannot run this workflow from the main branch. Please checkout a feature branch first."
return
}
Write-Host "Current branch: $currentBranch"
```

### Step 2: Push Branch and Create PR
Push the current branch to remote and create a Pull Request.

```powershell
# Push branch to remote
git push -u origin $currentBranch

# Create PR with auto-fill from commit messages
gh pr create --fill
```

If a PR already exists for this branch, continue with the existing PR.

### Step 3: Wait for Workflow Checks
Wait for all GitHub Actions workflow checks to complete and verify they pass.

```powershell
# Wait for checks to complete (will block until done)
gh pr checks --watch --required --interval 1 --fail-fast

# Verify all checks passed
$checksResult = gh pr checks
if ($LASTEXITCODE -ne 0) {
Write-Error "Some checks failed. Please review and fix before merging."
return
}
Write-Host "All checks passed!"
```

### Step 4: Merge the PR
Merge the PR using a regular merge to preserve the branch history, and delete the remote branch.

```powershell
# Merge PR and delete remote branch (regular merge to keep history)
gh pr merge --merge --delete-branch
```

### Step 5: Clean Up Local Branch
Switch to main and delete the local feature branch.

```powershell
# Switch to main branch
git checkout main

# Pull latest changes
git pull

# Delete local feature branch
git branch -d $currentBranch
```

### Step 6: Check and Remove Codespaces
Check if there are any codespaces associated with this branch and remove them.

```powershell
# List codespaces for this repository
$codespaces = gh codespace list --json name,gitStatus,repository --jq ".[] | select(.gitStatus.ref == `"$currentBranch`")"

if ($codespaces) {
Write-Host "Found codespaces on branch $currentBranch. Removing..."
# Delete codespaces on this branch
gh codespace list --json name,gitStatus --jq ".[] | select(.gitStatus.ref == `"$currentBranch`") | .name" | ForEach-Object {
gh codespace delete --codespace $_ --force
Write-Host "Deleted codespace: $_"
}
} else {
Write-Host "No codespaces found on branch $currentBranch"
}
```

## Success Criteria
- [ ] Verified not on main branch
- [ ] PR created and pushed to remote
- [ ] All workflow checks passed
- [ ] PR merged successfully
- [ ] Local and remote feature branches deleted
- [ ] Any codespaces on the branch removed

## Error Handling
- If on `main` branch: Stop immediately with clear message
- If checks fail: Stop and inform user to fix issues
- If merge conflicts: Stop and inform user to resolve conflicts
- If codespace deletion fails: Log warning but continue
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
{
"terminal.integrated.profiles.osx": {
"pwsh": {
"path": "pwsh",
"icon": "terminal-powershell",
"args": ["-NoExit", "-Command", "if (Test-Path './tools/Test_Helper') { Import-Module './tools/Test_Helper' -Force }"]
}
}
}
76 changes: 38 additions & 38 deletions Test/include/InvokeMockList.ps1
Original file line number Diff line number Diff line change
@@ -1,54 +1,54 @@

$MockCommandFile = $testRootPath | Join-Path -ChildPath "mockfiles.log"
# $MockCommandFile = $testRootPath | Join-Path -ChildPath "mockfiles.log"

function Trace-MockCommandFile{
[CmdletBinding()]
param(
[string] $Command,
[string] $FileName
)
# function Trace-MockCommandFile{
# [CmdletBinding()]
# param(
# [string] $Command,
# [string] $FileName
# )

# read content
$content = readMockCommandFile
# # read content
# $content = readMockCommandFile

# Check that the entry is already there
$result = $content | Where-Object{$_.command -eq $command}
if($null -ne $result) {return}
# # Check that the entry is already there
# $result = $content | Where-Object{$_.command -eq $command}
# if($null -ne $result) {return}

# add entry
$new = @{
Command = $command
FileName = $fileName
}
# # add entry
# $new = @{
# Command = $command
# FileName = $fileName
# }

$ret = @()
$ret += $content
$ret += $new
# $ret = @()
# $ret += $content
# $ret += $new

# Save list
writeMockCommandFile -Content $ret
}
# # Save list
# writeMockCommandFile -Content $ret
# }

function readMockCommandFile{
# function readMockCommandFile{

# Return empty list if the file does not exist
if(-not (Test-Path -Path $MockCommandFile)){
return @()
}
# # Return empty list if the file does not exist
# if(-not (Test-Path -Path $MockCommandFile)){
# return @()
# }

$ret = Get-Content -Path $MockCommandFile | ConvertFrom-Json
# $ret = Get-Content -Path $MockCommandFile | ConvertFrom-Json

# return an empty aray if content does not exists
$ret = $ret ?? @()
# # return an empty aray if content does not exists
# $ret = $ret ?? @()

return $ret
}
# return $ret
# }

function writeMockCommandFile($Content){
# function writeMockCommandFile($Content){

$list = $Content | ConvertTo-Json
# $list = $Content | ConvertTo-Json

$sorted = $list | Sort-Object fileName
# $sorted = $list | Sort-Object fileName

$sorted | Out-File -FilePath $MockCommandFile
}
# $sorted | Out-File -FilePath $MockCommandFile
# }
11 changes: 9 additions & 2 deletions Test/include/callPrivateContext.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ function Invoke-PrivateContext {
param (
[Parameter(Mandatory, Position = 0)]
[scriptblock]$ScriptBlock,
[string]$ModulePath
[string]$ModulePath,
[string[]]$Arguments
)

if ([string]::IsNullOrEmpty($ModulePath)) {
Expand All @@ -28,5 +29,11 @@ function Invoke-PrivateContext {
throw "Failed to import the main module."
}

& $module $ScriptBlock
if($Arguments){
& $module $ScriptBlock -Arguments $Arguments
}
else {
& $module $ScriptBlock
}

} Export-ModuleMember -Function Invoke-PrivateContext
61 changes: 60 additions & 1 deletion Test/include/invokeCommand.mock.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,63 @@ function Assert-MockFileNotfound{
Wait-Debugger
throw "File not found or wrong case name. Expected[ $filename ] - Found[$( $file.name )]"
}
}
}


#region Mock Command File Trace

$MockCommandFile = $testRootPath | Join-Path -ChildPath "mockfiles.log"

function Trace-MockCommandFile{
[CmdletBinding()]
param(
[string] $Command,
[string] $FileName
)

# read content
$content = readMockCommandFile

# Check that the entry is already there
$result = $content | Where-Object{$_.command -eq $command}
if($null -ne $result) {return}

# add entry
$new = @{
Command = $command
FileName = $fileName
}

$ret = @()
$ret += $content
$ret += $new

# Save list
writeMockCommandFile -Content $ret
}

function readMockCommandFile{

# Return empty list if the file does not exist
if(-not (Test-Path -Path $MockCommandFile)){
return @()
}

$ret = Get-Content -Path $MockCommandFile | ConvertFrom-Json

# return an empty aray if content does not exists
$ret = $ret ?? @()

return $ret
}

function writeMockCommandFile($Content){

$list = $Content | ConvertTo-Json

$sorted = $list | Sort-Object fileName

$sorted | Out-File -FilePath $MockCommandFile
}

# End region Mock Command File Trace
26 changes: 14 additions & 12 deletions Test/include/run_BeforeAfter.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
# - After each test
# - Before all tests
# - After all tests
#
# Copy this file to Test Private to avoid being replaced by updates

function Run_BeforeAll{
Write-Verbose "Run_BeforeAll"
}
# function Run_BeforeAll{
# Write-Verbose "Run_BeforeAll"
# }

function Run_AfterAll{
Write-Verbose "Run_AfterAll"
}
# function Run_AfterAll{
# Write-Verbose "Run_AfterAll"
# }

function Run_BeforeEach{
Write-Verbose "Run_BeforeEach"
}
# function Run_BeforeEach{
# Write-Verbose "Run_BeforeEach"
# }

function Run_AfterEach{
Write-Verbose "Run_AfterEach"
}
# function Run_AfterEach{
# Write-Verbose "Run_AfterEach"
# }

Export-ModuleMember -Function Run_*
14 changes: 10 additions & 4 deletions Test/public/dependencies.test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,19 @@
[Parameter(Mandatory,Position=2)][string]$Folder
)

# Mock GetMyModuleRootPath on SideBySide
# Check that happens before ImportFromModuleManager
# that we are testing here
# Mock "$($MODULE_NAME)RootPath" on SideBySide

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
# Module path that pretends to be me
$modulePath = "$Folder/$Name"

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
# Ceate the fake me module
New-ModuleV3 -Name $Name -Path $folder

# Resolve the absolute path
$path = Convert-Path -Path $modulePath
MockCallToString -Command 'GetMyModuleRootPath' -OutString "$path"

Check notice

Code scanning / PSScriptAnalyzer

Line has trailing whitespace Note

Line has trailing whitespace
# As we are testing this code in IncludeHelper module this is the command "Invoke-$($MODULE_NAME)RootPath"
MockCallToString -Command 'Invoke-IncludeHelperRootPath' -OutString "$path"
}

# Set-MyInvokeCommandAlias -Alias "TestGitHubRepo" -Command 'Invoke-WebRequest -Uri "{url}" -Method Head -ErrorAction SilentlyContinue | ForEach-Object { $_.StatusCode -eq 200 }'
Expand Down
Loading
Loading