|
| 1 | +Here, we'll help you understand how to contribute to the project, and talk about fun stuff like styles and guidelines. |
| 2 | + |
| 3 | +# Contributing |
| 4 | + |
| 5 | +Let's sum this up saying that we'd love your help. There are several ways to contribute: |
| 6 | + |
| 7 | +- Create new commands (PowerShell knowledge required) |
| 8 | +- Report bugs (everyone can do it) |
| 9 | +- Tests (Pester knowledge required) |
| 10 | +- Documentation: functions, website, this guide, everything can be improved (everyone can) |
| 11 | +- Code review (PowerShell knowledge required) |
| 12 | + |
| 13 | +## Documentation |
| 14 | + |
| 15 | +Documentation is an area that is a good starting point. |
| 16 | +The documentation focus is around our comment-based help (CBH). |
| 17 | +The CBH is included with every public command (and some internal), and is the content you see using `Get-Help Function-Name`. |
| 18 | +Reviewing the content to ensure it is clear on what the command is used for, along with working examples is a key area of discussion. |
| 19 | +Whether you are first starting out with PowerShell or have been using it for years, your fresh eyes can help spot inaccuracies or areas of improvement on how we document each command. |
| 20 | +```Powershell |
| 21 | +function Get-Example { |
| 22 | + <# |
| 23 | + .SYNOPSIS |
| 24 | + A brief description of the function or script. |
| 25 | +
|
| 26 | + .DESCRIPTION |
| 27 | + A longer description. |
| 28 | +
|
| 29 | + .PARAMETER FirstParameter |
| 30 | + Description of each of the parameters. |
| 31 | + Note: |
| 32 | + To make it easier to keep the comments synchronized with changes to the parameters, |
| 33 | + the preferred location for parameter documentation comments is not here, |
| 34 | + but within the param block, directly above each parameter. |
| 35 | +
|
| 36 | + .PARAMETER SecondParameter |
| 37 | + Description of each of the parameters. |
| 38 | +
|
| 39 | + .INPUTS |
| 40 | + Description of objects that can be piped to the script. |
| 41 | +
|
| 42 | + .OUTPUTS |
| 43 | + Description of objects that are output by the script. |
| 44 | +
|
| 45 | + .EXAMPLE |
| 46 | + Example of how to run the script. |
| 47 | +
|
| 48 | + .LINK |
| 49 | + Links to further documentation. |
| 50 | +
|
| 51 | + .NOTES |
| 52 | + Detail on what the script does, if this is needed. |
| 53 | +
|
| 54 | + #> |
| 55 | +``` |
| 56 | +More examples can be found by looking into Comment based help for powershell online or in the [Microsoft Documentation](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comment_based_help?view=powershell-6). |
| 57 | + |
| 58 | +## Fix Bugs |
| 59 | +Submit Pull Requests targeting ideally just one ps1 file, with the name of the function being fixed as a title. Everyone will chime in reviewing the code and either approve the PR or request changes. The more targeted and focused the PR, the easier to merge, the fastest to go into the next release. Keep them as simple as possible to speed up the process. Helpful guide below: |
| 60 | + |
| 61 | +- Fork the project, clone your fork, and configure the remotes |
| 62 | + - If you cloned the project a while ago, get teh latest changes |
| 63 | +- Create a new topic branch (off the main project branch) to contain your feature, change, or fix. |
| 64 | + ```git checkout -b <topic-branch-name>``` |
| 65 | +- Commit your changes in logical chunks. For any Git project, some good rules for commit messages are |
| 66 | + - the first line is commit summary, 50 characters or less, |
| 67 | + - followed by an empty line |
| 68 | + - followed by an explanation of the commit, wrapped to 72 characters. |
| 69 | +- The first line of a commit message becomes the title of a pull request on GitHub, like the subject line of an email. Including the key info in the first line will help us respond faster to your pull. |
| 70 | +- Push your topic branch up to your fork |
| 71 | + ```git push origin <topic-branch-name>``` |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | +## Parameters and Variables |
| 76 | + |
| 77 | +As a reference: |
| 78 | +- when we refer to [parameters](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parameters) these at the command level for accepting input; used when calling a given command like `New-ClientIISSite -WebsiteDomain ggastrocloud.com` (`WebsiteDomain` is the parameter). |
| 79 | +- A [variable](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_variables) is used within a given command to store values or objects that are used in the given command's code. |
| 80 | + |
| 81 | +We chose to follow the standards below when creating parameters and variables for a function: |
| 82 | + |
| 83 | +1) Any variable used in the parameter block must have first letter of each word capitalized. (e.g. `$SqlInstance`) |
| 84 | +1) Any variable used in the parameter block **is required** to be singular. |
| 85 | +1) Any variable not part of the parameter block, that is multiple words, will follow the camelCase format. (e.g. `$dbLogin`) |
| 86 | +1) Refrain from using single character variable names (e.g. `$i` or `$x`). Try to make them "readable" in the sense that if someone sees the variable name they can get a hint what it presents (e.g. `$url`, `$site`) OR e.g. `foreach ($database in $databases)` instead of `foreach ($db in $dbs)` |
| 87 | +1) When you are working with "objects", say with databases, what variable name you use should be based on what operation you are doing. As an example: in situations where you are looping over the databases for an instance, try to use a plural variable name for the collection and then single or abbreviated name in the loop for each object of that collection. e.g. `foreach ($database in $databases)`. |
| 88 | + |
| 89 | + |
| 90 | + |
| 91 | +## Formatting and indentation |
| 92 | + |
| 93 | +Consistency is key; throughout the project and accept PRs coming from anybody. |
| 94 | +When using VSCode, install the powershell extension. They have a keyboard shortcut to format files: |
| 95 | +SHIFT+ALT+F |
| 96 | + |
| 97 | + |
| 98 | +## Tests |
| 99 | + |
| 100 | +Remember that tests are needed to make sure the code behaves properly. The ultimate goal is for any user to be able to run this modules' tests within their environment and, depending on the result, be sure everything works as expected. |
| 101 | + |
| 102 | +### How to write tests |
| 103 | + |
| 104 | +To save resources and be more flexible, we split tests with tags into two main categories, `UnitTests` and `IntegrationTests`. Below is a starting list of things to consider when writing your test: |
| 105 | + |
| 106 | +- `UnitTests` do not require an instance to be up and running, and are easily the most flexible to be ran on every user computer. - `IntegrationTests` instead require one or more active instances, and there is a bit of setup to do in order to run them. |
| 107 | +- Every one of the `IntegrationTests` may need to create a resource (e.g. a database Or an IIS Site). |
| 108 | +- Every resource should be named with the `testEnv_` prefix. _The test should attempt to clean up after itself leaving a pristine environment._ |
| 109 | +- Try to write tests thinking they may run in each and every user's test environment. |
| 110 | + |
| 111 | +You'll see that every test file is named with a simple convention `Verb-Noun*.Tests.ps1`, and this is required by [Pester](https://GitHub.com/pester/Pester), which is the de-facto standard for running tests in PowerShell. |
| 112 | + |
| 113 | +### Installing Pester (PSv5a and above) |
| 114 | + |
| 115 | +```Powershell |
| 116 | +If ($PSVersionTable.PSVersion.Major -eq 5) { |
| 117 | + if (Get-Module -ListAvailable -Name Pester) { |
| 118 | + Write-Output "Module exists" |
| 119 | + Write-Output "Attempting to update" |
| 120 | + Update-Module Pester -Force |
| 121 | + } |
| 122 | + else { |
| 123 | + Write-Output "Module does not exist" |
| 124 | + Write-Output "Attempting to Install" |
| 125 | + Install-module Pester -Force |
| 126 | + } |
| 127 | +} |
| 128 | +``` |
| 129 | + |
| 130 | +#### Serialize Data For Mock data |
| 131 | + |
| 132 | +```Powershell |
| 133 | +#Location to send the Serialized Data to Disk |
| 134 | +$ExportPath= "$env:APPDATA\PoshXmlSerializationData.xml" |
| 135 | +#Function you want to Serialize |
| 136 | +$data = Get-ChildItem C:\Users\ |
| 137 | +#Serialize the data to disk |
| 138 | +$data | Export-Clixml $ExportPath |
| 139 | +#copy the file item to the clipboard |
| 140 | +get-content $ExportPath | clip |
| 141 | +#Place the file into a variable in the test file |
| 142 | +$MockedSerializedgetChildItem =@' |
| 143 | +<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"> |
| 144 | + <Obj RefId="0"> |
| 145 | + <TN RefId="0"> |
| 146 | + <T>System.IO.DirectoryInfo</T> |
| 147 | + <T>System.IO.FileSystemInfo</T> |
| 148 | + <T>System.MarshalByRefObject</T> |
| 149 | + <T>System.Object</T> |
| 150 | + ... |
| 151 | +'@ |
| 152 | +#To Deserialize the data use the following: |
| 153 | +$MockedItem = [System.Management.Automation.PSSerializer]::DeserializeAsList($MockedSerializedgetChildItem) |
| 154 | +#your $mockeditem will now contain the original data Allowing you to set static variables |
| 155 | +``` |
| 156 | + |
| 157 | +#### Tagging Unit Tests |
| 158 | +With Pester you have the ability to tag test describe blocks `Describe -Tags ('Unit')` This allows you to run blocks of tests without needing to subdivide tests into multiple files |
| 159 | +Unfortunately, these tags are not hardcoded - for our Module we will be using the following tags |
| 160 | +- Acceptance |
| 161 | +- Unit |
| 162 | +- Integration |
| 163 | +This means that all describe blocks need to be tagged. |
| 164 | + |
| 165 | +#### $TestDrive variable to output files too |
| 166 | +TestDrive is a PowerShell PSDrive for file activity limited to the scope of a single Describe or Context block in pester. |
| 167 | +Pester creates a PSDrive inside the user's temporary drive that is accessible via a named PSDrive TestDrive:. Pester will remove this drive after the test completes. You may use this drive to isolate the file operations of your test to a temporary store. |
| 168 | +More information can be found on the [Pester Wiki](https://github.com/pester/Pester/wiki/TestDrive) |
| 169 | + |
| 170 | +#### Testing code coverage with Pester |
| 171 | +To run a code coverage test against your unit tests use the following command |
| 172 | +```Powershell |
| 173 | +invoke-pester .\Tests\FunctionName.tests.ps1 -codecoverage .\Private\functionname.ps1 |
| 174 | +``` |
| 175 | + |
| 176 | +## Extensions |
| 177 | +##### Markdown editor |
| 178 | +Created in Markdown editor extion on visual studio code |
| 179 | +###### Markdown editor ShortCuts |
| 180 | + |
| 181 | +Keybindings |
| 182 | +The cmd key for Windows is ctrl. |
| 183 | + |
| 184 | +Shortcuts Functionality |
| 185 | +cmd-k v Created in Markdown editor extion on visual studio code Open preview to the Side |
| 186 | +ctrl-shift-v Open preview |
| 187 | +ctrl-shift-s Sync preview / Sync source |
| 188 | +shift-enter Run Code Chunk |
| 189 | +ctrl-shift-enter Run all Code Chunks |
| 190 | +cmd-= or cmd-shift-= Preview zoom in |
| 191 | +cmd-- or cmd-shift-_ Preview zoom out |
| 192 | +cmd-0 Preview reset zoom |
| 193 | +esc Toggle sidebar TOC |
0 commit comments