@babajide234/git-merge-workflow 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,36 @@
1
+ # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3
+
4
+ name: Node.js Package
5
+
6
+ on:
7
+ release:
8
+ types: [created]
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 20
18
+ - run: npm ci
19
+ - run: npm test
20
+
21
+ publish-gpr:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: read
26
+ packages: write
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: actions/setup-node@v4
30
+ with:
31
+ node-version: 20
32
+ registry-url: https://npm.pkg.github.com/
33
+ - run: npm ci
34
+ - run: npm publish
35
+ env:
36
+ NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -0,0 +1,34 @@
1
+ name: Publish PowerShell Module
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ publish-to-gallery:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v3
13
+
14
+ - name: Build and Publish
15
+ env:
16
+ NUGET_KEY: ${{ secrets.NUGET_KEY }}
17
+ shell: pwsh
18
+ run: |
19
+ Publish-Module -Path . -NuGetApiKey $env:NUGET_KEY -Verbose
20
+
21
+ publish-to-npm:
22
+ runs-on: ubuntu-latest
23
+ needs: publish-to-gallery
24
+ steps:
25
+ - uses: actions/checkout@v3
26
+ - uses: actions/setup-node@v3
27
+ with:
28
+ node-version: '16.x'
29
+ registry-url: 'https://registry.npmjs.org'
30
+
31
+ - run: npm install
32
+ - run: npm publish --access public
33
+ env:
34
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -0,0 +1,96 @@
1
+ # Developer Guide: Git Merge Workflow (GMW)
2
+
3
+ This guide explains how the **Git Merge Workflow** PowerShell module works and how you can modify it.
4
+
5
+ ## 📂 Project Structure
6
+
7
+ The module is located at:
8
+ `c:\Users\jyde2\OneDrive\Documents\WindowsPowerShell\Modules\GitMergeWorkflow`
9
+
10
+ - **GitMergeWorkflow.psd1**: The *Module Manifest*. Contains metadata (version, author, description) and defines which files are processed when the module is imported.
11
+ - **GitMergeWorkflow.psm1**: The *Script Module*. Contains the actual source code and logic for the functions. **This is where you will make most changes.**
12
+ - **Install.ps1**: A helper script to install the module on a new machine.
13
+ - **package.json**: configuration for NPM publishing (if applicable).
14
+
15
+ ## 🧠 How It Works
16
+
17
+ The core logic resides in `GitMergeWorkflow.psm1`.
18
+
19
+ ### Main Function: `Invoke-GitMergeWorkflow`
20
+ This is the function executed when you run `gmw`.
21
+
22
+ 1. **Configuration Loading**:
23
+ - Calls `Get-GitWorkflowConfig` to look for a `.git-merge-workflow.json` file in your repository root.
24
+ - Sets defaults (`develop` for target, `-staging` for suffix) if no config is found.
25
+
26
+ 2. **Environment Checks**:
27
+ - Checks if `git` is available and if the current directory is a git repository.
28
+ - Validates that you are NOT currently on the target branch (e.g., `develop`) or the staging branch.
29
+
30
+ 3. **Staging Phase**:
31
+ - Determines the staging branch name (e.g., `feature-xyz-staging`).
32
+ - Checks if the staging branch exists locally or remotely.
33
+ - **Merges** your current feature branch into this staging branch.
34
+ - **Pushes** the staging branch to the remote (`origin`).
35
+ - *Recent Update*: This step now includes error handling. If the push fails (e.g., permissions issue), it asks if you want to skip and proceed.
36
+
37
+ 4. **Target Phase**:
38
+ - Checkouts the target branch (`develop`).
39
+ - Pulls the latest changes.
40
+ - **Merges** the staging branch into the target branch.
41
+ - **Pushes** the target branch to remote.
42
+
43
+ 5. **Cleanup**:
44
+ - Returns you to your original feature branch.
45
+
46
+ ### Helper Functions
47
+ - `Exec-Git`: A wrapper around git commands to handle errors and verbose output consistently.
48
+ - `New-GitWorkflowConfig`: Generates the JSON configuration file.
49
+
50
+ ## 🛠️ How to Edit and Test
51
+
52
+ Since this is a PowerShell module, changes are not picked up immediately if the module is already loaded in your session.
53
+
54
+ ### 1. Edit the Code
55
+ Open `GitMergeWorkflow.psm1` in VS Code or your preferred editor.
56
+
57
+ **Example**: Adding a new log message.
58
+ ```powershell
59
+ # Inside Invoke-GitMergeWorkflow
60
+ Write-Host "Starting my custom workflow..." -ForegroundColor Magenta
61
+ ```
62
+
63
+ ### 2. Reload the Module
64
+ After saving your changes, you must reload the module in your PowerShell terminal to see them take effect.
65
+
66
+ Run this command:
67
+ ```powershell
68
+ Import-Module GitMergeWorkflow -Force
69
+ ```
70
+ *The `-Force` flag is crucial as it unloads the old version and loads the new one.*
71
+
72
+ ### 3. Test
73
+ Run the command again:
74
+ ```powershell
75
+ gmw -WhatIf
76
+ ```
77
+ *Using `-WhatIf` (Dry Run) is a safe way to test logic changes without actually running git commands, provided the script supports it (mostly used for ShouldProcess).*
78
+
79
+ For real testing, just run `gmw` in a test repository.
80
+
81
+ ## 📦 Configuration
82
+
83
+ The behavior can be customized per-repository using a `.git-merge-workflow.json` file:
84
+
85
+ ```json
86
+ {
87
+ "TargetBranch": "main",
88
+ "StagingSuffix": "-qa",
89
+ "Remote": "upstream"
90
+ }
91
+ ```
92
+
93
+ You can generate this file using:
94
+ ```powershell
95
+ New-GitWorkflowConfig
96
+ ```
@@ -0,0 +1,18 @@
1
+ @{
2
+ RootModule = 'GitMergeWorkflow.psm1'
3
+ ModuleVersion = '1.0.0'
4
+ GUID = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
5
+ Author = 'babajide Tomoshegbo'
6
+ CompanyName = 'babajide234'
7
+ Copyright = '(c) 2025 Expedier. All rights reserved.'
8
+ Description = 'Automated Git workflow for merging feature branches through staging to develop'
9
+ PowerShellVersion = '5.1'
10
+ FunctionsToExport = @('Invoke-GitMergeWorkflow', 'New-GitWorkflowConfig', 'Get-GitWorkflowConfig')
11
+ AliasesToExport = @('git-merge-workflow', 'gmw')
12
+ PrivateData = @{
13
+ PSData = @{
14
+ Tags = @('Git', 'Workflow', 'Automation', 'Merge', 'DevOps')
15
+ ProjectUri = 'https://github.com/babajide234/GitMergeWorkflow'
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,343 @@
1
+
2
+ function Get-GitWorkflowConfig {
3
+ <#
4
+ .SYNOPSIS
5
+ Retrieves the Git Merge Workflow configuration from the current repository
6
+ .DESCRIPTION
7
+ Looks for a .git-merge-workflow.json file in the root of the git repository.
8
+ If found, parses and returns the configuration.
9
+ If not found, returns null.
10
+ #>
11
+ [CmdletBinding()]
12
+ param()
13
+
14
+ try {
15
+ # Get git root
16
+ $gitRoot = git rev-parse --show-toplevel 2>$null
17
+ if ($LASTEXITCODE -eq 0 -and $gitRoot) {
18
+ $configPath = Join-Path $gitRoot ".git-merge-workflow.json"
19
+ if (Test-Path $configPath) {
20
+ return Get-Content $configPath -Raw | ConvertFrom-Json
21
+ }
22
+ }
23
+ } catch {
24
+ Write-Verbose "Error reading config: $_"
25
+ }
26
+ return $null
27
+ }
28
+
29
+ function New-GitWorkflowConfig {
30
+ <#
31
+ .SYNOPSIS
32
+ Creates a new configuration file for the Git Merge Workflow
33
+ .DESCRIPTION
34
+ Creates a .git-merge-workflow.json file in the root of the current git repository.
35
+ .PARAMETER TargetBranch
36
+ The default target branch (default: develop)
37
+ .PARAMETER StagingSuffix
38
+ The suffix for staging branches (default: -staging)
39
+ .PARAMETER Remote
40
+ The default remote name (default: origin)
41
+ .EXAMPLE
42
+ New-GitWorkflowConfig -TargetBranch "main" -StagingSuffix "-test"
43
+ #>
44
+ [CmdletBinding(SupportsShouldProcess=$true)]
45
+ param(
46
+ [string]$TargetBranch = "develop",
47
+ [string]$StagingSuffix = "-staging",
48
+ [string]$Remote = "origin"
49
+ )
50
+
51
+ # Check if in git repo
52
+ $gitRoot = git rev-parse --show-toplevel 2>$null
53
+ if ($LASTEXITCODE -ne 0 -or -not $gitRoot) {
54
+ Write-Error "Not in a git repository. Please run inside a git repository."
55
+ return
56
+ }
57
+
58
+ $configPath = Join-Path $gitRoot ".git-merge-workflow.json"
59
+
60
+ $config = @{
61
+ TargetBranch = $TargetBranch
62
+ StagingSuffix = $StagingSuffix
63
+ Remote = $Remote
64
+ }
65
+
66
+ $json = $config | ConvertTo-Json -Depth 2
67
+
68
+ if ($PSCmdlet.ShouldProcess($configPath, "Create configuration file")) {
69
+ $json | Set-Content $configPath
70
+ Write-Host "Configuration file created at: $configPath" -ForegroundColor Green
71
+ Write-Host "Content:" -ForegroundColor Cyan
72
+ Write-Host $json
73
+ }
74
+ }
75
+
76
+ function Invoke-GitMergeWorkflow {
77
+ <#
78
+ .SYNOPSIS
79
+ Automated Git workflow to merge current branch to staging and then to develop
80
+ .DESCRIPTION
81
+ This function automates the process of:
82
+ 1. Getting the current branch name
83
+ 2. Merging current branch to {branch}-staging
84
+ 3. Merging {branch}-staging to develop
85
+ 4. Pushing all changes
86
+
87
+ Configuration can be stored in .git-merge-workflow.json in the repository root.
88
+ .PARAMETER CommitMessage
89
+ Optional commit message if there are uncommitted changes
90
+ .PARAMETER StagingBranch
91
+ Optional custom staging branch name.
92
+ Defaults to {current-branch}{staging-suffix} (configured in JSON or defaults to -staging)
93
+ .PARAMETER TargetBranch
94
+ Optional target branch name.
95
+ Defaults to 'develop' or value in configuration file.
96
+ .PARAMETER Remote
97
+ Optional remote name.
98
+ Defaults to 'origin' or value in configuration file.
99
+ .EXAMPLE
100
+ Invoke-GitMergeWorkflow
101
+ .EXAMPLE
102
+ Invoke-GitMergeWorkflow -CommitMessage "Fix: Updated business contact form"
103
+ .EXAMPLE
104
+ git-merge-workflow -CommitMessage "Feature: Added new component" -WhatIf
105
+ #>
106
+
107
+ [CmdletBinding(SupportsShouldProcess=$true)]
108
+ param(
109
+ [Parameter(Mandatory=$false)]
110
+ [string]$CommitMessage = "",
111
+
112
+ [Parameter(Mandatory=$false)]
113
+ [string]$StagingBranch = "",
114
+
115
+ [Parameter(Mandatory=$false)]
116
+ [string]$TargetBranch = "",
117
+
118
+ [Parameter(Mandatory=$false)]
119
+ [string]$Remote = ""
120
+ )
121
+
122
+ # Load configuration
123
+ $config = Get-GitWorkflowConfig
124
+
125
+ # Set defaults (Priority: Parameter > Config > Hardcoded Default)
126
+ if (-not $TargetBranch) {
127
+ $TargetBranch = if ($config.TargetBranch) { $config.TargetBranch } else { "develop" }
128
+ }
129
+
130
+ if (-not $Remote) {
131
+ $Remote = if ($config.Remote) { $config.Remote } else { "origin" }
132
+ }
133
+
134
+ $stagingSuffix = if ($config.StagingSuffix) { $config.StagingSuffix } else { "-staging" }
135
+
136
+ # Internal helper to execute git commands with error handling
137
+ function Exec-Git {
138
+ [CmdletBinding()]
139
+ param(
140
+ [Parameter(Mandatory=$true, Position=0)]
141
+ [string]$Command,
142
+
143
+ [Parameter(Mandatory=$false)]
144
+ [string]$ErrorMessage,
145
+
146
+ [Parameter(Mandatory=$false)]
147
+ [switch]$IgnoreError,
148
+
149
+ [Parameter(Mandatory=$false)]
150
+ [switch]$ReturnOutput,
151
+
152
+ [Parameter(ValueFromRemainingArguments=$true)]
153
+ [string[]]$Arguments
154
+ )
155
+
156
+ $cmdDesc = "git $Command $Arguments"
157
+
158
+ if ($PSCmdlet.ShouldProcess("Git Repository", "Execute: $cmdDesc")) {
159
+ # Construct the command to run
160
+ # Note: We use & operator to run git with arguments
161
+ $output = & git $Command $Arguments 2>&1
162
+ $exitCode = $LASTEXITCODE
163
+
164
+ if ($ReturnOutput) {
165
+ return $output
166
+ } elseif ($output) {
167
+ # If not capturing output, write it to the stream (except errors which we handle below)
168
+ $output | ForEach-Object { Write-Verbose $_ }
169
+ }
170
+
171
+ if (-not $IgnoreError -and $exitCode -ne 0) {
172
+ $msg = if ($ErrorMessage) { $ErrorMessage } else { "Git command failed: $cmdDesc" }
173
+ throw "$msg`nDetails: $output"
174
+ }
175
+ }
176
+ }
177
+
178
+ Write-Host "`n=== Git Merge Workflow ===" -ForegroundColor Cyan
179
+ Write-Host "Starting automated merge process...`n" -ForegroundColor Cyan
180
+
181
+ # Check if we're in a git repository
182
+ try {
183
+ Exec-Git "rev-parse" "--is-inside-work-tree" -ErrorMessage "Not a git repository" -ReturnOutput | Out-Null
184
+ } catch {
185
+ Write-Error $_.Exception.Message
186
+ return
187
+ }
188
+
189
+ # Get current branch
190
+ $currentBranch = (git branch --show-current).Trim()
191
+ Write-Host "Current branch: $currentBranch" -ForegroundColor Yellow
192
+
193
+ if ([string]::IsNullOrWhiteSpace($currentBranch)) {
194
+ Write-Error "Could not determine current branch."
195
+ return
196
+ }
197
+
198
+ # Validate we are not on target or explicitly named staging
199
+ if ($currentBranch -eq $TargetBranch) {
200
+ Write-Error "You are currently on the target branch '$TargetBranch'. Please checkout your feature branch first."
201
+ return
202
+ }
203
+
204
+ # Define staging branch
205
+ if (-not $StagingBranch) {
206
+ $StagingBranch = "$currentBranch$stagingSuffix"
207
+ }
208
+
209
+ if ($currentBranch -eq $StagingBranch) {
210
+ Write-Error "You are currently on the staging branch '$StagingBranch'. Please checkout your feature branch first."
211
+ return
212
+ }
213
+
214
+ Write-Host "`nStaging branch: $StagingBranch" -ForegroundColor Yellow
215
+ Write-Host "Target branch: $TargetBranch" -ForegroundColor Yellow
216
+ Write-Host "Remote: $Remote" -ForegroundColor Yellow
217
+
218
+ # Store starting branch to return to it later
219
+ $originalBranch = $currentBranch
220
+
221
+ try {
222
+ # Verify remote connection before proceeding
223
+ Write-Host "`nVerifying connection to $Remote..." -ForegroundColor Yellow
224
+ Exec-Git -Command "ls-remote" -Arguments $Remote, "HEAD" -ErrorMessage "Could not connect to remote '$Remote'. Please check your internet connection and git credentials." -ReturnOutput | Out-Null
225
+ Write-Host "Connection successful!" -ForegroundColor Green
226
+
227
+ # Check for uncommitted changes
228
+ $status = git status --porcelain
229
+ if ($status) {
230
+ if ($CommitMessage) {
231
+ Write-Host "`nCommitting changes..." -ForegroundColor Yellow
232
+ if ($PSCmdlet.ShouldProcess("Current Branch", "Add all changes and commit with message '$CommitMessage'")) {
233
+ Exec-Git "add" "." -ErrorMessage "Failed to add changes"
234
+ Exec-Git "commit" "-m" "$CommitMessage" -ErrorMessage "Failed to commit changes"
235
+ Write-Host "Changes committed!" -ForegroundColor Green
236
+ }
237
+ } else {
238
+ Write-Error "You have uncommitted changes! Please commit them first or use -CommitMessage parameter"
239
+ git status
240
+ return
241
+ }
242
+ }
243
+
244
+ # --- Handle Staging Branch ---
245
+
246
+ # Check if staging branch exists locally
247
+ $branchExists = git branch --list $StagingBranch
248
+ if (-not $branchExists) {
249
+ Write-Host "`nStaging branch doesn't exist locally. Checking remote..." -ForegroundColor Yellow
250
+ # Check if exists on remote (explicit check to avoid silent failures)
251
+ $remoteBranchExists = $false
252
+ try {
253
+ $lsRemote = Exec-Git -Command "ls-remote" -Arguments "--heads", $Remote, $StagingBranch -ReturnOutput
254
+ if ($lsRemote) { $remoteBranchExists = $true }
255
+ } catch {
256
+ Write-Warning "Could not check remote branch: $_"
257
+ }
258
+
259
+ if ($remoteBranchExists) {
260
+ Write-Host "Fetching remote staging branch..." -ForegroundColor Yellow
261
+ Exec-Git -Command "fetch" -Arguments $Remote, $StagingBranch
262
+ Exec-Git -Command "checkout" -Arguments "-b", $StagingBranch, "$Remote/$StagingBranch"
263
+ } else {
264
+ Write-Host "Creating new staging branch..." -ForegroundColor Yellow
265
+ Exec-Git -Command "checkout" -Arguments "-b", $StagingBranch
266
+ }
267
+ } else {
268
+ Write-Host "Checking out staging branch..." -ForegroundColor Yellow
269
+ Exec-Git -Command "checkout" -Arguments $StagingBranch
270
+ }
271
+
272
+ # Pull latest from staging (if tracked)
273
+ Write-Host "`nPulling latest changes from staging..." -ForegroundColor Yellow
274
+ # We use IgnoreError because it might fail if there's no tracking info yet, which is acceptable here
275
+ Exec-Git -Command "pull" -Arguments $Remote, $StagingBranch -IgnoreError
276
+
277
+ # Merge current branch into staging
278
+ Write-Host "`nMerging $currentBranch into $StagingBranch..." -ForegroundColor Yellow
279
+ Exec-Git -Command "merge" -Arguments $currentBranch, "--no-ff", "-m", "Merge $currentBranch into $StagingBranch" -ErrorMessage "Merge conflict detected in staging! Please resolve conflicts manually."
280
+
281
+ Write-Host "Successfully merged to staging!" -ForegroundColor Green
282
+
283
+ # Push staging
284
+ Write-Host "`nPushing $StagingBranch to remote..." -ForegroundColor Yellow
285
+ try {
286
+ Exec-Git -Command "push" -Arguments "-u", $Remote, $StagingBranch -ErrorMessage "Failed to push staging branch"
287
+ Write-Host "Staging branch pushed!" -ForegroundColor Green
288
+ } catch {
289
+ Write-Warning "Failed to push staging branch to remote."
290
+ Write-Warning "Error: $_"
291
+ if ($PSCmdlet.ShouldContinue("Do you want to skip pushing the staging branch and continue to merge into $TargetBranch?", "Skip Staging Push")) {
292
+ Write-Host "Skipping staging push..." -ForegroundColor Yellow
293
+ } else {
294
+ throw $_
295
+ }
296
+ }
297
+
298
+ # --- Handle Target Branch ---
299
+
300
+ # Checkout target branch
301
+ Write-Host "`nChecking out $TargetBranch branch..." -ForegroundColor Yellow
302
+ Exec-Git "checkout" $TargetBranch -ErrorMessage "Failed to checkout $TargetBranch"
303
+
304
+ # Pull latest from target
305
+ Write-Host "Pulling latest changes from $TargetBranch..." -ForegroundColor Yellow
306
+ Exec-Git "pull" $Remote $TargetBranch -ErrorMessage "Failed to pull $TargetBranch"
307
+
308
+ # Merge staging into target
309
+ Write-Host "`nMerging $StagingBranch into $TargetBranch..." -ForegroundColor Yellow
310
+ Exec-Git "merge" $StagingBranch "--no-ff" "-m" "Merge $StagingBranch into $TargetBranch" -ErrorMessage "Merge conflict detected in target! Please resolve conflicts manually."
311
+
312
+ Write-Host "Successfully merged to target!" -ForegroundColor Green
313
+
314
+ # Push target
315
+ Write-Host "`nPushing $TargetBranch to remote..." -ForegroundColor Yellow
316
+ Exec-Git "push" $Remote $TargetBranch -ErrorMessage "Failed to push $TargetBranch branch"
317
+ Write-Host "$TargetBranch branch pushed!" -ForegroundColor Green
318
+
319
+ Write-Host "`n=== Workflow Complete! ===" -ForegroundColor Green
320
+ Write-Host "Summary:" -ForegroundColor Cyan
321
+ Write-Host " ✓ Merged: $originalBranch → $StagingBranch → $TargetBranch" -ForegroundColor White
322
+ Write-Host " ✓ All changes pushed to remote`n" -ForegroundColor White
323
+
324
+ } catch {
325
+ Write-Error $_.Exception.Message
326
+ Write-Host "`nWorkflow failed. Attempting to return to original branch..." -ForegroundColor Red
327
+ } finally {
328
+ # Return to original branch
329
+ $finalBranch = (git branch --show-current).Trim()
330
+ if ($originalBranch -and $finalBranch -ne $originalBranch) {
331
+ Write-Host "`nReturning to $originalBranch..." -ForegroundColor Yellow
332
+ if ($PSCmdlet.ShouldProcess("Cleanup", "Checkout $originalBranch")) {
333
+ git checkout $originalBranch 2>$null | Out-Null
334
+ }
335
+ }
336
+ }
337
+ }
338
+
339
+ # Create aliases for easier usage
340
+ New-Alias -Name git-merge-workflow -Value Invoke-GitMergeWorkflow -Force
341
+ New-Alias -Name gmw -Value Invoke-GitMergeWorkflow -Force
342
+
343
+ Export-ModuleMember -Function Invoke-GitMergeWorkflow, New-GitWorkflowConfig, Get-GitWorkflowConfig -Alias git-merge-workflow, gmw
package/Install.ps1 ADDED
@@ -0,0 +1,31 @@
1
+ # Simple installation script for GitMergeWorkflow module
2
+
3
+ $moduleName = "GitMergeWorkflow"
4
+ $currentUserModules = [System.IO.Path]::Combine($env:USERPROFILE, "Documents", "WindowsPowerShell", "Modules")
5
+ $destPath = Join-Path $currentUserModules $moduleName
6
+
7
+ Write-Host "Installing $moduleName to $destPath..." -ForegroundColor Cyan
8
+
9
+ # Create modules directory if it doesn't exist
10
+ if (-not (Test-Path $currentUserModules)) {
11
+ New-Item -Path $currentUserModules -ItemType Directory -Force | Out-Null
12
+ }
13
+
14
+ # Copy module files
15
+ $scriptPath = $PSScriptRoot
16
+ if (-not $scriptPath) { $scriptPath = Get-Location }
17
+
18
+ if (Test-Path $destPath) {
19
+ Write-Warning "Module already exists. Updating..."
20
+ Remove-Item $destPath -Recurse -Force
21
+ }
22
+
23
+ Copy-Item -Path $scriptPath -Destination $destPath -Recurse -Force
24
+
25
+ # Verify installation
26
+ if (Test-Path (Join-Path $destPath "$moduleName.psd1")) {
27
+ Write-Host "Installation successful!" -ForegroundColor Green
28
+ Write-Host "You can now run: Import-Module $moduleName" -ForegroundColor Yellow
29
+ } else {
30
+ Write-Error "Installation failed."
31
+ }
package/PUBLISHING.md ADDED
@@ -0,0 +1,41 @@
1
+ # How to Publish `@babajide234/git-merge-workflow` to npm
2
+
3
+ ## Prerequisites
4
+
5
+ 1. **NPM Account**: You must have an account on [npmjs.com](https://www.npmjs.com/).
6
+ 2. **Login**: You must be logged in as `babajide234`.
7
+
8
+ ## Publishing Steps
9
+
10
+ 1. **Login to npm**:
11
+ Open your terminal in the project directory and run:
12
+ ```bash
13
+ npm login
14
+ ```
15
+ Follow the prompts to authenticate via the browser.
16
+
17
+ 2. **Verify Configuration**:
18
+ Ensure `package.json` has the correct version.
19
+ Current version: `1.0.0`
20
+
21
+ 3. **Publish**:
22
+ By default, scoped packages (`@org/pkg`) are published as **private**.
23
+
24
+ - **To publish publicly** (visible to everyone):
25
+ ```bash
26
+ npm publish --access public
27
+ ```
28
+
29
+ - **To publish privately** (only visible to org members - requires paid npm plan):
30
+ ```bash
31
+ npm publish
32
+ ```
33
+
34
+ ## Post-Publishing
35
+
36
+ - **Update Version**: For future updates, remember to bump the version number in `package.json` (e.g., `1.0.1`) before publishing again.
37
+ ```bash
38
+ npm version patch # 1.0.0 -> 1.0.1
39
+ npm version minor # 1.0.0 -> 1.1.0
40
+ npm version major # 1.0.0 -> 2.0.0
41
+ ```
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Git Merge Workflow PowerShell Module
2
+
3
+ Automate your git merge workflow with safety and ease. This module helps you merge your current feature branch to a staging branch (e.g., `feature-branch-staging`), and then to a target branch (e.g., `develop`), ensuring a consistent workflow.
4
+
5
+ ## Features
6
+
7
+ - **Automated Merging**: Merges current branch -> Staging -> Target.
8
+ - **Safety Checks**: Prevents running on wrong branches, checks for uncommitted changes.
9
+ - **Conflict Handling**: Stops immediately on merge conflicts so you can resolve them.
10
+ - **Automatic Cleanup**: Returns you to your original branch even if the script fails.
11
+ - **Configurable**: Define project-specific settings via a JSON configuration file.
12
+ - **Dry Run**: Support for `-WhatIf` to preview actions.
13
+
14
+ ## Installation
15
+
16
+ ### Via NPM (Recommended for Node.js users)
17
+ You can install this tool globally using npm:
18
+
19
+ ```bash
20
+ npm install -g @expedier/git-merge-workflow
21
+ ```
22
+ This will make the `gmw` and `git-merge-workflow` commands available in your terminal.
23
+
24
+ ### Manual Installation
25
+ 1. Download this repository.
26
+ 2. Run the included installation script:
27
+ ```powershell
28
+ .\Install.ps1
29
+ ```
30
+ Or copy the `GitMergeWorkflow` folder to your PowerShell modules directory manually.
31
+ 3. Import the module (if not auto-loaded):
32
+ ```powershell
33
+ Import-Module GitMergeWorkflow
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Basic Usage
39
+ Run the workflow from your feature branch:
40
+ ```powershell
41
+ Invoke-GitMergeWorkflow
42
+ # OR use the alias
43
+ gmw
44
+ ```
45
+
46
+ ### With Commit Message
47
+ If you have uncommitted changes, you can commit them as part of the workflow:
48
+ ```powershell
49
+ gmw -CommitMessage "Feat: Completed login page"
50
+ ```
51
+
52
+ ### Dry Run (Preview)
53
+ See what commands would be executed without actually running them:
54
+ ```powershell
55
+ gmw -WhatIf
56
+ ```
57
+
58
+ ### Custom Branches
59
+ Override default branches on the fly:
60
+ ```powershell
61
+ gmw -TargetBranch "main" -StagingBranch "custom-staging"
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ You can create a configuration file for your project so you don't have to pass parameters every time.
67
+
68
+ 1. Navigate to your project root.
69
+ 2. Run the configuration generator:
70
+ ```powershell
71
+ New-GitWorkflowConfig -TargetBranch "main" -StagingSuffix "-test"
72
+ ```
73
+
74
+ This creates a `.git-merge-workflow.json` file:
75
+ ```json
76
+ {
77
+ "TargetBranch": "main",
78
+ "StagingSuffix": "-test",
79
+ "Remote": "origin"
80
+ }
81
+ ```
82
+
83
+ ## Publishing (For Maintainers)
84
+
85
+ ### GitHub Actions
86
+ This repository is configured to automatically publish to:
87
+ 1. **PowerShell Gallery** (if `NUGET_KEY` secret is set)
88
+ 2. **NPM Registry** (if `NPM_TOKEN` secret is set)
89
+
90
+ When you create a new Release in GitHub.
91
+
92
+ ### Manual Publishing
93
+
94
+ **To NPM:**
95
+ ```bash
96
+ npm login
97
+ npm publish --access public
98
+ ```
99
+
100
+ **To PowerShell Gallery:**
101
+ ```powershell
102
+ Publish-Module -Path . -NuGetApiKey <Your-API-Key>
103
+ ```
104
+
105
+ ## Functions
106
+
107
+ - `Invoke-GitMergeWorkflow` (Alias: `gmw`, `git-merge-workflow`): The main workflow command.
108
+ - `New-GitWorkflowConfig`: Generates the `.git-merge-workflow.json` configuration file.
109
+ - `Get-GitWorkflowConfig`: Reads the current configuration.
110
+
111
+ ## License
112
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('child_process');
4
+ const path = require('path');
5
+
6
+ // Path to the PowerShell module
7
+ const modulePath = path.resolve(__dirname, '../GitMergeWorkflow.psd1');
8
+
9
+ // Arguments passed to the CLI
10
+ const args = process.argv.slice(2);
11
+
12
+ // Construct the PowerShell command
13
+ // We import the module and then invoke the function with passed arguments
14
+ const psCommand = `
15
+ $ErrorActionPreference = 'Stop'
16
+ Import-Module '${modulePath}' -Force
17
+ Invoke-GitMergeWorkflow ${args.join(' ')}
18
+ `;
19
+
20
+ // Determine which PowerShell executable to use (pwsh for Core, powershell for Windows PowerShell)
21
+ const psExecutable = process.platform === 'win32' ? 'powershell' : 'pwsh';
22
+
23
+ const child = spawn(psExecutable, ['-NoProfile', '-Command', psCommand], {
24
+ stdio: 'inherit',
25
+ shell: true
26
+ });
27
+
28
+ child.on('exit', (code) => {
29
+ process.exit(code);
30
+ });
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@babajide234/git-merge-workflow",
3
+ "version": "1.0.0",
4
+ "description": "Automated Git workflow for merging feature branches through staging to develop",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "git-merge-workflow": "./bin/cli.js",
8
+ "gmw": "./bin/cli.js"
9
+ },
10
+ "scripts": {
11
+ "test": "echo \"Error: no test specified\" && exit 1"
12
+ },
13
+ "keywords": [
14
+ "git",
15
+ "workflow",
16
+ "powershell",
17
+ "automation",
18
+ "devops"
19
+ ],
20
+ "author": "babajide Tomoshegbo",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/babajide234/GitMergeWorkflow.git"
25
+ },
26
+ "engines": {
27
+ "node": ">=14"
28
+ }
29
+ }