From 3c2427c001d41ae2810ca9d7709f9e915aaf2111 Mon Sep 17 00:00:00 2001 From: adrianm Date: Fri, 15 Nov 2024 15:41:32 +0100 Subject: [PATCH 001/217] Added new tip about PSReadline Key Handler --- ...adlinekeyhandler-to-change-keybindings.ps1 | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/PowerShellTips/2024-11-15-use-set-psreadlinekeyhandler-to-change-keybindings.ps1 diff --git a/src/PowerShellTips/2024-11-15-use-set-psreadlinekeyhandler-to-change-keybindings.ps1 b/src/PowerShellTips/2024-11-15-use-set-psreadlinekeyhandler-to-change-keybindings.ps1 new file mode 100644 index 00000000..c7211d40 --- /dev/null +++ b/src/PowerShellTips/2024-11-15-use-set-psreadlinekeyhandler-to-change-keybindings.ps1 @@ -0,0 +1,33 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-11-15') +$tip.Title = 'Use Set-PSReadLineKeyHandler to change keybindings' +$tip.TipText = @' +You can use the Set-PSReadLineKeyHandler cmdlet to change key bindings. + +A handy shortcut to set is for AcceptNextSuggestionWord which is built within ForwardWord function. This function is bound to the key chord Ctrl + F on Unix but not on Windows. The following is a way to enable that mapping on Windows. +'@ +$tip.Example = @' +# With the following example you will be able to set the Ctrl+f to accept the next word of an inline suggestion. +Set-PSReadLineKeyHandler -Chord "Ctrl+f" -Function ForwardWord + +# You could change the Right arrow to accept the next word instead of the whole suggestion line. +Set-PSReadLineKeyHandler -Chord "RightArrow" -Function ForwardWord +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/scripting/learn/shell/using-predictors?view=powershell-7.4#changing-keybindings' + 'https://learn.microsoft.com/en-us/powershell/module/psreadline/set-psreadlinekeyhandler?view=powershell-7.4' +) +$tip.Category = [tiPS.TipCategory]::Terminal # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Adrian Muscat (adrimus)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 513e07969101269ee9b6ee83628fe152a3e9a422 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 7 Nov 2024 09:20:22 -0600 Subject: [PATCH 002/217] tip: Update tip to put the main website as the first url --- ...4-11-06-join-the-research-triangle-powershell-user-group.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellTips/2024-11-06-join-the-research-triangle-powershell-user-group.ps1 b/src/PowerShellTips/2024-11-06-join-the-research-triangle-powershell-user-group.ps1 index 70bde6e4..3a1639cf 100644 --- a/src/PowerShellTips/2024-11-06-join-the-research-triangle-powershell-user-group.ps1 +++ b/src/PowerShellTips/2024-11-06-join-the-research-triangle-powershell-user-group.ps1 @@ -6,9 +6,9 @@ The Research Triangle User Group (RTPSUG) meets virtually, typically once or twi "@ $tip.Example = '' $tip.Urls = @( + 'https://rtpsug.com' 'https://www.meetup.com/research-triangle-powershell-users-group/' 'https://www.youtube.com/c/RTPSUG/' - 'https://rtpsug.com' ) $tip.Category = [tiPS.TipCategory]::Community # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. $tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. From ce031eb8e66485d364e585f682b6964b53228983 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Sat, 16 Nov 2024 13:52:10 -0600 Subject: [PATCH 003/217] chore: Rebuild tips json file --- src/tiPS/PowerShellTips.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 6628fa38..9d9ed0fb 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -762,5 +762,32 @@ "Category": 0, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2024-11-06T00:00:00", + "Title": "Join the Research Triangle PowerShell User Group!", + "TipText": "The Research Triangle User Group (RTPSUG) meets virtually, typically once or twice a month, to share ideas and discuss all things PowerShell. Community members often demo modules they've built or PowerShell things they have learned. It's free to attend and everyone is welcome. You can even reach out to the organizers to present something you've built or learned. Presentations are often uploaded to YouTube, allowing you to catch up on sessions you've missed. RTPSUG is an excellent way to stay up to date with both PowerShell technology and the PowerShell community.", + "Example": "", + "Urls": [ + "https://rtpsug.com", + "https://www.meetup.com/research-triangle-powershell-users-group/", + "https://www.youtube.com/c/RTPSUG/" + ], + "Category": 0, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2024-11-15T00:00:00", + "Title": "Use Set-PSReadLineKeyHandler to change keybindings", + "TipText": "You can use the Set-PSReadLineKeyHandler cmdlet to change key bindings.\r\n\r\nA handy shortcut to set is for AcceptNextSuggestionWord which is built within ForwardWord function. This function is bound to the key chord Ctrl + F on Unix but not on Windows. The following is a way to enable that mapping on Windows.", + "Example": "# With the following example you will be able to set the Ctrl+f to accept the next word of an inline suggestion.\r\nSet-PSReadLineKeyHandler -Chord \"Ctrl+f\" -Function ForwardWord\r\n\r\n# You could change the Right arrow to accept the next word instead of the whole suggestion line.\r\nSet-PSReadLineKeyHandler -Chord \"RightArrow\" -Function ForwardWord", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/scripting/learn/shell/using-predictors?view=powershell-7.4#changing-keybindings", + "https://learn.microsoft.com/en-us/powershell/module/psreadline/set-psreadlinekeyhandler?view=powershell-7.4" + ], + "Category": 7, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Adrian Muscat (adrimus)" } ] From 43a97961cbd5223588176fcf3ea3841e48cd84df Mon Sep 17 00:00:00 2001 From: adrianm Date: Mon, 18 Nov 2024 09:58:55 +0100 Subject: [PATCH 004/217] New tip about array objects --- ...2024-11-18-get-the-members-of-an-array.ps1 | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 diff --git a/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 b/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 new file mode 100644 index 00000000..4143ccdc --- /dev/null +++ b/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 @@ -0,0 +1,46 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-11-18') +$tip.Title = 'Get the members of an array' +$tip.TipText = @' +PowerShell sends the items in an array one at a time when you pipe an array to Get-Member and it ignores duplicates +'@ +$tip.Example = @' +# When you pipe to Get-Member PowerShell enumerates the array and you get the properties of the items inside the array, in this case a string +PS C:\> [array]$myArray = @('one','two','three') +PS C:\> $myarray | Get-Member + + TypeName: System.String + +# This example will output the members of the array +PS C:\> Get-Member -InputObject $myArray + + TypeName: System.Object[] + +# This will also do the same by making the array the second item in an array of arrays +,$myArray | Get-Member + +# To see what type of object is in a variable use the GetType method. +PS C:\> $myArray.GetType() + +IsPublic IsSerial Name BaseType +-------- -------- ---- -------- +True True Object[] System.Array +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays?view=powershell-7.4' + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arrays?view=powershell-7.4#get-the-members-of-an-array' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Adrian Muscat (adrimus)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From cc6b12ffb565dbc903f9a5dfddbe8f644ffd08af Mon Sep 17 00:00:00 2001 From: adrimus <37830358+adrimus@users.noreply.github.com> Date: Mon, 18 Nov 2024 17:15:38 +0100 Subject: [PATCH 005/217] Update 2024-11-18-get-the-members-of-an-array.ps1 Changed the case on $myarray on line 10 --- src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 b/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 index 4143ccdc..e5be7f5b 100644 --- a/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 +++ b/src/PowerShellTips/2024-11-18-get-the-members-of-an-array.ps1 @@ -7,7 +7,7 @@ PowerShell sends the items in an array one at a time when you pipe an array to G $tip.Example = @' # When you pipe to Get-Member PowerShell enumerates the array and you get the properties of the items inside the array, in this case a string PS C:\> [array]$myArray = @('one','two','three') -PS C:\> $myarray | Get-Member +PS C:\> $myArray | Get-Member TypeName: System.String From 8f013bdc7be864dcd66b782568209bfb814d2ce9 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Mon, 25 Nov 2024 14:16:17 -0600 Subject: [PATCH 006/217] Update PR template --- .github/pull_request_template.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e4db35be..a283f5b9 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,11 @@ +If this PR is simply to add a new Tip, delete all of this template text and just mention you are adding a new tip. + +If you are making changes to the module's functionality, please fill out the template below. + ### Summary A brief summary of the change this PR brings. -If this PR is simply to add a new Tip, you can remove all of the sections below, as they do not apply. - ### Checklist Addresses issue #ISSUE_NUMBER (if applicable) From 0cb87145d0b1031e4ccf0a8faf8b5bdce1c1fbc6 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 20:41:12 -0600 Subject: [PATCH 007/217] tip: Add tip for ErrorAction --- ...ange-what-happens-when-an-error-occurs.ps1 | 48 +++++++++++++++++++ src/tiPS/PowerShellTips.json | 26 ++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 diff --git a/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 b/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 new file mode 100644 index 00000000..9fdf97be --- /dev/null +++ b/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 @@ -0,0 +1,48 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-11-27') +$tip.Title = 'Use ErrorAction to change what happens when an error occurs' +$tip.TipText = @' +The `-ErrorAction` common parameter allows you to change what happens when a non-terminating error occurs in a cmdlet or script, such as when `Write-Error` is used. The default behavior is to display an error message and continue executing the script. You can change this behavior to: + +- `Stop`: Display the error message and stop executing the script. That is, treat it as a terminating error. +- `Continue`: Display the error message and continue executing the script. This is the default. +- `SilentlyContinue`: Suppress the error message (so it is not written to the error stream) and continue executing the script. +- `Ignore`: Suppress the error message and continue executing the script. Unlike SilentlyContinue, Ignore doesn't add the error message to the $Error automatic variable. +- `Inquire`: Display the error message and prompt the user to continue or stop executing the script. +- `Break`: Display the error message and enter the debugger. Also breaks into the debugger when a terminating error occurs. + +You can set the global behaviour for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified. +'@ +$tip.Example = @' +function Test-ErrorAction { + [CmdletBinding()] # This attribute is required to use the `-ErrorAction` common parameter. + param() + + Write-Error "This is an error message" +} + +Test-ErrorAction # Displays the error message and continues executing the script. +Test-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script. + +$ErrorActionPreference = "SilentlyContinue" # Sets the global error action preference to suppress error messages. +Test-ErrorAction # Suppresses the error message and continues executing the script, because the global setting is SilentlyContinue. +Test-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script, because the `-ErrorAction` parameter overrides the global setting. +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-erroraction' + 'https://devblogs.microsoft.com/scripting/handling-errors-the-powershell-way/' +) +$tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 9d9ed0fb..44f8845b 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -789,5 +789,31 @@ "Category": 7, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Adrian Muscat (adrimus)" + }, + { + "CreatedDate": "2024-11-18T00:00:00", + "Title": "Get the members of an array", + "TipText": "PowerShell sends the items in an array one at a time when you pipe an array to Get-Member and it ignores duplicates", + "Example": "# When you pipe to Get-Member PowerShell enumerates the array and you get the properties of the items inside the array, in this case a string\r\nPS C:\\> [array]$myArray = @('one','two','three')\r\nPS C:\\> $myArray | Get-Member\r\n\r\n TypeName: System.String\r\n\r\n# This example will output the members of the array\r\nPS C:\\> Get-Member -InputObject $myArray\r\n\r\n TypeName: System.Object[]\r\n\r\n# This will also do the same by making the array the second item in an array of arrays\r\n,$myArray | Get-Member\r\n\r\n# To see what type of object is in a variable use the GetType method.\r\nPS C:\\> $myArray.GetType()\r\n\r\nIsPublic IsSerial Name BaseType\r\n-------- -------- ---- --------\r\nTrue True Object[] System.Array", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays?view=powershell-7.4", + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_arrays?view=powershell-7.4#get-the-members-of-an-array" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Adrian Muscat (adrimus)" + }, + { + "CreatedDate": "2024-11-27T00:00:00", + "Title": "Use ErrorAction to change what happens when an error occurs", + "TipText": "The `-ErrorAction` common parameter allows you to change what happens when a non-terminating error occurs in a cmdlet or script, such as when `Write-Error` is used. The default behavior is to display an error message and continue executing the script. You can change this behavior to:\r\n\r\n- `Stop`: Display the error message and stop executing the script. That is, treat it as a terminating error.\r\n- `Continue`: Display the error message and continue executing the script. This is the default.\r\n- `SilentlyContinue`: Suppress the error message (so it is not written to the error stream) and continue executing the script.\r\n- `Ignore`: Suppress the error message and continue executing the script. Unlike SilentlyContinue, Ignore doesn't add the error message to the $Error automatic variable.\r\n- `Inquire`: Display the error message and prompt the user to continue or stop executing the script.\r\n- `Break`: Display the error message and enter the debugger. Also breaks into the debugger when a terminating error occurs.\r\n\r\nYou can set the global behaviour for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified.", + "Example": "function Test-ErrorAction {\r\n [CmdletBinding()] # This attribute is required to use the `-ErrorAction` common parameter.\r\n param()\r\n\r\n Write-Error \"This is an error message\"\r\n}\r\n\r\nTest-ErrorAction # Displays the error message and continues executing the script.\r\nTest-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script.\r\n\r\n$ErrorActionPreference = \"SilentlyContinue\" # Sets the global error action preference to suppress error messages.\r\nTest-ErrorAction # Suppresses the error message and continues executing the script, because the global setting is SilentlyContinue.\r\nTest-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script, because the `-ErrorAction` parameter overrides the global setting.", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-erroraction", + "https://devblogs.microsoft.com/scripting/handling-errors-the-powershell-way/" + ], + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 464a86f1ae954ed417ac005195afa7d4b5828526 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 21:22:41 -0600 Subject: [PATCH 008/217] tip: Fix spelling --- ...-erroraction-to-change-what-happens-when-an-error-occurs.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 b/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 index 9fdf97be..e857d6d0 100644 --- a/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 +++ b/src/PowerShellTips/2024-11-27-use-erroraction-to-change-what-happens-when-an-error-occurs.ps1 @@ -11,7 +11,7 @@ The `-ErrorAction` common parameter allows you to change what happens when a non - `Inquire`: Display the error message and prompt the user to continue or stop executing the script. - `Break`: Display the error message and enter the debugger. Also breaks into the debugger when a terminating error occurs. -You can set the global behaviour for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified. +You can set the global behavior for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified. '@ $tip.Example = @' function Test-ErrorAction { From 7083bf104485fbf7437074367541e7638cc0efe0 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 21:39:43 -0600 Subject: [PATCH 009/217] tip: Add tip for ErrorVariable --- ...le-to-save-cmdlet-errors-to-a-variable.ps1 | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 diff --git a/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 new file mode 100644 index 00000000..88faa898 --- /dev/null +++ b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 @@ -0,0 +1,53 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-11-27') +$tip.Title = 'Use ErrorVariable to save cmdlet errors to a variable' +$tip.TipText = @' +When running a cmdlet in PowerShell, you can use the `-ErrorVariable` parameter to save any errors that occur during the cmdlet's execution to a variable. This can be useful for capturing errors and handling them programmatically. There is also a `-WarningVariable` parameter that works similarly for warnings. + +You can also couple these with the `-ErrorAction` and `-WarningAction` common parameters to control how errors and warnings are handled. For example, you can set `-ErrorAction` to `SilentlyContinue` to suppress errors from being displayed on the console, while still capturing them in the error variable. +'@ +$tip.Example = @' +function Test-ErrorVariable { + [CmdletBinding()] # This attribute is required to use the `-ErrorVariable` common parameter. + param() + + Write-Error "This is an error message that should be IGNORED" + Write-Error "This is another error message" +} + +# You don't need to initialize the error and warning variable, but it's a good practice. +$errors = @() +$warnings = @() + +# Use ErrorAction SilentlyContinue to suppress errors from being displayed on the console while still capturing them in the errors variable. +Test-ErrorVariable -WarningVariable warnings -ErrorVariable errors -ErrorAction SilentlyContinue + +if ($errors) { + # Here you can inspect the errors and handle them as needed. + $errors | ForEach-Object { + if ($_ -like '*IGNORED*') { + Write-Verbose "Ignoring error: $_" + } else { + Write-Error "Error: $_" + } + } +} +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-errorvariable' + 'https://stuart-moore.com/powershell-using-errorvariable-and-warningvariable/' +) +$tip.Category = [tiPS.TipCategory]::Other # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Your name and/or username' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From f10240351b117136f9c5258e5b773fc1caa3e19c Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 21:46:12 -0600 Subject: [PATCH 010/217] tip: Use spaces in tip --- ...le-to-save-cmdlet-errors-to-a-variable.ps1 | 24 +++++++++---------- src/tiPS/PowerShellTips.json | 15 +++++++++++- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 index 88faa898..b5babd0e 100644 --- a/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 +++ b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 @@ -8,11 +8,11 @@ You can also couple these with the `-ErrorAction` and `-WarningAction` common pa '@ $tip.Example = @' function Test-ErrorVariable { - [CmdletBinding()] # This attribute is required to use the `-ErrorVariable` common parameter. - param() + [CmdletBinding()] # This attribute is required to use the `-ErrorVariable` common parameter. + param() - Write-Error "This is an error message that should be IGNORED" - Write-Error "This is another error message" + Write-Error "This is an error message that should be IGNORED" + Write-Error "This is another error message" } # You don't need to initialize the error and warning variable, but it's a good practice. @@ -23,14 +23,14 @@ $warnings = @() Test-ErrorVariable -WarningVariable warnings -ErrorVariable errors -ErrorAction SilentlyContinue if ($errors) { - # Here you can inspect the errors and handle them as needed. - $errors | ForEach-Object { - if ($_ -like '*IGNORED*') { - Write-Verbose "Ignoring error: $_" - } else { - Write-Error "Error: $_" - } - } + # Here you can inspect the errors and handle them as needed. + $errors | ForEach-Object { + if ($_ -like '*IGNORED*') { + Write-Verbose "Ignoring error: $_" + } else { + Write-Error "Error: $_" + } + } } '@ $tip.Urls = @( diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 44f8845b..35d4ae43 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -806,7 +806,7 @@ { "CreatedDate": "2024-11-27T00:00:00", "Title": "Use ErrorAction to change what happens when an error occurs", - "TipText": "The `-ErrorAction` common parameter allows you to change what happens when a non-terminating error occurs in a cmdlet or script, such as when `Write-Error` is used. The default behavior is to display an error message and continue executing the script. You can change this behavior to:\r\n\r\n- `Stop`: Display the error message and stop executing the script. That is, treat it as a terminating error.\r\n- `Continue`: Display the error message and continue executing the script. This is the default.\r\n- `SilentlyContinue`: Suppress the error message (so it is not written to the error stream) and continue executing the script.\r\n- `Ignore`: Suppress the error message and continue executing the script. Unlike SilentlyContinue, Ignore doesn't add the error message to the $Error automatic variable.\r\n- `Inquire`: Display the error message and prompt the user to continue or stop executing the script.\r\n- `Break`: Display the error message and enter the debugger. Also breaks into the debugger when a terminating error occurs.\r\n\r\nYou can set the global behaviour for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified.", + "TipText": "The `-ErrorAction` common parameter allows you to change what happens when a non-terminating error occurs in a cmdlet or script, such as when `Write-Error` is used. The default behavior is to display an error message and continue executing the script. You can change this behavior to:\r\n\r\n- `Stop`: Display the error message and stop executing the script. That is, treat it as a terminating error.\r\n- `Continue`: Display the error message and continue executing the script. This is the default.\r\n- `SilentlyContinue`: Suppress the error message (so it is not written to the error stream) and continue executing the script.\r\n- `Ignore`: Suppress the error message and continue executing the script. Unlike SilentlyContinue, Ignore doesn't add the error message to the $Error automatic variable.\r\n- `Inquire`: Display the error message and prompt the user to continue or stop executing the script.\r\n- `Break`: Display the error message and enter the debugger. Also breaks into the debugger when a terminating error occurs.\r\n\r\nYou can set the global behavior for the current scope by setting the `$ErrorActionPreference` variable. This will be the default value for all cmdlets called that don't have the `-ErrorAction` parameter specified.", "Example": "function Test-ErrorAction {\r\n [CmdletBinding()] # This attribute is required to use the `-ErrorAction` common parameter.\r\n param()\r\n\r\n Write-Error \"This is an error message\"\r\n}\r\n\r\nTest-ErrorAction # Displays the error message and continues executing the script.\r\nTest-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script.\r\n\r\n$ErrorActionPreference = \"SilentlyContinue\" # Sets the global error action preference to suppress error messages.\r\nTest-ErrorAction # Suppresses the error message and continues executing the script, because the global setting is SilentlyContinue.\r\nTest-ErrorAction -ErrorAction Stop # Displays the error message and stops executing the script, because the `-ErrorAction` parameter overrides the global setting.", "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-erroraction", @@ -815,5 +815,18 @@ "Category": 6, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2024-11-27T00:00:00", + "Title": "Use ErrorVariable to save cmdlet errors to a variable", + "TipText": "When running a cmdlet in PowerShell, you can use the `-ErrorVariable` parameter to save any errors that occur during the cmdlet's execution to a variable. This can be useful for capturing errors and handling them programmatically. There is also a `-WarningVariable` parameter that works similarly for warnings.\r\n\r\nYou can also couple these with the `-ErrorAction` and `-WarningAction` common parameters to control how errors and warnings are handled. For example, you can set `-ErrorAction` to `SilentlyContinue` to suppress errors from being displayed on the console, while still capturing them in the error variable.", + "Example": "function Test-ErrorVariable {\r\n [CmdletBinding()] # This attribute is required to use the `-ErrorVariable` common parameter.\r\n param()\r\n\r\n Write-Error \"This is an error message that should be IGNORED\"\r\n Write-Error \"This is another error message\"\r\n}\r\n\r\n# You don't need to initialize the error and warning variable, but it's a good practice.\r\n$errors = @()\r\n$warnings = @()\r\n\r\n# Use ErrorAction SilentlyContinue to suppress errors from being displayed on the console while still capturing them in the errors variable.\r\nTest-ErrorVariable -WarningVariable warnings -ErrorVariable errors -ErrorAction SilentlyContinue\r\n\r\nif ($errors) {\r\n # Here you can inspect the errors and handle them as needed.\r\n $errors | ForEach-Object {\r\n if ($_ -like '*IGNORED*') {\r\n Write-Verbose \"Ignoring error: $_\"\r\n } else {\r\n Write-Error \"Error: $_\"\r\n }\r\n }\r\n}", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-errorvariable", + "https://stuart-moore.com/powershell-using-errorvariable-and-warningvariable/" + ], + "Category": 8, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Your name and/or username" } ] From e4798a325c6245899b8c16e9b9c18305c4a3b391 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 21:47:07 -0600 Subject: [PATCH 011/217] tip: Finish filling in tip fields --- ...-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 index b5babd0e..b2e8eab6 100644 --- a/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 +++ b/src/PowerShellTips/2024-11-27-use-errorvariable-to-save-cmdlet-errors-to-a-variable.ps1 @@ -37,8 +37,8 @@ $tip.Urls = @( 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-errorvariable' 'https://stuart-moore.com/powershell-using-errorvariable-and-warningvariable/' ) -$tip.Category = [tiPS.TipCategory]::Other # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. -$tip.Author = 'Your name and/or username' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +$tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. #$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. # Category meanings: From 9bdb93d0f179c7ee7d5b8e94b1c63bcd4f2e01d9 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 27 Nov 2024 21:49:26 -0600 Subject: [PATCH 012/217] chore: Regenerate tips json file --- src/tiPS/PowerShellTips.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 35d4ae43..fed4b1fd 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -825,8 +825,8 @@ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters#-errorvariable", "https://stuart-moore.com/powershell-using-errorvariable-and-warningvariable/" ], - "Category": 8, + "Category": 6, "ExpiryDate": "9999-12-31T23:59:59.9999999", - "Author": "Your name and/or username" + "Author": "Daniel Schroeder (deadlydog)" } ] From 74203ca4502eef6ed90a546a3e3634df59776b07 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 26 Dec 2024 22:22:31 -0600 Subject: [PATCH 013/217] tip: Add tip for PowerShell Summit --- ...d-the-powershell--devops-global-summit.ps1 | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/PowerShellTips/2024-12-26-attend-the-powershell--devops-global-summit.ps1 diff --git a/src/PowerShellTips/2024-12-26-attend-the-powershell--devops-global-summit.ps1 b/src/PowerShellTips/2024-12-26-attend-the-powershell--devops-global-summit.ps1 new file mode 100644 index 00000000..e93ce730 --- /dev/null +++ b/src/PowerShellTips/2024-12-26-attend-the-powershell--devops-global-summit.ps1 @@ -0,0 +1,28 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-12-26') +$tip.Title = 'Attend the PowerShell + DevOps Global Summit' +$tip.TipText = @' +The PowerShell + DevOps Global Summit happens every year somewhere in the United States, usually in April. The conference is a great place to learn about PowerShell and DevOps, and to meet and network with other people in the PowerShell community, including Microsoft MVPs and the Microsoft PowerShell team. Discuss the latest trends, best practices, and tips and tricks with other PowerShell enthusiasts! + +Want to speak at the conference? The call for speakers is typically open during October and November, where you can submit your session ideas for consideration. Speakers often receive a free ticket to the conference and sometimes additional reimbursement. It's a great opportunity to share your knowledge with the community. + +Check the website for the latest information on the conference dates, location, sessions, and registration details. +'@ +$tip.Example = 'Start-Process https://www.powershellsummit.org' +$tip.Urls = @( + 'https://www.powershellsummit.org' +) +$tip.Category = [tiPS.TipCategory]::Community # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 44a69dbe6f5ad894e2d5c16db37a29c409df2111 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 26 Dec 2024 22:43:30 -0600 Subject: [PATCH 014/217] tip: Add tip for the VSTeam module for Azure DevOps --- ...utomate-azure-devops-tasks-with-vsteam.ps1 | 38 +++++++++++++++++++ src/tiPS/PowerShellTips.json | 26 +++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/PowerShellTips/2024-12-26-automate-azure-devops-tasks-with-vsteam.ps1 diff --git a/src/PowerShellTips/2024-12-26-automate-azure-devops-tasks-with-vsteam.ps1 b/src/PowerShellTips/2024-12-26-automate-azure-devops-tasks-with-vsteam.ps1 new file mode 100644 index 00000000..70767cad --- /dev/null +++ b/src/PowerShellTips/2024-12-26-automate-azure-devops-tasks-with-vsteam.ps1 @@ -0,0 +1,38 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2024-12-26') +$tip.Title = 'Automate Azure DevOps tasks with VSTeam' +$tip.TipText = @' +Many organizations use Azure DevOps as their application lifecycle management (ALM) tool. VSTeam is a PowerShell module that provides cmdlets for many Azure DevOps tasks, which can be easier than calling the Azure DevOps APIs directly. It's a great way to simplify and automate many Azure DevOps tasks, such as retrieving and updating work items, teams, git repos, pull requests, release definitions, and more. +'@ +$tip.Example = @' +# List all commits in the demo project for a specific repository. +Get-VSTeamGitCommit -ProjectName demo -RepositoryId 118C262F-0D4C-4B76-BD9B-7DD8CA12F196 + +# List of all agent pools. +Get-VSTeamPool + +# Gets work items with IDs 47 and 48. +Get-VSTeamWorkItem -Id 47,48 + +# Updates the title of work item 1. +Update-VSTeamWorkItem -WorkItemId 1 -Title "Updated Work Item Title" +'@ +$tip.Urls = @( + 'https://methodsandpractices.github.io/vsteam-docs/' + 'https://methodsandpractices.github.io/vsteam-docs/docs/modules/vsteam/commands/' + 'https://github.com/MethodsAndPractices/vsteam-docs' +) +$tip.Category = [tiPS.TipCategory]::Module # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index fed4b1fd..d154de46 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -828,5 +828,31 @@ "Category": 6, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2024-12-26T00:00:00", + "Title": "Attend the PowerShell + DevOps Global Summit", + "TipText": "The PowerShell + DevOps Global Summit happens every year somewhere in the United States, usually in April. The conference is a great place to learn about PowerShell and DevOps, and to meet and network with other people in the PowerShell community, including Microsoft MVPs and the Microsoft PowerShell team. Discuss the latest trends, best practices, and tips and tricks with other PowerShell enthusiasts!\r\n\r\nWant to speak at the conference? The call for speakers is typically open during October and November, where you can submit your session ideas for consideration. Speakers often receive a free ticket to the conference and sometimes additional reimbursement. It's a great opportunity to share your knowledge with the community.\r\n\r\nCheck the website for the latest information on the conference dates, location, sessions, and registration details.", + "Example": "Start-Process https://www.powershellsummit.org", + "Urls": [ + "https://www.powershellsummit.org" + ], + "Category": 0, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2024-12-26T00:00:00", + "Title": "Automate Azure DevOps tasks with VSTeam", + "TipText": "Many organizations use Azure DevOps as their application lifecycle management (ALM) tool. VSTeam is a PowerShell module that provides cmdlets for many Azure DevOps tasks, which can be easier than calling the Azure DevOps APIs directly. It's a great way to simplify and automate many Azure DevOps tasks, such as retrieving and updating work items, teams, git repos, pull requests, release definitions, and more.", + "Example": "# List all commits in the demo project for a specific repository.\r\nGet-VSTeamGitCommit -ProjectName demo -RepositoryId 118C262F-0D4C-4B76-BD9B-7DD8CA12F196\r\n\r\n# List of all agent pools.\r\nGet-VSTeamPool\r\n\r\n# Gets work items with IDs 47 and 48.\r\nGet-VSTeamWorkItem -Id 47,48\r\n\r\n# Updates the title of work item 1.\r\nUpdate-VSTeamWorkItem -WorkItemId 1 -Title \"Updated Work Item Title\"", + "Urls": [ + "https://methodsandpractices.github.io/vsteam-docs/", + "https://methodsandpractices.github.io/vsteam-docs/docs/modules/vsteam/commands/", + "https://github.com/MethodsAndPractices/vsteam-docs" + ], + "Category": 2, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 4037b4ae66edd17f4bb71f1e745159972ac4767e Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 8 Jan 2025 14:41:34 -0600 Subject: [PATCH 015/217] tip: Add tip for Start-Transcript --- ...anscript-for-a-quick-and-easy-log-file.ps1 | 43 +++++++++++++++++++ src/tiPS/PowerShellTips.json | 14 ++++++ 2 files changed, 57 insertions(+) create mode 100644 src/PowerShellTips/2025-01-08-use-start-transcript-for-a-quick-and-easy-log-file.ps1 diff --git a/src/PowerShellTips/2025-01-08-use-start-transcript-for-a-quick-and-easy-log-file.ps1 b/src/PowerShellTips/2025-01-08-use-start-transcript-for-a-quick-and-easy-log-file.ps1 new file mode 100644 index 00000000..3bfcf78b --- /dev/null +++ b/src/PowerShellTips/2025-01-08-use-start-transcript-for-a-quick-and-easy-log-file.ps1 @@ -0,0 +1,43 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-01-08') +$tip.Title = 'Use Start-Transcript for a quick and easy log file' +$tip.TipText = @' +You can use the Start-Transcript cmdlet to easily create a log file of your PowerShell session. This is useful for keeping a record of what you did during an interactive session, or in your scripts to log any output for troubleshooting purposes. + +If you do not specify the log file path, the log file will be created in the user's Home/Documents directory with a timestamped filename. The log file will remain locked by the PowerShell process until Stop-Transcript is called, so be sure to call Stop-Transcript when you are done. + +It is often preferable to log output to a central logging system, however, that often requires much more code and may be overkill for some scenarios. Logging to a local file with Start-Transcript is a quick and easy alternative to capture output for later reference. +'@ +$tip.Example = @' +try { + # Log all script output to a file for easy reference later if needed. + # $PSCommandPath will be the file path of the PowerShell script that is running. + # Include the date and time in the log file name to make it unique instead of overwriting it every run. + [string] $lastRunLogFilePath = "$PSCommandPath.LastRun.log" + Start-Transcript -Path $lastRunLogFilePath + + # Put your script code here... +} +finally { + Stop-Transcript +} +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.host/start-transcript' + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.host/stop-transcript' + 'https://lazyadmin.nl/powershell/start-transcript/' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index d154de46..ce008ffb 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -854,5 +854,19 @@ "Category": 2, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-01-08T00:00:00", + "Title": "Use Start-Transcript for a quick and easy log file", + "TipText": "You can use the Start-Transcript cmdlet to easily create a log file of your PowerShell session. This is useful for keeping a record of what you did during an interactive session, or in your scripts to log any output for troubleshooting purposes.\r\n\r\nIf you do not specify the log file path, the log file will be created in the user's Home/Documents directory with a timestamped filename. The log file will remain locked by the PowerShell process until Stop-Transcript is called, so be sure to call Stop-Transcript when you are done.\r\n\r\nIt is often preferable to log output to a central logging system, however, that often requires much more code and may be overkill for some scenarios. Logging to a local file with Start-Transcript is a quick and easy alternative to capture output for later reference.", + "Example": "try {\r\n # Log all script output to a file for easy reference later if needed.\r\n # $PSCommandPath will be the file path of the PowerShell script that is running.\r\n # Include the date and time in the log file name to make it unique instead of overwriting it every run.\r\n [string] $lastRunLogFilePath = \"$PSCommandPath.LastRun.log\"\r\n Start-Transcript -Path $lastRunLogFilePath\r\n\r\n # Put your script code here...\r\n}\r\nfinally {\r\n Stop-Transcript\r\n}", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.host/start-transcript", + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.host/stop-transcript", + "https://lazyadmin.nl/powershell/start-transcript/" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 31c4a90a780c351355f4525e3dd03f32848fdc99 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Tue, 11 Feb 2025 17:48:43 -0600 Subject: [PATCH 016/217] chore: Automatically assign labels to bugs and feature requests --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 587a7d61..a616dc63 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: 'Bug: ' -labels: '' +labels: ["bug"] assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7a147e04..f215b9fe 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: 'Feature Request: ' -labels: '' +labels: ["enhancement"] assignees: '' --- From e5beaede1d8f887d0d1be6d28ef314f004c90040 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Tue, 11 Feb 2025 21:38:17 -0600 Subject: [PATCH 017/217] docs: Update emojis --- ReadMe.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index b0801172..a007702e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -47,7 +47,7 @@ This module brings tips to you with minimal effort required on your part. You can configure tiPS to show a tip every time you open your PowerShell terminal, or show a tip on demand by running the `tips` command. -## 🖼 Screenshots +## 🖼️ Screenshots Calling the `tips` command to show a tip in the terminal: @@ -89,7 +89,7 @@ Add-TiPSImportToPowerShellProfile > You can remove the import statement from your PowerShell profile by running the `Remove-TiPSImportFromPowerShellProfile` command. -### ⚙ Recommended configuration +### ⚙️ Recommended configuration The following configuration is a good balance for displaying new tips automatically and not being overwhelmed by them. @@ -140,7 +140,7 @@ Possible values for the `-AutomaticallyWritePowerShellTip` parameter are `Never` Tips will only be automatically shown in interactive PowerShell sessions. This prevents them from appearing unexpectedly when running scripts or other automated processes. -### ⬆ Automatic updates +### ⬆️ Automatic updates New tips are obtained by updating the tiPS module. Instead of remembering to manually update the module, you can have the module automatically update itself by running: @@ -209,7 +209,7 @@ tiPS is meant to be a community driven project, so please help make it better by Issues, Discussions, and Pull Requests are welcome. See [the Contributing page](/docs/Contributing.md) for more details. -## 🛣 Roadmap +## 🛣️ Roadmap Below is a short list of planned enhancements for tiPS: @@ -224,7 +224,7 @@ Have other ideas? See what's changed in the module over time by viewing [the changelog](Changelog.md). -## ❤ Donate to support this project +## ❤️ Donate to support this project Buy me a bagel for providing this module open source and for free 🙂 From c0c18ca2c5a26f6d73cd1819e05d35d5ff971b84 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Mon, 17 Mar 2025 21:12:14 -0600 Subject: [PATCH 018/217] tip: Add Update-TypeData tip --- ...s-with-your-own-properties-and-methods.ps1 | 57 +++++++++++++++++++ src/tiPS/PowerShellTips.json | 14 +++++ 2 files changed, 71 insertions(+) create mode 100644 src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 diff --git a/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 b/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 new file mode 100644 index 00000000..e5f7cc95 --- /dev/null +++ b/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 @@ -0,0 +1,57 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-03-17') +$tip.Title = 'Extend types with your own properties and methods' +$tip.TipText = @' +The `Update-TypeData` cmdlet can be used to add custom properties and methods to a type. This is useful when you want to extend the functionality of a type that you did not define, such as a built-in .NET class. + +The `Update-TypeData` cmdlet has a `-MemberType` parameter that can be used to specify the type of member to add. The most common types are `NoteProperty` and `ScriptMethod`. The `NoteProperty` type is used to add a new property to an object, while the `ScriptMethod` type is used to add a method to an object to perform some action. + +This is similar to using the `Add-Member` cmdlet, but `Update-TypeData` modifies the type data for all instances of the type, while `Add-Member` modifies only the instance you used it on. +'@ +$tip.Example = @' +# Define the new function logic that we want add to the type. +[scriptblock] $GetValueOrDefaultFunction = { + param($key, $defaultValue) + if ($this.ContainsKey($key)) { + $this[$key] + } else { + $defaultValue + } +} + +# Define that we want to add the new method to the Hashtable type, and call it GetValueOrDefault. +$extendedTypeData = @{ + TypeName = 'System.Collections.Hashtable' + MemberType = 'ScriptMethod' + MemberName = 'GetValueOrDefault' + Value = $GetValueOrDefaultFunction +} + +# Add the new method to the Hashtable type, via splatting. +Update-TypeData @extendedTypeData + +# Now we can use the new method on any Hashtable object. +[hashtable] $myHashTable = @{ 'key1' = 'value1' } +$myHashTable.GetValueOrDefault('key1', 'unknown') # Returns 'value1'. +$myHashTable.GetValueOrDefault('key2', 'unknown') # Returns 'unknown'. +$myHashTable['key2'] # Returns $null. +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/update-typedata' + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes_properties#defining-instance-properties-with-update-typedata' + 'https://x.com/blackboxcoder/status/1716585384102985949?t=-Ox1iPV67-4Vqb8wIZ275A' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index ce008ffb..30d5d1bf 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -868,5 +868,19 @@ "Category": 3, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-03-17T00:00:00", + "Title": "Extend types with your own properties and methods", + "TipText": "The `Update-TypeData` cmdlet can be used to add custom properties and methods to a type. This is useful when you want to extend the functionality of a type that you did not define, such as a built-in .NET class.\r\n\r\nThe `Update-TypeData` cmdlet has a `-MemberType` parameter that can be used to specify the type of member to add. The most common types are `NoteProperty` and `ScriptMethod`. The `NoteProperty` type is used to add a new property to an object, while the `ScriptMethod` type is used to add a method to an object to perform some action.\r\n\r\nThis is similar to using the `Add-Member` cmdlet, but `Update-TypeData` modifies the type data for all instances of the type, while `Add-Member` modifies only the instance you used it on.", + "Example": "# Define the new function logic that we want add to the type.\r\n[scriptblock] $GetValueOrDefaultFunction = {\r\n param($key, $defaultValue)\r\n if ($this.ContainsKey($key)) {\r\n $this[$key]\r\n } else {\r\n $defaultValue\r\n }\r\n}\r\n\r\n# Define that we want to add the new method to the Hashtable type, and call it GetValueOrDefault.\r\n$extendedTypeData = @{\r\n TypeName = 'System.Collections.Hashtable'\r\n MemberType = 'ScriptMethod'\r\n MemberName = 'GetValueOrDefault'\r\n Value = $GetValueOrDefaultFunction\r\n}\r\n\r\n# Add the new method to the Hashtable type, via splatting.\r\nUpdate-TypeData @extendedTypeData\r\n\r\n# Now we can use the new method on any Hashtable object.\r\n[hashtable] $myHashTable = @{ 'key1' = 'value1' }\r\n$myHashTable.GetValueOrDefault('key1', 'unknown') # Returns 'value1'.\r\n$myHashTable.GetValueOrDefault('key2', 'unknown') # Returns 'unknown'.\r\n$myHashTable['key2'] # Returns $null.", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/update-typedata", + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes_properties#defining-instance-properties-with-update-typedata", + "https://x.com/blackboxcoder/status/1716585384102985949?t=-Ox1iPV67-4Vqb8wIZ275A" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 1f3229bf1ddd674494dd4ad181bdc0f95ee576fa Mon Sep 17 00:00:00 2001 From: deadlydog Date: Mon, 17 Mar 2025 21:27:38 -0600 Subject: [PATCH 019/217] tip: Update example code a bit --- ...3-17-extend-types-with-your-own-properties-and-methods.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 b/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 index e5f7cc95..b195c8cf 100644 --- a/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 +++ b/src/PowerShellTips/2025-03-17-extend-types-with-your-own-properties-and-methods.ps1 @@ -13,9 +13,9 @@ $tip.Example = @' [scriptblock] $GetValueOrDefaultFunction = { param($key, $defaultValue) if ($this.ContainsKey($key)) { - $this[$key] + return $this[$key] } else { - $defaultValue + return $defaultValue } } From a2db860646cb733cfb87ec39998d16233a2acdd5 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Mon, 17 Mar 2025 21:32:35 -0600 Subject: [PATCH 020/217] tip: Add null-coelescing operators tip --- ...cks-with-the-null-coalescing-operators.ps1 | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/PowerShellTips/2025-03-17-avoid-null-checks-with-the-null-coalescing-operators.ps1 diff --git a/src/PowerShellTips/2025-03-17-avoid-null-checks-with-the-null-coalescing-operators.ps1 b/src/PowerShellTips/2025-03-17-avoid-null-checks-with-the-null-coalescing-operators.ps1 new file mode 100644 index 00000000..35e658ec --- /dev/null +++ b/src/PowerShellTips/2025-03-17-avoid-null-checks-with-the-null-coalescing-operators.ps1 @@ -0,0 +1,54 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-03-17') +$tip.Title = 'Avoid null checks with the null-coalescing operators' +$tip.TipText = @' +PowerShell 7 introduced the null-coalescing operators `??` and `??=`. These operators allow you to simplify your code by avoiding explicit null checks. + +The null-coalescing operator `??` returns the left-hand operand if it is not null; otherwise, it returns the right-hand operand. This is useful for providing default values. + +The null-coalescing assignment operator `??=` assigns the right-hand operand to the left-hand operand only if the left-hand operand is null. This is useful to help ensure a variable has a value. +'@ +$tip.Example = @' +# Example of using the null-coalescing operator. +$nullValue = $null +$realValue = 'Real Value' +$defaultValue = 'Default Value' +$result = $nullValue ?? $defaultValue # $result will be 'Default Value'. +$result = $realValue ?? $defaultValue # $result will be 'Real Value'. + +# Example of using the null-coalescing assignment operator. +$existingValue = $null +$existingValue ??= 'Assigned Value' # $existingValue will be 'Assigned Value'. +$existingValue ??= 'Another Value' # $existingValue will still be 'Assigned Value'. + +# Example of using the null-coalescing operator with a function. +function Get-Value { + param ([string]$inputValue) + return $inputValue ?? 'No Value Provided' +} + +# Example of using the null-coalescing assignment operator with a function. +function Set-Value { + param ([string]$inputValue) + $inputValue ??= 'Default Value' + return $inputValue +} +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#null-coalescing-operator-' + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#null-coalescing-assignment-operator-' +) +$tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 9c110c84f6666b7e0439074b1edb3a78aaa7fdaf Mon Sep 17 00:00:00 2001 From: deadlydog Date: Mon, 17 Mar 2025 21:33:08 -0600 Subject: [PATCH 021/217] chore: Run build task to generate new tips json file --- src/tiPS/PowerShellTips.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 30d5d1bf..d85f9eee 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -869,11 +869,24 @@ "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" }, + { + "CreatedDate": "2025-03-17T00:00:00", + "Title": "Avoid null checks with the null-coalescing operators", + "TipText": "PowerShell 7 introduced the null-coalescing operators `??` and `??=`. These operators allow you to simplify your code by avoiding explicit null checks.\r\n\r\nThe null-coalescing operator `??` returns the left-hand operand if it is not null; otherwise, it returns the right-hand operand. This is useful for providing default values.\r\n\r\nThe null-coalescing assignment operator `??=` assigns the right-hand operand to the left-hand operand only if the left-hand operand is null. This is useful to help ensure a variable has a value.", + "Example": "# Example of using the null-coalescing operator.\r\n$nullValue = $null\r\n$realValue = 'Real Value'\r\n$defaultValue = 'Default Value'\r\n$result = $nullValue ?? $defaultValue # $result will be 'Default Value'.\r\n$result = $realValue ?? $defaultValue # $result will be 'Real Value'.\r\n\r\n# Example of using the null-coalescing assignment operator.\r\n$existingValue = $null\r\n$existingValue ??= 'Assigned Value' # $existingValue will be 'Assigned Value'.\r\n$existingValue ??= 'Another Value' # $existingValue will still be 'Assigned Value'.\r\n\r\n# Example of using the null-coalescing operator with a function.\r\nfunction Get-Value {\r\n\tparam ([string]$inputValue)\r\n\treturn $inputValue ?? 'No Value Provided'\r\n}\r\n\r\n# Example of using the null-coalescing assignment operator with a function.\r\nfunction Set-Value {\r\n\tparam ([string]$inputValue)\r\n\t$inputValue ??= 'Default Value'\r\n\treturn $inputValue\r\n}", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#null-coalescing-operator-", + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators#null-coalescing-assignment-operator-" + ], + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, { "CreatedDate": "2025-03-17T00:00:00", "Title": "Extend types with your own properties and methods", "TipText": "The `Update-TypeData` cmdlet can be used to add custom properties and methods to a type. This is useful when you want to extend the functionality of a type that you did not define, such as a built-in .NET class.\r\n\r\nThe `Update-TypeData` cmdlet has a `-MemberType` parameter that can be used to specify the type of member to add. The most common types are `NoteProperty` and `ScriptMethod`. The `NoteProperty` type is used to add a new property to an object, while the `ScriptMethod` type is used to add a method to an object to perform some action.\r\n\r\nThis is similar to using the `Add-Member` cmdlet, but `Update-TypeData` modifies the type data for all instances of the type, while `Add-Member` modifies only the instance you used it on.", - "Example": "# Define the new function logic that we want add to the type.\r\n[scriptblock] $GetValueOrDefaultFunction = {\r\n param($key, $defaultValue)\r\n if ($this.ContainsKey($key)) {\r\n $this[$key]\r\n } else {\r\n $defaultValue\r\n }\r\n}\r\n\r\n# Define that we want to add the new method to the Hashtable type, and call it GetValueOrDefault.\r\n$extendedTypeData = @{\r\n TypeName = 'System.Collections.Hashtable'\r\n MemberType = 'ScriptMethod'\r\n MemberName = 'GetValueOrDefault'\r\n Value = $GetValueOrDefaultFunction\r\n}\r\n\r\n# Add the new method to the Hashtable type, via splatting.\r\nUpdate-TypeData @extendedTypeData\r\n\r\n# Now we can use the new method on any Hashtable object.\r\n[hashtable] $myHashTable = @{ 'key1' = 'value1' }\r\n$myHashTable.GetValueOrDefault('key1', 'unknown') # Returns 'value1'.\r\n$myHashTable.GetValueOrDefault('key2', 'unknown') # Returns 'unknown'.\r\n$myHashTable['key2'] # Returns $null.", + "Example": "# Define the new function logic that we want add to the type.\r\n[scriptblock] $GetValueOrDefaultFunction = {\r\n param($key, $defaultValue)\r\n if ($this.ContainsKey($key)) {\r\n return $this[$key]\r\n } else {\r\n return $defaultValue\r\n }\r\n}\r\n\r\n# Define that we want to add the new method to the Hashtable type, and call it GetValueOrDefault.\r\n$extendedTypeData = @{\r\n TypeName = 'System.Collections.Hashtable'\r\n MemberType = 'ScriptMethod'\r\n MemberName = 'GetValueOrDefault'\r\n Value = $GetValueOrDefaultFunction\r\n}\r\n\r\n# Add the new method to the Hashtable type, via splatting.\r\nUpdate-TypeData @extendedTypeData\r\n\r\n# Now we can use the new method on any Hashtable object.\r\n[hashtable] $myHashTable = @{ 'key1' = 'value1' }\r\n$myHashTable.GetValueOrDefault('key1', 'unknown') # Returns 'value1'.\r\n$myHashTable.GetValueOrDefault('key2', 'unknown') # Returns 'unknown'.\r\n$myHashTable['key2'] # Returns $null.", "Urls": [ "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/update-typedata", "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes_properties#defining-instance-properties-with-update-typedata", From 63f47016c9103bf3a48ea7b61a97377ead700c6f Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 26 Mar 2025 22:03:41 -0600 Subject: [PATCH 022/217] feat: Add VS Code task to run CSpell locally, and ignore files in /bin and /obj directories --- .cspell.json | 4 +++- .vscode/tasks.json | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index f67e1152..fdd1fb7b 100644 --- a/.cspell.json +++ b/.cspell.json @@ -9,7 +9,9 @@ ".devcontainer/devcontainer.json", ".github/workflows/build-and-test-powershell-module.yml", ".github/workflows/build-test-and-deploy-powershell-module.yml", - "src/tiPS/PowerShellTips.json" + "src/tiPS/PowerShellTips.json", + "**/bin/**", + "**/obj/**" ], "words": [ "colours", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 4afda726..9ba1a31b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -10,6 +10,7 @@ }, "dependsOn": [ "Run PSScriptAnalyzer linter", + "Run CSpell spell checker", "Convert PowerShellTips files to JSON file" ] }, @@ -47,6 +48,30 @@ "$func-powershell-watch" ] }, + { + "label": "Run CSpell spell checker", + "type": "shell", + "options": { + "shell": { + "executable": "pwsh", + "args": [ + "-NoProfile", + "-Command" + ] + } + }, + "command": "try { & npx -v > $null } catch {}; if ($?) { & npx cspell . } else { Write-Warning 'Node.js is not installed, so cannot download and run npx cspell.' }", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "dedicated", + "clear": true, + "group": "build" + }, + "problemMatcher": [ + "$func-powershell-watch" + ] + }, { "label": "Convert PowerShellTips files to JSON file", "type": "shell", From 9ac31e7b4ae3d1089a53bc9585016452972a130f Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 26 Mar 2025 22:13:07 -0600 Subject: [PATCH 023/217] chore: Add comments --- .cspell.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cspell.json b/.cspell.json index fdd1fb7b..d0a8edfe 100644 --- a/.cspell.json +++ b/.cspell.json @@ -10,8 +10,8 @@ ".github/workflows/build-and-test-powershell-module.yml", ".github/workflows/build-test-and-deploy-powershell-module.yml", "src/tiPS/PowerShellTips.json", - "**/bin/**", - "**/obj/**" + "**/bin/**", // Ignore C# build output files. + "**/obj/**" // Ignore C# build output files. ], "words": [ "colours", From efb20ccb874d758606d5a86a282fd9d1c4b566dd Mon Sep 17 00:00:00 2001 From: deadlydog Date: Wed, 26 Mar 2025 22:16:21 -0600 Subject: [PATCH 024/217] docs: Update docs to mention CSpell VS code task --- docs/Contributing.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Contributing.md b/docs/Contributing.md index e1ee956c..1917fdef 100644 --- a/docs/Contributing.md +++ b/docs/Contributing.md @@ -72,6 +72,8 @@ The build process performs the following operations: 1. Generate the PowerShellTips.json file from the files in the PowerShellTips directory. 1. [This ADR](/docs/ArchitectureDecisionRecords/004-Save-all-tips-to-a-single-file.md) explains why we save all of the tips to a single file. 1. Run the PSScriptAnalyzer linter on all of the PowerShell files. +1. Run the CSpell spell checker on all files to find any spelling mistakes. + 1. If CSpell flags a word that is not actually misspelled, you can add it to the `.cspell.json` file in the root of the repository. 1. (Pipeline build only) Concatenate all of the PowerShell file contents into the psm1 file, and delete the ps1 files. 1. [This ADR](/docs/ArchitectureDecisionRecords/005-How-to-dot-source-files-into-the-module-psm1-file.md) explains why we concatenate the files into the psm1 file. From ad8d69ec6f2db63559b2ae59fe6a13013328256d Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 06:08:34 +0000 Subject: [PATCH 025/217] chore: Update devcontainer to use latest image version and install CSpell --- .devcontainer/devcontainer.json | 7 ++++--- .gitignore | 6 +++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 732cf6c7..5c77bc2f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,7 @@ { "name": "PowerShell", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/powershell:lts-debian-11", + "image": "mcr.microsoft.com/dotnet/sdk:9.0", "features": { "ghcr.io/devcontainers/features/common-utils:2": { "installZsh": "true", @@ -11,10 +11,11 @@ "upgradePackages": "false", "nonFreePackages": "true" }, - "ghcr.io/devcontainers/features/dotnet:2": "latest" + "ghcr.io/devcontainers/features/dotnet:2": "latest" // Installs the dotnet CLI. }, - "postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"; pwsh -c 'install-module Pester -force'; pwsh -c 'install-module PSScriptAnalyzer -force'", + // Set pwsh as the default shell for the devcontainer, install required PowerShell modules, and install NPM. + "postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"; pwsh -c \"Install-Module Pester -Force\"; pwsh -c \"Install-Module PSScriptAnalyzer -Force\"; sudo apt update; sudo DEBIAN_FRONTEND=noninteractive apt install -y npm; npm install cspell", // Configure tool-specific properties. "customizations": { diff --git a/.gitignore b/.gitignore index fc344c6f..be06620f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ -# Ignore Pester code coverage report file +# Ignore Pester code coverage report file. coverage.xml +# Ignore NPM files. +package-lock.json +package.json + # Created by https://www.gitignore.io/api/powershell,visualstudio,visualstudiocode # Edit at https://www.gitignore.io/?templates=powershell,visualstudio,visualstudiocode From ba1e0b86c258224739fe7d1e94f0e10b483bfb18 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 00:20:56 -0600 Subject: [PATCH 026/217] chore: Update CSpell task to be more resilient and install CSpell if needed --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9ba1a31b..3d490f1a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -60,7 +60,7 @@ ] } }, - "command": "try { & npx -v > $null } catch {}; if ($?) { & npx cspell . } else { Write-Warning 'Node.js is not installed, so cannot download and run npx cspell.' }", + "command": "try { & npx -v > $null } catch {}; if (-not $?) { Write-Warning 'Node.js is not installed, so cannot download and run npx cspell.' } else { try { & npx cspell . } catch {}; if (-not $?) { & npm install cspell; & npx cspell . }; if (-not $?) { Write-Warning 'There was a problem installing or running cspell' } }", "group": "build", "presentation": { "reveal": "always", From 2dfe0b7aa23ad890c092341d5e5ab9b938b94775 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 06:31:32 +0000 Subject: [PATCH 027/217] chore: Don't spellcheck the .gitignore --- .cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.cspell.json b/.cspell.json index d0a8edfe..cf11c712 100644 --- a/.cspell.json +++ b/.cspell.json @@ -9,6 +9,7 @@ ".devcontainer/devcontainer.json", ".github/workflows/build-and-test-powershell-module.yml", ".github/workflows/build-test-and-deploy-powershell-module.yml", + ".gitignore", "src/tiPS/PowerShellTips.json", "**/bin/**", // Ignore C# build output files. "**/obj/**" // Ignore C# build output files. From c9c3af5cb54546910d03effaae8d4c7af9c64455 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 00:34:18 -0600 Subject: [PATCH 028/217] chore: Add comment explaining code a bit --- .vscode/tasks.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3d490f1a..f9f05383 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -60,6 +60,7 @@ ] } }, + // If npx is not available, warn that Node.js is not installed. If we cannot run cspell, try to install and run it, and warn if we still cannot run it. "command": "try { & npx -v > $null } catch {}; if (-not $?) { Write-Warning 'Node.js is not installed, so cannot download and run npx cspell.' } else { try { & npx cspell . } catch {}; if (-not $?) { & npm install cspell; & npx cspell . }; if (-not $?) { Write-Warning 'There was a problem installing or running cspell' } }", "group": "build", "presentation": { From 5ff46b1ea05dd09d150e3c4ed2340c7adb9b9c16 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 00:41:46 -0600 Subject: [PATCH 029/217] chore: Update comment --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5c77bc2f..b8fe4e03 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,7 +14,7 @@ "ghcr.io/devcontainers/features/dotnet:2": "latest" // Installs the dotnet CLI. }, - // Set pwsh as the default shell for the devcontainer, install required PowerShell modules, and install NPM. + // Set pwsh as the default shell for the devcontainer, install required PowerShell modules, and install NPM and CSpell. "postCreateCommand": "sudo chsh vscode -s \"$(which pwsh)\"; pwsh -c \"Install-Module Pester -Force\"; pwsh -c \"Install-Module PSScriptAnalyzer -Force\"; sudo apt update; sudo DEBIAN_FRONTEND=noninteractive apt install -y npm; npm install cspell", // Configure tool-specific properties. From cbabd652112b79d9d9ef95700d8ddda02b38d58e Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 23:57:20 -0600 Subject: [PATCH 030/217] feat: Initial issue template for submitting a new tip --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/new_powershell_tip.yml diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml new file mode 100644 index 00000000..e2933844 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -0,0 +1,97 @@ +name: PowerShell Tip Submission +description: Submit a new PowerShell tip to be included in the tiPS module +title: "Tip: " +labels: ["new-tip"] +body: + - type: markdown + attributes: + value: | + THIS FORM DOES NOT WORK YET! IT IS STILL A WORK IN PROGRESS! + Please do not use it yet. It is here for reference only. + + Thanks for submitting a new PowerShell tip! Please fill in all required fields below. + The more information you provide, the easier it will be for us to review and include your tip. + + - type: input + id: title + attributes: + label: Title (required) + description: A concise title for your tip (max 75 characters) + validations: + required: true + + - type: textarea + id: tiptext + attributes: + label: Tip Text (required) + description: Detailed explanation of the tip. Be clear and concise. + validations: + required: true + + - type: textarea + id: example + attributes: + label: Example Code (optional) + description: Provide a working PowerShell example that demonstrates your tip. + render: powershell + value: | + # Your example code here + + - type: dropdown + id: category + attributes: + label: Category (required) + description: Select the category that best fits your tip + options: + - Community (Social events and community resources) + - Editor (Editor tips and extensions) + - Module (Modules and module tips) + - NativeCmdlet (Native cmdlet tips) + - Performance (Tips to improve runtime performance) + - Security (Security tips) + - Syntax (Syntax tips) + - Terminal (Terminal shortcuts and tips) + - Other (Tips that don't fit into any other category) + validations: + required: true + + - type: input + id: url1 + attributes: + label: URL 1 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + + - type: input + id: url2 + attributes: + label: URL 2 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + + - type: input + id: url3 + attributes: + label: URL 3 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + + - type: input + id: author + attributes: + label: Author (optional) + description: Your name and/or username. Leave blank if you prefer to remain anonymous. + placeholder: e.g. Daniel Schroeder (deadlydog) + + - type: textarea + id: additional + attributes: + label: Additional Information + description: Any additional context or information about your tip + + - type: markdown + attributes: + value: | + By submitting this tip, you agree to make it available under the project's license. + The tip's CreatedDate will be set to the date when it's accepted, and ExpiryDate will + be set to the maximum date unless otherwise specified. From 60b75b728c1982574fd5c2bfdd747bb95eb9a021 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Thu, 27 Mar 2025 23:58:35 -0600 Subject: [PATCH 031/217] docs: Mention new tip submission method in ReadMe, but commented out for now until it is ready --- ReadMe.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index a007702e..000ad57f 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -193,7 +193,17 @@ tiPS is open source, and contributions are not only welcome, they are encouraged Have a PowerShell tip you want to share? Know of a great module, blog post, or community event that you think others should know about? + +There are 2 ways to submit your tip to tiPS: +1. Use [the GitHub issue template](https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml) to create a PR for your new tip. + This is the easiest method, but since an app creates the PR, you will not be recorded as the contributor in git. + However, you can still put your name or handle in the tip's `Author` field. +1. Fork the repo and create a PR for your tip the traditional way, by following the steps below. + This method is a bit more work, but you will be recorded as the contributor in git. + +Follow the steps below to fork the repo and manually submit your PR: +--> Follow these steps to add your tip to tiPS: 1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). From 7bc92ef781429017640501328aba8ce850a2e9ba Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 00:24:26 -0600 Subject: [PATCH 032/217] Copilot's initial pass on creating the action --- .../workflows/process-new-powershell-tip.yml | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 .github/workflows/process-new-powershell-tip.yml diff --git a/.github/workflows/process-new-powershell-tip.yml b/.github/workflows/process-new-powershell-tip.yml new file mode 100644 index 00000000..f0f3aa34 --- /dev/null +++ b/.github/workflows/process-new-powershell-tip.yml @@ -0,0 +1,169 @@ +name: Process New PowerShell Tip + +on: + issues: + types: [opened] + +jobs: + process-new-tip: + if: contains(github.event.issue.labels.*.name, 'new-tip') + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup PowerShell + uses: actions/setup-powershell@v1 + with: + powershell-version: '7.2' + + - name: Extract tip information from issue + id: extract-tip + run: | + $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' + $title = $issue.title -replace '^\[TIP\]\s*', '' + $body = $issue.body + + # Parse the issue body to extract fields + $tipTitle = $null + $tipText = $null + $example = $null + $category = $null + $urls = @() + $author = $null + + # Extract data from the JSON representation of the issue + # The structure will depend on the form fields defined in the YAML template + foreach ($item in ($body | ConvertFrom-Json)) { + $id = $item.id + $value = $item.value + + switch ($id) { + 'title' { $tipTitle = $value } + 'tiptext' { $tipText = $value } + 'example' { $example = $value } + 'category' { + # Extract just the category name without description + if ($value -match '^([^(]+)') { + $category = $Matches[1].Trim() + } + } + 'url1' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } + 'url2' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } + 'url3' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } + 'author' { $author = $value } + } + } + + # Set current date as CreatedDate + $createdDate = Get-Date -Format "yyyy-MM-dd" + + # Create file content + $fileContent = @" +# This PowerShell tip was submitted by $author on $createdDate. + +`$PowerShellTip = [tiPS.PowerShellTip]@{ + CreatedDate = [DateTime]::Parse('$createdDate') + Title = '$($tipTitle -replace "'", "''")' + TipText = @' +$tipText +'@ +"@ + + if (-not [string]::IsNullOrWhiteSpace($example)) { + $fileContent += @" + + Example = @' +$example +'@ +"@ + } + + if ($urls.Count -gt 0) { + $fileContent += @" + + Urls = @( +"@ + foreach ($url in $urls) { + $fileContent += @" + '$url' +"@ + } + $fileContent += @" + ) +"@ + } + + $fileContent += @" + + Category = [tiPS.TipCategory]::$category +} +"@ + + # Create branch name and filename + $branchName = "new-tip/issue-$($issue.number)" + $fileName = "$createdDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" + $filePath = "src/PowerShellTips/$fileName" + + # Output variables for next steps + Write-Output "::set-output name=branch_name::$branchName" + Write-Output "::set-output name=file_name::$fileName" + Write-Output "::set-output name=file_path::$filePath" + Write-Output "::set-output name=file_content::$fileContent" + Write-Output "::set-output name=issue_number::$($issue.number)" + Write-Output "::set-output name=tip_title::$tipTitle" + shell: pwsh + + - name: Create branch + run: | + git config --global user.name 'GitHub Action' + git config --global user.email 'action@github.com' + git checkout -b "${{ steps.extract-tip.outputs.branch_name }}" + shell: bash + + - name: Create tip file + run: | + # Ensure directory exists + $directory = Split-Path -Parent "${{ steps.extract-tip.outputs.file_path }}" + if (-not (Test-Path $directory)) { + New-Item -ItemType Directory -Path $directory -Force + } + + # Create the file + Set-Content -Path "${{ steps.extract-tip.outputs.file_path }}" -Value "${{ steps.extract-tip.outputs.file_content }}" + shell: pwsh + + - name: Push changes and create PR + run: | + git add "${{ steps.extract-tip.outputs.file_path }}" + git commit -m "Add new PowerShell tip: ${{ steps.extract-tip.outputs.tip_title }}" + git push --set-upstream origin "${{ steps.extract-tip.outputs.branch_name }}" + + # Create PR + gh pr create \ + --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" \ + --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.extract-tip.outputs.issue_number }}." \ + --label "enhancement" \ + --label "new-tip" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + + - name: Add comment to issue + run: | + gh issue comment "${{ steps.extract-tip.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.extract-tip.outputs.branch_name }} --json number --jq '.[0].number')" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash + + - name: Close issue + run: | + gh issue close "${{ steps.extract-tip.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip." + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: bash From f8f890578aecf2054de27ade4dfdfe207f2f3c3c Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:28:45 -0600 Subject: [PATCH 033/217] Rearrange issue fields and add Expiry Date --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index e2933844..43186d58 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -21,7 +21,7 @@ body: required: true - type: textarea - id: tiptext + id: tipText attributes: label: Tip Text (required) description: Detailed explanation of the tip. Be clear and concise. @@ -37,24 +37,6 @@ body: value: | # Your example code here - - type: dropdown - id: category - attributes: - label: Category (required) - description: Select the category that best fits your tip - options: - - Community (Social events and community resources) - - Editor (Editor tips and extensions) - - Module (Modules and module tips) - - NativeCmdlet (Native cmdlet tips) - - Performance (Tips to improve runtime performance) - - Security (Security tips) - - Syntax (Syntax tips) - - Terminal (Terminal shortcuts and tips) - - Other (Tips that don't fit into any other category) - validations: - required: true - - type: input id: url1 attributes: @@ -76,6 +58,24 @@ body: description: URL with additional information (must start with http:// or https://) placeholder: https://example.com + - type: dropdown + id: category + attributes: + label: Category (required) + description: Select the category that best fits your tip + options: + - Community (Social events and community resources) + - Editor (Editor tips and extensions) + - Module (Modules and module tips) + - NativeCmdlet (Native cmdlet tips) + - Performance (Tips to improve runtime performance) + - Security (Security tips) + - Syntax (Syntax tips) + - Terminal (Terminal shortcuts and tips) + - Other (Tips that don't fit into any other category) + validations: + required: true + - type: input id: author attributes: @@ -84,10 +84,11 @@ body: placeholder: e.g. Daniel Schroeder (deadlydog) - type: textarea - id: additional + id: expiryDate attributes: - label: Additional Information - description: Any additional context or information about your tip + label: Expiry Date (optional) + description: Date when the tip should expire (format of YYYY-MM-DD). Mostly applicable when promoting a community event on a specific date. Leave blank for no expiry. + placeholder: YYYY-MM-DD - type: markdown attributes: From 01259ae59b71b315af19d3e7e79efa8416cbb1ce Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:29:46 -0600 Subject: [PATCH 034/217] fix: Fix up the process new PowerShell tip workflow, and add utility function for getting the file contents --- .../ProcessNewPowerShellTipIssueFunctions.ps1 | 56 ++++++++++ ...l => process-new-powershell-tip-issue.yml} | 103 ++++++------------ 2 files changed, 92 insertions(+), 67 deletions(-) create mode 100644 .github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 rename .github/workflows/{process-new-powershell-tip.yml => process-new-powershell-tip-issue.yml} (70%) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 new file mode 100644 index 00000000..92fa1bdf --- /dev/null +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -0,0 +1,56 @@ +function Get-PowerShellTipFileContents { + param( + [Parameter(Mandatory = $true, HelpMessage = 'The date the tip was created. Format: YYYY-MM-DD')] + [ValidateNotNullOrWhiteSpace()] + [string] $TipCreatedDate, + + [Parameter(Mandatory = $true, HelpMessage = 'The title of the tip. Must be 75 characters or less.')] + [ValidateNotNullOrWhiteSpace()] + [string] $TipTitle, + + [Parameter(Mandatory = $true, HelpMessage = 'The text of the tip.')] + [ValidateNotNullOrWhiteSpace()] + [string] $TipText, + + [Parameter(Mandatory = $false, HelpMessage = 'The example code for the tip. Use an empty string if no example is provided.')] + [string] $TipExample = '', + + [Parameter(Mandatory = $false, HelpMessage = 'The URLs for the tip. Use an empty array if no URLs are provided.')] + [string[]] $TipUrls = @(), + + [Parameter(Mandatory = $true, HelpMessage = 'The category of the tip. Must be one of the following: Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other.')] + [ValidateSet('Community', 'Editor', 'Module', 'NativeCmdlet', 'Performance', 'Security', 'Syntax', 'Terminal', 'Other')] + [string] $TipCategory, + + [Parameter(Mandatory = $false, HelpMessage = 'The author of the tip. Use an empty string if no author is provided.')] + [string] $TipAuthor = '', + + [Parameter(Mandatory = $false, HelpMessage = 'The expiry date of the tip. Format: YYYY-MM-DD. Use an empty string if no expiry date is provided.')] + [string] $TipExpiryDate = '' + ) + + [string] $tipTemplateFileContents = @" +`$tip = [tiPS.PowerShellTip]::new() +`$tip.CreatedDate = [DateTime]::Parse('$TipCreatedDate') +`$tip.Title = '$($TipTitle.Replace("'", "''"))' +`$tip.TipText = $TipText +`$tip.Example = $TipExample +`$tip.Urls = $TipUrls +`$tip.Category = [tiPS.TipCategory]::$TipCategory # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +`$tip.Author = '$TipAuthor' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#`$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. +"@ + + return $tipTemplateFileContents +} diff --git a/.github/workflows/process-new-powershell-tip.yml b/.github/workflows/process-new-powershell-tip-issue.yml similarity index 70% rename from .github/workflows/process-new-powershell-tip.yml rename to .github/workflows/process-new-powershell-tip-issue.yml index f0f3aa34..ace48638 100644 --- a/.github/workflows/process-new-powershell-tip.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -16,98 +16,67 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - - name: Setup PowerShell - uses: actions/setup-powershell@v1 with: - powershell-version: '7.2' + fetch-depth: 0 - name: Extract tip information from issue id: extract-tip run: | $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - $title = $issue.title -replace '^\[TIP\]\s*', '' + [string] $tipTitle = $issue.title -replace '^\Tip:\s*', '' $body = $issue.body - # Parse the issue body to extract fields - $tipTitle = $null - $tipText = $null - $example = $null - $category = $null - $urls = @() - $author = $null + # Parse the issue body to extract fields. + [string] $tipText = [string]::Empty + [string] $tipExample = [string]::Empty + [string] $tipCategory = [string]::Empty + [string[]] $tipUrls = @() + [string] $tipAuthor = [string]::Empty + [string] $tipExpiryDate = [string]::Empty - # Extract data from the JSON representation of the issue - # The structure will depend on the form fields defined in the YAML template + # Extract data from the JSON representation of the issue. + # The structure will depend on the form fields defined in the YAML issue template. foreach ($item in ($body | ConvertFrom-Json)) { $id = $item.id $value = $item.value switch ($id) { - 'title' { $tipTitle = $value } - 'tiptext' { $tipText = $value } - 'example' { $example = $value } + 'tipText' { $tipText = $value } + 'example' { $tipExample = $value } 'category' { - # Extract just the category name without description + # Extract just the category name without description in parentheses. if ($value -match '^([^(]+)') { - $category = $Matches[1].Trim() + $tipCategory = $Matches[1].Trim() } } - 'url1' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } - 'url2' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } - 'url3' { if (-not [string]::IsNullOrWhiteSpace($value)) { $urls += $value } } - 'author' { $author = $value } + 'url1' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } + 'url2' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } + 'url3' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } + 'author' { $tipAuthor = $value } + 'expiryDate' { $tipExpiryDate = $value } } } - # Set current date as CreatedDate - $createdDate = Get-Date -Format "yyyy-MM-dd" - - # Create file content - $fileContent = @" -# This PowerShell tip was submitted by $author on $createdDate. - -`$PowerShellTip = [tiPS.PowerShellTip]@{ - CreatedDate = [DateTime]::Parse('$createdDate') - Title = '$($tipTitle -replace "'", "''")' - TipText = @' -$tipText -'@ -"@ - - if (-not [string]::IsNullOrWhiteSpace($example)) { - $fileContent += @" - - Example = @' -$example -'@ -"@ + # Set current date as CreatedDate. + $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" + + # Get the file contents by dot-sourcing the file with the function to call. + . $GITHUB_WORKSPACE/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 + $getFileContentsParameters = @{ + TipCreatedDate = $tipCreatedDate + TipTitle = $tipTitle + TipText = $tipText + TipExample = $tipExample + TipUrls = $tipUrls + TipCategory = $tipCategory + TipAuthor = $tipAuthor + TipExpiryDate = $tipExpiryDate } - - if ($urls.Count -gt 0) { - $fileContent += @" - - Urls = @( -"@ - foreach ($url in $urls) { - $fileContent += @" - '$url' -"@ - } - $fileContent += @" - ) -"@ - } - - $fileContent += @" - - Category = [tiPS.TipCategory]::$category -} -"@ + [string] $fileContent = Get-PowerShellTipFileContents @getFileContentsParameters # Create branch name and filename $branchName = "new-tip/issue-$($issue.number)" - $fileName = "$createdDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" + $fileName = "$tipCreatedDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" $filePath = "src/PowerShellTips/$fileName" # Output variables for next steps From 7b50ba811b0571c73278204404ec105207785e7b Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:40:21 -0600 Subject: [PATCH 035/217] chore: Update new issue and workflow for clarity --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 35 ++++++++++++------- .../process-new-powershell-tip-issue.yml | 7 +--- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 43186d58..0e640700 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -25,6 +25,7 @@ body: attributes: label: Tip Text (required) description: Detailed explanation of the tip. Be clear and concise. + placeholder: Write your tip description here... validations: required: true @@ -34,8 +35,7 @@ body: label: Example Code (optional) description: Provide a working PowerShell example that demonstrates your tip. render: powershell - value: | - # Your example code here + placeholder: Your example code here... - type: input id: url1 @@ -62,17 +62,26 @@ body: id: category attributes: label: Category (required) - description: Select the category that best fits your tip + description: Select the category that best fits your tip. + - Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. + - Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. + - Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. + - NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. + - Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. + - Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. + - Syntax - Syntax tips. e.g. splatting, pipeline, etc. + - Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. + - Other - Tips that don't fit into any of the other categories. options: - - Community (Social events and community resources) - - Editor (Editor tips and extensions) - - Module (Modules and module tips) - - NativeCmdlet (Native cmdlet tips) - - Performance (Tips to improve runtime performance) - - Security (Security tips) - - Syntax (Syntax tips) - - Terminal (Terminal shortcuts and tips) - - Other (Tips that don't fit into any other category) + - Community + - Editor + - Module + - NativeCmdlet + - Performance + - Security + - Syntax + - Terminal + - Other validations: required: true @@ -88,7 +97,7 @@ body: attributes: label: Expiry Date (optional) description: Date when the tip should expire (format of YYYY-MM-DD). Mostly applicable when promoting a community event on a specific date. Leave blank for no expiry. - placeholder: YYYY-MM-DD + placeholder: '2025-10-25' - type: markdown attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ace48638..e8953579 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -43,12 +43,7 @@ jobs: switch ($id) { 'tipText' { $tipText = $value } 'example' { $tipExample = $value } - 'category' { - # Extract just the category name without description in parentheses. - if ($value -match '^([^(]+)') { - $tipCategory = $Matches[1].Trim() - } - } + 'category' { $tipCategory = $value } 'url1' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } 'url2' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } 'url3' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } From 4eca3628433ceae01c7cb78996e07f8d66c49859 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:44:11 -0600 Subject: [PATCH 036/217] chore: Fix bug with issue title --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 0e640700..e9e209c8 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,6 +1,6 @@ name: PowerShell Tip Submission description: Submit a new PowerShell tip to be included in the tiPS module -title: "Tip: " +title: "New Tip Submission - Ignore this field" labels: ["new-tip"] body: - type: markdown diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index e8953579..46ac3dd2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -23,10 +23,10 @@ jobs: id: extract-tip run: | $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - [string] $tipTitle = $issue.title -replace '^\Tip:\s*', '' $body = $issue.body # Parse the issue body to extract fields. + [string] $tipTitle = [string]::Empty [string] $tipText = [string]::Empty [string] $tipExample = [string]::Empty [string] $tipCategory = [string]::Empty @@ -41,6 +41,7 @@ jobs: $value = $item.value switch ($id) { + 'title' { $tipTitle = $value } 'tipText' { $tipText = $value } 'example' { $tipExample = $value } 'category' { $tipCategory = $value } From f9fb9f34d40a0e294e526036fbddf96e55084c3d Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:45:36 -0600 Subject: [PATCH 037/217] chore: Update issue field titles --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index e9e209c8..4dd5756e 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,4 +1,4 @@ -name: PowerShell Tip Submission +name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" labels: ["new-tip"] @@ -15,7 +15,7 @@ body: - type: input id: title attributes: - label: Title (required) + label: Tip Title (required) description: A concise title for your tip (max 75 characters) validations: required: true From b566158a87c905239188b67161fedf4819b35a84 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:46:51 -0600 Subject: [PATCH 038/217] chore: Add issue placeholder --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 4dd5756e..4d05b05a 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -17,6 +17,7 @@ body: attributes: label: Tip Title (required) description: A concise title for your tip (max 75 characters) + placeholder: e.g. Use `-Filter` with `Get-ChildItem` to speed up file searches validations: required: true From f6ded628b8ba597f6f3d958c6bdda31b2f4e6f6b Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:48:39 -0600 Subject: [PATCH 039/217] chore: Update issue field type --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 4d05b05a..0b15a969 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -93,7 +93,7 @@ body: description: Your name and/or username. Leave blank if you prefer to remain anonymous. placeholder: e.g. Daniel Schroeder (deadlydog) - - type: textarea + - type: input id: expiryDate attributes: label: Expiry Date (optional) From 5da8fe0c3c9da0347ef8d4f968a8cff456a42b3e Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 01:54:10 -0600 Subject: [PATCH 040/217] chore: Update automation issue label --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 0b15a969..3a67eb08 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,7 +1,7 @@ name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" -labels: ["new-tip"] +labels: ["automation-new-tip-do-not-use "] body: - type: markdown attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 46ac3dd2..b37f0b83 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -6,7 +6,7 @@ on: jobs: process-new-tip: - if: contains(github.event.issue.labels.*.name, 'new-tip') + if: contains(github.event.issue.labels.*.name, 'automation-new-tip-do-not-use ') runs-on: ubuntu-latest permissions: contents: write From 5484ac7f36753cbadead91b8fc5e8f4c3cf26f23 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 02:06:21 -0600 Subject: [PATCH 041/217] chore: Adjust issue label --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 3a67eb08..0b15a969 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,7 +1,7 @@ name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" -labels: ["automation-new-tip-do-not-use "] +labels: ["new-tip"] body: - type: markdown attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index b37f0b83..46ac3dd2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -6,7 +6,7 @@ on: jobs: process-new-tip: - if: contains(github.event.issue.labels.*.name, 'automation-new-tip-do-not-use ') + if: contains(github.event.issue.labels.*.name, 'new-tip') runs-on: ubuntu-latest permissions: contents: write From bc55b40a19e2697896250912344c63abb9490ae5 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 02:09:16 -0600 Subject: [PATCH 042/217] chore: Adjust issue labels again --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 0b15a969..8ddab409 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,7 +1,7 @@ name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" -labels: ["new-tip"] +labels: ["automation-new-tip-do-not-use"] body: - type: markdown attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 46ac3dd2..2598d037 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -6,7 +6,7 @@ on: jobs: process-new-tip: - if: contains(github.event.issue.labels.*.name, 'new-tip') + if: contains(github.event.issue.labels.*.name, 'automation-new-tip-do-not-use') runs-on: ubuntu-latest permissions: contents: write From 1d9a9f5b182db21e8f3b3640e8ed1e5ed4b7afbf Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 02:12:57 -0600 Subject: [PATCH 043/217] ci: Fix how variables are passed to next steps in action --- .../process-new-powershell-tip-issue.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2598d037..beae8702 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -70,18 +70,18 @@ jobs: } [string] $fileContent = Get-PowerShellTipFileContents @getFileContentsParameters - # Create branch name and filename + # Create branch name and filename. $branchName = "new-tip/issue-$($issue.number)" $fileName = "$tipCreatedDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" $filePath = "src/PowerShellTips/$fileName" - # Output variables for next steps - Write-Output "::set-output name=branch_name::$branchName" - Write-Output "::set-output name=file_name::$fileName" - Write-Output "::set-output name=file_path::$filePath" - Write-Output "::set-output name=file_content::$fileContent" - Write-Output "::set-output name=issue_number::$($issue.number)" - Write-Output "::set-output name=tip_title::$tipTitle" + # Output variables for next steps. + "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "file_name=$fileName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "file_path=$filePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "file_content=$fileContent" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "issue_number=$($issue.number)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append shell: pwsh - name: Create branch From 5464d832121b4e41011d0a54b2c58cfe0c72e650 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 02:18:27 -0600 Subject: [PATCH 044/217] ci: Refactor workflow file --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index beae8702..c5a96cbe 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -21,6 +21,7 @@ jobs: - name: Extract tip information from issue id: extract-tip + shell: pwsh run: | $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' $body = $issue.body @@ -82,7 +83,6 @@ jobs: "file_content=$fileContent" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "issue_number=$($issue.number)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - shell: pwsh - name: Create branch run: | From fc4fb8e642bf71e2b8afdb3ef217826433f0aeee Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 11:14:48 -0600 Subject: [PATCH 045/217] chore: Fix how GitHub issue data is extracted --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 + .../ProcessNewPowerShellTipIssueFunctions.ps1 | 2 +- .../process-new-powershell-tip-issue.yml | 81 ++++++++++++++----- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 8ddab409..5d46cbfb 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -3,6 +3,8 @@ description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" labels: ["automation-new-tip-do-not-use"] body: + # NOTE: The input label is used by the process-new-powershell-tip-issue.yml workflow to extract the data from the issue body. + # DO NOT change the labels or required validation without also changing the parsing logic. - type: markdown attributes: value: | diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index 92fa1bdf..0f37bd9e 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -1,4 +1,4 @@ -function Get-PowerShellTipFileContents { +function New-PowerShellTipFileContents { param( [Parameter(Mandatory = $true, HelpMessage = 'The date the tip was created. Format: YYYY-MM-DD')] [ValidateNotNullOrWhiteSpace()] diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index c5a96cbe..e9bbf4de 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -26,7 +26,7 @@ jobs: $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' $body = $issue.body - # Parse the issue body to extract fields. + # Define the variables to extract the GitHub issue fields into. [string] $tipTitle = [string]::Empty [string] $tipText = [string]::Empty [string] $tipExample = [string]::Empty @@ -35,29 +35,72 @@ jobs: [string] $tipAuthor = [string]::Empty [string] $tipExpiryDate = [string]::Empty - # Extract data from the JSON representation of the issue. - # The structure will depend on the form fields defined in the YAML issue template. - foreach ($item in ($body | ConvertFrom-Json)) { - $id = $item.id - $value = $item.value - - switch ($id) { - 'title' { $tipTitle = $value } - 'tipText' { $tipText = $value } - 'example' { $tipExample = $value } - 'category' { $tipCategory = $value } - 'url1' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } - 'url2' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } - 'url3' { if (-not [string]::IsNullOrWhiteSpace($value)) { $tipUrls += $value } } - 'author' { $tipAuthor = $value } - 'expiryDate' { $tipExpiryDate = $value } + # Extract the data from the markdown representation of the issue. + # GitHub Forms generates structured markdown with specific section headers we can match against. + + # Extract Title + if ($body -match '### Title \(required\)\s+([^\r\n]+)') { + $tipTitle = $Matches[1].Trim() + Write-Output "Extracted Title: $tipTitle" + } + + # Extract Tip Text + if ($body -match '### Tip Text \(required\)\s+([\s\S]*?)(?=###|$)') { + $tipText = $Matches[1].Trim() + Write-Output "Extracted Tip Text: $($tipText.Substring(0, [Math]::Min(30, $tipText.Length)))..." + } + + # Extract Example Code + if ($body -match '### Example Code \(optional\)\s+```powershell\s+([\s\S]*?)```') { + $tipExample = $Matches[1].Trim() + Write-Output "Example code extracted with length: $($tipExample.Length)" + } + + # Extract URLs (up to 3) + if ($body -match '### URL 1 \(optional\)\s+([^\r\n]+)') { + $url = $Matches[1].Trim() + if (-not [string]::IsNullOrWhiteSpace($url)) { + $tipUrls += $url + Write-Output "Extracted URL 1: $url" + } + } + + if ($body -match '### URL 2 \(optional\)\s+([^\r\n]+)') { + $url = $Matches[1].Trim() + if (-not [string]::IsNullOrWhiteSpace($url)) { + $tipUrls += $url + Write-Output "Extracted URL 2: $url" } } + if ($body -match '### URL 3 \(optional\)\s+([^\r\n]+)') { + $url = $Matches[1].Trim() + if (-not [string]::IsNullOrWhiteSpace($url)) { + $tipUrls += $url + Write-Output "Extracted URL 3: $url" + } + } + + # Extract Category + if ($body -match '### Category \(required\)\s+([^\r\n]+)') { + $fullCategory = $Matches[1].Trim() + # Extract just the category name (before any parentheses) + if ($fullCategory -match '^([^(]+)') { + $tipCategory = $Matches[1].Trim() + Write-Output "Extracted Category: $tipCategory" + } + } + + # Extract Author + if ($body -match '### Author \(optional\)\s+([^\r\n]+)') { + $tipAuthor = $Matches[1].Trim() + Write-Output "Extracted Author: $tipAuthor" + } + # Set current date as CreatedDate. $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" - # Get the file contents by dot-sourcing the file with the function to call. + # Get the file contents to use by dot-sourcing the file with the function to call. . $GITHUB_WORKSPACE/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 $getFileContentsParameters = @{ TipCreatedDate = $tipCreatedDate @@ -69,7 +112,7 @@ jobs: TipAuthor = $tipAuthor TipExpiryDate = $tipExpiryDate } - [string] $fileContent = Get-PowerShellTipFileContents @getFileContentsParameters + [string] $fileContent = New-PowerShellTipFileContents @getFileContentsParameters # Create branch name and filename. $branchName = "new-tip/issue-$($issue.number)" From 13aae9a84e073983f3ce7ce194fc3e894bcc38fa Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 11:18:25 -0600 Subject: [PATCH 046/217] chore: Also run on issue labeled to make testing easier --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index e9bbf4de..860b190a 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -2,7 +2,7 @@ name: Process New PowerShell Tip on: issues: - types: [opened] + types: [opened, labeled] jobs: process-new-tip: From 75ecdb2a851cbefad251050cff9599e722684ca5 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 11:21:44 -0600 Subject: [PATCH 047/217] ci: Try to fix script parsing --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 860b190a..7a7a5ce4 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -101,7 +101,7 @@ jobs: $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" # Get the file contents to use by dot-sourcing the file with the function to call. - . $GITHUB_WORKSPACE/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 + . "$GITHUB_WORKSPACE/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" $getFileContentsParameters = @{ TipCreatedDate = $tipCreatedDate TipTitle = $tipTitle From 3d0d129341bce2e74eb43f17b1d5f5c35ba5edb3 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 11:27:54 -0600 Subject: [PATCH 048/217] ci: Fix workflow path issue --- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 7a7a5ce4..4d81b726 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -101,7 +101,8 @@ jobs: $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" # Get the file contents to use by dot-sourcing the file with the function to call. - . "$GITHUB_WORKSPACE/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" + [string] $gitRootDirectoryPath = $Env:GITHUB_WORKSPACE + . "$gitRootDirectoryPath/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" $getFileContentsParameters = @{ TipCreatedDate = $tipCreatedDate TipTitle = $tipTitle From 01cccb8a47ebdb03dfeab5b84abe2713b43e1611 Mon Sep 17 00:00:00 2001 From: deadlydog Date: Fri, 28 Mar 2025 17:04:57 -0600 Subject: [PATCH 049/217] chore: Fix workflow regex parsing logic --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 15 +--- .../process-new-powershell-tip-issue.yml | 73 +++++++++++-------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 5d46cbfb..e58c8669 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -3,8 +3,8 @@ description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" labels: ["automation-new-tip-do-not-use"] body: - # NOTE: The input label is used by the process-new-powershell-tip-issue.yml workflow to extract the data from the issue body. - # DO NOT change the labels or required validation without also changing the parsing logic. + # NOTE: The input label, required validation, and order is used by the process-new-powershell-tip-issue.yml workflow to extract the data from the issue body. + # DO NOT change the labels or required validation or ordering without also changing the regex parsing logic of that file. - type: markdown attributes: value: | @@ -65,16 +65,7 @@ body: id: category attributes: label: Category (required) - description: Select the category that best fits your tip. - - Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. - - Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. - - Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. - - NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. - - Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. - - Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. - - Syntax - Syntax tips. e.g. splatting, pipeline, etc. - - Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. - - Other - Tips that don't fit into any of the other categories. + description: Select the category that best fits your tip.\nCommunity - Social events and community resources. e.g. PowerShell Summit, podcasts, etc.\nEditor - Editor tips and extensions. e.g. VSCode, ISE, etc.\nModule - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc.\nNativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc.\nPerformance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc.\nSecurity - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc.\nSyntax - Syntax tips. e.g. splatting, pipeline, etc.\nTerminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc.\nOther - Tips that don't fit into any of the other categories. options: - Community - Editor diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 4d81b726..680c7334 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -37,63 +37,72 @@ jobs: # Extract the data from the markdown representation of the issue. # GitHub Forms generates structured markdown with specific section headers we can match against. + # Below is a sample of what the body data may look like: + # ### Tip Title (required)\n\nTest title\n\n### Tip Text (required)\n\nTest description\n\n### Example Code (optional)\n\n```powershell\nTest code\n```\n\n### URL 1 (optional)\n\nhttps://one.com\n\n### URL 2 (optional)\n\nhttp://two.com\n\n### URL 3 (optional)\n\n_No response_\n\n### Category (required)\n\nTerminal\n\n### Author (optional)\n\n_No response_\n\n### Expiry Date (optional)\n\n_No response_ - # Extract Title - if ($body -match '### Title \(required\)\s+([^\r\n]+)') { - $tipTitle = $Matches[1].Trim() + # The default text that GitHub Issues uses for optional fields that are not filled in. + [string] $noResponseText = '_No response_' + + # Extract Title. + [regex] $titleRegex = '### Tip Title \(required\)\\n\\n(?.*?)\\n\\n### Tip Text' + if ($body -match $titleRegex) { + $tipTitle = $Matches['Title'].Trim() Write-Output "Extracted Title: $tipTitle" } - # Extract Tip Text - if ($body -match '### Tip Text \(required\)\s+([\s\S]*?)(?=###|$)') { - $tipText = $Matches[1].Trim() - Write-Output "Extracted Tip Text: $($tipText.Substring(0, [Math]::Min(30, $tipText.Length)))..." + # Extract Tip Text. + [regex] $tipTextRegex = '### Tip Text \(required\)\\n\\n(?<TipText>.*?)\\n\\n### Example Code' + if ($body -match $tipTextRegex) { + $tipText = $Matches['TipText'].Trim() + Write-Output "Extracted Tip Text: $tipText" } - # Extract Example Code - if ($body -match '### Example Code \(optional\)\s+```powershell\s+([\s\S]*?)```') { - $tipExample = $Matches[1].Trim() - Write-Output "Example code extracted with length: $($tipExample.Length)" + # Extract Example Code. + [regex] $exampleRegex = '### Example Code \(optional\)\\n\\n```powershell\\n(?<ExampleCode>.*?)```\\n\\n### URL 1' + if ($body -match $exampleRegex) { + $tipExample = $Matches['ExampleCode'].Trim() + Write-Output "Extracted Example Code: $tipExample" } - # Extract URLs (up to 3) - if ($body -match '### URL 1 \(optional\)\s+([^\r\n]+)') { - $url = $Matches[1].Trim() + # Extract URLs (up to 3). + [regex] $url1Regex = '### URL 1 \(optional\)\\n\\n(?<Url1>.*?)\\n\\n### URL 2' + if ($body -match $url1Regex) { + $url = $Matches['Url1'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { $tipUrls += $url Write-Output "Extracted URL 1: $url" } } - if ($body -match '### URL 2 \(optional\)\s+([^\r\n]+)') { - $url = $Matches[1].Trim() + [regex] $url2Regex = '### URL 2 \(optional\)\\n\\n(?<Url2>.*?)\\n\\n### URL 3' + if ($body -match $url2Regex) { + $url = $Matches['Url2'].Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { $tipUrls += $url Write-Output "Extracted URL 2: $url" } } - if ($body -match '### URL 3 \(optional\)\s+([^\r\n]+)') { - $url = $Matches[1].Trim() + [regex] $url3Regex = '### URL 3 \(optional\)\\n\\n(?<Url3>.*?)\\n\\n### Category' + if ($body -match $url3Regex) { + $url = $Matches['Url3'].Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { $tipUrls += $url Write-Output "Extracted URL 3: $url" } } - # Extract Category - if ($body -match '### Category \(required\)\s+([^\r\n]+)') { - $fullCategory = $Matches[1].Trim() - # Extract just the category name (before any parentheses) - if ($fullCategory -match '^([^(]+)') { - $tipCategory = $Matches[1].Trim() - Write-Output "Extracted Category: $tipCategory" - } + # Extract Category. + [regex] $categoryRegex = '### Category \(required\)\\n\\n(?<Category>.*?)\\n\\n### Author' + if ($body -match $categoryRegex) { + $tipCategory = $Matches['Category'].Trim() + Write-Output "Extracted Category: $tipCategory" } - # Extract Author - if ($body -match '### Author \(optional\)\s+([^\r\n]+)') { - $tipAuthor = $Matches[1].Trim() + # Extract Author. + [regex] $authorRegex = '### Author \(optional\)\\n\\n(?<Author>.*?)\\n\\n### Expiry Date' + if ($body -match $authorRegex) { + $tipAuthor = $Matches['Author'].Trim() Write-Output "Extracted Author: $tipAuthor" } @@ -107,10 +116,10 @@ jobs: TipCreatedDate = $tipCreatedDate TipTitle = $tipTitle TipText = $tipText - TipExample = $tipExample + TipExample = $tipExample.Replace($noResponseText, '').Trim() TipUrls = $tipUrls - TipCategory = $tipCategory - TipAuthor = $tipAuthor + TipCategory = $tipCategory.Replace($noResponseText, '').Trim() + TipAuthor = $tipAuthor.Replace($noResponseText, '').Trim() TipExpiryDate = $tipExpiryDate } [string] $fileContent = New-PowerShellTipFileContents @getFileContentsParameters From 7f629c27c1480bd6e756fe02588291553e7c4f1b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 17:09:23 -0600 Subject: [PATCH 050/217] chore: Update issue template --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index e58c8669..2da048c8 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -65,7 +65,17 @@ body: id: category attributes: label: Category (required) - description: Select the category that best fits your tip.\nCommunity - Social events and community resources. e.g. PowerShell Summit, podcasts, etc.\nEditor - Editor tips and extensions. e.g. VSCode, ISE, etc.\nModule - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc.\nNativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc.\nPerformance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc.\nSecurity - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc.\nSyntax - Syntax tips. e.g. splatting, pipeline, etc.\nTerminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc.\nOther - Tips that don't fit into any of the other categories. + description: | + Select the category that best fits your tip. + Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. + Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. + Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. + NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. + Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. + Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. + Syntax - Syntax tips. e.g. splatting, pipeline, etc. + Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. + Other - Tips that don't fit into any of the other categories. options: - Community - Editor From b1b1f66fd31f813393a356055066b08cce3d9b4c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 17:18:24 -0600 Subject: [PATCH 051/217] chore: Add troubleshooting output to workflow logs --- .github/workflows/process-new-powershell-tip-issue.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 680c7334..bc6c4c6b 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -26,6 +26,9 @@ jobs: $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' $body = $issue.body + Write-Output "Displaying issue body for troubleshooting purposes:" + Write-Output $body + # Define the variables to extract the GitHub issue fields into. [string] $tipTitle = [string]::Empty [string] $tipText = [string]::Empty From b534ad38e2023d37efa12f180c15545c460a7160 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 17:21:49 -0600 Subject: [PATCH 052/217] chore: Try to fix workflow regex parsing logic --- .../process-new-powershell-tip-issue.yml | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index bc6c4c6b..1f183e05 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -41,34 +41,54 @@ jobs: # Extract the data from the markdown representation of the issue. # GitHub Forms generates structured markdown with specific section headers we can match against. # Below is a sample of what the body data may look like: - # ### Tip Title (required)\n\nTest title\n\n### Tip Text (required)\n\nTest description\n\n### Example Code (optional)\n\n```powershell\nTest code\n```\n\n### URL 1 (optional)\n\nhttps://one.com\n\n### URL 2 (optional)\n\nhttp://two.com\n\n### URL 3 (optional)\n\n_No response_\n\n### Category (required)\n\nTerminal\n\n### Author (optional)\n\n_No response_\n\n### Expiry Date (optional)\n\n_No response_ + # + # ### Tip Title (required) + # Test title + # ### Tip Text (required) + # Test description + # ### Example Code (optional) + # ```powershell + # Test code + # ``` + # ### URL 1 (optional) + # https://one.com + # ### URL 2 (optional) + # http://two.com + # ### URL 3 (optional) + # _No response_ + # ### Category (required) + # Terminal + # ### Author (optional) + # _No response_ + # ### Expiry Date (optional) + # _No response_ # The default text that GitHub Issues uses for optional fields that are not filled in. [string] $noResponseText = '_No response_' # Extract Title. - [regex] $titleRegex = '### Tip Title \(required\)\\n\\n(?<Title>.*?)\\n\\n### Tip Text' + [regex] $titleRegex = '### Tip Title \(required\)\s+(?<Title>.*?)\s+### Tip Text' if ($body -match $titleRegex) { $tipTitle = $Matches['Title'].Trim() Write-Output "Extracted Title: $tipTitle" } # Extract Tip Text. - [regex] $tipTextRegex = '### Tip Text \(required\)\\n\\n(?<TipText>.*?)\\n\\n### Example Code' + [regex] $tipTextRegex = '### Tip Text \(required\)\s+(?<TipText>.*?)\s+### Example Code' if ($body -match $tipTextRegex) { $tipText = $Matches['TipText'].Trim() Write-Output "Extracted Tip Text: $tipText" } # Extract Example Code. - [regex] $exampleRegex = '### Example Code \(optional\)\\n\\n```powershell\\n(?<ExampleCode>.*?)```\\n\\n### URL 1' + [regex] $exampleRegex = '### Example Code \(optional\)\s+```powershell\\n(?<ExampleCode>.*?)```\s+### URL 1' if ($body -match $exampleRegex) { $tipExample = $Matches['ExampleCode'].Trim() Write-Output "Extracted Example Code: $tipExample" } # Extract URLs (up to 3). - [regex] $url1Regex = '### URL 1 \(optional\)\\n\\n(?<Url1>.*?)\\n\\n### URL 2' + [regex] $url1Regex = '### URL 1 \(optional\)\s+(?<Url1>.*?)\s+### URL 2' if ($body -match $url1Regex) { $url = $Matches['Url1'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { @@ -77,7 +97,7 @@ jobs: } } - [regex] $url2Regex = '### URL 2 \(optional\)\\n\\n(?<Url2>.*?)\\n\\n### URL 3' + [regex] $url2Regex = '### URL 2 \(optional\)\s+(?<Url2>.*?)\s+### URL 3' if ($body -match $url2Regex) { $url = $Matches['Url2'].Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { @@ -86,7 +106,7 @@ jobs: } } - [regex] $url3Regex = '### URL 3 \(optional\)\\n\\n(?<Url3>.*?)\\n\\n### Category' + [regex] $url3Regex = '### URL 3 \(optional\)\s+(?<Url3>.*?)\s+### Category' if ($body -match $url3Regex) { $url = $Matches['Url3'].Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { @@ -96,14 +116,14 @@ jobs: } # Extract Category. - [regex] $categoryRegex = '### Category \(required\)\\n\\n(?<Category>.*?)\\n\\n### Author' + [regex] $categoryRegex = '### Category \(required\)\s+(?<Category>.*?)\s+### Author' if ($body -match $categoryRegex) { $tipCategory = $Matches['Category'].Trim() Write-Output "Extracted Category: $tipCategory" } # Extract Author. - [regex] $authorRegex = '### Author \(optional\)\\n\\n(?<Author>.*?)\\n\\n### Expiry Date' + [regex] $authorRegex = '### Author \(optional\)\s+(?<Author>.*?)\s+### Expiry Date' if ($body -match $authorRegex) { $tipAuthor = $Matches['Author'].Trim() Write-Output "Extracted Author: $tipAuthor" From cfc5ce9218de3890f1631b78ccd7e2ad15eb86c8 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 18:20:49 -0600 Subject: [PATCH 053/217] chore: Add logging statements to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1f183e05..3f1e7c3e 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -23,13 +23,14 @@ jobs: id: extract-tip shell: pwsh run: | + Write-Output "Reading information from GitHub issue..." $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' $body = $issue.body Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output $body - # Define the variables to extract the GitHub issue fields into. + Write-Output "Extracting information from issue body to local variables..." [string] $tipTitle = [string]::Empty [string] $tipText = [string]::Empty [string] $tipExample = [string]::Empty @@ -132,9 +133,11 @@ jobs: # Set current date as CreatedDate. $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" - # Get the file contents to use by dot-sourcing the file with the function to call. + Write-Output "Dot-sourcing utility script used to get file contents..." [string] $gitRootDirectoryPath = $Env:GITHUB_WORKSPACE . "$gitRootDirectoryPath/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" + + Write-Output "Calling function to get file contents..." $getFileContentsParameters = @{ TipCreatedDate = $tipCreatedDate TipTitle = $tipTitle @@ -152,7 +155,7 @@ jobs: $fileName = "$tipCreatedDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" $filePath = "src/PowerShellTips/$fileName" - # Output variables for next steps. + Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "file_name=$fileName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "file_path=$filePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 8f882f4295e5947886ca44abafc7a758cc15a11d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 18:28:50 -0600 Subject: [PATCH 054/217] chore: Fix workflow to respect the TipExpiryDate --- .../ProcessNewPowerShellTipIssueFunctions.ps1 | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index 0f37bd9e..c3c33082 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -29,7 +29,7 @@ function New-PowerShellTipFileContents { [string] $TipExpiryDate = '' ) - [string] $tipTemplateFileContents = @" + [string] $tipFileContents = @" `$tip = [tiPS.PowerShellTip]::new() `$tip.CreatedDate = [DateTime]::Parse('$TipCreatedDate') `$tip.Title = '$($TipTitle.Replace("'", "''"))' @@ -40,17 +40,14 @@ function New-PowerShellTipFileContents { `$tip.Author = '$TipAuthor' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. #`$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. -# Category meanings: -# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. -# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. -# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. -# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. -# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. -# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. -# Syntax: Syntax tips. e.g. splatting, pipeline, etc. -# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. -# Other: Tips that don't fit into any of the other categories. +# Tip submitted via GitHub issue workflow. "@ - return $tipTemplateFileContents + # If a TipExpiryDate is provided, uncomment the TipExpiryDate line. + if (-not [string]::IsNullOrWhiteSpace($TipExpiryDate)) { + [string] $expiryTextToMatch = '$tip.ExpiryDate = [DateTime]::Parse(' + $tipFileContents = $tipFileContents.Replace("#$expiryTextToMatch", $expiryTextToMatch) + } + + return $tipFileContents } From 11c419713918cc0eb09f7d59cca8105c98df0308 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 19:16:31 -0600 Subject: [PATCH 055/217] refactor: Rename variables and ensure UTF8 encoding is used to create new tip files --- tools/New-PowerShellTip.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/New-PowerShellTip.ps1 b/tools/New-PowerShellTip.ps1 index 6723215c..bd20ee7d 100644 --- a/tools/New-PowerShellTip.ps1 +++ b/tools/New-PowerShellTip.ps1 @@ -29,13 +29,13 @@ $dummyTip = [tiPS.PowerShellTip]::new() $dummyTip.CreatedDate = [DateTime]::Today $dummyTip.Title = $tipTitle.Trim() -[string] $today = $dummyTip.CreatedDate.ToString('yyyy-MM-dd') +[string] $createdDate = $dummyTip.CreatedDate.ToString('yyyy-MM-dd') [string] $powerShellTipsFilesDirectoryPath = Resolve-Path -Path "$PSScriptRoot/../src/PowerShellTips" [string] $newTipFileName = $dummyTip.Id + '.ps1' [string] $newTipFilePath = Join-Path -Path $powerShellTipsFilesDirectoryPath -ChildPath $newTipFileName [string] $tipTemplateFileContents = @" `$tip = [tiPS.PowerShellTip]::new() -`$tip.CreatedDate = [DateTime]::Parse('$today') +`$tip.CreatedDate = [DateTime]::Parse('$createdDate') `$tip.Title = '$($tipTitle.Replace("'", "''"))' `$tip.TipText = @' A short description of the tip. @@ -69,7 +69,7 @@ Example code to demonstrate the tip. This can also be multiple lines if needed. "@ Write-Output "Creating new PowerShell Tip file and opening it: $newTipFilePath" -Set-Content -Path $newTipFilePath -Value $tipTemplateFileContents -Force +Set-Content -Path $newTipFilePath -Value $tipTemplateFileContents -Encoding utf8 -Force try { Invoke-Item -Path $newTipFilePath -ErrorVariable openTipFileError From d18b9272e740a1ce5b90cb426863778744e9f571 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 19:19:02 -0600 Subject: [PATCH 056/217] chore: Refactor workflow to create file from PowerShell script instead of stuffing file contents in an environment variable --- .../ProcessNewPowerShellTipIssueFunctions.ps1 | 30 +++++--- .../process-new-powershell-tip-issue.yml | 71 ++++++++----------- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index c3c33082..dfde5e26 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -1,9 +1,5 @@ -function New-PowerShellTipFileContents { +function New-PowerShellTipFile { param( - [Parameter(Mandatory = $true, HelpMessage = 'The date the tip was created. Format: YYYY-MM-DD')] - [ValidateNotNullOrWhiteSpace()] - [string] $TipCreatedDate, - [Parameter(Mandatory = $true, HelpMessage = 'The title of the tip. Must be 75 characters or less.')] [ValidateNotNullOrWhiteSpace()] [string] $TipTitle, @@ -29,9 +25,22 @@ function New-PowerShellTipFileContents { [string] $TipExpiryDate = '' ) - [string] $tipFileContents = @" + Write-Information "Building tiPS C# assemblies and importing module..." -InformationAction Continue + . "$PSScriptRoot/../../tools/Helpers/ImportBuiltModule.ps1" + + # The Tip filename is based on the ID, which is based on the date and title, so load a dummy PowerShellTip to get the filename to use. + $dummyTip = [tiPS.PowerShellTip]::new() + $dummyTip.CreatedDate = [DateTime]::Today + $dummyTip.Title = $TipTitle.Trim() + + [string] $createdDate = $dummyTip.CreatedDate.ToString('yyyy-MM-dd') + [string] $powerShellTipsFilesDirectoryPath = Resolve-Path -Path "$PSScriptRoot/../../src/PowerShellTips" + [string] $newTipFileName = $dummyTip.Id + '.ps1' + [string] $newTipFilePath = Join-Path -Path $powerShellTipsFilesDirectoryPath -ChildPath $newTipFileName + + [string] $newTipFileContent = @" `$tip = [tiPS.PowerShellTip]::new() -`$tip.CreatedDate = [DateTime]::Parse('$TipCreatedDate') +`$tip.CreatedDate = [DateTime]::Parse('$createdDate') `$tip.Title = '$($TipTitle.Replace("'", "''"))' `$tip.TipText = $TipText `$tip.Example = $TipExample @@ -46,8 +55,11 @@ function New-PowerShellTipFileContents { # If a TipExpiryDate is provided, uncomment the TipExpiryDate line. if (-not [string]::IsNullOrWhiteSpace($TipExpiryDate)) { [string] $expiryTextToMatch = '$tip.ExpiryDate = [DateTime]::Parse(' - $tipFileContents = $tipFileContents.Replace("#$expiryTextToMatch", $expiryTextToMatch) + $newTipFileContent = $newTipFileContent.Replace("#$expiryTextToMatch", $expiryTextToMatch) } - return $tipFileContents + Write-Information "Creating new tip file '$newTipFilePath'..." -InformationAction Continue + Set-Content -Path $newTipFilePath -Value $newTipFileContent -Encoding utf8 -Force + + return $newTipFilePath } diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 3f1e7c3e..1a7b8efc 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -7,7 +7,7 @@ on: jobs: process-new-tip: if: contains(github.event.issue.labels.*.name, 'automation-new-tip-do-not-use') - runs-on: ubuntu-latest + runs-on: windows-latest # Use Windows to ensure dotnet SDK is installed to build the assemblies. permissions: contents: write issues: write @@ -19,6 +19,24 @@ jobs: with: fetch-depth: 0 + - name: Create branch for PR + id: create-branch + shell: pwsh + run: | + Write-Output "Reading information from GitHub issue..." + $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' + $issueNumber = $issue.number + + $branchName = "new-tip/issue-$issueNumber" + + Write-Output "Creating and checking out new branch: $branchName" + git config --global user.name 'GitHub Action - tiPS Automation' + git config --global user.email 'tiPSAutomation@DoesNotExist.com' + git checkout -b "$branchName" + + Write-Output "Writing variables to environment variables for later steps..." + "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + - name: Extract tip information from issue id: extract-tip shell: pwsh @@ -130,16 +148,12 @@ jobs: Write-Output "Extracted Author: $tipAuthor" } - # Set current date as CreatedDate. - $tipCreatedDate = Get-Date -Format "yyyy-MM-dd" - - Write-Output "Dot-sourcing utility script used to get file contents..." + Write-Output "Dot-sourcing utility script used to create the new tip file..." [string] $gitRootDirectoryPath = $Env:GITHUB_WORKSPACE . "$gitRootDirectoryPath/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" - Write-Output "Calling function to get file contents..." - $getFileContentsParameters = @{ - TipCreatedDate = $tipCreatedDate + Write-Output "Calling function to create new tip file..." + $newTipFileParameters = @{ TipTitle = $tipTitle TipText = $tipText TipExample = $tipExample.Replace($noResponseText, '').Trim() @@ -148,45 +162,18 @@ jobs: TipAuthor = $tipAuthor.Replace($noResponseText, '').Trim() TipExpiryDate = $tipExpiryDate } - [string] $fileContent = New-PowerShellTipFileContents @getFileContentsParameters - - # Create branch name and filename. - $branchName = "new-tip/issue-$($issue.number)" - $fileName = "$tipCreatedDate-$($tipTitle.ToLower() -replace '[^a-z0-9]', '-' -replace '-+', '-').ps1" - $filePath = "src/PowerShellTips/$fileName" + [string] $newTipFilePath = New-PowerShellTipFile @newTipFileParameters Write-Output "Writing variables to environment variables for later steps..." - "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "file_name=$fileName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "file_path=$filePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "file_content=$fileContent" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "issue_number=$($issue.number)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - name: Create branch - run: | - git config --global user.name 'GitHub Action' - git config --global user.email 'action@github.com' - git checkout -b "${{ steps.extract-tip.outputs.branch_name }}" - shell: bash - - - name: Create tip file - run: | - # Ensure directory exists - $directory = Split-Path -Parent "${{ steps.extract-tip.outputs.file_path }}" - if (-not (Test-Path $directory)) { - New-Item -ItemType Directory -Path $directory -Force - } - - # Create the file - Set-Content -Path "${{ steps.extract-tip.outputs.file_path }}" -Value "${{ steps.extract-tip.outputs.file_content }}" - shell: pwsh - - name: Push changes and create PR run: | git add "${{ steps.extract-tip.outputs.file_path }}" - git commit -m "Add new PowerShell tip: ${{ steps.extract-tip.outputs.tip_title }}" - git push --set-upstream origin "${{ steps.extract-tip.outputs.branch_name }}" + git commit -m "Add new tip: ${{ steps.extract-tip.outputs.tip_title }}" + git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" # Create PR gh pr create \ @@ -198,16 +185,16 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - - name: Add comment to issue + - name: Add comment to issue with link to PR run: | - gh issue comment "${{ steps.extract-tip.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.extract-tip.outputs.branch_name }} --json number --jq '.[0].number')" + gh issue comment "${{ steps.extract-tip.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - name: Close issue run: | - gh issue close "${{ steps.extract-tip.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip." + gh issue close "${{ steps.extract-tip.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash From cd2a90861a9f1c7462c1021b0c8a6e2a1e962e00 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 19:21:23 -0600 Subject: [PATCH 057/217] chore: Refactor some workflow variables --- .../workflows/process-new-powershell-tip-issue.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1a7b8efc..1f04fa01 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -36,6 +36,7 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "issue_number=$issueNumber)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Extract tip information from issue id: extract-tip @@ -165,20 +166,19 @@ jobs: [string] $newTipFilePath = New-PowerShellTipFile @newTipFileParameters Write-Output "Writing variables to environment variables for later steps..." - "file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "issue_number=$($issue.number)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "tip_file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Push changes and create PR run: | - git add "${{ steps.extract-tip.outputs.file_path }}" + git add "${{ steps.extract-tip.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.extract-tip.outputs.tip_title }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" # Create PR gh pr create \ --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" \ - --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.extract-tip.outputs.issue_number }}." \ + --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." \ --label "enhancement" \ --label "new-tip" env: @@ -187,14 +187,14 @@ jobs: - name: Add comment to issue with link to PR run: | - gh issue comment "${{ steps.extract-tip.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash - name: Close issue run: | - gh issue close "${{ steps.extract-tip.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." + gh issue close "${{ steps.create-branch.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} shell: bash From 786a0f7df5266be8f671fb0a64fc23c9e79de7b7 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 19:26:09 -0600 Subject: [PATCH 058/217] ci: Add logging statements --- .github/workflows/process-new-powershell-tip-issue.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1f04fa01..37a0c5f3 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -170,12 +170,14 @@ jobs: "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Push changes and create PR + shell: pwsh run: | + Write-Output "Committing changes to local branch and pushing to remote..." git add "${{ steps.extract-tip.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.extract-tip.outputs.tip_title }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" - # Create PR + Write-Output "Creating pull request..." gh pr create \ --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" \ --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." \ @@ -183,18 +185,17 @@ jobs: --label "new-tip" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash - name: Add comment to issue with link to PR + shell: pwsh run: | gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash - name: Close issue + shell: pwsh run: | gh issue close "${{ steps.create-branch.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - shell: bash From 2e001cb204e75728dc452d802def29dde3d0511a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 20:51:41 -0600 Subject: [PATCH 059/217] chore: Capture build output and display it without returning it --- .github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index dfde5e26..37891cba 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -26,7 +26,9 @@ function New-PowerShellTipFile { ) Write-Information "Building tiPS C# assemblies and importing module..." -InformationAction Continue - . "$PSScriptRoot/../../tools/Helpers/ImportBuiltModule.ps1" + $output = . "$PSScriptRoot/../../tools/Helpers/ImportBuiltModule.ps1" + + Write-Information $output -InformationAction Continue # The Tip filename is based on the ID, which is based on the date and title, so load a dummy PowerShellTip to get the filename to use. $dummyTip = [tiPS.PowerShellTip]::new() From 98b406ad6863175cb5f8c46fa4956a226fed156a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 20:57:55 -0600 Subject: [PATCH 060/217] chore: Still trying to fix up workflow --- .../workflows/ProcessNewPowerShellTipIssueFunctions.ps1 | 7 +++++-- .github/workflows/process-new-powershell-tip-issue.yml | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index 37891cba..8e6e835b 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -26,9 +26,12 @@ function New-PowerShellTipFile { ) Write-Information "Building tiPS C# assemblies and importing module..." -InformationAction Continue - $output = . "$PSScriptRoot/../../tools/Helpers/ImportBuiltModule.ps1" + $buildOutput = . "$PSScriptRoot/../../tools/Helpers/ImportBuiltModule.ps1" - Write-Information $output -InformationAction Continue + # Write the build output as Information messages so it doesn't affect the function's return value. + foreach ($entry in $buildOutput) { + Write-Information $entry -InformationAction Continue + } # The Tip filename is based on the ID, which is based on the date and title, so load a dummy PowerShellTip to get the filename to use. $dummyTip = [tiPS.PowerShellTip]::new() diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 37a0c5f3..ffb0f79c 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -178,10 +178,10 @@ jobs: git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" Write-Output "Creating pull request..." - gh pr create \ - --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" \ - --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." \ - --label "enhancement" \ + gh pr create ` + --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` + --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." ` + --label "enhancement" ` --label "new-tip" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 2ed824226bd0d1fcb9246081e3abe5f9e8804294 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:12:55 -0600 Subject: [PATCH 061/217] chore: Refactor workflow labels a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .../workflows/process-new-powershell-tip-issue.yml | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 2da048c8..349e9d3a 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,7 +1,7 @@ name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module title: "New Tip Submission - Ignore this field" -labels: ["automation-new-tip-do-not-use"] +labels: ["automation-new-tip-issue-do-not-use"] body: # NOTE: The input label, required validation, and order is used by the process-new-powershell-tip-issue.yml workflow to extract the data from the issue body. # DO NOT change the labels or required validation or ordering without also changing the regex parsing logic of that file. diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ffb0f79c..c224d7b0 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -1,12 +1,12 @@ -name: Process New PowerShell Tip +name: Process New PowerShell Tip Issue on: issues: types: [opened, labeled] jobs: - process-new-tip: - if: contains(github.event.issue.labels.*.name, 'automation-new-tip-do-not-use') + process-new-tip-issue: + if: contains(github.event.issue.labels.*.name, 'automation-new-tip-issue-do-not-use') runs-on: windows-latest # Use Windows to ensure dotnet SDK is installed to build the assemblies. permissions: contents: write @@ -179,10 +179,9 @@ jobs: Write-Output "Creating pull request..." gh pr create ` - --title "New PowerShell Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` + --title "Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." ` - --label "enhancement" ` - --label "new-tip" + --label "automation-new-tip-pr-do-not-use" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 17fc56f1794f6e37d0cdba2c0bf3d96fa2928a21 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:29:04 -0600 Subject: [PATCH 062/217] chore: Fix typo --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index c224d7b0..f44597f8 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -36,7 +36,7 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "issue_number=$issueNumber)" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Extract tip information from issue id: extract-tip From c9e1a4e7df9f109261dacb861178dd155cb5bf5f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:35:06 -0600 Subject: [PATCH 063/217] chore: Rename workflow and include comment --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f44597f8..985435ce 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -1,8 +1,8 @@ -name: Process New PowerShell Tip Issue +name: Process-new-PowerShell-tip-issue on: issues: - types: [opened, labeled] + types: [opened, labeled] # Include 'labeled' to make troubleshooting easier. jobs: process-new-tip-issue: From 471e58f976fe1e3bf780df793d08ca527eef81b0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:36:03 -0600 Subject: [PATCH 064/217] chore: Fix URLs in workflow to ignore empty fields --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 985435ce..2b463254 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -119,7 +119,7 @@ jobs: [regex] $url2Regex = '### URL 2 \(optional\)\s+(?<Url2>.*?)\s+### URL 3' if ($body -match $url2Regex) { - $url = $Matches['Url2'].Trim() + $url = $Matches['Url2'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { $tipUrls += $url Write-Output "Extracted URL 2: $url" @@ -128,7 +128,7 @@ jobs: [regex] $url3Regex = '### URL 3 \(optional\)\s+(?<Url3>.*?)\s+### Category' if ($body -match $url3Regex) { - $url = $Matches['Url3'].Trim() + $url = $Matches['Url3'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { $tipUrls += $url Write-Output "Extracted URL 3: $url" From 6270b91776dc645d10d270c4b4b98ab105aa4338 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:39:46 -0600 Subject: [PATCH 065/217] chore: Join URLs together properly in workflow --- .github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index 8e6e835b..e9916684 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -49,7 +49,7 @@ function New-PowerShellTipFile { `$tip.Title = '$($TipTitle.Replace("'", "''"))' `$tip.TipText = $TipText `$tip.Example = $TipExample -`$tip.Urls = $TipUrls +`$tip.Urls = @('$($TipUrls -join "','")') `$tip.Category = [tiPS.TipCategory]::$TipCategory # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. `$tip.Author = '$TipAuthor' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. #`$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. From d1b9a1bbe8282860d4636dc84626b2f1b4024e19 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:46:23 -0600 Subject: [PATCH 066/217] chore: Update wording in workflow message --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2b463254..66aa6215 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -188,7 +188,7 @@ jobs: - name: Add comment to issue with link to PR shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for your submission! I've created a pull request with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! A pull request has been created with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From a3cc005236cf0740e524a6d54cbd2512d052d92f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 22:51:36 -0600 Subject: [PATCH 067/217] chore: Refactor workflow name --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 66aa6215..39fc22d4 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -1,4 +1,4 @@ -name: Process-new-PowerShell-tip-issue +name: process-new-powershell-tip-issue on: issues: From 02190e12665e54556008f18ce34c2413b201e5b0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 28 Mar 2025 23:50:17 -0600 Subject: [PATCH 068/217] chore feat: Notify user sooner that a PR is being created for their tip submission --- .github/workflows/process-new-powershell-tip-issue.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 39fc22d4..a1840a81 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -38,6 +38,13 @@ jobs: "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + - name: Add comment to issue letting user know we are processing it + shell: pwsh + run: | + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙌 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Extract tip information from issue id: extract-tip shell: pwsh @@ -188,7 +195,7 @@ jobs: - name: Add comment to issue with link to PR shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! A pull request has been created with your tip. You can view it here: ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')" + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! ✨🙏 A pull request has been created for your tip. You can view it at PR ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 17406c8c3ccd8e6f933e1e690047f74e7b25e3b0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:00:25 -0600 Subject: [PATCH 069/217] chore: Refactor how PR URL is obtained --- .github/workflows/process-new-powershell-tip-issue.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a1840a81..236b6613 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -41,7 +41,7 @@ jobs: - name: Add comment to issue letting user know we are processing it shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙌 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -177,6 +177,7 @@ jobs: "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Push changes and create PR + id: create-pr shell: pwsh run: | Write-Output "Committing changes to local branch and pushing to remote..." @@ -185,17 +186,20 @@ jobs: git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" Write-Output "Creating pull request..." - gh pr create ` + [string] $prUrl = gh pr create ` --title "Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." ` --label "automation-new-tip-pr-do-not-use" + + Write-Output "Writing variables to environment variables for later steps..." + "pr_url=$prUrl" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Add comment to issue with link to PR shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! ✨🙏 A pull request has been created for your tip. You can view it at PR ${{ github.server_url }}/${{ github.repository }}/pull/$(gh pr list --head ${{ steps.create-branch.outputs.branch_name }} --json number --jq '.[0].number')." + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From de1facc5b5d6a71aae5b5bfaed25861ce886b69d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:07:43 -0600 Subject: [PATCH 070/217] chore: Disable troubleshooting mod --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 236b6613..43125681 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -2,7 +2,7 @@ name: process-new-powershell-tip-issue on: issues: - types: [opened, labeled] # Include 'labeled' to make troubleshooting easier. + types: [opened] #, labeled] # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. jobs: process-new-tip-issue: From 15337d4cd22c06917f4a0bf82a315950ed44bfee Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:13:54 -0600 Subject: [PATCH 071/217] chore: Re-enable troubleshooting steps --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 43125681..2304bf76 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -2,7 +2,7 @@ name: process-new-powershell-tip-issue on: issues: - types: [opened] #, labeled] # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. + types: [opened, labeled] # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. jobs: process-new-tip-issue: From 678b032959468295af945907eb0df35e38e2bcaf Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:16:25 -0600 Subject: [PATCH 072/217] chore: Refactor workflow a bit --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2304bf76..58a880d6 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -25,9 +25,9 @@ jobs: run: | Write-Output "Reading information from GitHub issue..." $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - $issueNumber = $issue.number + [string] $issueNumber = $issue.number - $branchName = "new-tip/issue-$issueNumber" + [string] $branchName = "new-tip/issue-$issueNumber" Write-Output "Creating and checking out new branch: $branchName" git config --global user.name 'GitHub Action - tiPS Automation' From e18977f0cc3686e962b0f0db9a8ac69d4ea35771 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:21:54 -0600 Subject: [PATCH 073/217] chore: Testing to fix action --- .../workflows/process-new-powershell-tip-issue.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 58a880d6..3ec66564 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -38,12 +38,12 @@ jobs: "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - name: Add comment to issue letting user know we are processing it - shell: pwsh - run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # - name: Add comment to issue letting user know we are processing it + # shell: pwsh + # run: | + # gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Extract tip information from issue id: extract-tip From fa23822eda322026042b07096f4f9c55b801a1e0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:24:05 -0600 Subject: [PATCH 074/217] chore: Testing --- .../process-new-powershell-tip-issue.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 3ec66564..47dbd061 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -36,14 +36,14 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - # - name: Add comment to issue letting user know we are processing it - # shell: pwsh - # run: | - # gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + + - name: Add comment to issue letting user know we are processing it + shell: pwsh + run: | + gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Extract tip information from issue id: extract-tip From e8691aa0f36b26454571c22da712a1b6d445ca30 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:27:59 -0600 Subject: [PATCH 075/217] chore: Testing --- .github/workflows/process-new-powershell-tip-issue.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 47dbd061..982185d4 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -35,8 +35,6 @@ jobs: git checkout -b "$branchName" Write-Output "Writing variables to environment variables for later steps..." - "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - # "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Add comment to issue letting user know we are processing it shell: pwsh From 7a71ada43519cdbe4012cdc4575571f2c4fc751d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:30:17 -0600 Subject: [PATCH 076/217] chore: Restore lines that are not the problem --- .github/workflows/process-new-powershell-tip-issue.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 982185d4..58a880d6 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -35,6 +35,8 @@ jobs: git checkout -b "$branchName" Write-Output "Writing variables to environment variables for later steps..." + "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Add comment to issue letting user know we are processing it shell: pwsh From c01fb7226ddb6b71de7a0c9f1bf9e580b169a229 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:36:22 -0600 Subject: [PATCH 077/217] chore: Testing --- .../process-new-powershell-tip-issue.yml | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 58a880d6..a4bd39e2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -23,20 +23,20 @@ jobs: id: create-branch shell: pwsh run: | - Write-Output "Reading information from GitHub issue..." - $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - [string] $issueNumber = $issue.number + # Write-Output "Reading information from GitHub issue..." + # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' + # [string] $issueNumber = $issue.number - [string] $branchName = "new-tip/issue-$issueNumber" + # [string] $branchName = "new-tip/issue-$issueNumber" - Write-Output "Creating and checking out new branch: $branchName" - git config --global user.name 'GitHub Action - tiPS Automation' - git config --global user.email 'tiPSAutomation@DoesNotExist.com' - git checkout -b "$branchName" + # Write-Output "Creating and checking out new branch: $branchName" + # git config --global user.name 'GitHub Action - tiPS Automation' + # git config --global user.email 'tiPSAutomation@DoesNotExist.com' + # git checkout -b "$branchName" - Write-Output "Writing variables to environment variables for later steps..." - "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + # Write-Output "Writing variables to environment variables for later steps..." + # "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + # "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Add comment to issue letting user know we are processing it shell: pwsh From 0b1cde08c8f54aa7b4b5c76358f66c795774ef17 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:39:15 -0600 Subject: [PATCH 078/217] chore: Testing --- .../process-new-powershell-tip-issue.yml | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a4bd39e2..68b9301e 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -19,24 +19,7 @@ jobs: with: fetch-depth: 0 - - name: Create branch for PR - id: create-branch - shell: pwsh - run: | - # Write-Output "Reading information from GitHub issue..." - # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - # [string] $issueNumber = $issue.number - - # [string] $branchName = "new-tip/issue-$issueNumber" - - # Write-Output "Creating and checking out new branch: $branchName" - # git config --global user.name 'GitHub Action - tiPS Automation' - # git config --global user.email 'tiPSAutomation@DoesNotExist.com' - # git checkout -b "$branchName" - - # Write-Output "Writing variables to environment variables for later steps..." - # "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - # "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + - name: Add comment to issue letting user know we are processing it shell: pwsh From c3c1f0fc3d00c156c7e237535014106d0ef67ac5 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:44:06 -0600 Subject: [PATCH 079/217] chore: Restore step and use different method to get issue number --- .../process-new-powershell-tip-issue.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 68b9301e..98148f74 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -19,7 +19,21 @@ jobs: with: fetch-depth: 0 - + - name: Create branch for PR + id: create-branch + shell: pwsh + run: | + [string] $issueNumber = '${{ github.event.issue.number }}' + [string] $branchName = "new-tip/issue-$issueNumber" + + Write-Output "Creating and checking out new branch: $branchName" + git config --global user.name 'GitHub Action - tiPS Automation' + git config --global user.email 'tiPSAutomation@DoesNotExist.com' + git checkout -b "$branchName" + + Write-Output "Writing variables to environment variables for later steps..." + "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Add comment to issue letting user know we are processing it shell: pwsh From df37262f3566cd7ffea600585c229fdf0cb7e195 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:46:59 -0600 Subject: [PATCH 080/217] chore: Refactor how issue number is retrieved --- .github/workflows/process-new-powershell-tip-issue.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 98148f74..35db4c76 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -33,12 +33,11 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - "issue_number=$issueNumber" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Add comment to issue letting user know we are processing it shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + gh issue comment "${{ github.event.issue.number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -185,7 +184,7 @@ jobs: Write-Output "Creating pull request..." [string] $prUrl = gh pr create ` --title "Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` - --body "This PR adds a new PowerShell tip submitted via issue #${{ steps.create-branch.outputs.issue_number }}." ` + --body "This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}." ` --label "automation-new-tip-pr-do-not-use" Write-Output "Writing variables to environment variables for later steps..." @@ -196,13 +195,13 @@ jobs: - name: Add comment to issue with link to PR shell: pwsh run: | - gh issue comment "${{ steps.create-branch.outputs.issue_number }}" --body "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}." + gh issue comment "${{ github.event.issue.number }}" --body "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Close issue shell: pwsh run: | - gh issue close "${{ steps.create-branch.outputs.issue_number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." + gh issue close "${{ github.event.issue.number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 3a7a07e88b2d1b3fa20160338feedeb74307b754 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:55:06 -0600 Subject: [PATCH 081/217] chore: Simplify how we obtain issue body in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 35db4c76..a275fe87 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -23,8 +23,7 @@ jobs: id: create-branch shell: pwsh run: | - [string] $issueNumber = '${{ github.event.issue.number }}' - [string] $branchName = "new-tip/issue-$issueNumber" + [string] $branchName = "new-tip/issue-${{ github.event.issue.number }}" Write-Output "Creating and checking out new branch: $branchName" git config --global user.name 'GitHub Action - tiPS Automation' @@ -46,8 +45,9 @@ jobs: shell: pwsh run: | Write-Output "Reading information from GitHub issue..." - $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - $body = $issue.body + # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' + # Need to escape single quotes in the issue body so they don't break the PowerShell syntax. + $body = '${{ github.event.issue.body }}' Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output $body From efde4780865ea682efd146d99c50ef6bca28ba6d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 00:57:24 -0600 Subject: [PATCH 082/217] chore: Try using here-string to avoid parse errors in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a275fe87..a6a8303a 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -47,7 +47,9 @@ jobs: Write-Output "Reading information from GitHub issue..." # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' # Need to escape single quotes in the issue body so they don't break the PowerShell syntax. - $body = '${{ github.event.issue.body }}' + $body = @' + ${{ github.event.issue.body }} + '@ Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output $body From da4451b7d2d6443ee7db33b5c0c14a92f98bd35b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 01:06:11 -0600 Subject: [PATCH 083/217] chore: Wrap body in double quotes as they are less likely to not be in pairs than single quotes --- .github/workflows/process-new-powershell-tip-issue.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a6a8303a..141f4333 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -46,10 +46,8 @@ jobs: run: | Write-Output "Reading information from GitHub issue..." # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' - # Need to escape single quotes in the issue body so they don't break the PowerShell syntax. - $body = @' - ${{ github.event.issue.body }} - '@ + # Need to escape quotes in the issue body so they don't break the PowerShell syntax. + $body = "${{ github.event.issue.body }}" Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output $body From 929a015f9cf910e74482c5aeb08f4b41a2e2f0c4 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 12:37:50 -0600 Subject: [PATCH 084/217] chore: Trying to get quotes working in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 141f4333..36f3419d 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -47,7 +47,9 @@ jobs: Write-Output "Reading information from GitHub issue..." # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' # Need to escape quotes in the issue body so they don't break the PowerShell syntax. - $body = "${{ github.event.issue.body }}" + $body = @' + ${{ github.event.issue.body }} + '@ Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output $body From 768ff3dbd9ce628856105fdd224977aa3436041c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 12:48:24 -0600 Subject: [PATCH 085/217] chore: Still trying to read special characters from issue body properly --- .github/workflows/process-new-powershell-tip-issue.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 36f3419d..a3cdf623 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -40,12 +40,20 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # - name: Write tip information to local file + # id: write-issue-body + # shell: pwsh + # run: | + # Write-Output "Creating issue body file..." + + # Write-Output "Writing variables to environment variables for later steps..." + # "issue_body_file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + - name: Extract tip information from issue id: extract-tip shell: pwsh run: | Write-Output "Reading information from GitHub issue..." - # $issue = ConvertFrom-Json '${{ toJson(github.event.issue) }}' # Need to escape quotes in the issue body so they don't break the PowerShell syntax. $body = @' ${{ github.event.issue.body }} From 516f260798e9da80866fa2d7137c2f020372d7a2 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 13:04:06 -0600 Subject: [PATCH 086/217] chore: Refactor workflow to make issue body output obvious --- .../workflows/process-new-powershell-tip-issue.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a3cdf623..3cd55ae6 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -40,27 +40,19 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # - name: Write tip information to local file - # id: write-issue-body - # shell: pwsh - # run: | - # Write-Output "Creating issue body file..." - - # Write-Output "Writing variables to environment variables for later steps..." - # "issue_body_file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - name: Extract tip information from issue id: extract-tip shell: pwsh run: | Write-Output "Reading information from GitHub issue..." - # Need to escape quotes in the issue body so they don't break the PowerShell syntax. $body = @' ${{ github.event.issue.body }} '@ Write-Output "Displaying issue body for troubleshooting purposes:" + Write-Output "----------------------------------------" Write-Output $body + Write-Output "----------------------------------------" Write-Output "Extracting information from issue body to local variables..." [string] $tipTitle = [string]::Empty From 21b2ff6ac62f97c541d8251b9ccf8bce962b1794 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 13:34:40 -0600 Subject: [PATCH 087/217] chore: Fix regex to use multiline matching for Tip Text and Example Code --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 3cd55ae6..c5894ba2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -99,14 +99,14 @@ jobs: } # Extract Tip Text. - [regex] $tipTextRegex = '### Tip Text \(required\)\s+(?<TipText>.*?)\s+### Example Code' + [regex] $tipTextRegex = '(?s)### Tip Text \(required\)\s+(?<TipText>.*?)\s+### Example Code' if ($body -match $tipTextRegex) { $tipText = $Matches['TipText'].Trim() Write-Output "Extracted Tip Text: $tipText" } # Extract Example Code. - [regex] $exampleRegex = '### Example Code \(optional\)\s+```powershell\\n(?<ExampleCode>.*?)```\s+### URL 1' + [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\\n(?<ExampleCode>.*?)```\s+### URL 1' if ($body -match $exampleRegex) { $tipExample = $Matches['ExampleCode'].Trim() Write-Output "Extracted Example Code: $tipExample" From 448c6c7c4b20ffcab33df306d552a86d07484ce7 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 13:50:27 -0600 Subject: [PATCH 088/217] chore: Refactor workflow for clarity --- .../process-new-powershell-tip-issue.yml | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index c5894ba2..59620335 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -1,8 +1,11 @@ name: process-new-powershell-tip-issue +# Trigger whenever a new issue is opened, and ensure (in the job) it has the automation label meaning we should process it. on: issues: - types: [opened, labeled] # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. + # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. + # Do not leave it on though, as it will result in duplicate PRs being created when new tips are submitted. + types: [opened] #, labeled] jobs: process-new-tip-issue: @@ -14,6 +17,13 @@ jobs: pull-requests: write steps: + - name: Add comment to issue letting user know we are processing it + shell: pwsh + run: | + gh issue comment "${{ github.event.issue.number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout repository uses: actions/checkout@v3 with: @@ -33,15 +43,8 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - - name: Add comment to issue letting user know we are processing it - shell: pwsh - run: | - gh issue comment "${{ github.event.issue.number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract tip information from issue - id: extract-tip + - name: Extract tip information from issue and create new tip file + id: create-tip-file shell: pwsh run: | Write-Output "Reading information from GitHub issue..." @@ -179,13 +182,13 @@ jobs: shell: pwsh run: | Write-Output "Committing changes to local branch and pushing to remote..." - git add "${{ steps.extract-tip.outputs.tip_file_path }}" - git commit -m "Add new tip: ${{ steps.extract-tip.outputs.tip_title }}" + git add "${{ steps.create-tip-file.outputs.tip_file_path }}" + git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" Write-Output "Creating pull request..." [string] $prUrl = gh pr create ` - --title "Tip: ${{ steps.extract-tip.outputs.tip_title }}" ` + --title "Tip: ${{ steps.create-tip-file.outputs.tip_title }}" ` --body "This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}." ` --label "automation-new-tip-pr-do-not-use" From 1387c35a4c6aef60e5f033c9339755a852c90b9e Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 14:04:56 -0600 Subject: [PATCH 089/217] chore: Update messaging in issue comments created by workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 59620335..609051a1 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -189,7 +189,7 @@ jobs: Write-Output "Creating pull request..." [string] $prUrl = gh pr create ` --title "Tip: ${{ steps.create-tip-file.outputs.tip_title }}" ` - --body "This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}." ` + --body "This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}.\n\nNext steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR.\n\nThis PR was created automatically using a GitHub Action." ` --label "automation-new-tip-pr-do-not-use" Write-Output "Writing variables to environment variables for later steps..." @@ -207,6 +207,6 @@ jobs: - name: Close issue shell: pwsh run: | - gh issue close "${{ github.event.issue.number }}" --comment "This issue has been processed and a pull request has been created with your tip. Closing this issue." + gh issue close "${{ github.event.issue.number }}" --comment "This issue has been processed and pull request ${{ steps.create-pr.outputs.pr_url }} has been created with your tip. Closing this issue." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 0ad737cceb2b1731bf8da6c641dab6eaff049201 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 14:28:26 -0600 Subject: [PATCH 090/217] chore: Add comment to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 609051a1..2486c2f7 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -101,14 +101,14 @@ jobs: Write-Output "Extracted Title: $tipTitle" } - # Extract Tip Text. + # Extract Tip Text. Use '(?s)' for multiline match mode, since these are multiline strings. [regex] $tipTextRegex = '(?s)### Tip Text \(required\)\s+(?<TipText>.*?)\s+### Example Code' if ($body -match $tipTextRegex) { $tipText = $Matches['TipText'].Trim() Write-Output "Extracted Tip Text: $tipText" } - # Extract Example Code. + # Extract Example Code. Use '(?s)' for multiline match mode, since these are multiline strings. [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\\n(?<ExampleCode>.*?)```\s+### URL 1' if ($body -match $exampleRegex) { $tipExample = $Matches['ExampleCode'].Trim() From 52504b00eb11c6881ce89a44207c16aa9e38cdf0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 14:43:55 -0600 Subject: [PATCH 091/217] chore: Fix workflow by moving step after checkout --- .github/workflows/process-new-powershell-tip-issue.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2486c2f7..4acc40b3 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -17,6 +17,11 @@ jobs: pull-requests: write steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Add comment to issue letting user know we are processing it shell: pwsh run: | @@ -24,11 +29,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Checkout repository - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - name: Create branch for PR id: create-branch shell: pwsh From ef10ae33343dcf78b583e8218e8d3b8f5d4d5fc3 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 15:11:45 -0600 Subject: [PATCH 092/217] chore: Remove comment step and update comment and close steps with more info in workflow --- .../process-new-powershell-tip-issue.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 4acc40b3..395cd435 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -25,7 +25,10 @@ jobs: - name: Add comment to issue letting user know we are processing it shell: pwsh run: | - gh issue comment "${{ github.event.issue.number }}" --body "Thank you for your submission! 🙏 A pull request is being created for your tip and should be linked to this issue shortly... ⏱️" + [string] $runUrl = "$Env:GITHUB_SERVER_URL/${{ github.repository }}/actions/runs/${{ github.run_id }}" + + gh issue comment "${{ github.event.issue.number }}" ` + --body "Thank you for your submission! 🙏 A pull request is being created for your tip via the following GitHub Actions run and should be linked to this issue shortly... ⏱️\n\n$runUrl" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -197,16 +200,10 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Add comment to issue with link to PR - shell: pwsh - run: | - gh issue comment "${{ github.event.issue.number }}" --body "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}." - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Close issue shell: pwsh run: | - gh issue close "${{ github.event.issue.number }}" --comment "This issue has been processed and pull request ${{ steps.create-pr.outputs.pr_url }} has been created with your tip. Closing this issue." + gh issue close "${{ github.event.issue.number }}" ` + --comment "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}.\n\nThis issue has been processed and will now be closed." env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From e06db842d4699e69de6e28073632eaefc652e478 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 15:12:50 -0600 Subject: [PATCH 093/217] chore: Allow labeling to kick off workflow for testing --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 395cd435..3ae7544b 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -5,7 +5,7 @@ on: issues: # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. # Do not leave it on though, as it will result in duplicate PRs being created when new tips are submitted. - types: [opened] #, labeled] + types: [opened, labeled] jobs: process-new-tip-issue: From e89b0a923c4cffb4272c1de1bc44521ced9546fb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 15:21:08 -0600 Subject: [PATCH 094/217] chore: Fix comments added by workflow so line breaks show up properly --- .../process-new-powershell-tip-issue.yml | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 3ae7544b..caa37131 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -26,9 +26,15 @@ jobs: shell: pwsh run: | [string] $runUrl = "$Env:GITHUB_SERVER_URL/${{ github.repository }}/actions/runs/${{ github.run_id }}" + [string] $message = @" + Thank you for your submission! 🙏 - gh issue comment "${{ github.event.issue.number }}" ` - --body "Thank you for your submission! 🙏 A pull request is being created for your tip via the following GitHub Actions run and should be linked to this issue shortly... ⏱️\n\n$runUrl" + A pull request is being created for your tip via the following GitHub Actions run and should be linked to this issue shortly... ⏱️ + + $runUrl + "@ + + gh issue comment "${{ github.event.issue.number }}" --body $message env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -189,10 +195,18 @@ jobs: git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" + [string] $message = @" + This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}. + + Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. + + This PR was created automatically using a GitHub Action. + "@ + Write-Output "Creating pull request..." [string] $prUrl = gh pr create ` --title "Tip: ${{ steps.create-tip-file.outputs.tip_title }}" ` - --body "This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}.\n\nNext steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR.\n\nThis PR was created automatically using a GitHub Action." ` + --body $message ` --label "automation-new-tip-pr-do-not-use" Write-Output "Writing variables to environment variables for later steps..." @@ -203,7 +217,15 @@ jobs: - name: Close issue shell: pwsh run: | - gh issue close "${{ github.event.issue.number }}" ` - --comment "Thanks for contributing! 🙌 A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}.\n\nThis issue has been processed and will now be closed." + [string] $message = @" + Thanks for contributing! 🙌 + + A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}. + + This issue has been processed and will now be closed. + "@ + + Write-Output "Closing issue and adding comment..." + gh issue close "${{ github.event.issue.number }}" --comment $message env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 171e1edafc172e4dfad97fc326548cd81562c750 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 15:25:45 -0600 Subject: [PATCH 095/217] chore: Allow workflow to be rerun without failing on git command --- .github/workflows/process-new-powershell-tip-issue.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index caa37131..83d24f6f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -193,6 +193,9 @@ jobs: Write-Output "Committing changes to local branch and pushing to remote..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" + + # Git pull is only needed when run fails and needs to be re-run. + git pull --rebase origin "${{ steps.create-branch.outputs.branch_name }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" [string] $message = @" From 6c3ac7fd3cc2f4cdd27de67cb50adadd90137dfb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 15:30:07 -0600 Subject: [PATCH 096/217] chore: Remove unneeded code from workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 83d24f6f..caa37131 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -193,9 +193,6 @@ jobs: Write-Output "Committing changes to local branch and pushing to remote..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" - - # Git pull is only needed when run fails and needs to be re-run. - git pull --rebase origin "${{ steps.create-branch.outputs.branch_name }}" git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" [string] $message = @" From bfd8061a6f378d7099e04364baf05351f959f12f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:03:55 -0600 Subject: [PATCH 097/217] chore: Trim tip title length if needed in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index caa37131..2304c34f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -107,6 +107,15 @@ jobs: [regex] $titleRegex = '### Tip Title \(required\)\s+(?<Title>.*?)\s+### Tip Text' if ($body -match $titleRegex) { $tipTitle = $Matches['Title'].Trim() + + # Trim title to 75 characters max. + # Normally we would let the class validation logic handle this, but we want to do as much as possible + # to ensure the PR creation doesn't fail, as this flow is only triggered on issue creation and we don't + # want to force the user to create a whole new issue just to adjust the title length. + if ($tipTitle.Length -gt 75) { + $tipTitle = $tipTitle.Substring(0, 75) + } + Write-Output "Extracted Title: $tipTitle" } From c0ed3250dec6713fc05e0f07f8927475e8d4a7f1 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:12:20 -0600 Subject: [PATCH 098/217] chore: Fix script to insert strings into script properly --- .../workflows/ProcessNewPowerShellTipIssueFunctions.ps1 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index e9916684..22a22d6e 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -47,8 +47,12 @@ function New-PowerShellTipFile { `$tip = [tiPS.PowerShellTip]::new() `$tip.CreatedDate = [DateTime]::Parse('$createdDate') `$tip.Title = '$($TipTitle.Replace("'", "''"))' -`$tip.TipText = $TipText -`$tip.Example = $TipExample +`$tip.TipText = @' +$TipText +'@ +`$tip.Example = @' +$TipExample +'@ `$tip.Urls = @('$($TipUrls -join "','")') `$tip.Category = [tiPS.TipCategory]::$TipCategory # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. `$tip.Author = '$TipAuthor' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. From 9747ef801d3ca8f6094349008fcc5835e4e7d3df Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:25:41 -0600 Subject: [PATCH 099/217] chore: Update comments wording in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2304c34f..57e60a8f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -205,10 +205,14 @@ jobs: git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" [string] $message = @" - This PR adds a new PowerShell tip submitted via issue #${{ github.event.issue.number }}. + This PR adds the new PowerShell tip submitted via issue #${{ github.event.issue.number }}. Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. + Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. + + 🎉 Thank you for contributing to tiPS! 🎉 + This PR was created automatically using a GitHub Action. "@ @@ -231,6 +235,8 @@ jobs: A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}. + Subscribe to the PR for notifications on any next steps and to see when your tip has been merged into tiPS. + This issue has been processed and will now be closed. "@ From 6873e41d92bb9a8547b506032bd94b8f2f4133f7 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:34:38 -0600 Subject: [PATCH 100/217] chore: Fix how Example Code is extracted in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 57e60a8f..ae75f9bf 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -127,7 +127,7 @@ jobs: } # Extract Example Code. Use '(?s)' for multiline match mode, since these are multiline strings. - [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\\n(?<ExampleCode>.*?)```\s+### URL 1' + [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\s+(?<ExampleCode>.*?)```\s+### URL 1' if ($body -match $exampleRegex) { $tipExample = $Matches['ExampleCode'].Trim() Write-Output "Extracted Example Code: $tipExample" From f460d96a525a3cf55a451aeca649ebfbcb17b701 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:40:33 -0600 Subject: [PATCH 101/217] chore: Disable troubleshooting workflow trigger --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ae75f9bf..09df7815 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -5,7 +5,7 @@ on: issues: # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. # Do not leave it on though, as it will result in duplicate PRs being created when new tips are submitted. - types: [opened, labeled] + types: [opened] #, labeled] jobs: process-new-tip-issue: From c3616fc86d0b355245cea87590cd3140dfc6cd91 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:44:35 -0600 Subject: [PATCH 102/217] chore: Adjust issue template wording a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 349e9d3a..28494000 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -12,7 +12,6 @@ body: Please do not use it yet. It is here for reference only. Thanks for submitting a new PowerShell tip! Please fill in all required fields below. - The more information you provide, the easier it will be for us to review and include your tip. - type: input id: title @@ -38,7 +37,7 @@ body: label: Example Code (optional) description: Provide a working PowerShell example that demonstrates your tip. render: powershell - placeholder: Your example code here... + placeholder: Provide example code here... - type: input id: url1 From 2f8880f44e18a594409198ee27f9692decdd5a34 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:51:22 -0600 Subject: [PATCH 103/217] chore: Move Category field higher in new tip issue form since it is required --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 48 +++++++++---------- .../process-new-powershell-tip-issue.yml | 28 +++++------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 28494000..45c901cd 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -16,7 +16,7 @@ body: - type: input id: title attributes: - label: Tip Title (required) + label: Tip Title description: A concise title for your tip (max 75 characters) placeholder: e.g. Use `-Filter` with `Get-ChildItem` to speed up file searches validations: @@ -25,7 +25,7 @@ body: - type: textarea id: tipText attributes: - label: Tip Text (required) + label: Tip Text description: Detailed explanation of the tip. Be clear and concise. placeholder: Write your tip description here... validations: @@ -39,31 +39,10 @@ body: render: powershell placeholder: Provide example code here... - - type: input - id: url1 - attributes: - label: URL 1 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com - - - type: input - id: url2 - attributes: - label: URL 2 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com - - - type: input - id: url3 - attributes: - label: URL 3 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com - - type: dropdown id: category attributes: - label: Category (required) + label: Category description: | Select the category that best fits your tip. Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. @@ -88,6 +67,27 @@ body: validations: required: true + - type: input + id: url1 + attributes: + label: URL 1 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + + - type: input + id: url2 + attributes: + label: URL 2 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + + - type: input + id: url3 + attributes: + label: URL 3 (optional) + description: URL with additional information (must start with http:// or https://) + placeholder: https://example.com + - type: input id: author attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 09df7815..b36e0105 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -79,9 +79,9 @@ jobs: # GitHub Forms generates structured markdown with specific section headers we can match against. # Below is a sample of what the body data may look like: # - # ### Tip Title (required) + # ### Tip Title # Test title - # ### Tip Text (required) + # ### Tip Text # Test description # ### Example Code (optional) # ```powershell @@ -93,7 +93,7 @@ jobs: # http://two.com # ### URL 3 (optional) # _No response_ - # ### Category (required) + # ### Category # Terminal # ### Author (optional) # _No response_ @@ -104,7 +104,7 @@ jobs: [string] $noResponseText = '_No response_' # Extract Title. - [regex] $titleRegex = '### Tip Title \(required\)\s+(?<Title>.*?)\s+### Tip Text' + [regex] $titleRegex = '### Tip Title\s+(?<Title>.*?)\s+### Tip Text' if ($body -match $titleRegex) { $tipTitle = $Matches['Title'].Trim() @@ -120,19 +120,26 @@ jobs: } # Extract Tip Text. Use '(?s)' for multiline match mode, since these are multiline strings. - [regex] $tipTextRegex = '(?s)### Tip Text \(required\)\s+(?<TipText>.*?)\s+### Example Code' + [regex] $tipTextRegex = '(?s)### Tip Text\s+(?<TipText>.*?)\s+### Example Code' if ($body -match $tipTextRegex) { $tipText = $Matches['TipText'].Trim() Write-Output "Extracted Tip Text: $tipText" } # Extract Example Code. Use '(?s)' for multiline match mode, since these are multiline strings. - [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\s+(?<ExampleCode>.*?)```\s+### URL 1' + [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\s+(?<ExampleCode>.*?)```\s+### Category' if ($body -match $exampleRegex) { $tipExample = $Matches['ExampleCode'].Trim() Write-Output "Extracted Example Code: $tipExample" } + # Extract Category. + [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+### URL 1' + if ($body -match $categoryRegex) { + $tipCategory = $Matches['Category'].Trim() + Write-Output "Extracted Category: $tipCategory" + } + # Extract URLs (up to 3). [regex] $url1Regex = '### URL 1 \(optional\)\s+(?<Url1>.*?)\s+### URL 2' if ($body -match $url1Regex) { @@ -152,7 +159,7 @@ jobs: } } - [regex] $url3Regex = '### URL 3 \(optional\)\s+(?<Url3>.*?)\s+### Category' + [regex] $url3Regex = '### URL 3 \(optional\)\s+(?<Url3>.*?)\s+### Author' if ($body -match $url3Regex) { $url = $Matches['Url3'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { @@ -161,13 +168,6 @@ jobs: } } - # Extract Category. - [regex] $categoryRegex = '### Category \(required\)\s+(?<Category>.*?)\s+### Author' - if ($body -match $categoryRegex) { - $tipCategory = $Matches['Category'].Trim() - Write-Output "Extracted Category: $tipCategory" - } - # Extract Author. [regex] $authorRegex = '### Author \(optional\)\s+(?<Author>.*?)\s+### Expiry Date' if ($body -match $authorRegex) { From 5cb0bc68e87fa5146d8486a02c1597215ec11c2f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 18:57:13 -0600 Subject: [PATCH 104/217] chore: Update wording on tip submission issue form --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 45c901cd..f404cafb 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -26,7 +26,7 @@ body: id: tipText attributes: label: Tip Text - description: Detailed explanation of the tip. Be clear and concise. + description: Detailed explanation of the tip. Try to be clear and concise. placeholder: Write your tip description here... validations: required: true @@ -35,7 +35,7 @@ body: id: example attributes: label: Example Code (optional) - description: Provide a working PowerShell example that demonstrates your tip. + description: Provide one or more PowerShell examples that demonstrates your tip. render: powershell placeholder: Provide example code here... @@ -71,22 +71,22 @@ body: id: url1 attributes: label: URL 1 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com + description: URL with additional information or examples (must start with http:// or https://) + placeholder: https://LearnMoreHere.com - type: input id: url2 attributes: label: URL 2 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com + description: URL with additional information or examples (must start with http:// or https://) + placeholder: https://AndSeeOtherExamplesHere.com - type: input id: url3 attributes: label: URL 3 (optional) - description: URL with additional information (must start with http:// or https://) - placeholder: https://example.com + description: URL with additional information or examples (must start with http:// or https://) + placeholder: https://OfficialDocsOrBlogPostOrSocialMediaPost.com - type: input id: author @@ -105,6 +105,4 @@ body: - type: markdown attributes: value: | - By submitting this tip, you agree to make it available under the project's license. - The tip's CreatedDate will be set to the date when it's accepted, and ExpiryDate will - be set to the maximum date unless otherwise specified. + By submitting this tip, you agree to make it available under the project's license (MIT). From 43c99ff1e4d384be6a1fea5cd2e797de8d24ef81 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 19:00:47 -0600 Subject: [PATCH 105/217] chore: Update issue form wording --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index f404cafb..c2452862 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -99,7 +99,7 @@ body: id: expiryDate attributes: label: Expiry Date (optional) - description: Date when the tip should expire (format of YYYY-MM-DD). Mostly applicable when promoting a community event on a specific date. Leave blank for no expiry. + description: Date when the tip should expire and no longer be shown (format of YYYY-MM-DD). Mostly applicable when promoting a community event on a specific date. Leave blank for no expiry. placeholder: '2025-10-25' - type: markdown From 2830aa89fb8b30fd26838cbca66fb9012df3434b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 19:04:01 -0600 Subject: [PATCH 106/217] chore: Update issue form wording --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index c2452862..1e70f87f 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -86,7 +86,7 @@ body: attributes: label: URL 3 (optional) description: URL with additional information or examples (must start with http:// or https://) - placeholder: https://OfficialDocsOrBlogPostOrSocialMediaPost.com + placeholder: https://OfficialDocs.com/OrBlogPost/OrSocialMediaPost - type: input id: author From e7be62437e7b91869dc7d916f46e03c20510a3d5 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 19:15:16 -0600 Subject: [PATCH 107/217] chore: Fix build by suppressing PSScriptAnalyzer rule --- .github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 index 22a22d6e..482373a2 100644 --- a/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 +++ b/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1 @@ -1,4 +1,5 @@ function New-PowerShellTipFile { + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param( [Parameter(Mandatory = $true, HelpMessage = 'The title of the tip. Must be 75 characters or less.')] [ValidateNotNullOrWhiteSpace()] From f0a1c5ebfc974eae85676802750f9f2e612df1c6 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 20:20:46 -0600 Subject: [PATCH 108/217] chore: Use user PAT to create PRs so that workflow runs get triggered --- .github/workflows/process-new-powershell-tip-issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index b36e0105..a077dcf0 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -225,7 +225,9 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "pr_url=$prUrl" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Must use a user token instead of built-in GITHUB_TOKEN so that workflows will be triggered on the created PR. + # For more information see: https://github.com/peter-evans/create-pull-request/issues/48 + GITHUB_TOKEN: ${{ secrets.TIPS_GITHUB_ACTIONS_PR_CREATION_TOKEN }} - name: Close issue shell: pwsh From e90a8286ca61cd8bddd16bb85e308256b09ad047 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 20:34:41 -0600 Subject: [PATCH 109/217] docs: Update ReadMe with new GitHub issue form method of submitting new tips --- ReadMe.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 000ad57f..e931ed15 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -36,7 +36,7 @@ tiPS provides a low-effort way to learn new things about PowerShell, and help yo tiPS is community driven. Have a tip, module, blog post, or community event that you think others may find valuable? -See the Contributing section below for how to add your tips to tiPS. +See [the Contributing section below](#-contribute-a-tip) for how to easily add your own tips to tiPS. If you enjoy this module, consider giving it a GitHub star ⭐ to show your support. @@ -193,18 +193,16 @@ tiPS is open source, and contributions are not only welcome, they are encouraged Have a PowerShell tip you want to share? Know of a great module, blog post, or community event that you think others should know about? -<!--> + There are 2 ways to submit your tip to tiPS: 1. Use [the GitHub issue template](https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml) to create a PR for your new tip. - This is the easiest method, but since an app creates the PR, you will not be recorded as the contributor in git. + This is the easiest method, but since a GitHub Action creates the PR, you will not be recorded as the contributor in git. However, you can still put your name or handle in the tip's `Author` field. 1. Fork the repo and create a PR for your tip the traditional way, by following the steps below. This method is a bit more work, but you will be recorded as the contributor in git. Follow the steps below to fork the repo and manually submit your PR: ---> -Follow these steps to add your tip to tiPS: 1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). 1. Clone the repo to your local machine, or open it in GitHub Codespaces, and create a new branch. @@ -212,7 +210,7 @@ Follow these steps to add your tip to tiPS: 1. Modify it with your tip info and commit your changes. 1. Submit a pull request from your fork back to this repo ([See GitHub docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)). -🎦 [This video](https://youtu.be/OBg1KJf8sC4?si=CXEtMmaaZ3ybQAVF) walks through the above steps, showing how to contribute a new tip 🎦 +🎦 [This video](https://youtu.be/OBg1KJf8sC4?si=CXEtMmaaZ3ybQAVF) walks through the above steps, showing how to fork the repo to contribute a new tip 🎦 tiPS is meant to be a community driven project, so please help make it better by contributing your tips. From d5769528570fc20ceb8bd7eb92d0f75ed755a44c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 20:41:39 -0600 Subject: [PATCH 110/217] docs: Restyle contributing section a bit --- ReadMe.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index e931ed15..3c473ccf 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -202,15 +202,14 @@ There are 2 ways to submit your tip to tiPS: 1. Fork the repo and create a PR for your tip the traditional way, by following the steps below. This method is a bit more work, but you will be recorded as the contributor in git. -Follow the steps below to fork the repo and manually submit your PR: - -1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). -1. Clone the repo to your local machine, or open it in GitHub Codespaces, and create a new branch. -1. Run the [New-PowerShellTip script](/tools/New-PowerShellTip.ps1) to create your new tip file in the [PowerShellTips directory](/src/PowerShellTips/). -1. Modify it with your tip info and commit your changes. -1. Submit a pull request from your fork back to this repo ([See GitHub docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)). - -🎦 [This video](https://youtu.be/OBg1KJf8sC4?si=CXEtMmaaZ3ybQAVF) walks through the above steps, showing how to fork the repo to contribute a new tip 🎦 + Follow the steps below to fork the repo and manually submit your PR: + 1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). + 1. Clone the repo to your local machine, or open it in GitHub Codespaces, and create a new branch. + 1. Run the [New-PowerShellTip script](/tools/New-PowerShellTip.ps1) to create your new tip file in the [PowerShellTips directory](/src/PowerShellTips/). + 1. Modify it with your tip info and commit your changes. + 1. Submit a pull request from your fork back to this repo ([See GitHub docs](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork)). + + 🎦 [This video](https://youtu.be/OBg1KJf8sC4?si=CXEtMmaaZ3ybQAVF) walks through the above steps, showing how to fork the repo to contribute a new tip 🎦 tiPS is meant to be a community driven project, so please help make it better by contributing your tips. From 2281e0910188e392cebd5d8ee4d6f295db954e28 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 29 Mar 2025 20:43:21 -0600 Subject: [PATCH 111/217] chore: Update issue form instructions a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 1e70f87f..ec76ede3 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -1,6 +1,6 @@ name: PowerShell tip submission description: Submit a new PowerShell tip to be included in the tiPS module -title: "New Tip Submission - Ignore this field" +title: "New Tip Submission - Ignore this field and fill in the ones below" labels: ["automation-new-tip-issue-do-not-use"] body: # NOTE: The input label, required validation, and order is used by the process-new-powershell-tip-issue.yml workflow to extract the data from the issue body. From 625374852b7a22cd51dfa4db19707a5a8ea4ccb6 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:05:39 -0600 Subject: [PATCH 112/217] chore: Update new tip contribution issue template --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index ec76ede3..82b296d4 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -8,10 +8,7 @@ body: - type: markdown attributes: value: | - THIS FORM DOES NOT WORK YET! IT IS STILL A WORK IN PROGRESS! - Please do not use it yet. It is here for reference only. - - Thanks for submitting a new PowerShell tip! Please fill in all required fields below. + Thanks for contributing to tiPS! Fill out the fields below to submit a new PowerShell tip. - type: input id: title @@ -39,12 +36,10 @@ body: render: powershell placeholder: Provide example code here... - - type: dropdown - id: category + - type: markdown attributes: - label: Category - description: | - Select the category that best fits your tip. + value: | + Category descriptions: Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. @@ -54,6 +49,11 @@ body: Syntax - Syntax tips. e.g. splatting, pipeline, etc. Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. Other - Tips that don't fit into any of the other categories. + - type: dropdown + id: category + attributes: + label: Category + description: Select the category that best fits your tip. options: - Community - Editor From 37345c85d9e58101a9d1f361b1a722f8a8376092 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:06:48 -0600 Subject: [PATCH 113/217] chore: Update issue template a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 82b296d4..9de12740 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -39,7 +39,7 @@ body: - type: markdown attributes: value: | - Category descriptions: + ## Category descriptions: Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. From 3baa876a4dd707b6c1acd51af7ed4a5a80218122 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:07:10 -0600 Subject: [PATCH 114/217] chore: Update issue template a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 9de12740..8e8bbe57 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -39,7 +39,7 @@ body: - type: markdown attributes: value: | - ## Category descriptions: + ### Category descriptions: Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. From 1356f0de5b6d1de71c9d1120c7cfe74fdf34b957 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:33:50 -0600 Subject: [PATCH 115/217] chore: Move category descriptions below the category dropdown --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 27 ++++++++++--------- .../process-new-powershell-tip-issue.yml | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 8e8bbe57..dc64a7d9 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -36,19 +36,6 @@ body: render: powershell placeholder: Provide example code here... - - type: markdown - attributes: - value: | - ### Category descriptions: - Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. - Editor - Editor tips and extensions. e.g. VSCode, ISE, etc. - Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. - NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. - Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. - Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. - Syntax - Syntax tips. e.g. splatting, pipeline, etc. - Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. - Other - Tips that don't fit into any of the other categories. - type: dropdown id: category attributes: @@ -67,6 +54,20 @@ body: validations: required: true + - type: markdown + attributes: + value: | + ### Category descriptions: + Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. + Editor - Editor tips and extensions. e.g. VS Code, ISE, etc. + Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. + NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. + Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. + Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. + Syntax - Syntax tips. e.g. splatting, pipeline, keywords, etc. + Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. + Other - Tips that don't fit into any of the other categories. + - type: input id: url1 attributes: diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a077dcf0..afc45562 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -134,7 +134,7 @@ jobs: } # Extract Category. - [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+### URL 1' + [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+### Category descriptions' if ($body -match $categoryRegex) { $tipCategory = $Matches['Category'].Trim() Write-Output "Extracted Category: $tipCategory" From f9ea4104cfabd74f27d009078e4acb66a93c741d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:34:50 -0600 Subject: [PATCH 116/217] chore: Update issue template a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 2 +- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index dc64a7d9..a32d8a56 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -57,7 +57,7 @@ body: - type: markdown attributes: value: | - ### Category descriptions: + #### Category descriptions: Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. Editor - Editor tips and extensions. e.g. VS Code, ISE, etc. Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index afc45562..15d0a489 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -134,7 +134,7 @@ jobs: } # Extract Category. - [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+### Category descriptions' + [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+#### Category descriptions' if ($body -match $categoryRegex) { $tipCategory = $Matches['Category'].Trim() Write-Output "Extracted Category: $tipCategory" From 1dc3bd6e8d8bdca294b646cf35f560043fdf590d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 19:46:46 -0600 Subject: [PATCH 117/217] chore: Update category descriptions a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 18 +++++++++--------- tools/New-PowerShellTip.ps1 | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index a32d8a56..188194c6 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -58,15 +58,15 @@ body: attributes: value: | #### Category descriptions: - Community - Social events and community resources. e.g. PowerShell Summit, podcasts, etc. - Editor - Editor tips and extensions. e.g. VS Code, ISE, etc. - Module - Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. - NativeCmdlet - Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. - Performance - Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. - Security - Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. - Syntax - Syntax tips. e.g. splatting, pipeline, keywords, etc. - Terminal - Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. - Other - Tips that don't fit into any of the other categories. + Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. + Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. + Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. + NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. + Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. + Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. + Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. + Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. + Other: Tips that don't fit into any of the other categories. - type: input id: url1 diff --git a/tools/New-PowerShellTip.ps1 b/tools/New-PowerShellTip.ps1 index bd20ee7d..dfcdc781 100644 --- a/tools/New-PowerShellTip.ps1 +++ b/tools/New-PowerShellTip.ps1 @@ -58,12 +58,12 @@ Example code to demonstrate the tip. This can also be multiple lines if needed. # Category meanings: # Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. -# Editor: Editor tips and extensions. e.g. VSCode, ISE, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. # Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. # NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. # Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. # Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. -# Syntax: Syntax tips. e.g. splatting, pipeline, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. # Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. # Other: Tips that don't fit into any of the other categories. "@ From c3f4fe63bfaaa01ecff2b0ca3417b037c88c993d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Wed, 2 Apr 2025 20:22:31 -0600 Subject: [PATCH 118/217] chore: Add https:// to URLs in workflow if they do not have it --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 6 +++--- .../workflows/process-new-powershell-tip-issue.yml | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 188194c6..19b50fe1 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -72,21 +72,21 @@ body: id: url1 attributes: label: URL 1 (optional) - description: URL with additional information or examples (must start with http:// or https://) + description: URL with additional information or examples. placeholder: https://LearnMoreHere.com - type: input id: url2 attributes: label: URL 2 (optional) - description: URL with additional information or examples (must start with http:// or https://) + description: URL with additional information or examples. placeholder: https://AndSeeOtherExamplesHere.com - type: input id: url3 attributes: label: URL 3 (optional) - description: URL with additional information or examples (must start with http:// or https://) + description: URL with additional information or examples. placeholder: https://OfficialDocs.com/OrBlogPost/OrSocialMediaPost - type: input diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 15d0a489..a48cbb3d 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -145,6 +145,10 @@ jobs: if ($body -match $url1Regex) { $url = $Matches['Url1'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { + # Ensure URL starts with http(s)://. + if (-not ($url.StartsWith('http://') -or $url.StartsWith('https://'))) { + $url = "https://$url" + } $tipUrls += $url Write-Output "Extracted URL 1: $url" } @@ -154,6 +158,10 @@ jobs: if ($body -match $url2Regex) { $url = $Matches['Url2'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { + # Ensure URL starts with http(s)://. + if (-not ($url.StartsWith('http://') -or $url.StartsWith('https://'))) { + $url = "https://$url" + } $tipUrls += $url Write-Output "Extracted URL 2: $url" } @@ -163,6 +171,10 @@ jobs: if ($body -match $url3Regex) { $url = $Matches['Url3'].Replace($noResponseText, '').Trim() if (-not [string]::IsNullOrWhiteSpace($url)) { + # Ensure URL starts with http(s)://. + if (-not ($url.StartsWith('http://') -or $url.StartsWith('https://'))) { + $url = "https://$url" + } $tipUrls += $url Write-Output "Extracted URL 3: $url" } From f071ab4155b8a4bd1feb72a1d5fcf28eeaeb6928 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:25:42 -0600 Subject: [PATCH 119/217] chore fix: Include the Expiry Date properly in the tip workflow. chore feat: Allow user to get Git attribution in issue workflow --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 7 ++++++ .../process-new-powershell-tip-issue.yml | 25 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 19b50fe1..412eeb1c 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -103,6 +103,13 @@ body: description: Date when the tip should expire and no longer be shown (format of YYYY-MM-DD). Mostly applicable when promoting a community event on a specific date. Leave blank for no expiry. placeholder: '2025-10-25' + - type: input + id: gitHubCoAuthor + attributes: + label: Name and GitHub Email (optional) + description: Your name and GitHub email address in the format, name <email address>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous. + placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> + - type: markdown attributes: value: | diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a48cbb3d..1361f51d 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -74,6 +74,7 @@ jobs: [string[]] $tipUrls = @() [string] $tipAuthor = [string]::Empty [string] $tipExpiryDate = [string]::Empty + [string] $gitHubCoAuthor = [string]::Empty # Extract the data from the markdown representation of the issue. # GitHub Forms generates structured markdown with specific section headers we can match against. @@ -187,6 +188,20 @@ jobs: Write-Output "Extracted Author: $tipAuthor" } + # Extract Expiry Date. + [regex] $expiryDateRegex = '### Expiry Date \(optional\)\s+(?<ExpiryDate>.*?)\s+### Name and GitHub Email' + if ($body -match $expiryDateRegex) { + $tipExpiryDate = $Matches['ExpiryDate'].Trim() + Write-Output "Extracted Expiry Date: $tipExpiryDate" + } + + # Extract GitHub Co-Author. + [regex] $gitHubCoAuthorRegex = '### Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)\s+' + if ($body -match $gitHubCoAuthorRegex) { + $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() + Write-Output "Extracted GitHub Email: $gitHubCoAuthor" + } + Write-Output "Dot-sourcing utility script used to create the new tip file..." [string] $gitRootDirectoryPath = $Env:GITHUB_WORKSPACE . "$gitRootDirectoryPath/.github/workflows/ProcessNewPowerShellTipIssueFunctions.ps1" @@ -206,14 +221,22 @@ jobs: Write-Output "Writing variables to environment variables for later steps..." "tip_file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append + "github_coauthor=$gitHubCoAuthor" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append - name: Push changes and create PR id: create-pr shell: pwsh run: | + [string] $coAuthorCommitMessage = [string]::Empty + [string] $gitHubCoAuthor = '${{ steps.create-tip-file.outputs.github_coauthor }}' + if ($gitHubCoAuthor -ne [string]::Empty) { + $coAuthorCommitMessage = "-m ""Co-authored-by: $gitHubCoAuthor""" + Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" + } + Write-Output "Committing changes to local branch and pushing to remote..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" - git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" + git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" [string] $message = @" From a4dead8543f2a5f6312364e642b81e39e228ad58 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:33:20 -0600 Subject: [PATCH 120/217] chore feat: Do not close issue until PR is merged or closed --- .../process-new-powershell-tip-issue.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1361f51d..2e7e4fcc 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -34,6 +34,7 @@ jobs: $runUrl "@ + Write-Output "Adding comment with link to workflow run to issue..." gh issue comment "${{ github.event.issue.number }}" --body $message env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -44,9 +45,11 @@ jobs: run: | [string] $branchName = "new-tip/issue-${{ github.event.issue.number }}" - Write-Output "Creating and checking out new branch: $branchName" + Write-Output "Setting up git user information for automated workflow..." git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' + + Write-Output "Creating and checking out new branch: $branchName" git checkout -b "$branchName" Write-Output "Writing variables to environment variables for later steps..." @@ -248,8 +251,10 @@ jobs: 🎉 Thank you for contributing to tiPS! 🎉 - This PR was created automatically using a GitHub Action. + This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. "@ + # Using "resolve #issue_number" in the PR message above will automatically close the issue when the PR is merged. + # For more information see: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword Write-Output "Creating pull request..." [string] $prUrl = gh pr create ` @@ -274,10 +279,10 @@ jobs: Subscribe to the PR for notifications on any next steps and to see when your tip has been merged into tiPS. - This issue has been processed and will now be closed. + This issue will be automatically closed when the PR is merged or closed. "@ - Write-Output "Closing issue and adding comment..." - gh issue close "${{ github.event.issue.number }}" --comment $message + Write-Output "Adding comment with link to PR to issue..." + gh issue comment "${{ github.event.issue.number }}" --body $message env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 1e4fac9a2f823fe47ce67790a2fda353f457180a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:39:22 -0600 Subject: [PATCH 121/217] chore refactor: Update workflow step names --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 2e7e4fcc..aacdf1ef 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -22,7 +22,7 @@ jobs: with: fetch-depth: 0 - - name: Add comment to issue letting user know we are processing it + - name: Comment on issue letting user know we are processing it shell: pwsh run: | [string] $runUrl = "$Env:GITHUB_SERVER_URL/${{ github.repository }}/actions/runs/${{ github.run_id }}" @@ -269,7 +269,7 @@ jobs: # For more information see: https://github.com/peter-evans/create-pull-request/issues/48 GITHUB_TOKEN: ${{ secrets.TIPS_GITHUB_ACTIONS_PR_CREATION_TOKEN }} - - name: Close issue + - name: Comment on issue with link to PR shell: pwsh run: | [string] $message = @" From 9fc2510a5312f4ed878d841808e6e9792f038fe5 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:42:21 -0600 Subject: [PATCH 122/217] chore: Update issue template label --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 4 ++-- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 412eeb1c..e3a1d1a3 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -106,8 +106,8 @@ body: - type: input id: gitHubCoAuthor attributes: - label: Name and GitHub Email (optional) - description: Your name and GitHub email address in the format, name <email address>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous. + label: Git Display Name and GitHub Email (optional) + description: Your name and GitHub email address in the format, DisplayName \<EmailAddress\>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous. placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> - type: markdown diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index aacdf1ef..97402b67 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -192,14 +192,14 @@ jobs: } # Extract Expiry Date. - [regex] $expiryDateRegex = '### Expiry Date \(optional\)\s+(?<ExpiryDate>.*?)\s+### Name and GitHub Email' + [regex] $expiryDateRegex = '### Expiry Date \(optional\)\s+(?<ExpiryDate>.*?)\s+### Git Display Name and GitHub Email' if ($body -match $expiryDateRegex) { $tipExpiryDate = $Matches['ExpiryDate'].Trim() Write-Output "Extracted Expiry Date: $tipExpiryDate" } # Extract GitHub Co-Author. - [regex] $gitHubCoAuthorRegex = '### Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)\s+' + [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)\s+' if ($body -match $gitHubCoAuthorRegex) { $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() Write-Output "Extracted GitHub Email: $gitHubCoAuthor" From 14cd5edbedfd72310cd2daf60bf90309c6fd5d0f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:54:40 -0600 Subject: [PATCH 123/217] chore: Update issue template label --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index e3a1d1a3..cda7eeb2 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -107,7 +107,10 @@ body: id: gitHubCoAuthor attributes: label: Git Display Name and GitHub Email (optional) - description: Your name and GitHub email address in the format, DisplayName \<EmailAddress\>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous. + description: > + Your display name and GitHub email address in the format: DisplayName \<EmailAddress\> + + This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> - type: markdown From 54d8613c963264de643b1f9c67e6393cad99bdce Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 20:56:28 -0600 Subject: [PATCH 124/217] chore: Update issue template label a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index cda7eeb2..3ea69398 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -108,9 +108,7 @@ body: attributes: label: Git Display Name and GitHub Email (optional) description: > - Your display name and GitHub email address in the format: DisplayName \<EmailAddress\> - - This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. + Your display name and GitHub email address in the format: DisplayName \<EmailAddress\>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> - type: markdown From 2a5cbcb65940126009583f6787a67f571929bc8a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:09:30 -0600 Subject: [PATCH 125/217] chore: Update comments in workflow with updated example --- .../process-new-powershell-tip-issue.yml | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 97402b67..a749253e 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -84,25 +84,46 @@ jobs: # Below is a sample of what the body data may look like: # # ### Tip Title - # Test title + # + # Testing title + # # ### Tip Text + # # Test description + # # ### Example Code (optional) + # # ```powershell - # Test code + # Example code # ``` + # + # ### Category + # + # Syntax + # # ### URL 1 (optional) - # https://one.com + # + # https://example.com + # # ### URL 2 (optional) - # http://two.com + # + # https://anotherExample.com + # # ### URL 3 (optional) + # # _No response_ - # ### Category - # Terminal + # # ### Author (optional) - # _No response_ + # + # Daniel Schroeder (deadlydog) + # # ### Expiry Date (optional) + # # _No response_ + # + # ### Git Display Name and GitHub Email (optional) + # + # Daniel Schroeder <deadlydog@hotmail.com> # The default text that GitHub Issues uses for optional fields that are not filled in. [string] $noResponseText = '_No response_' From 7a5db9d4c1f7aa8bede6c891643728de14e5efb2 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:10:32 -0600 Subject: [PATCH 126/217] chore fix: Properly capture the Category from the issue template --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a749253e..0a272f5d 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -159,7 +159,7 @@ jobs: } # Extract Category. - [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+#### Category descriptions' + [regex] $categoryRegex = '### Category\s+(?<Category>.*?)\s+### URL 1' if ($body -match $categoryRegex) { $tipCategory = $Matches['Category'].Trim() Write-Output "Extracted Category: $tipCategory" From 87022038b721050c3d7543a52f7c2479f8d8e09a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:29:23 -0600 Subject: [PATCH 127/217] chore feat: Allow workflow to rerun when issue is edited --- .github/workflows/process-new-powershell-tip-issue.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 0a272f5d..f2fe91d8 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -3,9 +3,7 @@ name: process-new-powershell-tip-issue # Trigger whenever a new issue is opened, and ensure (in the job) it has the automation label meaning we should process it. on: issues: - # Can add 'labeled' to make troubleshooting easier and simply remove/add label to trigger workflow run. - # Do not leave it on though, as it will result in duplicate PRs being created when new tips are submitted. - types: [opened] #, labeled] + types: [opened, edited] jobs: process-new-tip-issue: @@ -29,9 +27,11 @@ jobs: [string] $message = @" Thank you for your submission! 🙏 - A pull request is being created for your tip via the following GitHub Actions run and should be linked to this issue shortly... ⏱️ + A pull request is being created for your tip via the following GitHub Actions workflow run and should be linked to this issue shortly... ⏱️ $runUrl + + If the run fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description to fix it up and it will automatically re-run the workflow and update the PR. "@ Write-Output "Adding comment with link to workflow run to issue..." From abb7625c80489fc40bd7cf1414330f100ab6130c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:35:31 -0600 Subject: [PATCH 128/217] chore fix: Capture GitHubCoAuthor properly in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f2fe91d8..682f924f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -220,7 +220,7 @@ jobs: } # Extract GitHub Co-Author. - [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)\s+' + [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)$' if ($body -match $gitHubCoAuthorRegex) { $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() Write-Output "Extracted GitHub Email: $gitHubCoAuthor" From 32b26d82780e26ec0654865eb6c2ba64fd3aa191 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:38:48 -0600 Subject: [PATCH 129/217] chore: Update comment in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 682f924f..8aa7f651 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -223,7 +223,7 @@ jobs: [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)$' if ($body -match $gitHubCoAuthorRegex) { $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() - Write-Output "Extracted GitHub Email: $gitHubCoAuthor" + Write-Output "Extracted GitHub Co-Author: $gitHubCoAuthor" } Write-Output "Dot-sourcing utility script used to create the new tip file..." From 28694392172bf963462eb8036648bfb80259592d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:58:08 -0600 Subject: [PATCH 130/217] chore fix: Allow workflow to update remote branch --- .github/workflows/process-new-powershell-tip-issue.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 8aa7f651..f9102df2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -52,6 +52,9 @@ jobs: Write-Output "Creating and checking out new branch: $branchName" git checkout -b "$branchName" + Write-Output "Fetching latest branch changes from remote branch if it exists, in case this was triggered from editing an issue. We will get an error when trying to push if we're not on the latest version of the branch..." + git pull origin/$branchName $branchName --rebase + Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 5226c3933eb557203486860955c9a634d2519507 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 21:59:00 -0600 Subject: [PATCH 131/217] chore: Remove unnecessary rebase flag from workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f9102df2..f4ceb2f8 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -53,7 +53,7 @@ jobs: git checkout -b "$branchName" Write-Output "Fetching latest branch changes from remote branch if it exists, in case this was triggered from editing an issue. We will get an error when trying to push if we're not on the latest version of the branch..." - git pull origin/$branchName $branchName --rebase + git pull origin/$branchName $branchName Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 306a2229119ff160df5061ba4eb3834e5cced79c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 22:04:12 -0600 Subject: [PATCH 132/217] chore fix: Ignore expected errors in workflow and convert them to stdout --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f4ceb2f8..7970766c 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -53,7 +53,7 @@ jobs: git checkout -b "$branchName" Write-Output "Fetching latest branch changes from remote branch if it exists, in case this was triggered from editing an issue. We will get an error when trying to push if we're not on the latest version of the branch..." - git pull origin/$branchName $branchName + git pull origin/$branchName $branchName 2>&1 # Convert errors to stdout since they are expected when the branch doesn't exist yet. Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From f7014a7df76c03d13903cddda1adcb087a73e2c0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 22:12:51 -0600 Subject: [PATCH 133/217] chore fix: Pull branch if it exists on the remote in workflow --- .../workflows/process-new-powershell-tip-issue.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 7970766c..f3b7230a 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -49,11 +49,17 @@ jobs: git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' - Write-Output "Creating and checking out new branch: $branchName" - git checkout -b "$branchName" + # Check if branch exists on remote and pull latest changes if it does. + [string] $remoteBranchName = "origin/$branchName" + if (git show-ref --verify --quiet "$remoteBranchName") { + Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." + git pull origin "$branchName" + } else { + Write-Output "Branch '$branchName' does not exist on remote. No need to pull it." + } - Write-Output "Fetching latest branch changes from remote branch if it exists, in case this was triggered from editing an issue. We will get an error when trying to push if we're not on the latest version of the branch..." - git pull origin/$branchName $branchName 2>&1 # Convert errors to stdout since they are expected when the branch doesn't exist yet. + Write-Output "Checking out branch: $branchName" + git checkout -b "$branchName" Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 789426a74f8533d6ee164c65131bca2f3b79584b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 22:16:12 -0600 Subject: [PATCH 134/217] chore: Add comment to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f3b7230a..1c25aa52 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -260,6 +260,8 @@ jobs: id: create-pr shell: pwsh run: | + # Use GitHub's Co-Author feature to add the user as a committer on the git commit. + # GitHub docs: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors [string] $coAuthorCommitMessage = [string]::Empty [string] $gitHubCoAuthor = '${{ steps.create-tip-file.outputs.github_coauthor }}' if ($gitHubCoAuthor -ne [string]::Empty) { From c169c3c42c45a45261045ae24e7002d9dcb53ba2 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 22:31:19 -0600 Subject: [PATCH 135/217] chore fix: Fix logic to check remote branch in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1c25aa52..ea02fb7b 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -51,7 +51,9 @@ jobs: # Check if branch exists on remote and pull latest changes if it does. [string] $remoteBranchName = "origin/$branchName" - if (git show-ref --verify --quiet "$remoteBranchName") { + [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") + [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) + if ($remoteBranchExists) { Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." git pull origin "$branchName" } else { From daa57da05c71fa7dc57e8c3a37202887bd59da15 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 23:18:35 -0600 Subject: [PATCH 136/217] chore: Only create PR if it does not already exist in workflow --- .../process-new-powershell-tip-issue.yml | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ea02fb7b..1ab6d1b5 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -39,7 +39,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Create branch for PR + - name: Checkout branch for PR id: create-branch shell: pwsh run: | @@ -276,25 +276,47 @@ jobs: git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" - [string] $message = @" - This PR adds the new PowerShell tip submitted via issue #${{ github.event.issue.number }}. + Write-Output "Checking if a PR already exists for this branch..." + $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") + + # Get the PR number from the output. + # The output will look like this when a PR is found for the branch: + # Showing 1 of 1 pull request in deadlydog/PowerShell.tiPS that matches your search + # ID TITLE BRANCH CREATED AT + # #110 Tip: Test title new-tip/issue-109 about 1 hour ago + [string] $prNumber = [string]::Empty + [regex] $prNumberRegex = '#(?<PRNumber>\d+)' + if ($prOutput -match $prNumberRegex) { + $prNumber = $Matches['PRNumber'] + Write-Output "PR already exists. PR number: $prNumber" + } - Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. + # If the PR number was not found, create a new PR. + [string] $prUrl = [string]::Empty + if ([string]::IsNullOrWhiteSpace($prNumber)) { + [string] $message = @" + This PR adds the new PowerShell tip submitted via issue #${{ github.event.issue.number }}. - Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. + Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. - 🎉 Thank you for contributing to tiPS! 🎉 + Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. - This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. - "@ - # Using "resolve #issue_number" in the PR message above will automatically close the issue when the PR is merged. - # For more information see: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword - - Write-Output "Creating pull request..." - [string] $prUrl = gh pr create ` - --title "Tip: ${{ steps.create-tip-file.outputs.tip_title }}" ` - --body $message ` - --label "automation-new-tip-pr-do-not-use" + 🎉 Thank you for contributing to tiPS! 🎉 + + This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. + "@ + # Using "resolve #issue_number" in the PR message above will automatically close the issue when the PR is merged. + # For more information see: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword + + Write-Output "Creating pull request..." + $prUrl = gh pr create ` + --title "Tip: ${{ steps.create-tip-file.outputs.tip_title }}" ` + --body $message ` + --label "automation-new-tip-pr-do-not-use" + } else { + $prUrl = "https://github.com/${{ github.repository }}/pull/$prNumber" + Write-Output "PR already exists. PR URL: $prUrl" + } Write-Output "Writing variables to environment variables for later steps..." "pr_url=$prUrl" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From c46d370ab3a62bf1487bb2875ab41ccfdb234634 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 3 Apr 2025 23:29:51 -0600 Subject: [PATCH 137/217] chore: Refactor workflow code --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1ab6d1b5..f7875363 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -266,7 +266,7 @@ jobs: # GitHub docs: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors [string] $coAuthorCommitMessage = [string]::Empty [string] $gitHubCoAuthor = '${{ steps.create-tip-file.outputs.github_coauthor }}' - if ($gitHubCoAuthor -ne [string]::Empty) { + if (-not ([string]::IsNullOrWhiteSpace($gitHubCoAuthor))) { $coAuthorCommitMessage = "-m ""Co-authored-by: $gitHubCoAuthor""" Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" } From c603dd79668fac2597a1959a462cf503b16cdd92 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 00:16:04 -0600 Subject: [PATCH 138/217] chore: Add logging to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f7875363..19ea0ae9 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -264,6 +264,7 @@ jobs: run: | # Use GitHub's Co-Author feature to add the user as a committer on the git commit. # GitHub docs: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors + Write-Output "Setting up git co-author information for git commit..." [string] $coAuthorCommitMessage = [string]::Empty [string] $gitHubCoAuthor = '${{ steps.create-tip-file.outputs.github_coauthor }}' if (-not ([string]::IsNullOrWhiteSpace($gitHubCoAuthor))) { @@ -279,7 +280,7 @@ jobs: Write-Output "Checking if a PR already exists for this branch..." $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") - # Get the PR number from the output. + # Get the PR number from the output, if it exists. # The output will look like this when a PR is found for the branch: # Showing 1 of 1 pull request in deadlydog/PowerShell.tiPS that matches your search # ID TITLE BRANCH CREATED AT @@ -315,7 +316,7 @@ jobs: --label "automation-new-tip-pr-do-not-use" } else { $prUrl = "https://github.com/${{ github.repository }}/pull/$prNumber" - Write-Output "PR already exists. PR URL: $prUrl" + Write-Output "PR already existed. PR URL: $prUrl" } Write-Output "Writing variables to environment variables for later steps..." From 2669bb45dc458464a6d0e8d39c56bf176918b0be Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 00:19:48 -0600 Subject: [PATCH 139/217] chore: Trim PR Number in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 19ea0ae9..4d7b5237 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -288,7 +288,7 @@ jobs: [string] $prNumber = [string]::Empty [regex] $prNumberRegex = '#(?<PRNumber>\d+)' if ($prOutput -match $prNumberRegex) { - $prNumber = $Matches['PRNumber'] + $prNumber = $Matches['PRNumber'].Trim() Write-Output "PR already exists. PR number: $prNumber" } From c7a3085b5c9b99e82cfe02ff0fe5849a27cdc564 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 00:23:12 -0600 Subject: [PATCH 140/217] chore: Fix syntax of here-string in workflow --- .../workflows/process-new-powershell-tip-issue.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 4d7b5237..34aa8bb4 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -296,16 +296,16 @@ jobs: [string] $prUrl = [string]::Empty if ([string]::IsNullOrWhiteSpace($prNumber)) { [string] $message = @" - This PR adds the new PowerShell tip submitted via issue #${{ github.event.issue.number }}. + This PR adds the new PowerShell tip submitted via issue #${{ github.event.issue.number }}. - Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. + Next steps are to wait for the PR checks to pass, and for the maintainer to review and merge this PR. - Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. + Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. - 🎉 Thank you for contributing to tiPS! 🎉 + 🎉 Thank you for contributing to tiPS! 🎉 - This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. - "@ + This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. + "@ # Using "resolve #issue_number" in the PR message above will automatically close the issue when the PR is merged. # For more information see: https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword From d79a6f351bbf2b758b99a5c272a55c7e7f8edc00 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 08:33:07 -0600 Subject: [PATCH 141/217] chore fix: Properly detect existing PR number --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 34aa8bb4..72f37ce6 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -286,7 +286,7 @@ jobs: # ID TITLE BRANCH CREATED AT # #110 Tip: Test title new-tip/issue-109 about 1 hour ago [string] $prNumber = [string]::Empty - [regex] $prNumberRegex = '#(?<PRNumber>\d+)' + [regex] $prNumberRegex = '(?s)#(?<PRNumber>\d+)' # Use '(?s)' for multiline match mode. if ($prOutput -match $prNumberRegex) { $prNumber = $Matches['PRNumber'].Trim() Write-Output "PR already exists. PR number: $prNumber" From 6eadb87a200fe21040272203afc9bcfb85d44494 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 08:38:18 -0600 Subject: [PATCH 142/217] chore: Update wording of issue comments left by workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 72f37ce6..b22b7d24 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -30,8 +30,6 @@ jobs: A pull request is being created for your tip via the following GitHub Actions workflow run and should be linked to this issue shortly... ⏱️ $runUrl - - If the run fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description to fix it up and it will automatically re-run the workflow and update the PR. "@ Write-Output "Adding comment with link to workflow run to issue..." @@ -302,6 +300,8 @@ jobs: Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. + If the PR check fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description and it will automatically re-run the workflow to update the PR. + 🎉 Thank you for contributing to tiPS! 🎉 This PR was created automatically using a GitHub Action to resolve #${{ github.event.issue.number }}. @@ -334,7 +334,9 @@ jobs: A pull request has been created for your tip. You can view it at PR ${{ steps.create-pr.outputs.pr_url }}. - Subscribe to the PR for notifications on any next steps and to see when your tip has been merged into tiPS. + Subscribe to the PR to receive notifications for any comments and to see when your tip has been merged into tiPS. + + If the PR check fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description and it will automatically re-run the workflow to update the PR. This issue will be automatically closed when the PR is merged or closed. "@ From 75d3211b94e3d6a7cf8867aaa8af47b41ab908f8 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 08:45:29 -0600 Subject: [PATCH 143/217] chore fix: Fix how the PR number is extracted from command output --- .github/workflows/process-new-powershell-tip-issue.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index b22b7d24..445df760 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -279,12 +279,14 @@ jobs: $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") # Get the PR number from the output, if it exists. - # The output will look like this when a PR is found for the branch: + # The output to the console will look like this when a PR is found for the branch: # Showing 1 of 1 pull request in deadlydog/PowerShell.tiPS that matches your search # ID TITLE BRANCH CREATED AT - # #110 Tip: Test title new-tip/issue-109 about 1 hour ago + # #110 Tip: Test title new-tip/issue-109 about 10 hours ago + # But the actual output captured by the variable will look like this: + # 110 Tip: Test title new-tip/issue-109 OPEN 2025-04-04T03:45:47Z [string] $prNumber = [string]::Empty - [regex] $prNumberRegex = '(?s)#(?<PRNumber>\d+)' # Use '(?s)' for multiline match mode. + [regex] $prNumberRegex = '^(?<PRNumber>\d+)' if ($prOutput -match $prNumberRegex) { $prNumber = $Matches['PRNumber'].Trim() Write-Output "PR already exists. PR number: $prNumber" From 9c3758a8424d1d819389342e71e28b3b9ab85faf Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 08:51:03 -0600 Subject: [PATCH 144/217] chore: Try rebasing to prevent other commits from showing in workflow PR --- .github/workflows/process-new-powershell-tip-issue.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 445df760..b45958b7 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -60,6 +60,7 @@ jobs: Write-Output "Checking out branch: $branchName" git checkout -b "$branchName" + git rebase main Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From ef2247e79a8deee9eeafcc8cb3d7547b07f70cc5 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 08:59:06 -0600 Subject: [PATCH 145/217] chore: Update issue comment left by workflow a bit --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index b45958b7..444c5e95 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -303,7 +303,7 @@ jobs: Subscribe to this PR to receive notifications for any comments and to see when your tip has been merged into tiPS. - If the PR check fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description and it will automatically re-run the workflow to update the PR. + If the PR check fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description and it will automatically re-run the workflow to update this PR. 🎉 Thank you for contributing to tiPS! 🎉 From e883b314234c728f669160e34de7a43aac8410fe Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:02:47 -0600 Subject: [PATCH 146/217] chore fix: Properly ignore all optional fields when they are not provided --- .github/workflows/process-new-powershell-tip-issue.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 444c5e95..20629b32 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -164,7 +164,7 @@ jobs: # Extract Example Code. Use '(?s)' for multiline match mode, since these are multiline strings. [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\s+(?<ExampleCode>.*?)```\s+### Category' if ($body -match $exampleRegex) { - $tipExample = $Matches['ExampleCode'].Trim() + $tipExample = $Matches['ExampleCode'].Replace($noResponseText, '').Trim() Write-Output "Extracted Example Code: $tipExample" } @@ -218,21 +218,21 @@ jobs: # Extract Author. [regex] $authorRegex = '### Author \(optional\)\s+(?<Author>.*?)\s+### Expiry Date' if ($body -match $authorRegex) { - $tipAuthor = $Matches['Author'].Trim() + $tipAuthor = $Matches['Author'].Replace($noResponseText, '').Trim() Write-Output "Extracted Author: $tipAuthor" } # Extract Expiry Date. [regex] $expiryDateRegex = '### Expiry Date \(optional\)\s+(?<ExpiryDate>.*?)\s+### Git Display Name and GitHub Email' if ($body -match $expiryDateRegex) { - $tipExpiryDate = $Matches['ExpiryDate'].Trim() + $tipExpiryDate = $Matches['ExpiryDate'].Replace($noResponseText, '').Trim() Write-Output "Extracted Expiry Date: $tipExpiryDate" } # Extract GitHub Co-Author. [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)$' if ($body -match $gitHubCoAuthorRegex) { - $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() + $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Replace($noResponseText, '').Trim() Write-Output "Extracted GitHub Co-Author: $gitHubCoAuthor" } From 4ab23324f4ac0c51469c63e00a94c753df852d62 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:13:36 -0600 Subject: [PATCH 147/217] chore fix: Sanitize the Tip Expiry Date and GitHub CoAuthor when none are provided --- .../workflows/process-new-powershell-tip-issue.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 20629b32..ae01b2ed 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -164,7 +164,7 @@ jobs: # Extract Example Code. Use '(?s)' for multiline match mode, since these are multiline strings. [regex] $exampleRegex = '(?s)### Example Code \(optional\)\s+```powershell\s+(?<ExampleCode>.*?)```\s+### Category' if ($body -match $exampleRegex) { - $tipExample = $Matches['ExampleCode'].Replace($noResponseText, '').Trim() + $tipExample = $Matches['ExampleCode'].Trim() Write-Output "Extracted Example Code: $tipExample" } @@ -218,21 +218,21 @@ jobs: # Extract Author. [regex] $authorRegex = '### Author \(optional\)\s+(?<Author>.*?)\s+### Expiry Date' if ($body -match $authorRegex) { - $tipAuthor = $Matches['Author'].Replace($noResponseText, '').Trim() + $tipAuthor = $Matches['Author'].Trim() Write-Output "Extracted Author: $tipAuthor" } # Extract Expiry Date. [regex] $expiryDateRegex = '### Expiry Date \(optional\)\s+(?<ExpiryDate>.*?)\s+### Git Display Name and GitHub Email' if ($body -match $expiryDateRegex) { - $tipExpiryDate = $Matches['ExpiryDate'].Replace($noResponseText, '').Trim() + $tipExpiryDate = $Matches['ExpiryDate'].Trim() Write-Output "Extracted Expiry Date: $tipExpiryDate" } # Extract GitHub Co-Author. [regex] $gitHubCoAuthorRegex = '### Git Display Name and GitHub Email \(optional\)\s+(?<GitHubCoAuthor>.*?)$' if ($body -match $gitHubCoAuthorRegex) { - $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Replace($noResponseText, '').Trim() + $gitHubCoAuthor = $Matches['GitHubCoAuthor'].Trim() Write-Output "Extracted GitHub Co-Author: $gitHubCoAuthor" } @@ -248,10 +248,13 @@ jobs: TipUrls = $tipUrls TipCategory = $tipCategory.Replace($noResponseText, '').Trim() TipAuthor = $tipAuthor.Replace($noResponseText, '').Trim() - TipExpiryDate = $tipExpiryDate + TipExpiryDate = $tipExpiryDate.Replace($noResponseText, '').Trim() } [string] $newTipFilePath = New-PowerShellTipFile @newTipFileParameters + # Sanitize the GitHub Co-Author string if none was provided. + $gitHubCoAuthor = $gitHubCoAuthor.Replace($noResponseText, '').Trim() + Write-Output "Writing variables to environment variables for later steps..." "tip_file_path=$newTipFilePath" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append "tip_title=$tipTitle" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 7d1de1efeba174c3c69409bdc56b1c4e7c85fc66 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:31:19 -0600 Subject: [PATCH 148/217] chore: Trying to prevent main branch commits from showing in PR --- .../workflows/process-new-powershell-tip-issue.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ae01b2ed..a881f9ac 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -55,11 +55,14 @@ jobs: Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." git pull origin "$branchName" } else { - Write-Output "Branch '$branchName' does not exist on remote. No need to pull it." + Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." + git branch "$branchName" "origin/main" --set-upstream } - Write-Output "Checking out branch: $branchName" - git checkout -b "$branchName" + Write-Output "Switching to branch: $branchName" + git switch "$branchName" + + Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." git rebase main Write-Output "Writing variables to environment variables for later steps..." @@ -277,7 +280,8 @@ jobs: Write-Output "Committing changes to local branch and pushing to remote..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage - git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" + git push + #git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" Write-Output "Checking if a PR already exists for this branch..." $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") From b400f849e4e2723fa9d00a81a4bb84dfa823b5f9 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:38:19 -0600 Subject: [PATCH 149/217] chore fix: Use modern git commands --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a881f9ac..1f992349 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -56,7 +56,7 @@ jobs: git pull origin "$branchName" } else { Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." - git branch "$branchName" "origin/main" --set-upstream + git branch "$branchName" --set-upstream-to "origin/$branchName" } Write-Output "Switching to branch: $branchName" From 9eb796e36a91c1ca0627a1eb9a5d36d89a3cdce3 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:47:56 -0600 Subject: [PATCH 150/217] chore fix: Fix up git command syntax when creating branch --- .../workflows/process-new-powershell-tip-issue.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 1f992349..c4f0d600 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -47,7 +47,7 @@ jobs: git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' - # Check if branch exists on remote and pull latest changes if it does. + # Check if branch exists on remote and pull it if it does. [string] $remoteBranchName = "origin/$branchName" [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) @@ -56,7 +56,7 @@ jobs: git pull origin "$branchName" } else { Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." - git branch "$branchName" --set-upstream-to "origin/$branchName" + git branch "$branchName" } Write-Output "Switching to branch: $branchName" @@ -277,11 +277,12 @@ jobs: Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" } - Write-Output "Committing changes to local branch and pushing to remote..." + Write-Output "Committing changes to local branch..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage - git push - #git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" + + Write-Output "Pushing changes to remote branch..." + git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" Write-Output "Checking if a PR already exists for this branch..." $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") From ce09640ff1b441cb1a244377b7e45375e5a3e135 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 09:57:32 -0600 Subject: [PATCH 151/217] chore fix: Use git checkout instead of switch to prevent problems --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index c4f0d600..76708104 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -59,8 +59,8 @@ jobs: git branch "$branchName" } - Write-Output "Switching to branch: $branchName" - git switch "$branchName" + Write-Output "Checking out branch: $branchName" + git checkout "$branchName" Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." git rebase main From 0bddffc3531f3e0f4ee72d6dde4e2ff44ca59705 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:07:07 -0600 Subject: [PATCH 152/217] chore: Add more logging to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 76708104..ec435988 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -277,8 +277,10 @@ jobs: Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" } - Write-Output "Committing changes to local branch..." + Write-Output "Adding new tip file to git staging area..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" + + Write-Output "Committing changes to local branch..." git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage Write-Output "Pushing changes to remote branch..." From 87dc402f04db66584281a86afe49afab43acb84b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:13:15 -0600 Subject: [PATCH 153/217] chore: Trying to fix git in workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ec435988..199fd203 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -55,15 +55,15 @@ jobs: Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." git pull origin "$branchName" } else { - Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." - git branch "$branchName" + #Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." + #git branch "$branchName" } Write-Output "Checking out branch: $branchName" - git checkout "$branchName" + git checkout -b "$branchName" - Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." - git rebase main + #Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." + #git rebase main Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 007923aae5f2800b752f1e9dedfdf39f9d347968 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:15:59 -0600 Subject: [PATCH 154/217] chore: Undo troubleshooting changes --- .github/workflows/process-new-powershell-tip-issue.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 199fd203..ec435988 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -55,15 +55,15 @@ jobs: Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." git pull origin "$branchName" } else { - #Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." - #git branch "$branchName" + Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." + git branch "$branchName" } Write-Output "Checking out branch: $branchName" - git checkout -b "$branchName" + git checkout "$branchName" - #Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." - #git rebase main + Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." + git rebase main Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 1ad91d30a6a8ef9dde9dd40f7a9d0d9ae39c7bde Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:17:14 -0600 Subject: [PATCH 155/217] chore: Add temp troubleshooting code to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index ec435988..5317cedf 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -277,6 +277,13 @@ jobs: Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" } + # Temp troubleshooting code + $filePath = '${{ steps.create-tip-file.outputs.tip_file_path }}' + Write-Output "Checking if file exists: $filePath" + if (-not (Test-Path $filePath)) { + Write-Output "File does not exist." + } + Write-Output "Adding new tip file to git staging area..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" From 27bac3d58e5017291fadb2e56e8a40d94673c1ee Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:20:53 -0600 Subject: [PATCH 156/217] chore: Troubleshooting workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 5317cedf..cf11cbd1 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -288,7 +288,8 @@ jobs: git add "${{ steps.create-tip-file.outputs.tip_file_path }}" Write-Output "Committing changes to local branch..." - git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage + #git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage + git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" Write-Output "Pushing changes to remote branch..." git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" From acbda47698deebebf85c2cb20c20efce62236e45 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:48:07 -0600 Subject: [PATCH 157/217] chore fix: Only add Co-author if one was provided --- .../process-new-powershell-tip-issue.yml | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index cf11cbd1..81d5d267 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -267,29 +267,22 @@ jobs: id: create-pr shell: pwsh run: | + [string] $commitMessage = "New tip: ${{ steps.create-tip-file.outputs.tip_title }}" + # Use GitHub's Co-Author feature to add the user as a committer on the git commit. # GitHub docs: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors - Write-Output "Setting up git co-author information for git commit..." - [string] $coAuthorCommitMessage = [string]::Empty [string] $gitHubCoAuthor = '${{ steps.create-tip-file.outputs.github_coauthor }}' if (-not ([string]::IsNullOrWhiteSpace($gitHubCoAuthor))) { - $coAuthorCommitMessage = "-m ""Co-authored-by: $gitHubCoAuthor""" + [string] $coAuthorCommitMessage = "Co-authored-by: $gitHubCoAuthor" Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" - } - - # Temp troubleshooting code - $filePath = '${{ steps.create-tip-file.outputs.tip_file_path }}' - Write-Output "Checking if file exists: $filePath" - if (-not (Test-Path $filePath)) { - Write-Output "File does not exist." + $commitMessage += [Environment]::NewLine + [Environment]::NewLine + $coAuthorCommitMessage" } Write-Output "Adding new tip file to git staging area..." git add "${{ steps.create-tip-file.outputs.tip_file_path }}" Write-Output "Committing changes to local branch..." - #git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" $coAuthorCommitMessage - git commit -m "Add new tip: ${{ steps.create-tip-file.outputs.tip_title }}" + git commit -m "$commitMessage" Write-Output "Pushing changes to remote branch..." git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" From e0e471500c34cc61bd09c4f691a6184927f7b186 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:55:07 -0600 Subject: [PATCH 158/217] fix: Remove empty URLs when trimming all PowerShellTip properties --- src/CSharpClasses/tiPSClasses/PowerShellTip.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CSharpClasses/tiPSClasses/PowerShellTip.cs b/src/CSharpClasses/tiPSClasses/PowerShellTip.cs index 9a4dfd3a..47ac1cde 100644 --- a/src/CSharpClasses/tiPSClasses/PowerShellTip.cs +++ b/src/CSharpClasses/tiPSClasses/PowerShellTip.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace tiPS { @@ -72,6 +73,7 @@ public void TrimAllProperties() { Urls[i] = Urls[i].Trim(); } + Urls = Urls.Where(url => !string.IsNullOrWhiteSpace(url)).ToArray(); // Remove empty URLs. Author = Author.Trim(); } From 4096447941d78401ef50e43473f182a5dce5638b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 10:59:29 -0600 Subject: [PATCH 159/217] test: Add test to ensure empty URLs are removed during trimming --- src/tiPS/Classes/PowerShellTip.Tests.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tiPS/Classes/PowerShellTip.Tests.ps1 b/src/tiPS/Classes/PowerShellTip.Tests.ps1 index fb094175..4796f4b6 100644 --- a/src/tiPS/Classes/PowerShellTip.Tests.ps1 +++ b/src/tiPS/Classes/PowerShellTip.Tests.ps1 @@ -57,6 +57,16 @@ Describe 'Trimming all tip properties' { $tip.Urls | Should -Be $urls $tip.Author | Should -Be $author } + + It 'Should remove empty URLs from the URL array' { + [tiPS.PowerShellTip] $tip = $ValidTip + [string[]] $urls = @('https://Url1.com', '', 'http://Url2.com') + $tip.Urls = $urls + + { $tip.TrimAllProperties() } | Should -Not -Throw + + $tip.Urls | Should -Be @('https://Url1.com', 'http://Url2.com') + } } Context 'Given the properties need whitespace trimmed' { From 6bb9bd2e825660bcf2b1e60a6f11059d227f7c39 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:00:41 -0600 Subject: [PATCH 160/217] chore fix: Remove dangling quotation mark --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 81d5d267..0e91a1b7 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -275,7 +275,7 @@ jobs: if (-not ([string]::IsNullOrWhiteSpace($gitHubCoAuthor))) { [string] $coAuthorCommitMessage = "Co-authored-by: $gitHubCoAuthor" Write-Output "Adding co-author to commit message: $coAuthorCommitMessage" - $commitMessage += [Environment]::NewLine + [Environment]::NewLine + $coAuthorCommitMessage" + $commitMessage += [Environment]::NewLine + [Environment]::NewLine + $coAuthorCommitMessage } Write-Output "Adding new tip file to git staging area..." From 76d580ed5a312ddcbfe78c89543f04ff21f084aa Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:04:43 -0600 Subject: [PATCH 161/217] docs: Update ReadMe information around submitting tips --- ReadMe.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 3c473ccf..18d1cece 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -197,10 +197,9 @@ Know of a great module, blog post, or community event that you think others shou There are 2 ways to submit your tip to tiPS: 1. Use [the GitHub issue template](https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml) to create a PR for your new tip. - This is the easiest method, but since a GitHub Action creates the PR, you will not be recorded as the contributor in git. - However, you can still put your name or handle in the tip's `Author` field. + This is the easiest way to submit a tip. 1. Fork the repo and create a PR for your tip the traditional way, by following the steps below. - This method is a bit more work, but you will be recorded as the contributor in git. + You will need to use fork the repo if you want to contribute other changes to the module as well, besides just new tips. Follow the steps below to fork the repo and manually submit your PR: 1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). From d9ab127d31353d8203270d7cc52284aec7727ca9 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:09:45 -0600 Subject: [PATCH 162/217] chore: Fetch entire git history so we can rebase properly --- .github/workflows/process-new-powershell-tip-issue.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 0e91a1b7..b7f605fe 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -17,8 +17,6 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - with: - fetch-depth: 0 - name: Comment on issue letting user know we are processing it shell: pwsh From 47e4c0ed039e189266b9309ca2d49ac3f0a79f29 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:11:27 -0600 Subject: [PATCH 163/217] chore: Update issue comment left by workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index b7f605fe..8bb1ae7a 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -350,7 +350,7 @@ jobs: If the PR check fails due to a spelling mistake, or you want to update the tip information, you can edit the issue description and it will automatically re-run the workflow to update the PR. - This issue will be automatically closed when the PR is merged or closed. + This issue will be automatically closed when the PR is merged. "@ Write-Output "Adding comment with link to PR to issue..." From 41d5a34e0877db4de48257b074f5eba915706fec Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:17:15 -0600 Subject: [PATCH 164/217] chore: Use git force push to branch since we are rebasing on main each time --- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 8bb1ae7a..d521b12e 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -283,7 +283,8 @@ jobs: git commit -m "$commitMessage" Write-Output "Pushing changes to remote branch..." - git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" + # Use force push because we rebased the branch on main, and the commit history may have changed. + git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" --force-with-lease Write-Output "Checking if a PR already exists for this branch..." $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") From 6d62f14040fd786c1c059c4c67e6baf32ee0da9f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:25:41 -0600 Subject: [PATCH 165/217] chore: Add logging to workflow --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index d521b12e..de3876e0 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -45,7 +45,7 @@ jobs: git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' - # Check if branch exists on remote and pull it if it does. + Write-Output "Checking if branch '$branchName' already exists on remote..." [string] $remoteBranchName = "origin/$branchName" [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) From b8ac504445305e12257296560506ed426414fbfb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:33:20 -0600 Subject: [PATCH 166/217] chore: Adjust how we create the git branch in workflow --- .../process-new-powershell-tip-issue.yml | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index de3876e0..515c14cc 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -45,23 +45,20 @@ jobs: git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' + Write-Output "Creating and checking out local branch: $branchName" + git checkout -b "$branchName" + Write-Output "Checking if branch '$branchName' already exists on remote..." [string] $remoteBranchName = "origin/$branchName" [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) if ($remoteBranchExists) { - Write-Output "Branch '$branchName' already exists on remote. Pulling latest changes..." - git pull origin "$branchName" - } else { - Write-Output "Branch '$branchName' does not exist on remote. Creating local branch..." - git branch "$branchName" - } + Write-Output "Branch '$branchName' already exists on remote. Getting remote changes..." + git reset --hard "origin/$branchName" - Write-Output "Checking out branch: $branchName" - git checkout "$branchName" - - Write-Output "Rebasing branch '$branchName' on main to ensure it has latest changes..." - git rebase main + Write-Output "Rebasing branch '$branchName' on main to ensure it has latest main branch changes..." + git rebase main + } Write-Output "Writing variables to environment variables for later steps..." "branch_name=$branchName" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append From 104d84f26783587d0020e105d63996024b2afff4 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:42:49 -0600 Subject: [PATCH 167/217] chore fix: Do not fail step if remote branch does not exist --- .github/workflows/process-new-powershell-tip-issue.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 515c14cc..900393fb 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -39,12 +39,12 @@ jobs: id: create-branch shell: pwsh run: | - [string] $branchName = "new-tip/issue-${{ github.event.issue.number }}" - Write-Output "Setting up git user information for automated workflow..." git config --global user.name 'GitHub Action - tiPS Automation' git config --global user.email 'tiPSAutomation@DoesNotExist.com' + [string] $branchName = 'new-tip/issue-${{ github.event.issue.number }}' + Write-Output "Creating and checking out local branch: $branchName" git checkout -b "$branchName" @@ -58,6 +58,10 @@ jobs: Write-Output "Rebasing branch '$branchName' on main to ensure it has latest main branch changes..." git rebase main + } else { + # If the branch doesn't exist, the 'git show-ref' command will have returned a non-zero exit code. + # Reset the PowerShell LastExitCode variable to 0 to avoid failing the workflow run. + $LastExitCode = 0 } Write-Output "Writing variables to environment variables for later steps..." From bedc1233c6e4598b4c3ba7b0dfdd62a8f95a49bc Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:49:42 -0600 Subject: [PATCH 168/217] chore refactor: Workflow logging refactor --- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 900393fb..12fa25eb 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -330,9 +330,10 @@ jobs: --label "automation-new-tip-pr-do-not-use" } else { $prUrl = "https://github.com/${{ github.repository }}/pull/$prNumber" - Write-Output "PR already existed. PR URL: $prUrl" } + Write-Output "PR URL is: $prUrl" + Write-Output "Writing variables to environment variables for later steps..." "pr_url=$prUrl" | Out-File -FilePath $Env:GITHUB_OUTPUT -Encoding utf8 -Append env: From 347999f783ca9fe7b833b02d75235a9f5df966f0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:55:03 -0600 Subject: [PATCH 169/217] chore refactor: Use variable name --- .github/workflows/process-new-powershell-tip-issue.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 12fa25eb..53174cfe 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -54,7 +54,7 @@ jobs: [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) if ($remoteBranchExists) { Write-Output "Branch '$branchName' already exists on remote. Getting remote changes..." - git reset --hard "origin/$branchName" + git reset --hard "$remoteBranchName" Write-Output "Rebasing branch '$branchName' on main to ensure it has latest main branch changes..." git rebase main From 9dc4604f0704fe66fbd23822d822ba409ad4d9cb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 11:56:52 -0600 Subject: [PATCH 170/217] chore: Add troubleshooting logging --- .github/workflows/process-new-powershell-tip-issue.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 53174cfe..a55c6ae6 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -51,6 +51,7 @@ jobs: Write-Output "Checking if branch '$branchName' already exists on remote..." [string] $remoteBranchName = "origin/$branchName" [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") + Write-Output "Remote branch SHA: $remoteBranchSha" [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) if ($remoteBranchExists) { Write-Output "Branch '$branchName' already exists on remote. Getting remote changes..." From 490fcc8565c34af442e4d73e276ed477008e0b45 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 12:01:03 -0600 Subject: [PATCH 171/217] chore: Ensure workflow run fails if changes are not pushed to remote branch --- .github/workflows/process-new-powershell-tip-issue.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index a55c6ae6..f867026f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -288,6 +288,10 @@ jobs: # Use force push because we rebased the branch on main, and the commit history may have changed. git push --set-upstream origin "${{ steps.create-branch.outputs.branch_name }}" --force-with-lease + if ($LastExitCode -ne 0) { + throw "Git push to remote branch failed. Exiting workflow run." + } + Write-Output "Checking if a PR already exists for this branch..." $prOutput = (& gh pr list --head "${{ steps.create-branch.outputs.branch_name }}") From 40f3cbc43044479245337de41054da019ffe10f3 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 12:03:08 -0600 Subject: [PATCH 172/217] chore fix: Fetch all git history for all branches --- .github/workflows/process-new-powershell-tip-issue.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f867026f..917c8ee7 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -17,6 +17,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 + with: + fetch-depth: 0 # Fetch all history for all branches and tags to ensure we can rebase the branch on main. - name: Comment on issue letting user know we are processing it shell: pwsh From b384ec02c9579bbb0788861626fe5fa8400fdad9 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 12:06:35 -0600 Subject: [PATCH 173/217] chore: Remote troubleshooting statement --- .github/workflows/process-new-powershell-tip-issue.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 917c8ee7..f6d7489f 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -53,7 +53,6 @@ jobs: Write-Output "Checking if branch '$branchName' already exists on remote..." [string] $remoteBranchName = "origin/$branchName" [string] $remoteBranchSha = (& git show-ref "$remoteBranchName") - Write-Output "Remote branch SHA: $remoteBranchSha" [bool] $remoteBranchExists = -not ([string]::IsNullOrWhitespace($remoteBranchSha)) if ($remoteBranchExists) { Write-Output "Branch '$branchName' already exists on remote. Getting remote changes..." @@ -62,7 +61,7 @@ jobs: Write-Output "Rebasing branch '$branchName' on main to ensure it has latest main branch changes..." git rebase main } else { - # If the branch doesn't exist, the 'git show-ref' command will have returned a non-zero exit code. + # If the remote branch doesn't exist, the 'git show-ref' command will have returned a non-zero exit code. # Reset the PowerShell LastExitCode variable to 0 to avoid failing the workflow run. $LastExitCode = 0 } From cbb3d4b1e56d5f305c2c21ca920b04f4dc81fc23 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 12:12:18 -0600 Subject: [PATCH 174/217] chore: Update GitHub issue template for clarity --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 3ea69398..0583d7fd 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -108,10 +108,15 @@ body: attributes: label: Git Display Name and GitHub Email (optional) description: > - Your display name and GitHub email address in the format: DisplayName \<EmailAddress\>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. + Your display name and GitHub email address. Must be in the GitHub co-author commit format: DisplayName \<EmailAddress\>. e.g. Daniel Schroeder \<deadlydog@hotmail.com\>. placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> - type: markdown attributes: value: | - By submitting this tip, you agree to make it available under the project's license (MIT). + This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. + + - type: markdown + attributes: + value: | + ### By submitting this tip, you agree to make it available under the project's license (MIT). From 2c4f6c4b04945ad666fce0b1ad6663cd10e9c7f7 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 4 Apr 2025 12:13:57 -0600 Subject: [PATCH 175/217] chore: Update issue template a bit --- .github/ISSUE_TEMPLATE/new_powershell_tip.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml index 0583d7fd..b804fb62 100644 --- a/.github/ISSUE_TEMPLATE/new_powershell_tip.yml +++ b/.github/ISSUE_TEMPLATE/new_powershell_tip.yml @@ -108,15 +108,10 @@ body: attributes: label: Git Display Name and GitHub Email (optional) description: > - Your display name and GitHub email address. Must be in the GitHub co-author commit format: DisplayName \<EmailAddress\>. e.g. Daniel Schroeder \<deadlydog@hotmail.com\>. + Your display name and GitHub email address. Must be in the GitHub co-author commit format: DisplayName \<EmailAddress\>. e.g. Daniel Schroeder \<deadlydog@hotmail.com\>. This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. placeholder: e.g. Daniel Schroeder <deadlydog@hotmail.com> - type: markdown attributes: value: | - This allows you to get attribution in the git history and GitHub. If you do not want to use your public GitHub email address, you can use your private GitHub email address, which can be enabled and found at https://github.com/settings/emails. Leave blank if you prefer to remain anonymous in the git history. - - - type: markdown - attributes: - value: | - ### By submitting this tip, you agree to make it available under the project's license (MIT). + #### By submitting this tip, you agree to make it available under the project's license (MIT). From 8bcacec20476cc781b806bbca2d125dfb5057ba1 Mon Sep 17 00:00:00 2001 From: GitHub Action - tiPS Automation <tiPSAutomation@DoesNotExist.com> Date: Fri, 4 Apr 2025 19:55:07 +0000 Subject: [PATCH 176/217] New tip: Submit your own tiPS tips from the web form Co-authored-by: Daniel Schroeder <deadlydog@hotmail.com> --- ...mit-your-own-tips-tips-from-the-web-form.ps1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/PowerShellTips/2025-04-04-submit-your-own-tips-tips-from-the-web-form.ps1 diff --git a/src/PowerShellTips/2025-04-04-submit-your-own-tips-tips-from-the-web-form.ps1 b/src/PowerShellTips/2025-04-04-submit-your-own-tips-tips-from-the-web-form.ps1 new file mode 100644 index 00000000..241aea5e --- /dev/null +++ b/src/PowerShellTips/2025-04-04-submit-your-own-tips-tips-from-the-web-form.ps1 @@ -0,0 +1,17 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-04-04') +$tip.Title = 'Submit your own tiPS tips from the web form' +$tip.TipText = @' +You can now easily submit your own PowerShell tips for the tiPS module right from the GitHub repository website! There is a new GitHub issue template called "PowerShell tip submission". When you open an issue you will be prompted for your tip's information, such as the tip title, text, category, example code, and URLs. You can even enter your GitHub email address so that you are tagged as a co-author on the commit, allowing you to still get credit in the git history. + +This tip was submitted using a GitHub issue. Visit the website and submit a tip today! +'@ +$tip.Example = @' +Start-Process 'https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml' +'@ +$tip.Urls = @('https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml','https://github.com/deadlydog/PowerShell.tiPS#-contribute-a-tip') +$tip.Category = [tiPS.TipCategory]::Module # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Tip submitted via GitHub issue workflow. From 7752a7dcb12c577269d44ff2c6452bbe212ef17a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sun, 6 Apr 2025 14:02:15 -0600 Subject: [PATCH 177/217] docs: Fix typo in ReadMe --- ReadMe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 18d1cece..71aa67ea 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -198,8 +198,8 @@ There are 2 ways to submit your tip to tiPS: 1. Use [the GitHub issue template](https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml) to create a PR for your new tip. This is the easiest way to submit a tip. -1. Fork the repo and create a PR for your tip the traditional way, by following the steps below. - You will need to use fork the repo if you want to contribute other changes to the module as well, besides just new tips. +1. Fork the repo and create a PR for your tip the traditional way. + You will need to fork the repo if you want to contribute other changes to the module, besides just new tips. Follow the steps below to fork the repo and manually submit your PR: 1. Fork this repo to your account ([See GitHub docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)). From 62696cd77d795468cbed5c1798ab2377d5692c67 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 10 Apr 2025 10:43:46 -0600 Subject: [PATCH 178/217] tip: Add tip for null-conditional operators --- ...ks-by-using-null-conditional-operators.ps1 | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/PowerShellTips/2025-04-09-reduce-null-checks-by-using-null-conditional-operators.ps1 diff --git a/src/PowerShellTips/2025-04-09-reduce-null-checks-by-using-null-conditional-operators.ps1 b/src/PowerShellTips/2025-04-09-reduce-null-checks-by-using-null-conditional-operators.ps1 new file mode 100644 index 00000000..05c4f2d1 --- /dev/null +++ b/src/PowerShellTips/2025-04-09-reduce-null-checks-by-using-null-conditional-operators.ps1 @@ -0,0 +1,52 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-04-09') +$tip.Title = 'Reduce null checks by using null-conditional operators' +$tip.TipText = @' +PowerShell 7.1 introduced the null-conditional operators `?.` and `?[]`. These operators allow you to simplify your code by avoiding explicit null checks when accessing properties or elements of objects or arrays that may be null. + +By default, if you try to index into a null array (e.g. $nullArray[0]), an exception will be thrown. Similarly, if you have Strict Mode enabled and try to access a property of a null object (e.g. $nullObject.SomeProperty), an exception will be thrown. The null-conditional operators allow you to avoid these exceptions and return null instead. You can even chain these together when accessing nested properties. + +One slight caveat is that because '?' can be part of a variable name, you must use braces '{}' around the variable name. e.g. ${someVariable}?.Property or ${someVariable}?[0]. +'@ +$tip.Example = @' +# Example of using the null-conditional operator with an array. +$nullArray = $null +$element = $nullArray[0] # Throws exception 'InvalidOperation: Cannot index into a null array.' +$element = ${nullArray}?[0] # $element will be null without throwing an exception. + +$array = @('Element1', 'Element2') +$element = ${array}?[0] # $element will be 'Element1'. + +# Example of using the null-conditional operator with a property. +$nullObject = $null +$property = $nullObject.Property # $property will be null without throwing an exception, since Strict Mode is off. +$property = ${nullObject}?.Property # $property will be null without throwing an exception. + +Set-StrictMode -Version Latest +$property = $nullObject.Property # Throws a PropertyNotFoundException, since Strict Mode is on. +$property = ${nullObject}?.Property # $property will be null without throwing an exception. + +$object = [PSCustomObject]@{ Property = 'Value' } +$property = ${object}?.Property # $property will be 'Value'. + +# Example with a REST API call and potentially null nested properties. +$result = Invoke-RestMethod -Uri https://dummyjson.com/products +$productWidthOrNull = ${result}?.{products}?[0]?.{dimensions}?.width +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.4#null-conditional-operators--and-' +) +$tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 70029d27e3b2b031638b95f4dd7142de0f2289c6 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 10 Apr 2025 14:27:02 -0600 Subject: [PATCH 179/217] tip: Add how to get the .NET version pwsh is using --- ...nd-the-net-version-powershell-is-using.ps1 | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 diff --git a/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 b/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 new file mode 100644 index 00000000..45ccac5c --- /dev/null +++ b/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 @@ -0,0 +1,34 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-04-10') +$tip.Title = 'Find the .NET version PowerShell is using' +$tip.TipText = @' +$PSVersionTable will tell you which version of PowerShell is running, but it won't tell you which version of .NET is being used. This is important as sometimes you want to call .NET methods from PowerShell, or use .NET types, but they may have changed from one .NET version to the next. + +Minor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 maps to .NET Core 3.1, 7.1 maps to .NET 5, 7.2 to .NET 6, 7.3 to .NET 7, 7.4 to .NET 8, and 7.5 to .NET 9. This isn't necessarily easy to remember though, and it may change in the future. + +Rather than relying on remembering a convention, we can use the following command to display the version of .NET being used: +[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription + +Note: This property exists for all .NET Core versions, but was not introduced in .NET Framework until .NET Framework 4.7.1, so it may not work in Windows PowerShell versions using a lower version of .NET Framework. +'@ +$tip.Example = @' +# Display the .NET version the current PowerShell session is using. +[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.frameworkdescription' +) +$tip.Category = [tiPS.TipCategory]::Other # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 413851fde6af478412eaa76d42efecc3abfd6b47 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 10 Apr 2025 14:27:20 -0600 Subject: [PATCH 180/217] chore: Generate updated json file --- src/tiPS/PowerShellTips.json | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index d85f9eee..34ba081d 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -895,5 +895,42 @@ "Category": 3, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-04-04T00:00:00", + "Title": "Submit your own tiPS tips from the web form", + "TipText": "You can now easily submit your own PowerShell tips for the tiPS module right from the GitHub repository website! There is a new GitHub issue template called \"PowerShell tip submission\". When you open an issue you will be prompted for your tip's information, such as the tip title, text, category, example code, and URLs. You can even enter your GitHub email address so that you are tagged as a co-author on the commit, allowing you to still get credit in the git history.\r\n\r\nThis tip was submitted using a GitHub issue. Visit the website and submit a tip today!", + "Example": "Start-Process 'https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml'", + "Urls": [ + "https://github.com/deadlydog/PowerShell.tiPS/issues/new?template=new_powershell_tip.yml", + "https://github.com/deadlydog/PowerShell.tiPS#-contribute-a-tip" + ], + "Category": 2, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-04-09T00:00:00", + "Title": "Reduce null checks by using null-conditional operators", + "TipText": "PowerShell 7.1 introduced the null-conditional operators `?.` and `?[]`. These operators allow you to simplify your code by avoiding explicit null checks when accessing properties or elements of objects or arrays that may be null.\r\n\r\nBy default, if you try to index into a null array (e.g. $nullArray[0]), an exception will be thrown. Similarly, if you have Strict Mode enabled and try to access a property of a null object (e.g. $nullObject.SomeProperty), an exception will be thrown. The null-conditional operators allow you to avoid these exceptions and return null instead. You can even chain these together when accessing nested properties.\r\n\r\nOne slight caveat is that because '?' can be part of a variable name, you must use braces '{}' around the variable name. e.g. ${someVariable}?.Property or ${someVariable}?[0].", + "Example": "# Example of using the null-conditional operator with an array.\r\n$nullArray = $null\r\n$element = $nullArray[0] # Throws exception 'InvalidOperation: Cannot index into a null array.'\r\n$element = ${nullArray}?[0] # $element will be null without throwing an exception.\r\n\r\n$array = @('Element1', 'Element2')\r\n$element = ${array}?[0] # $element will be 'Element1'.\r\n\r\n# Example of using the null-conditional operator with a property.\r\n$nullObject = $null\r\n$property = $nullObject.Property # $property will be null without throwing an exception, since Strict Mode is off.\r\n$property = ${nullObject}?.Property # $property will be null without throwing an exception.\r\n\r\nSet-StrictMode -Version Latest\r\n$property = $nullObject.Property # Throws a PropertyNotFoundException, since Strict Mode is on.\r\n$property = ${nullObject}?.Property # $property will be null without throwing an exception.\r\n\r\n$object = [PSCustomObject]@{ Property = 'Value' }\r\n$property = ${object}?.Property # $property will be 'Value'.\r\n\r\n# Example with a REST API call and potentially null nested properties.\r\n$result = Invoke-RestMethod -Uri https://dummyjson.com/products\r\n$productWidthOrNull = ${result}?.{products}?[0]?.{dimensions}?.width", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_operators?view=powershell-7.4#null-conditional-operators--and-" + ], + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-04-10T00:00:00", + "Title": "Find the .NET version PowerShell is using", + "TipText": "$PSVersionTable will tell you which version of PowerShell is running, but it won't tell you which version of .NET is being used. This is important as sometimes you want to call .NET methods from PowerShell, or use .NET types, but they may have changed from one .NET version to the next.\r\n\r\nMinor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 maps to .NET Core 3.1, 7.1 maps to .NET 5, 7.2 to .NET 6, 7.3 to .NET 7, 7.4 to .NET 8, and 7.5 to .NET 9. This isn't necessarily easy to remember though, and it may change in the future.\r\n\r\nRather than relying on remembering a convention, we can use the following command to display the version of .NET being used:\r\n[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription\r\n\r\nNote: This property exists for all .NET Core versions, but was not introduced in .NET Framework until .NET Framework 4.7.1, so it may not work in Windows PowerShell versions using a lower version of .NET Framework.", + "Example": "# Display the .NET version the current PowerShell session is using.\r\n[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription", + "Urls": [ + "https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.frameworkdescription" + ], + "Category": 8, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 9ae097ad5c60f2893052c26c9506f6a7ddcbfe46 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Thu, 10 Apr 2025 14:30:33 -0600 Subject: [PATCH 181/217] tip: Update wording a bit --- .../2025-04-10-find-the-net-version-powershell-is-using.ps1 | 2 +- src/tiPS/PowerShellTips.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 b/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 index 45ccac5c..5de12e6c 100644 --- a/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 +++ b/src/PowerShellTips/2025-04-10-find-the-net-version-powershell-is-using.ps1 @@ -4,7 +4,7 @@ $tip.Title = 'Find the .NET version PowerShell is using' $tip.TipText = @' $PSVersionTable will tell you which version of PowerShell is running, but it won't tell you which version of .NET is being used. This is important as sometimes you want to call .NET methods from PowerShell, or use .NET types, but they may have changed from one .NET version to the next. -Minor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 maps to .NET Core 3.1, 7.1 maps to .NET 5, 7.2 to .NET 6, 7.3 to .NET 7, 7.4 to .NET 8, and 7.5 to .NET 9. This isn't necessarily easy to remember though, and it may change in the future. +Minor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 uses .NET Core 3.1, 7.1 uses .NET 5, 7.2 uses .NET 6, 7.3 uses .NET 7, 7.4 uses .NET 8, and 7.5 uses .NET 9. This isn't necessarily easy to remember though, and the convention may change in the future. Rather than relying on remembering a convention, we can use the following command to display the version of .NET being used: [System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index 34ba081d..fdb61f13 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -924,7 +924,7 @@ { "CreatedDate": "2025-04-10T00:00:00", "Title": "Find the .NET version PowerShell is using", - "TipText": "$PSVersionTable will tell you which version of PowerShell is running, but it won't tell you which version of .NET is being used. This is important as sometimes you want to call .NET methods from PowerShell, or use .NET types, but they may have changed from one .NET version to the next.\r\n\r\nMinor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 maps to .NET Core 3.1, 7.1 maps to .NET 5, 7.2 to .NET 6, 7.3 to .NET 7, 7.4 to .NET 8, and 7.5 to .NET 9. This isn't necessarily easy to remember though, and it may change in the future.\r\n\r\nRather than relying on remembering a convention, we can use the following command to display the version of .NET being used:\r\n[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription\r\n\r\nNote: This property exists for all .NET Core versions, but was not introduced in .NET Framework until .NET Framework 4.7.1, so it may not work in Windows PowerShell versions using a lower version of .NET Framework.", + "TipText": "$PSVersionTable will tell you which version of PowerShell is running, but it won't tell you which version of .NET is being used. This is important as sometimes you want to call .NET methods from PowerShell, or use .NET types, but they may have changed from one .NET version to the next.\r\n\r\nMinor Pwsh versions currently map to major .NET versions. For example, Pwsh 7.0 uses .NET Core 3.1, 7.1 uses .NET 5, 7.2 uses .NET 6, 7.3 uses .NET 7, 7.4 uses .NET 8, and 7.5 uses .NET 9. This isn't necessarily easy to remember though, and the convention may change in the future.\r\n\r\nRather than relying on remembering a convention, we can use the following command to display the version of .NET being used:\r\n[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription\r\n\r\nNote: This property exists for all .NET Core versions, but was not introduced in .NET Framework until .NET Framework 4.7.1, so it may not work in Windows PowerShell versions using a lower version of .NET Framework.", "Example": "# Display the .NET version the current PowerShell session is using.\r\n[System.Runtime.InteropServices.RuntimeInformation]::FrameworkDescription", "Urls": [ "https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.runtimeinformation.frameworkdescription" From 7de855724e599af707fa7b2486d2299f6276a5aa Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Fri, 18 Apr 2025 14:29:54 -0600 Subject: [PATCH 182/217] chore: Add spellcheck word --- .cspell.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.cspell.json b/.cspell.json index cf11c712..951b3b7f 100644 --- a/.cspell.json +++ b/.cspell.json @@ -27,6 +27,7 @@ "dawidd", // GitHub action author "deadlydog", // Username "devcontainer", // VS Code devcontainer + "DontShow", // PowerShell keyword "gittools", // GitHub action author "Hmmss", // Time format "jacoco", // Java code coverage From 584bd61ecae438dff68fb8e5caad04de5b4de6c6 Mon Sep 17 00:00:00 2001 From: GitHub Action - tiPS Automation <tiPSAutomation@DoesNotExist.com> Date: Fri, 18 Apr 2025 06:48:42 +0000 Subject: [PATCH 183/217] New tip: Capture superfluous parameters passed to your function(s) Co-authored-by: Christel VdH <christel.vanderherten@kicts.be> --- ...us-parameters-passed-to-your-functions.ps1 | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 diff --git a/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 b/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 new file mode 100644 index 00000000..39e8f86c --- /dev/null +++ b/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 @@ -0,0 +1,21 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-04-18') +$tip.Title = 'Capture superfluous parameters passed to your function(s)' +$tip.TipText = @' +Capture any parsed parameter to prevent a function from bombing out when being passed unknown / misspelled variables. +Comes in handy when parsing the $PSBoundparameters from a calling script with just a subset of parameters that are appropriate / needed by your (custom) function. +'@ +$tip.Example = @' +[cmdletbinding()] +param( +[Parameter(DontShow, ValueFromRemainingArguments)]$Superfluous +) + +Write-Verbose -Message "Ignoring superfluous params: $($Superfluous -join ' ')" +'@ +$tip.Urls = @('https://github.com/ChristelVDH/SyncAD2AAD/blob/main/ConnectTo-Graph.ps1') +$tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Christel VdH' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Tip submitted via GitHub issue workflow. From 9d9b7d7bbe752f9f920c0b66bf087bdc7e53209f Mon Sep 17 00:00:00 2001 From: GitHub Action - tiPS Automation <tiPSAutomation@DoesNotExist.com> Date: Fri, 18 Apr 2025 20:32:44 +0000 Subject: [PATCH 184/217] New tip: Capture superfluous parameters passed to your function(s) Co-authored-by: Christel VdH <christel.vanderherten@kicts.be> --- ...ture-superfluous-parameters-passed-to-your-functions.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 b/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 index 39e8f86c..ff553b6e 100644 --- a/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 +++ b/src/PowerShellTips/2025-04-18-capture-superfluous-parameters-passed-to-your-functions.ps1 @@ -3,17 +3,17 @@ $tip.CreatedDate = [DateTime]::Parse('2025-04-18') $tip.Title = 'Capture superfluous parameters passed to your function(s)' $tip.TipText = @' Capture any parsed parameter to prevent a function from bombing out when being passed unknown / misspelled variables. -Comes in handy when parsing the $PSBoundparameters from a calling script with just a subset of parameters that are appropriate / needed by your (custom) function. +Comes in handy when parsing the $PSBoundParameters from a calling script with just a subset of parameters that are appropriate / needed by your (custom) function. '@ $tip.Example = @' -[cmdletbinding()] +[CmdletBinding()] param( [Parameter(DontShow, ValueFromRemainingArguments)]$Superfluous ) Write-Verbose -Message "Ignoring superfluous params: $($Superfluous -join ' ')" '@ -$tip.Urls = @('https://github.com/ChristelVDH/SyncAD2AAD/blob/main/ConnectTo-Graph.ps1') +$tip.Urls = @('https://github.com/ChristelVDH/SyncAD2AAD/blob/main/ConnectTo-Graph.ps1','https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.parameterattribute.valuefromremainingarguments','https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.parameterattribute.dontshow') $tip.Category = [tiPS.TipCategory]::Syntax # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. $tip.Author = 'Christel VdH' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. #$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. From 405183c93d8a54740b06fe345b01ae6bff71659a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Tue, 29 Apr 2025 23:50:59 -0600 Subject: [PATCH 185/217] tip: Add tip for Measure-Object --- ...sure-object-to-get-stats-about-objects.ps1 | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/PowerShellTips/2025-04-29-use-measure-object-to-get-stats-about-objects.ps1 diff --git a/src/PowerShellTips/2025-04-29-use-measure-object-to-get-stats-about-objects.ps1 b/src/PowerShellTips/2025-04-29-use-measure-object-to-get-stats-about-objects.ps1 new file mode 100644 index 00000000..e2046f76 --- /dev/null +++ b/src/PowerShellTips/2025-04-29-use-measure-object-to-get-stats-about-objects.ps1 @@ -0,0 +1,45 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-04-29') +$tip.Title = 'Use Measure-Object to get stats about objects' +$tip.TipText = @' +You can use the Measure-Object cmdlet to get statistics about objects in PowerShell. This cmdlet can be used to calculate the sum, average, minimum, maximum, and count of numeric properties in objects. When used with text input, it can count characters, words, and lines. + +The cmdlet returns an object containing properties for each statistic, but the statistic is only actually calculated if you provided the switch for it. For example, if you only provide the -Sum switch, the Sum property will contain the sum of the values, but the Average property will be null since the -Average switch was not provided. +'@ +$tip.Example = @' +# Get all statistics about a range of numbers. +1..10 | Measure-Object -Average -Sum -Minimum -Maximum -StandardDeviation + +# Get all statistics about a string. +"Hello there" | Measure-Object -Character -Word -Line + +# Count the number of words in a file. +Get-Content 'C:\path\to\file.txt' | Measure-Object -Word + +# Calculate the total size (Length) of all files in the current directory. +Get-ChildItem | Measure-Object -Property Length -Sum + +# In an array of objects, find the one with the maximum value of the Num property. +@{num=3}, @{num=4}, @{num=5} | Measure-Object -Maximum Num + +# Get the total and maximum CPU time and paged memory size of all processes. +Get-Process | Measure-Object -Property CPU,PagedMemorySize -Sum -Maximum +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-object' + 'https://adamtheautomator.com/powershell-measure-object/' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 0d3b6c5df4476d893b8f5a28dea00ee8ef22f5fe Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Tue, 6 May 2025 11:23:59 -0600 Subject: [PATCH 186/217] tip: Add tip for Join-Path and Split-Path --- ...it-path-to-create-cross-platform-paths.ps1 | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 diff --git a/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 new file mode 100644 index 00000000..e53891b4 --- /dev/null +++ b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 @@ -0,0 +1,47 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-05-05') +$tip.Title = 'Use Join-Path and Split-Path to create cross-platform paths' +$tip.TipText = @' +When creating file paths in PowerShell, use the `Join-Path` cmdlet instead of string concatenation. This ensures that the correct path separator is used for the current platform (e.g. `\` on Windows and `/` on Linux/macOS). PowerShell 6 introduced the -AdditionalChildPaths parameter, which allows you to specify multiple child paths to join. + +Similarly, you can use the `Split-Path` cmdlet to split a path into its components. This is useful for extracting the directory or file name from a full path. +'@ +$tip.Example = @' +# Don't do this, as it may not work on all platforms. +[string] $configFilePath = "$HOME\Config\config.json" + +# Do this instead, as it works on all platforms. +[string] $configDirectoryPath = Join-Path -Path $HOME -ChildPath 'Config' +[string] $configFilePath = Join-Path $configDirectoryPath 'config.json' # Excludes -Path and -ChildPath for brevity. + +# In PowerShell 6+ you can join multiple child paths at once. +[string] $configFilePath = Join-Path -Path $HOME -AdditionalChildPaths 'Config', 'config.json' +[string] $xmlFilePath = Join-Path $HOME 'Config' 'config.xml' # Excludes parameter names for brevity. + +# Get the name of the file with and without the extension, it's parent directory path, and it's parent directory name. +[string] $fileName = Split-Path -Path $configFilePath -Leaf +[string] $fileNameWithoutExtension = Split-Path -Path $configFilePath -LeafBase +[string] $directoryPath = Split-Path -Path $configFilePath -Parent +[string] $directoryName = Split-Path -Path $directoryPath -Leaf + +# Change the working directory to the folder containing your PowerShell profile. +Set-Location (Split-Path -Path $PROFILE) +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/join-path' + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/split-path' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From 3450f220d36b3378f1c787c98c3e3fe6e15b293a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Tue, 6 May 2025 11:32:28 -0600 Subject: [PATCH 187/217] tip: Fix tip example code --- ...-path-and-split-path-to-create-cross-platform-paths.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 index e53891b4..64a5b6b6 100644 --- a/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 +++ b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 @@ -2,7 +2,7 @@ $tip = [tiPS.PowerShellTip]::new() $tip.CreatedDate = [DateTime]::Parse('2025-05-05') $tip.Title = 'Use Join-Path and Split-Path to create cross-platform paths' $tip.TipText = @' -When creating file paths in PowerShell, use the `Join-Path` cmdlet instead of string concatenation. This ensures that the correct path separator is used for the current platform (e.g. `\` on Windows and `/` on Linux/macOS). PowerShell 6 introduced the -AdditionalChildPaths parameter, which allows you to specify multiple child paths to join. +When creating file paths in PowerShell, use the `Join-Path` cmdlet instead of string concatenation. This ensures that the correct path separator is used for the current platform (e.g. `\` on Windows and `/` on Linux/macOS). PowerShell 6 introduced the -AdditionalChildPath parameter, which allows you to specify multiple child paths to join. Similarly, you can use the `Split-Path` cmdlet to split a path into its components. This is useful for extracting the directory or file name from a full path. '@ @@ -15,9 +15,12 @@ $tip.Example = @' [string] $configFilePath = Join-Path $configDirectoryPath 'config.json' # Excludes -Path and -ChildPath for brevity. # In PowerShell 6+ you can join multiple child paths at once. -[string] $configFilePath = Join-Path -Path $HOME -AdditionalChildPaths 'Config', 'config.json' +[string] $configFilePath = Join-Path -Path $HOME -AdditionalChildPath 'Config' 'config.json' [string] $xmlFilePath = Join-Path $HOME 'Config' 'config.xml' # Excludes parameter names for brevity. +# Use -Resolve to ensure we get an absolute path, and error if the path does not exist. +[string] $configFilePath = Join-Path $HOME 'Config' 'config.json' -Resolve + # Get the name of the file with and without the extension, it's parent directory path, and it's parent directory name. [string] $fileName = Split-Path -Path $configFilePath -Leaf [string] $fileNameWithoutExtension = Split-Path -Path $configFilePath -LeafBase From 61c61c3805f301f87b4eb21dba8c62e1ed5ccb3e Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Tue, 6 May 2025 11:40:53 -0600 Subject: [PATCH 188/217] tip: Add more code to example --- ...-path-and-split-path-to-create-cross-platform-paths.ps1 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 index 64a5b6b6..ed8b8924 100644 --- a/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 +++ b/src/PowerShellTips/2025-05-05-use-join-path-and-split-path-to-create-cross-platform-paths.ps1 @@ -8,13 +8,16 @@ Similarly, you can use the `Split-Path` cmdlet to split a path into its componen '@ $tip.Example = @' # Don't do this, as it may not work on all platforms. -[string] $configFilePath = "$HOME\Config\config.json" +[string] $configFilePath = "$HOME/Config/config.json" # Do this instead, as it works on all platforms. [string] $configDirectoryPath = Join-Path -Path $HOME -ChildPath 'Config' [string] $configFilePath = Join-Path $configDirectoryPath 'config.json' # Excludes -Path and -ChildPath for brevity. -# In PowerShell 6+ you can join multiple child paths at once. +# You can use System.IO.Path to easily join multiple paths. Helpful in Windows PowerShell. +[string] $configFilePath = [System.IO.Path]::Combine($HOME, 'Config', 'config.json') + +# In PowerShell 6+ you can join multiple child paths at once using -AdditionalChildPath. [string] $configFilePath = Join-Path -Path $HOME -AdditionalChildPath 'Config' 'config.json' [string] $xmlFilePath = Join-Path $HOME 'Config' 'config.xml' # Excludes parameter names for brevity. From bcf071112af827a55cb9a6d456f6341194d9c68c Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Tue, 6 May 2025 12:00:21 -0600 Subject: [PATCH 189/217] docs: Remove completed roadmap item from ReadMe --- ReadMe.md | 1 - 1 file changed, 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index 71aa67ea..ca6f27f8 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -219,7 +219,6 @@ See [the Contributing page](/docs/Contributing.md) for more details. Below is a short list of planned enhancements for tiPS: -- An easier way to add new tips. e.g. a simple web form that can be filled out. - A way to customize the look of the tip when it is displayed. e.g. add a border around it, change the colors, etc. - Add a `Write-PowerShellTip -Previous` switch to output the last shown tip. From 2fe4c38a2ac65b8c0f3888366fa300f97eaf2bb9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:20:10 +0000 Subject: [PATCH 190/217] Initial plan for issue From 34682f1479ef9c3a1030b7371692d673a7ffa9b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:26:07 +0000 Subject: [PATCH 191/217] Create GitHub Action to update README with contributors Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- .../workflows/update-readme-contributors.yml | 115 ++++++++++++++++++ test-contributors.ps1 | 25 ++++ 2 files changed, 140 insertions(+) create mode 100644 .github/workflows/update-readme-contributors.yml create mode 100644 test-contributors.ps1 diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml new file mode 100644 index 00000000..2f762461 --- /dev/null +++ b/.github/workflows/update-readme-contributors.yml @@ -0,0 +1,115 @@ +name: Update README Contributors + +on: + # Run weekly on Sunday at 00:00 UTC + schedule: + - cron: '0 0 * * 0' + + # Run when changes are merged to main + push: + branches: + - main + paths-ignore: + - 'ReadMe.md' # Skip when only the ReadMe.md changes to avoid infinite loops + + # Allows manual triggering from the Actions tab + workflow_dispatch: + +jobs: + update-contributors: + runs-on: ubuntu-latest + + steps: + - name: Checkout the repo + uses: actions/checkout@v4 + + - name: Update README with Contributors + id: update-readme + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + try { + // Fetch contributors from the repository + console.log('Fetching contributors from GitHub API...'); + const contributorsResponse = await github.rest.repos.listContributors({ + owner: context.repo.owner, + repo: context.repo.repo, + per_page: 100 + }); + + const contributors = contributorsResponse.data; + console.log(`Found ${contributors.length} contributors.`); + + if (contributors.length === 0) { + console.log('No contributors found. Skipping update.'); + return; + } + + // Read the README file + const readmePath = path.join(process.env.GITHUB_WORKSPACE, 'ReadMe.md'); + let readmeContent = fs.readFileSync(readmePath, 'utf8'); + + // Create the Contributors section + let contributorsSection = ` +## 👥 Contributors + +Thanks to these wonderful people who have contributed to tiPS: + +<p align="center"> +`; + + // Add each contributor to the section + for (const contributor of contributors) { + // Skip GitHub Actions bot or other bots + if (contributor.login === 'github-actions[bot]' || + contributor.login === 'dependabot[bot]') { + continue; + } + + contributorsSection += ` <a href="${contributor.html_url}" title="${contributor.login}"><img src="${contributor.avatar_url}" width="50" height="50" style="border-radius:50%;margin:5px;" alt="${contributor.login}"></a>\n`; + } + + contributorsSection += `</p> + +`; + + // Check if the README already has a Contributors section + if (readmeContent.includes('## 👥 Contributors')) { + // Replace the existing section + const pattern = /(## 👥 Contributors[\s\S]*?)(\r?\n\r?\n## )/; + readmeContent = readmeContent.replace(pattern, contributorsSection + '$2'); + } else { + // Insert before the Roadmap section + readmeContent = readmeContent.replace(/(## 🛣️ Roadmap)/, contributorsSection + '$1'); + } + + // Write the updated content back to the README file + fs.writeFileSync(readmePath, readmeContent); + + console.log('README updated with contributors.'); + + // Set output for next step + return true; + } catch (error) { + console.error(`Error updating README: ${error}`); + return false; + } + result-encoding: string + + - name: Commit and push changes if README was updated + if: steps.update-readme.outputs.result == 'true' + run: | + # Check if there are changes to commit + if [[ -z $(git status --porcelain) ]]; then + echo "No changes to commit. README is already up to date." + exit 0 + fi + + git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add ReadMe.md + git commit -m "docs: update contributors in README" + git push \ No newline at end of file diff --git a/test-contributors.ps1 b/test-contributors.ps1 new file mode 100644 index 00000000..8792d61a --- /dev/null +++ b/test-contributors.ps1 @@ -0,0 +1,25 @@ +# Test script to fetch contributors +$repoOwner = 'deadlydog' +$repoName = 'PowerShell.tiPS' +$maxContributors = 100 + +Write-Host "Fetching contributors from GitHub API..." +$contributorsApiUrl = "https://api.github.com/repos/$repoOwner/$repoName/contributors?per_page=$maxContributors" + +try { + $contributors = Invoke-RestMethod -Uri $contributorsApiUrl -Headers @{ + 'Accept' = 'application/vnd.github.v3+json' + 'User-Agent' = 'PowerShell-Script' + } + + Write-Host "Found $($contributors.Count) contributors." + + if ($contributors.Count -eq 0) { + Write-Warning "No contributors found." + } else { + # Display first 5 contributors for testing + $contributors | Select-Object -First 5 login, html_url, avatar_url | Format-Table + } +} catch { + Write-Warning "Error fetching contributors: $_" +} \ No newline at end of file From 75a07e723ee984395c03fde7280aa0f57e6d3e51 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:27:19 +0000 Subject: [PATCH 192/217] Improve GitHub Action for updating README contributors Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- .../workflows/update-readme-contributors.yml | 38 ++++++++++++++++--- test-contributors.ps1 | 25 ------------ 2 files changed, 32 insertions(+), 31 deletions(-) delete mode 100644 test-contributors.ps1 diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 2f762461..abd72d7f 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -11,6 +11,7 @@ on: - main paths-ignore: - 'ReadMe.md' # Skip when only the ReadMe.md changes to avoid infinite loops + - '.github/workflows/update-readme-contributors.yml' # Skip when this workflow file changes # Allows manual triggering from the Actions tab workflow_dispatch: @@ -22,11 +23,15 @@ jobs: steps: - name: Checkout the repo uses: actions/checkout@v4 - + with: + # Fetch with token that has write access to the repo + token: ${{ secrets.GITHUB_TOKEN }} + - name: Update README with Contributors id: update-readme uses: actions/github-script@v7 with: + github-token: ${{ secrets.GITHUB_TOKEN }} script: | const fs = require('fs'); const path = require('path'); @@ -45,7 +50,7 @@ jobs: if (contributors.length === 0) { console.log('No contributors found. Skipping update.'); - return; + return false; } // Read the README file @@ -78,7 +83,7 @@ Thanks to these wonderful people who have contributed to tiPS: // Check if the README already has a Contributors section if (readmeContent.includes('## 👥 Contributors')) { - // Replace the existing section + // Replace the existing section using regex to capture everything between the Contributors heading and the next heading const pattern = /(## 👥 Contributors[\s\S]*?)(\r?\n\r?\n## )/; readmeContent = readmeContent.replace(pattern, contributorsSection + '$2'); } else { @@ -91,10 +96,11 @@ Thanks to these wonderful people who have contributed to tiPS: console.log('README updated with contributors.'); - // Set output for next step + // Set output for next step - return true if we made changes return true; } catch (error) { console.error(`Error updating README: ${error}`); + core.setFailed(`Failed to update README: ${error.message}`); return false; } result-encoding: string @@ -108,8 +114,28 @@ Thanks to these wonderful people who have contributed to tiPS: exit 0 fi + # Configure git git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" + + # Add, commit and push changes git add ReadMe.md - git commit -m "docs: update contributors in README" - git push \ No newline at end of file + git commit -m "docs: update contributors in README [skip ci]" + + # Push changes - retry up to 3 times in case of network issues + MAX_RETRIES=3 + RETRY_COUNT=0 + + while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do + if git push; then + echo "Successfully pushed changes to the repository." + exit 0 + else + RETRY_COUNT=$((RETRY_COUNT+1)) + echo "Push failed. Retrying in 5 seconds... (Attempt $RETRY_COUNT of $MAX_RETRIES)" + sleep 5 + fi + done + + echo "Failed to push changes after $MAX_RETRIES attempts." + exit 1 \ No newline at end of file diff --git a/test-contributors.ps1 b/test-contributors.ps1 deleted file mode 100644 index 8792d61a..00000000 --- a/test-contributors.ps1 +++ /dev/null @@ -1,25 +0,0 @@ -# Test script to fetch contributors -$repoOwner = 'deadlydog' -$repoName = 'PowerShell.tiPS' -$maxContributors = 100 - -Write-Host "Fetching contributors from GitHub API..." -$contributorsApiUrl = "https://api.github.com/repos/$repoOwner/$repoName/contributors?per_page=$maxContributors" - -try { - $contributors = Invoke-RestMethod -Uri $contributorsApiUrl -Headers @{ - 'Accept' = 'application/vnd.github.v3+json' - 'User-Agent' = 'PowerShell-Script' - } - - Write-Host "Found $($contributors.Count) contributors." - - if ($contributors.Count -eq 0) { - Write-Warning "No contributors found." - } else { - # Display first 5 contributors for testing - $contributors | Select-Object -First 5 login, html_url, avatar_url | Format-Table - } -} catch { - Write-Warning "Error fetching contributors: $_" -} \ No newline at end of file From 696e5e3ccd58a6ebb9a7234c94d6163f528275b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:49:49 +0000 Subject: [PATCH 193/217] Convert bash script to PowerShell in GitHub workflow Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- .../workflows/update-readme-contributors.yml | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index abd72d7f..8e9e2a7a 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -107,12 +107,14 @@ Thanks to these wonderful people who have contributed to tiPS: - name: Commit and push changes if README was updated if: steps.update-readme.outputs.result == 'true' + shell: pwsh run: | # Check if there are changes to commit - if [[ -z $(git status --porcelain) ]]; then - echo "No changes to commit. README is already up to date." - exit 0 - fi + $gitStatus = git status --porcelain + if ([string]::IsNullOrWhiteSpace($gitStatus)) { + Write-Output "No changes to commit. README is already up to date." + exit 0 + } # Configure git git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" @@ -123,19 +125,21 @@ Thanks to these wonderful people who have contributed to tiPS: git commit -m "docs: update contributors in README [skip ci]" # Push changes - retry up to 3 times in case of network issues - MAX_RETRIES=3 - RETRY_COUNT=0 + $maxRetries = 3 + $retryCount = 0 - while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do - if git push; then - echo "Successfully pushed changes to the repository." - exit 0 - else - RETRY_COUNT=$((RETRY_COUNT+1)) - echo "Push failed. Retrying in 5 seconds... (Attempt $RETRY_COUNT of $MAX_RETRIES)" - sleep 5 - fi - done + while ($retryCount -lt $maxRetries) { + try { + git push + Write-Output "Successfully pushed changes to the repository." + exit 0 + } + catch { + $retryCount++ + Write-Output "Push failed. Retrying in 5 seconds... (Attempt $retryCount of $maxRetries)" + Start-Sleep -Seconds 5 + } + } - echo "Failed to push changes after $MAX_RETRIES attempts." + Write-Output "Failed to push changes after $maxRetries attempts." exit 1 \ No newline at end of file From d93200995c4de1d9eaf35f20c0963732ab8782b2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:50:26 +0000 Subject: [PATCH 194/217] Add test script for the PowerShell workflow commands Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- test-workflow.ps1 | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 test-workflow.ps1 diff --git a/test-workflow.ps1 b/test-workflow.ps1 new file mode 100644 index 00000000..8772d1e4 --- /dev/null +++ b/test-workflow.ps1 @@ -0,0 +1,49 @@ +# Test PowerShell script for the GitHub workflow +# This script simulates the git commands used in the workflow + +Write-Output "Testing git status detection..." + +# Simulate different git status results +$mockEmptyStatus = "" +$mockChangesStatus = " M ReadMe.md" + +# Test empty status +Write-Output "Testing with empty status (no changes):" +if ([string]::IsNullOrWhiteSpace($mockEmptyStatus)) { + Write-Output " No changes to commit. README is already up to date." +} else { + Write-Output " Changes detected, proceeding with commit and push." +} + +# Test with changes +Write-Output "Testing with changes status:" +if ([string]::IsNullOrWhiteSpace($mockChangesStatus)) { + Write-Output " No changes to commit. README is already up to date." +} else { + Write-Output " Changes detected, proceeding with commit and push." + + # Simulate git commands (just echo them) + Write-Output " git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'" + Write-Output " git config --local user.name 'github-actions[bot]'" + Write-Output " git add ReadMe.md" + Write-Output " git commit -m 'docs: update contributors in README [skip ci]'" + + # Simulate retry logic + $maxRetries = 3 + $retryCount = 0 + + # Mock a failure for the first attempt, success on second + Write-Output " Simulating push with retry logic:" + while ($retryCount -lt $maxRetries) { + if ($retryCount -lt 1) { + Write-Output " Attempt $($retryCount+1): Push failed. Retrying in 5 seconds..." + $retryCount++ + # In actual code we'd use Start-Sleep -Seconds 5 + } else { + Write-Output " Attempt $($retryCount+1): Successfully pushed changes to the repository." + break + } + } +} + +Write-Output "Test completed successfully." \ No newline at end of file From d33e2472e67170068fa6a26ab6d7f2068be46025 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 May 2025 23:58:52 +0000 Subject: [PATCH 195/217] Remove test-workflow.ps1 file as requested Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- test-workflow.ps1 | 49 ----------------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 test-workflow.ps1 diff --git a/test-workflow.ps1 b/test-workflow.ps1 deleted file mode 100644 index 8772d1e4..00000000 --- a/test-workflow.ps1 +++ /dev/null @@ -1,49 +0,0 @@ -# Test PowerShell script for the GitHub workflow -# This script simulates the git commands used in the workflow - -Write-Output "Testing git status detection..." - -# Simulate different git status results -$mockEmptyStatus = "" -$mockChangesStatus = " M ReadMe.md" - -# Test empty status -Write-Output "Testing with empty status (no changes):" -if ([string]::IsNullOrWhiteSpace($mockEmptyStatus)) { - Write-Output " No changes to commit. README is already up to date." -} else { - Write-Output " Changes detected, proceeding with commit and push." -} - -# Test with changes -Write-Output "Testing with changes status:" -if ([string]::IsNullOrWhiteSpace($mockChangesStatus)) { - Write-Output " No changes to commit. README is already up to date." -} else { - Write-Output " Changes detected, proceeding with commit and push." - - # Simulate git commands (just echo them) - Write-Output " git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'" - Write-Output " git config --local user.name 'github-actions[bot]'" - Write-Output " git add ReadMe.md" - Write-Output " git commit -m 'docs: update contributors in README [skip ci]'" - - # Simulate retry logic - $maxRetries = 3 - $retryCount = 0 - - # Mock a failure for the first attempt, success on second - Write-Output " Simulating push with retry logic:" - while ($retryCount -lt $maxRetries) { - if ($retryCount -lt 1) { - Write-Output " Attempt $($retryCount+1): Push failed. Retrying in 5 seconds..." - $retryCount++ - # In actual code we'd use Start-Sleep -Seconds 5 - } else { - Write-Output " Attempt $($retryCount+1): Successfully pushed changes to the repository." - break - } - } -} - -Write-Output "Test completed successfully." \ No newline at end of file From 5f56323340faebb101c925d647f8646614f1a64d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 19 May 2025 18:23:10 -0600 Subject: [PATCH 196/217] ci: Fix bad YAML syntax generated by Copilot --- .../workflows/update-readme-contributors.yml | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 8e9e2a7a..fc9a50a0 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -4,7 +4,7 @@ on: # Run weekly on Sunday at 00:00 UTC schedule: - cron: '0 0 * * 0' - + # Run when changes are merged to main push: branches: @@ -12,21 +12,21 @@ on: paths-ignore: - 'ReadMe.md' # Skip when only the ReadMe.md changes to avoid infinite loops - '.github/workflows/update-readme-contributors.yml' # Skip when this workflow file changes - + # Allows manual triggering from the Actions tab workflow_dispatch: jobs: update-contributors: runs-on: ubuntu-latest - + steps: - name: Checkout the repo uses: actions/checkout@v4 with: # Fetch with token that has write access to the repo token: ${{ secrets.GITHUB_TOKEN }} - + - name: Update README with Contributors id: update-readme uses: actions/github-script@v7 @@ -35,7 +35,7 @@ jobs: script: | const fs = require('fs'); const path = require('path'); - + try { // Fetch contributors from the repository console.log('Fetching contributors from GitHub API...'); @@ -44,43 +44,43 @@ jobs: repo: context.repo.repo, per_page: 100 }); - + const contributors = contributorsResponse.data; console.log(`Found ${contributors.length} contributors.`); - + if (contributors.length === 0) { console.log('No contributors found. Skipping update.'); return false; } - + // Read the README file const readmePath = path.join(process.env.GITHUB_WORKSPACE, 'ReadMe.md'); let readmeContent = fs.readFileSync(readmePath, 'utf8'); - + // Create the Contributors section let contributorsSection = ` -## 👥 Contributors + ## 👥 Contributors -Thanks to these wonderful people who have contributed to tiPS: + Thanks to these wonderful people who have contributed to tiPS: + + <p align="center"> + `; -<p align="center"> -`; - // Add each contributor to the section for (const contributor of contributors) { // Skip GitHub Actions bot or other bots - if (contributor.login === 'github-actions[bot]' || + if (contributor.login === 'github-actions[bot]' || contributor.login === 'dependabot[bot]') { continue; } - + contributorsSection += ` <a href="${contributor.html_url}" title="${contributor.login}"><img src="${contributor.avatar_url}" width="50" height="50" style="border-radius:50%;margin:5px;" alt="${contributor.login}"></a>\n`; } - + contributorsSection += `</p> -`; - + `; + // Check if the README already has a Contributors section if (readmeContent.includes('## 👥 Contributors')) { // Replace the existing section using regex to capture everything between the Contributors heading and the next heading @@ -90,12 +90,12 @@ Thanks to these wonderful people who have contributed to tiPS: // Insert before the Roadmap section readmeContent = readmeContent.replace(/(## 🛣️ Roadmap)/, contributorsSection + '$1'); } - + // Write the updated content back to the README file fs.writeFileSync(readmePath, readmeContent); - + console.log('README updated with contributors.'); - + // Set output for next step - return true if we made changes return true; } catch (error) { @@ -104,7 +104,7 @@ Thanks to these wonderful people who have contributed to tiPS: return false; } result-encoding: string - + - name: Commit and push changes if README was updated if: steps.update-readme.outputs.result == 'true' shell: pwsh @@ -115,19 +115,19 @@ Thanks to these wonderful people who have contributed to tiPS: Write-Output "No changes to commit. README is already up to date." exit 0 } - + # Configure git git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" - + # Add, commit and push changes git add ReadMe.md git commit -m "docs: update contributors in README [skip ci]" - + # Push changes - retry up to 3 times in case of network issues $maxRetries = 3 $retryCount = 0 - + while ($retryCount -lt $maxRetries) { try { git push @@ -140,6 +140,6 @@ Thanks to these wonderful people who have contributed to tiPS: Start-Sleep -Seconds 5 } } - + Write-Output "Failed to push changes after $maxRetries attempts." - exit 1 \ No newline at end of file + exit 1 From 58c9eb05e5ff110c74f2dd74e3b40aac7e529125 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 May 2025 00:40:03 +0000 Subject: [PATCH 197/217] Initial plan for issue From 26f6848ea47023895409b4a87114f34c6e5f4a58 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 May 2025 00:41:58 +0000 Subject: [PATCH 198/217] Replace direct push with PR creation in README contributors workflow Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- .../workflows/update-readme-contributors.yml | 51 +++++-------------- 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index fc9a50a0..4c7b408b 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -105,41 +105,18 @@ jobs: } result-encoding: string - - name: Commit and push changes if README was updated + - name: Create Pull Request if README was updated if: steps.update-readme.outputs.result == 'true' - shell: pwsh - run: | - # Check if there are changes to commit - $gitStatus = git status --porcelain - if ([string]::IsNullOrWhiteSpace($gitStatus)) { - Write-Output "No changes to commit. README is already up to date." - exit 0 - } - - # Configure git - git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --local user.name "github-actions[bot]" - - # Add, commit and push changes - git add ReadMe.md - git commit -m "docs: update contributors in README [skip ci]" - - # Push changes - retry up to 3 times in case of network issues - $maxRetries = 3 - $retryCount = 0 - - while ($retryCount -lt $maxRetries) { - try { - git push - Write-Output "Successfully pushed changes to the repository." - exit 0 - } - catch { - $retryCount++ - Write-Output "Push failed. Retrying in 5 seconds... (Attempt $retryCount of $maxRetries)" - Start-Sleep -Seconds 5 - } - } - - Write-Output "Failed to push changes after $maxRetries attempts." - exit 1 + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "docs: update contributors in README [skip ci]" + title: "docs: Update contributors in README" + body: | + This PR updates the README.md file with the latest contributors to the project. + + *This is an automated PR created by the update-readme-contributors workflow.* + branch: auto-update-readme-contributors + branch-suffix: timestamp + delete-branch: true + base: main From d00964b4ac9e1c69810fbafa1df45df714721f5c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 May 2025 00:42:37 +0000 Subject: [PATCH 199/217] Add explicit permissions for PR creation Co-authored-by: deadlydog <1187140+deadlydog@users.noreply.github.com> --- .github/workflows/update-readme-contributors.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 4c7b408b..742cdc03 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -19,6 +19,9 @@ on: jobs: update-contributors: runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - name: Checkout the repo From cd2182352296acfb58daea369569af6b879cf706 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 19 May 2025 18:52:02 -0600 Subject: [PATCH 200/217] ci: Fix whitespace indentation in multiline JavaScript lines --- .github/workflows/update-readme-contributors.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 742cdc03..3e57a761 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -62,12 +62,12 @@ jobs: // Create the Contributors section let contributorsSection = ` - ## 👥 Contributors + ## 👥 Contributors - Thanks to these wonderful people who have contributed to tiPS: + Thanks to these wonderful people who have contributed to tiPS: - <p align="center"> - `; + <p align="center"> + `; // Add each contributor to the section for (const contributor of contributors) { @@ -82,7 +82,7 @@ jobs: contributorsSection += `</p> - `; + `; // Check if the README already has a Contributors section if (readmeContent.includes('## 👥 Contributors')) { @@ -117,7 +117,7 @@ jobs: title: "docs: Update contributors in README" body: | This PR updates the README.md file with the latest contributors to the project. - + *This is an automated PR created by the update-readme-contributors workflow.* branch: auto-update-readme-contributors branch-suffix: timestamp From fd039d6a13e42a22f3bbf260cdb5d4230c231051 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 19 May 2025 18:56:56 -0600 Subject: [PATCH 201/217] ci: Fix workflow to not insert an additional newline character --- .github/workflows/update-readme-contributors.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 3e57a761..fb7cfbf2 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -61,8 +61,7 @@ jobs: let readmeContent = fs.readFileSync(readmePath, 'utf8'); // Create the Contributors section - let contributorsSection = ` - ## 👥 Contributors + let contributorsSection = `## 👥 Contributors Thanks to these wonderful people who have contributed to tiPS: From 986b08102fd6bf059e133a67cc3628ce600ddb78 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 19 May 2025 19:05:33 -0600 Subject: [PATCH 202/217] ci: Fix so PRs can run workflows by using a special user PAT instead of the native GITHUB_TOKEN --- .github/workflows/update-readme-contributors.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index fb7cfbf2..100dfe59 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -111,7 +111,9 @@ jobs: if: steps.update-readme.outputs.result == 'true' uses: peter-evans/create-pull-request@v5 with: - token: ${{ secrets.GITHUB_TOKEN }} + # Must use a user token instead of built-in GITHUB_TOKEN so that workflows will be triggered on the created PR. + # For more information see: https://github.com/peter-evans/create-pull-request/issues/48 + token: ${{ secrets.TIPS_GITHUB_ACTIONS_PR_CREATION_TOKEN }} commit-message: "docs: update contributors in README [skip ci]" title: "docs: Update contributors in README" body: | From 373828bb621e5c41ca20589e57e7e5a4c3d9560f Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 19 May 2025 19:16:54 -0600 Subject: [PATCH 203/217] ci: Revert previous change to use user PAT, as it did not make a difference --- .github/workflows/update-readme-contributors.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 100dfe59..fb7cfbf2 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -111,9 +111,7 @@ jobs: if: steps.update-readme.outputs.result == 'true' uses: peter-evans/create-pull-request@v5 with: - # Must use a user token instead of built-in GITHUB_TOKEN so that workflows will be triggered on the created PR. - # For more information see: https://github.com/peter-evans/create-pull-request/issues/48 - token: ${{ secrets.TIPS_GITHUB_ACTIONS_PR_CREATION_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} commit-message: "docs: update contributors in README [skip ci]" title: "docs: Update contributors in README" body: | From af46ebcdd17b262bda33ca125f8e131afc047d0a Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@users.noreply.github.com> Date: Tue, 20 May 2025 01:17:28 +0000 Subject: [PATCH 204/217] docs: update contributors in README [skip ci] --- ReadMe.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index ca6f27f8..f9f2f695 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -215,6 +215,20 @@ tiPS is meant to be a community driven project, so please help make it better by Issues, Discussions, and Pull Requests are welcome. See [the Contributing page](/docs/Contributing.md) for more details. +## 👥 Contributors + +Thanks to these wonderful people who have contributed to tiPS: + +<p align="center"> + <a href="https://github.com/deadlydog" title="deadlydog"><img src="https://avatars.githubusercontent.com/u/1187140?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="deadlydog"></a> + <a href="https://github.com/apps/copilot-swe-agent" title="Copilot"><img src="https://avatars.githubusercontent.com/in/1143301?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="Copilot"></a> + <a href="https://github.com/belibug" title="belibug"><img src="https://avatars.githubusercontent.com/u/61643561?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="belibug"></a> + <a href="https://github.com/ruudmens" title="ruudmens"><img src="https://avatars.githubusercontent.com/u/20253186?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="ruudmens"></a> + <a href="https://github.com/santisq" title="santisq"><img src="https://avatars.githubusercontent.com/u/23342410?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="santisq"></a> + <a href="https://github.com/adrimus" title="adrimus"><img src="https://avatars.githubusercontent.com/u/37830358?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="adrimus"></a> + <a href="https://github.com/ehmiiz" title="ehmiiz"><img src="https://avatars.githubusercontent.com/u/43292173?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="ehmiiz"></a> +</p> + ## 🛣️ Roadmap Below is a short list of planned enhancements for tiPS: From 7e4d770c007b222fc7d6983eaf8e13ba321726a3 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sun, 25 May 2025 11:33:16 -0600 Subject: [PATCH 205/217] chore: Try to fix whitespace detection in Contributors workflow --- .github/workflows/update-readme-contributors.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index fb7cfbf2..29d7a628 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -86,7 +86,7 @@ jobs: // Check if the README already has a Contributors section if (readmeContent.includes('## 👥 Contributors')) { // Replace the existing section using regex to capture everything between the Contributors heading and the next heading - const pattern = /(## 👥 Contributors[\s\S]*?)(\r?\n\r?\n## )/; + const pattern = /(## 👥 Contributors[\s\S]*?)(## 🛣️ Roadmap)/; readmeContent = readmeContent.replace(pattern, contributorsSection + '$2'); } else { // Insert before the Roadmap section From cc063435c4518a6fc7074d6a8481c85f508360c8 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sun, 25 May 2025 11:34:25 -0600 Subject: [PATCH 206/217] chore: Ignore GitHub Copilot as a contributor --- .github/workflows/update-readme-contributors.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/update-readme-contributors.yml b/.github/workflows/update-readme-contributors.yml index 29d7a628..d4e5c237 100644 --- a/.github/workflows/update-readme-contributors.yml +++ b/.github/workflows/update-readme-contributors.yml @@ -72,7 +72,8 @@ jobs: for (const contributor of contributors) { // Skip GitHub Actions bot or other bots if (contributor.login === 'github-actions[bot]' || - contributor.login === 'dependabot[bot]') { + contributor.login === 'dependabot[bot]' || + contributor.login === 'Copilot') { continue; } From 82d4224e19e906dacb0bc8fee4117a27787329fb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@users.noreply.github.com> Date: Sun, 25 May 2025 17:35:30 +0000 Subject: [PATCH 207/217] docs: update contributors in README [skip ci] --- ReadMe.md | 1 - 1 file changed, 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index f9f2f695..7bc3014a 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -221,7 +221,6 @@ Thanks to these wonderful people who have contributed to tiPS: <p align="center"> <a href="https://github.com/deadlydog" title="deadlydog"><img src="https://avatars.githubusercontent.com/u/1187140?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="deadlydog"></a> - <a href="https://github.com/apps/copilot-swe-agent" title="Copilot"><img src="https://avatars.githubusercontent.com/in/1143301?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="Copilot"></a> <a href="https://github.com/belibug" title="belibug"><img src="https://avatars.githubusercontent.com/u/61643561?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="belibug"></a> <a href="https://github.com/ruudmens" title="ruudmens"><img src="https://avatars.githubusercontent.com/u/20253186?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="ruudmens"></a> <a href="https://github.com/santisq" title="santisq"><img src="https://avatars.githubusercontent.com/u/23342410?v=4" width="50" height="50" style="border-radius:50%;margin:5px;" alt="santisq"></a> From a3b84c34ceca118fb52406ac2ee6f12273e354cc Mon Sep 17 00:00:00 2001 From: adrianm <adrian.muscat@systech.net> Date: Wed, 3 Sep 2025 16:01:25 +0200 Subject: [PATCH 208/217] feat: add new PowerShell tip on Array Lists --- src/PowerShellTips/2025-09-03-array-lists.ps1 | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/PowerShellTips/2025-09-03-array-lists.ps1 diff --git a/src/PowerShellTips/2025-09-03-array-lists.ps1 b/src/PowerShellTips/2025-09-03-array-lists.ps1 new file mode 100644 index 00000000..beb77fc8 --- /dev/null +++ b/src/PowerShellTips/2025-09-03-array-lists.ps1 @@ -0,0 +1,38 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-09-03') +$tip.Title = 'Array Lists' +$tip.TipText = @' +An Array list is similar to an array, but it does not have a fixed size like an array does. + +With a fixed-sized array and you add an item to the array, the array is actually recreated with the additional item. This can impact performance, when working with thousands of items. + +Another concern with fixed-size arrays is that there's no simple method to remove an item. + +'@ +$tip.Example = @' +# In PowerShell, you can create an Array list using the `System.Collections.ArrayList` class. Here's how you can create and use an Array list: + +[System.Collections.ArrayList]$computers = @('Server1', 'Server2', 'Server3') + +# To create an empty array ready to add items + +$computers=New-Object System.Collections.ArrayList +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/training/modules/work-arrays-hash-tables-window-powershell-scripts/3-work-array-lists-windows' + 'https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays?view=powershell-7.5#arraylist' +) +$tip.Category = [tiPS.TipCategory]::Performance # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Adrian Muscat (adrimus)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From a1d1360325d472421644bf72ca8911957836ecbb Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 12:55:49 -0600 Subject: [PATCH 209/217] tip: Add tip for Get-Verb --- ...-20-use-get-verb-to-see-approved-verbs.ps1 | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/PowerShellTips/2025-09-20-use-get-verb-to-see-approved-verbs.ps1 diff --git a/src/PowerShellTips/2025-09-20-use-get-verb-to-see-approved-verbs.ps1 b/src/PowerShellTips/2025-09-20-use-get-verb-to-see-approved-verbs.ps1 new file mode 100644 index 00000000..4301cf6f --- /dev/null +++ b/src/PowerShellTips/2025-09-20-use-get-verb-to-see-approved-verbs.ps1 @@ -0,0 +1,30 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-09-20') +$tip.Title = 'Use Get-Verb to see approved verbs' +$tip.TipText = @' +Use the Get-Verb cmdlet to see a list of all approved verbs in PowerShell. This is useful when creating your own functions or cmdlets, as using approved verbs helps ensure consistency and discoverability. You know right away what a function does simply by the verb it uses. + +Get-Verb is also great for learning about new verbs you may not have known about, including the typical alias abbreviations. +'@ +$tip.Example = @' +# List all approved verbs and their descriptions. +Get-Verb +'@ +$tip.Urls = @( + 'https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-verb' + 'https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands' +) +$tip.Category = [tiPS.TipCategory]::NativeCmdlet # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. From d1d8a75d01fe3b8ccdfbeca1636492070b7b0ee3 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 13:17:19 -0600 Subject: [PATCH 210/217] feat: Allow Biweekly and Monthly options for automatic write tip cadence --- Changelog.md | 6 +++ ReadMe.md | 2 +- .../tiPSClasses/Configuration.cs | 4 +- ...maticWritePowerShellTipFunctions.Tests.ps1 | 44 +++++++++++++++++++ .../AutomaticWritePowerShellTipFunctions.ps1 | 2 + src/tiPS/Public/Set-TiPSConfiguration.ps1 | 4 +- 6 files changed, 58 insertions(+), 4 deletions(-) diff --git a/Changelog.md b/Changelog.md index 11f3662f..9ae699e6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,12 @@ This page is a list of _notable_ changes made in each version. Every time a tip is added the patch version is incremented, so there will be a lot of patch version changes not documented here. +## v1.4.0 - September 20, 2025 + +Features: + +- Added `Biweekly` and `Monthly` options to the `AutomaticallyWritePowerShellTip` configuration setting to allow more flexibility in how often tips are automatically shown. + ## v1.3.7 - May 20, 2024 Fixes: diff --git a/ReadMe.md b/ReadMe.md index 7bc3014a..8c773b54 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -135,7 +135,7 @@ To have a tip automatically displayed every time you open your PowerShell termin Set-TiPSConfiguration -AutomaticallyWritePowerShellTip EverySession ``` -Possible values for the `-AutomaticallyWritePowerShellTip` parameter are `Never`, `EverySession`, `Daily`, and `Weekly`. +Possible values for the `-AutomaticallyWritePowerShellTip` parameter are `Never`, `EverySession`, `Daily`, `Weekly`, `Biweekly`, and `Monthly`. Tips will only be automatically shown in interactive PowerShell sessions. This prevents them from appearing unexpectedly when running scripts or other automated processes. diff --git a/src/CSharpClasses/tiPSClasses/Configuration.cs b/src/CSharpClasses/tiPSClasses/Configuration.cs index ee2a5f89..95dd6d33 100644 --- a/src/CSharpClasses/tiPSClasses/Configuration.cs +++ b/src/CSharpClasses/tiPSClasses/Configuration.cs @@ -14,7 +14,9 @@ public enum WritePowerShellTipCadence Never = 0, EverySession = 1, Daily = 2, - Weekly = 3 + Weekly = 3, + Biweekly = 4, + Monthly = 5 } public enum TipRetrievalOrder diff --git a/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.Tests.ps1 b/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.Tests.ps1 index 160090d8..3196ba05 100644 --- a/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.Tests.ps1 +++ b/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.Tests.ps1 @@ -83,6 +83,50 @@ InModuleScope -ModuleName tiPS { # Must use InModuleScope to call private functi } } + Context 'When the WritePowerShellTipCadence is Biweekly' { + It 'Should update the module if the last update was more than 14 days ago' { + $config = [tiPS.Configuration]::new() + $config.AutoWritePowerShellTipCadence = [tiPS.WritePowerShellTipCadence]::Biweekly + WriteLastAutomaticTipWrittenDate -LastAutomaticTipWrittenDate ([DateTime]::Now.Date.AddDays(-15)) + + WriteAutomaticPowerShellTipIfNeeded -Config $config + + Assert-MockCalled WriteAutomaticPowerShellTip -Times 1 -Exactly + } + + It 'Should not update the module if the last update was less than 14 days ago' { + $config = [tiPS.Configuration]::new() + $config.AutoWritePowerShellTipCadence = [tiPS.WritePowerShellTipCadence]::Biweekly + WriteLastAutomaticTipWrittenDate -LastAutomaticTipWrittenDate ([DateTime]::Now.Date.AddDays(-13)) + + WriteAutomaticPowerShellTipIfNeeded -Config $config + + Assert-MockCalled WriteAutomaticPowerShellTip -Times 0 -Exactly + } + } + + Context 'When the WritePowerShellTipCadence is Monthly' { + It 'Should update the module if the last update was more than 30 days ago' { + $config = [tiPS.Configuration]::new() + $config.AutoWritePowerShellTipCadence = [tiPS.WritePowerShellTipCadence]::Monthly + WriteLastAutomaticTipWrittenDate -LastAutomaticTipWrittenDate ([DateTime]::Now.Date.AddDays(-31)) + + WriteAutomaticPowerShellTipIfNeeded -Config $config + + Assert-MockCalled WriteAutomaticPowerShellTip -Times 1 -Exactly + } + + It 'Should not update the module if the last update was less than 30 days ago' { + $config = [tiPS.Configuration]::new() + $config.AutoWritePowerShellTipCadence = [tiPS.WritePowerShellTipCadence]::Monthly + WriteLastAutomaticTipWrittenDate -LastAutomaticTipWrittenDate ([DateTime]::Now.Date.AddDays(-29)) + + WriteAutomaticPowerShellTipIfNeeded -Config $config + + Assert-MockCalled WriteAutomaticPowerShellTip -Times 0 -Exactly + } + } + Context 'When the PowerShell session is not interactive' { BeforeEach { Mock -CommandName TestPowerShellSessionIsInteractive -MockWith { return $false } diff --git a/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.ps1 b/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.ps1 index aa0e1c87..b7005a24 100644 --- a/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.ps1 +++ b/src/tiPS/Private/AutomaticWritePowerShellTipFunctions.ps1 @@ -26,6 +26,8 @@ function WriteAutomaticPowerShellTipIfNeeded ([tiPS.WritePowerShellTipCadence]::EverySession) { $shouldShowTip = $true; break } ([tiPS.WritePowerShellTipCadence]::Daily) { $shouldShowTip = $daysSinceLastAutomaticTipWritten -ge 1; break } ([tiPS.WritePowerShellTipCadence]::Weekly) { $shouldShowTip = $daysSinceLastAutomaticTipWritten -ge 7; break } + ([tiPS.WritePowerShellTipCadence]::Biweekly) { $shouldShowTip = $daysSinceLastAutomaticTipWritten -ge 14; break } + ([tiPS.WritePowerShellTipCadence]::Monthly) { $shouldShowTip = $daysSinceLastAutomaticTipWritten -ge 30; break } } if ($shouldShowTip) diff --git a/src/tiPS/Public/Set-TiPSConfiguration.ps1 b/src/tiPS/Public/Set-TiPSConfiguration.ps1 index 40c27360..68c70cd4 100644 --- a/src/tiPS/Public/Set-TiPSConfiguration.ps1 +++ b/src/tiPS/Public/Set-TiPSConfiguration.ps1 @@ -18,11 +18,11 @@ function Set-TiPSConfiguration This also means that the new module version will not be used until the next time the module is imported, or the next time a PowerShell session is started. Old versions of the module are automatically deleted after a successful update. - Valid values are Never, Daily, Weekly, Monthly, and Yearly. Default is Never. + Valid values are Never, Daily, Weekly, Biweekly, and Monthly. Default is Never. .PARAMETER AutomaticallyWritePowerShellTip Whether to automatically write a PowerShell tip at session startup. - Valid values are Never, Daily, Weekly, Monthly, and Yearly. Default is Never. + Valid values are Never, EverySession, Daily, Weekly, Biweekly, and Monthly. Default is Never. .PARAMETER TipRetrievalOrder The order in which to retrieve PowerShell tips. From f0326235f03c0c1848f6cce1f2c06f994cd34929 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 13:25:18 -0600 Subject: [PATCH 211/217] chore: Do not spellcheck contributor usernames on the ReadMe --- .cspell.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.cspell.json b/.cspell.json index 951b3b7f..46e72d43 100644 --- a/.cspell.json +++ b/.cspell.json @@ -43,6 +43,8 @@ "Wordle" // Game ], "ignoreRegExpList": [ - "^\\$tip\\.Author = .*$" // Ignore tip Author names + "^\\$tip\\.Author = .*$", // Ignore tip Author names. + "<a .+title=\".+\"", // Ignore contributor usernames on the ReadMe page. + "<a .+alt=\".+\"" // Ignore contributor usernames on the ReadMe page. ] } From 073f614adb90a8ad4c6efa313d579fd0cf0c4f4d Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 13:49:34 -0600 Subject: [PATCH 212/217] docs: Add tip retrieval order to ReadMe --- ReadMe.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index 8c773b54..bc84cff3 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -135,7 +135,7 @@ To have a tip automatically displayed every time you open your PowerShell termin Set-TiPSConfiguration -AutomaticallyWritePowerShellTip EverySession ``` -Possible values for the `-AutomaticallyWritePowerShellTip` parameter are `Never`, `EverySession`, `Daily`, `Weekly`, `Biweekly`, and `Monthly`. +Possible values for the `-AutomaticallyWritePowerShellTip` parameter are `Never` (default), `EverySession`, `Daily`, `Weekly`, `Biweekly`, and `Monthly`. Tips will only be automatically shown in interactive PowerShell sessions. This prevents them from appearing unexpectedly when running scripts or other automated processes. @@ -149,12 +149,24 @@ Instead of remembering to manually update the module, you can have the module au Set-TiPSConfiguration -AutomaticallyUpdateModule Weekly ``` -Possible values for the `-AutomaticallyUpdateModule` parameter are `Never`, `Daily`, `Weekly`, `Biweekly`, and `Monthly`. +Possible values for the `-AutomaticallyUpdateModule` parameter are `Never` (default), `Daily`, `Weekly`, `Biweekly`, and `Monthly`. Automatic updates are performed in a background job, so they will not block your PowerShell session from starting. The updated module will be loaded the next time you open a PowerShell terminal or import tiPS. Old versions of the module are automatically deleted after a successful update. +### Tip retrieval order + +By default, the most recent tips are shown first. +This means that if a new tip is submitted, it will be shown next. +You can change the order in which tips are retrieved by running: + +```powershell +Set-TiPSConfiguration -TipOrder Random +``` + +Possible values for the `-TipOrder` parameter are `NewestFirst` (default), `OldestFirst`, and `Random`. + ### ❌ Uninstalling tiPS If you imported tiPS into your PowerShell profile, the import statement will not be removed if you just uninstall the tiPS module. From 8e76c936c39a50d375162ddd2a9e9e6ed819312b Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 14:00:16 -0600 Subject: [PATCH 213/217] docs: Add emoji to subheader --- ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReadMe.md b/ReadMe.md index bc84cff3..2617babc 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -155,7 +155,7 @@ Automatic updates are performed in a background job, so they will not block your The updated module will be loaded the next time you open a PowerShell terminal or import tiPS. Old versions of the module are automatically deleted after a successful update. -### Tip retrieval order +### 🔀 Tip retrieval order By default, the most recent tips are shown first. This means that if a new tip is submitted, it will be shown next. From 38fc14dfd1d6e3deb10b4bf3110d0f060df70ad0 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Sat, 20 Sep 2025 14:10:13 -0600 Subject: [PATCH 214/217] tip: Add tip showing how to adjust tiPS display frequency --- ...25-09-20-adjust-tips-display-frequency.ps1 | 31 ++++++++ src/tiPS/PowerShellTips.json | 78 +++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/PowerShellTips/2025-09-20-adjust-tips-display-frequency.ps1 diff --git a/src/PowerShellTips/2025-09-20-adjust-tips-display-frequency.ps1 b/src/PowerShellTips/2025-09-20-adjust-tips-display-frequency.ps1 new file mode 100644 index 00000000..9100c875 --- /dev/null +++ b/src/PowerShellTips/2025-09-20-adjust-tips-display-frequency.ps1 @@ -0,0 +1,31 @@ +$tip = [tiPS.PowerShellTip]::new() +$tip.CreatedDate = [DateTime]::Parse('2025-09-20') +$tip.Title = 'Adjust tiPS display frequency' +$tip.TipText = @' +You can adjust how often tips are automatically shown by using the `Set-TiPSConfiguration` command. + +If you find that you are seeing the same tips over and over, it means that you've viewed all of the tips currently in the tiPS module. +While new tips do get added to the module over time, you may want to adjust how often tips are shown, such as changing the frequency from Daily to Weekly. + +By default, tips are shown from newest to oldest, so even if you reduce the frequency you will still see newly added tips next. +'@ +$tip.Example = @' +Set-TiPSConfiguration -AutomaticallyWritePowerShellTip Biweekly +'@ +$tip.Urls = @( + 'https://github.com/deadlydog/PowerShell.tiPS?tab=readme-ov-file#-commands' +) +$tip.Category = [tiPS.TipCategory]::Module # Community, Editor, Module, NativeCmdlet, Performance, Security, Syntax, Terminal, or Other. +$tip.Author = 'Daniel Schroeder (deadlydog)' # Optional. Get credit for your tip. e.g. 'Daniel Schroeder (deadlydog)'. +#$tip.ExpiryDate = [DateTime]::Parse('2024-10-30') # Optional. If the tip is not relevant after a certain date, set the expiration date. e.g. Announcing a conference or event. + +# Category meanings: +# Community: Social events and community resources. e.g. PowerShell Summit, podcasts, etc. +# Editor: Editor tips and extensions. e.g. VS Code, ISE, etc. +# Module: Modules and module tips. e.g. PSScriptAnalyzer, Pester, etc. +# NativeCmdlet: Native cmdlet tips. e.g. Get-Process, Get-ChildItem, Get-Content, etc. +# Performance: Tips to improve runtime performance. e.g. foreach vs ForEach-Object, ForEach-Object -Parallel, etc. +# Security: Security tips. e.g. ExecutionPolicy, Constrained Language Mode, passwords, etc. +# Syntax: Syntax tips. e.g. splatting, pipeline, keywords, etc. +# Terminal: Terminal shortcuts and tips. e.g. PSReadLine, Windows Terminal, ConEmu, etc. +# Other: Tips that don't fit into any of the other categories. diff --git a/src/tiPS/PowerShellTips.json b/src/tiPS/PowerShellTips.json index fdb61f13..6754084b 100644 --- a/src/tiPS/PowerShellTips.json +++ b/src/tiPS/PowerShellTips.json @@ -932,5 +932,83 @@ "Category": 8, "ExpiryDate": "9999-12-31T23:59:59.9999999", "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-04-18T00:00:00", + "Title": "Capture superfluous parameters passed to your function(s)", + "TipText": "Capture any parsed parameter to prevent a function from bombing out when being passed unknown / misspelled variables.\r\nComes in handy when parsing the $PSBoundParameters from a calling script with just a subset of parameters that are appropriate / needed by your (custom) function.", + "Example": "[CmdletBinding()]\r\nparam(\r\n[Parameter(DontShow, ValueFromRemainingArguments)]$Superfluous\r\n)\r\n\r\nWrite-Verbose -Message \"Ignoring superfluous params: $($Superfluous -join ' ')\"", + "Urls": [ + "https://github.com/ChristelVDH/SyncAD2AAD/blob/main/ConnectTo-Graph.ps1", + "https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.parameterattribute.valuefromremainingarguments", + "https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.parameterattribute.dontshow" + ], + "Category": 6, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Christel VdH" + }, + { + "CreatedDate": "2025-04-29T00:00:00", + "Title": "Use Measure-Object to get stats about objects", + "TipText": "You can use the Measure-Object cmdlet to get statistics about objects in PowerShell. This cmdlet can be used to calculate the sum, average, minimum, maximum, and count of numeric properties in objects. When used with text input, it can count characters, words, and lines.\r\n\r\nThe cmdlet returns an object containing properties for each statistic, but the statistic is only actually calculated if you provided the switch for it. For example, if you only provide the -Sum switch, the Sum property will contain the sum of the values, but the Average property will be null since the -Average switch was not provided.", + "Example": "# Get all statistics about a range of numbers.\r\n1..10 | Measure-Object -Average -Sum -Minimum -Maximum -StandardDeviation\r\n\r\n# Get all statistics about a string.\r\n\"Hello there\" | Measure-Object -Character -Word -Line\r\n\r\n# Count the number of words in a file.\r\nGet-Content 'C:\\path\\to\\file.txt' | Measure-Object -Word\r\n\r\n# Calculate the total size (Length) of all files in the current directory.\r\nGet-ChildItem | Measure-Object -Property Length -Sum\r\n\r\n# In an array of objects, find the one with the maximum value of the Num property.\r\n@{num=3}, @{num=4}, @{num=5} | Measure-Object -Maximum Num\r\n\r\n# Get the total and maximum CPU time and paged memory size of all processes.\r\nGet-Process | Measure-Object -Property CPU,PagedMemorySize -Sum -Maximum", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-object", + "https://adamtheautomator.com/powershell-measure-object/" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-05-05T00:00:00", + "Title": "Use Join-Path and Split-Path to create cross-platform paths", + "TipText": "When creating file paths in PowerShell, use the `Join-Path` cmdlet instead of string concatenation. This ensures that the correct path separator is used for the current platform (e.g. `\\` on Windows and `/` on Linux/macOS). PowerShell 6 introduced the -AdditionalChildPath parameter, which allows you to specify multiple child paths to join.\r\n\r\nSimilarly, you can use the `Split-Path` cmdlet to split a path into its components. This is useful for extracting the directory or file name from a full path.", + "Example": "# Don't do this, as it may not work on all platforms.\r\n[string] $configFilePath = \"$HOME/Config/config.json\"\r\n\r\n# Do this instead, as it works on all platforms.\r\n[string] $configDirectoryPath = Join-Path -Path $HOME -ChildPath 'Config'\r\n[string] $configFilePath = Join-Path $configDirectoryPath 'config.json' # Excludes -Path and -ChildPath for brevity.\r\n\r\n# You can use System.IO.Path to easily join multiple paths. Helpful in Windows PowerShell.\r\n[string] $configFilePath = [System.IO.Path]::Combine($HOME, 'Config', 'config.json')\r\n\r\n# In PowerShell 6+ you can join multiple child paths at once using -AdditionalChildPath.\r\n[string] $configFilePath = Join-Path -Path $HOME -AdditionalChildPath 'Config' 'config.json'\r\n[string] $xmlFilePath = Join-Path $HOME 'Config' 'config.xml' # Excludes parameter names for brevity.\r\n\r\n# Use -Resolve to ensure we get an absolute path, and error if the path does not exist.\r\n[string] $configFilePath = Join-Path $HOME 'Config' 'config.json' -Resolve\r\n\r\n# Get the name of the file with and without the extension, it's parent directory path, and it's parent directory name.\r\n[string] $fileName = Split-Path -Path $configFilePath -Leaf\r\n[string] $fileNameWithoutExtension = Split-Path -Path $configFilePath -LeafBase\r\n[string] $directoryPath = Split-Path -Path $configFilePath -Parent\r\n[string] $directoryName = Split-Path -Path $directoryPath -Leaf\r\n\r\n# Change the working directory to the folder containing your PowerShell profile.\r\nSet-Location (Split-Path -Path $PROFILE)", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/join-path", + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.management/split-path" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-09-03T00:00:00", + "Title": "Array Lists", + "TipText": "An Array list is similar to an array, but it does not have a fixed size like an array does.\r\n\r\nWith a fixed-sized array and you add an item to the array, the array is actually recreated with the additional item. This can impact performance, when working with thousands of items.\r\n\r\nAnother concern with fixed-size arrays is that there's no simple method to remove an item.", + "Example": "# In PowerShell, you can create an Array list using the `System.Collections.ArrayList` class. Here's how you can create and use an Array list:\r\n\r\n[System.Collections.ArrayList]$computers = @('Server1', 'Server2', 'Server3')\r\n\r\n# To create an empty array ready to add items\r\n\r\n$computers=New-Object System.Collections.ArrayList", + "Urls": [ + "https://learn.microsoft.com/en-us/training/modules/work-arrays-hash-tables-window-powershell-scripts/3-work-array-lists-windows", + "https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-arrays?view=powershell-7.5#arraylist" + ], + "Category": 4, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Adrian Muscat (adrimus)" + }, + { + "CreatedDate": "2025-09-20T00:00:00", + "Title": "Adjust tiPS display frequency", + "TipText": "You can adjust how often tips are automatically shown by using the `Set-TiPSConfiguration` command.\r\n\r\nIf you find that you are seeing the same tips over and over, it means that you've viewed all of the tips currently in the tiPS module.\r\nWhile new tips do get added to the module over time, you may want to adjust how often tips are shown, such as changing the frequency from Daily to Weekly.\r\n\r\nBy default, tips are shown from newest to oldest, so even if you reduce the frequency you will still see newly added tips next.", + "Example": "Set-TiPSConfiguration -AutomaticallyWritePowerShellTip Biweekly", + "Urls": [ + "https://github.com/deadlydog/PowerShell.tiPS?tab=readme-ov-file#-commands" + ], + "Category": 2, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" + }, + { + "CreatedDate": "2025-09-20T00:00:00", + "Title": "Use Get-Verb to see approved verbs", + "TipText": "Use the Get-Verb cmdlet to see a list of all approved verbs in PowerShell. This is useful when creating your own functions or cmdlets, as using approved verbs helps ensure consistency and discoverability. You know right away what a function does simply by the verb it uses.\r\n\r\nGet-Verb is also great for learning about new verbs you may not have known about, including the typical alias abbreviations.", + "Example": "# List all approved verbs and their descriptions.\r\nGet-Verb", + "Urls": [ + "https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-verb", + "https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands" + ], + "Category": 3, + "ExpiryDate": "9999-12-31T23:59:59.9999999", + "Author": "Daniel Schroeder (deadlydog)" } ] From 8d1e18c6387f77abd0b7f74ce05c2cd6c0ad9648 Mon Sep 17 00:00:00 2001 From: Daniel Schroeder <deadlydog@hotmail.com> Date: Mon, 22 Sep 2025 13:58:06 -0600 Subject: [PATCH 215/217] Potential fix for code scanning alert no. 1: Code injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .../process-new-powershell-tip-issue.yml | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index f6d7489f..031c2e67 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -72,12 +72,25 @@ jobs: - name: Extract tip information from issue and create new tip file id: create-tip-file shell: pwsh + env: + ISSUE_BODY: ${{ github.event.issue.body }} run: | Write-Output "Reading information from GitHub issue..." - $body = @' - ${{ github.event.issue.body }} - '@ + $body = $Env:ISSUE_BODY + Write-Output "----------------------------------------" + + Write-Output "Extracting information from issue body to local variables..." + [string] $tipTitle = [string]::Empty + [string] $tipText = [string]::Empty + [string] $tipExample = [string]::Empty + [string] $tipCategory = [string]::Empty + [string[]] $tipUrls = @() + [string] $tipAuthor = [string]::Empty + [string] $tipExpiryDate = [string]::Empty + [string] $gitHubCoAuthor = [string]::Empty + # Extract the data from the markdown representation of the issue. + # GitHub Forms generates structured markdown with specific section headers we can match against. Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output "----------------------------------------" Write-Output $body From 96f90d0b4793a9789a535221de6c2edbf6319901 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 22 Sep 2025 14:00:57 -0600 Subject: [PATCH 216/217] chore: Remove duplicate code added by Copilot autofix --- .../process-new-powershell-tip-issue.yml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 031c2e67..887a46f2 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -77,20 +77,7 @@ jobs: run: | Write-Output "Reading information from GitHub issue..." $body = $Env:ISSUE_BODY - Write-Output "----------------------------------------" - - Write-Output "Extracting information from issue body to local variables..." - [string] $tipTitle = [string]::Empty - [string] $tipText = [string]::Empty - [string] $tipExample = [string]::Empty - [string] $tipCategory = [string]::Empty - [string[]] $tipUrls = @() - [string] $tipAuthor = [string]::Empty - [string] $tipExpiryDate = [string]::Empty - [string] $gitHubCoAuthor = [string]::Empty - - # Extract the data from the markdown representation of the issue. - # GitHub Forms generates structured markdown with specific section headers we can match against. + Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output "----------------------------------------" Write-Output $body From 4496e7f80e8b2ec66fda42f9d17d7c56f0186a67 Mon Sep 17 00:00:00 2001 From: deadlydog <deadlydog@hotmail.com> Date: Mon, 22 Sep 2025 14:06:49 -0600 Subject: [PATCH 217/217] refactor: Add comment explaining why we use an environment variable --- .github/workflows/process-new-powershell-tip-issue.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/process-new-powershell-tip-issue.yml b/.github/workflows/process-new-powershell-tip-issue.yml index 887a46f2..af95a300 100644 --- a/.github/workflows/process-new-powershell-tip-issue.yml +++ b/.github/workflows/process-new-powershell-tip-issue.yml @@ -73,11 +73,12 @@ jobs: id: create-tip-file shell: pwsh env: + # Avoid script injection by retrieving the issue body via an environment variable instead of injecting the text directly into the script. ISSUE_BODY: ${{ github.event.issue.body }} run: | Write-Output "Reading information from GitHub issue..." $body = $Env:ISSUE_BODY - + Write-Output "Displaying issue body for troubleshooting purposes:" Write-Output "----------------------------------------" Write-Output $body