Skip to content

Commit b0d2659

Browse files
authored
DSC Community guidelines instructions (#2128)
1 parent 3a792fc commit b0d2659

13 files changed

+629
-512
lines changed

.github/copilot-instructions.md

Lines changed: 21 additions & 512 deletions
Large diffs are not rendered by default.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
description: SqlServerDsc-specific guidelines for AI development.
3+
applyTo: "**"
4+
---
5+
6+
# SqlServerDsc Guidelines
7+
8+
## Naming
9+
- Public commands: `{Verb}-SqlDsc{Noun}` format
10+
11+
## Resources
12+
- Database Engine resources: inherit `SqlResourceBase`
13+
- `SqlResourceBase` provides: `InstanceName`, `ServerName`, `Credential`, `Reasons`, `GetServerObject()`
14+
15+
## SQL Server Interaction
16+
- Always prefer SMO over T-SQL
17+
- Unit tests: Use SMO stub types from SMO.cs, never mock SMO types
18+
- Run tests in new session after changing SMO.cs
19+
20+
## Testing CI Environment
21+
- Database Engine: instance `DSCSQLTEST`
22+
- Reporting Services: instance `SSRS`
23+
- Power BI Report Server: instance `PBIRS`
24+
25+
## Test Requirements
26+
- Unit tests: Add `$env:SqlServerDscCI = $true` in `BeforeAll`, remove in `AfterAll`
27+
- Integration tests: Use `Disconnect-SqlDscDatabaseEngine` after `Connect-SqlDscDatabaseEngine`
28+
- Test config: tests/Integration/Commands/README.md and tests/Integration/Resources/README.md
29+
- Integration test script files must be added to a group
30+
within the test stage in ./azure-pipelines.yml.
31+
- Choose the appropriate group number based on the required dependencies
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
description: Guidelines for maintaining a clear and consistent changelog.
3+
applyTo: "CHANGELOG.md"
4+
---
5+
6+
# Changelog Guidelines
7+
8+
- Always update the Unreleased section in CHANGELOG.md
9+
- Use Keep a Changelog format
10+
- Describe main changes as concise release notes
11+
- Reference issues using format #<issue_number>
12+
- No empty lines between list items in same section
13+
- Do not add item if there are already an existing item for the same change
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
description: Guidelines for implementing Desired State Configuration (DSC) class-based resources.
3+
applyTo: "source/[cC]lasses/**/*.ps1"
4+
---
5+
6+
# DSC Class-Based Resource Guidelines
7+
8+
**Applies to:** Classes with `[DscResource(...)]` decoration only.
9+
10+
## Requirements
11+
- File: `source/Classes/{ResourceName}.ps1`
12+
- Decoration: `[DscResource(RunAsCredential = 'Optional')]` (replace with `'Mandatory'` if required)
13+
- Inheritance: Must inherit `ResourceBase` (part of module DscResource.Base)
14+
- `$this.localizedData` hashtable auto-populated by `ResourceBase` from localization file
15+
16+
## Required Method Pattern
17+
18+
```powershell
19+
[MyResourceName] Get()
20+
{
21+
$currentState = ([ResourceBase] $this).Get()
22+
23+
# If needed, post-processing based on returned current state before returning to user
24+
25+
return $currentState
26+
}
27+
28+
[System.Boolean] Test()
29+
{
30+
$inDesiredState = ([ResourceBase] $this).Test()
31+
32+
# If needed, post-processing based on returned test result before returning to user
33+
34+
return $inDesiredState
35+
}
36+
37+
[void] Set()
38+
{
39+
([ResourceBase] $this).Set()
40+
41+
# If needed, additional state changes that could not be handled by Modify()
42+
}
43+
44+
hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
45+
{
46+
# Return current state as hashtable
47+
# Variable $properties contains the key properties (key-value pairs).
48+
}
49+
50+
hidden [void] Modify([System.Collections.Hashtable] $properties)
51+
{
52+
# Set desired state for non-compliant properties only
53+
# Variable $properties contains the properties (key-value pairs) that are not in desired state.
54+
}
55+
56+
hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
57+
{
58+
# Validate user-provided properties
59+
# Variable $properties contains properties user assigned values.
60+
}
61+
62+
hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties)
63+
{
64+
# Normalize user-provided properties
65+
# Variable $properties contains properties user assigned values.
66+
}
67+
```
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
description: Guidelines for implementing integration tests for commands.
3+
applyTo: "tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1"
4+
---
5+
6+
# Integration Tests Guidelines
7+
8+
## Requirements
9+
- Location Commands: `tests/Integration/Commands/{CommandName}.Integration.Tests.ps1`
10+
- Location Resources: `tests/Integration/Resources/{ResourceName}.Integration.Tests.ps1`
11+
- No mocking - real environment only
12+
- Cover all scenarios and code paths
13+
- Use `Get-ComputerName` for computer names in CI
14+
- Only run integration tests in CI unless explicitly instructed.
15+
16+
## Required Setup Block
17+
18+
```powershell
19+
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
20+
param ()
21+
22+
BeforeDiscovery {
23+
try
24+
{
25+
if (-not (Get-Module -Name 'DscResource.Test'))
26+
{
27+
# Assumes dependencies have been resolved, so if this module is not available, run 'noop' task.
28+
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
29+
{
30+
# Redirect all streams to $null, except the error stream (stream 2)
31+
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 3>&1 4>&1 5>&1 6>&1 > $null
32+
}
33+
34+
# If the dependencies have not been resolved, this will throw an error.
35+
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
36+
}
37+
}
38+
catch [System.IO.FileNotFoundException]
39+
{
40+
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
41+
}
42+
}
43+
44+
BeforeAll {
45+
$script:dscModuleName = 'SqlServerDsc'
46+
47+
Import-Module -Name $script:dscModuleName -Force -ErrorAction 'Stop'
48+
}
49+
```
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
description: Guidelines for implementing localization.
3+
applyTo: "source/**/*.ps1"
4+
---
5+
6+
# Localization Guidelines
7+
8+
## Requirements
9+
- Localize all Write-Debug, Write-Verbose, Write-Error, Write-Warning and $PSCmdlet.ThrowTerminatingError() messages
10+
- Use localized string keys, not hardcoded strings
11+
- Assume `$script:localizedData` is available
12+
13+
## String Files
14+
- Commands/functions: `source/en-US/SqlServerDsc.strings.psd1`
15+
- Class resources: `source/en-US/{ResourceClassName}.strings.psd1`
16+
17+
## Key Naming
18+
- Format: `FunctionName_Description` (underscore separators)
19+
- Example: `Get_SqlDscDatabase_ConnectingToDatabase`
20+
21+
## String Format
22+
```powershell
23+
ConvertFrom-StringData @'
24+
KeyName = Message with {0} placeholder. (PREFIX0001)
25+
'@
26+
```
27+
28+
## String IDs
29+
- Format: `(PREFIX####)`
30+
- PREFIX: First letter of each word in class or function name (SqlSetup → SS, Get-SqlDscDatabase → GSDD)
31+
- Number: Sequential from 0001
32+
33+
## Usage
34+
```powershell
35+
Write-Verbose -Message ($script:localizedData.KeyName -f $value1)
36+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
description: Guidelines for writing and maintaining Markdown documentation.
3+
applyTo: "**/*.md"
4+
---
5+
6+
# Markdown Style Guidelines
7+
8+
- Wrap lines at 80 characters
9+
- Use 2 spaces for indentation
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
description: Guidelines for implementing MOF DSC resources.
3+
applyTo: "source/DSCResources/**/*.psm1"
4+
---
5+
6+
# MOF-based Desired State Configuration (DSC) Resources Guidelines
7+
8+
## Required Functions
9+
- Every DSC resource must define: `Get-TargetResource`, `Set-TargetResource`, `Test-TargetResource`
10+
- Export using `*-TargetResource` pattern
11+
12+
## Function Return Types
13+
- `Get-TargetResource`: Must return hashtable with all resource properties
14+
- `Test-TargetResource`: Must return boolean ($true/$false)
15+
- `Set-TargetResource`: Must not return anything (void)
16+
17+
## Parameter Guidelines
18+
- `Get-TargetResource`: Only include parameters needed to retrieve actual current state values
19+
- `Get-TargetResource`: Remove non-mandatory parameters that are never used
20+
- `Set-TargetResource` and `Test-TargetResource`: Must have identical parameters
21+
- `Set-TargetResource` and `Test-TargetResource`: Unused mandatory parameters: Add "Not used in <function_name>" to help comment
22+
23+
## Required Elements
24+
- Each function must include `Write-Verbose` at least once
25+
- `Get-TargetResource`: Use verbose message starting with "Getting the current state of..."
26+
- `Set-TargetResource`: Use verbose message starting with "Setting the desired state of..."
27+
- `Test-TargetResource`: Use verbose message starting with "Determining the current state of..."
28+
- Use localized strings for all messages (Write-Verbose, Write-Error, etc.)
29+
- Import localized strings using `Get-LocalizedData` at module top
30+
31+
## Error Handling
32+
- Do not use `throw` for terminating errors
33+
- Use `try/catch` blocks to handle exceptions
34+
- Throw localized exceptions using the appropriate `New-*Exception` cmdlet:
35+
- [`New‑InvalidDataException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidDataException)
36+
- [`New-ArgumentException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ArgumentException)
37+
- [`New-InvalidOperationException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidOperationException)
38+
- [`New-ObjectNotFoundException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91ObjectNotFoundException)
39+
- [`New-InvalidResultException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91InvalidResultException)
40+
- [`New-NotImplementedException`](https://github.com/dsccommunity/DscResource.Common/wiki/New%E2%80%91NotImplementedException)
41+
42+
# MOF Resource Localization
43+
44+
## File Structure
45+
- Create `en-US` folder in each resource directory
46+
- Name strings file: `DSC_<ResourceName>.strings.psd1`
47+
- Use names returned from `Get-UICulture` for additional language folder names
48+
49+
## String File Format
50+
51+
- In `.strings.psd1` files, use underscores as word separators in localized
52+
string key names (for multi-word keys)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
description: Guidelines for writing and maintaining tests using Pester.
3+
applyTo: "**/*.[Tt]ests.ps1"
4+
---
5+
6+
# Tests Guidelines
7+
8+
## Core Requirements
9+
- All public commands, private functions and classes must have unit tests
10+
- Use Pester v5 syntax only
11+
- One `Describe` block per file matching the tested entity name
12+
- Test code only inside `Describe` blocks
13+
- Assertions only in `It` blocks
14+
- Never test `Write-Verbose`, `Write-Debug`, or parameter binding behavior
15+
- Pass all mandatory parameters to avoid prompts
16+
17+
## Structure & Scope
18+
- Public commands: Never use `InModuleScope`
19+
- Private functions/class resources: Always use `InModuleScope`
20+
- Each scenario = separate `Context` block
21+
- Use nested `Context` blocks for complex scenarios
22+
- Mocking in `BeforeAll` (`BeforeEach` only when required)
23+
- Setup/teardown in `BeforeAll`,`BeforeEach`/`AfterAll`,`AfterEach` close to usage
24+
25+
## Syntax Rules
26+
- PascalCase: `Describe`, `Context`, `It`, `Should`, `BeforeAll`, `BeforeEach`, `AfterAll`, `AfterEach`
27+
- `It` descriptions start with 'Should'
28+
- `Context` descriptions start with 'When'
29+
- Mock variables prefix: 'mock'
30+
- Prefer `-BeTrue`/`-BeFalse` over `-Be $true`/`-Be $false`
31+
- No `Should -Not -Throw` - invoke commands directly
32+
33+
## File Organization
34+
- Class resources: `tests/Unit/Classes/{Name}.Tests.ps1`
35+
- Public commands: `tests/Unit/Public/{Name}.Tests.ps1`
36+
- Private functions: `tests/Unit/Private/{Name}.Tests.ps1`
37+
38+
## Data-Driven Tests
39+
- Define variables in separate `BeforeDiscovery` for `-ForEach` (close to usage)
40+
- `-ForEach` allowed on `Context` and `It` blocks
41+
- Keep scope close to usage context
42+
43+
## Best Practices
44+
- Assign unused return objects to `$null`
45+
- Tested entity must be called from within the `It` blocks
46+
- Keep results and assertions in same `It` block
47+
- Cover all scenarios and code paths
48+
- Use `BeforeEach` and `AfterEach` sparingly

0 commit comments

Comments
 (0)