Skip to content

Commit 879c392

Browse files
committed
Refactor guidelines documentation for clarity and consistency across multiple files
1 parent a761170 commit 879c392

9 files changed

+194
-458
lines changed
Lines changed: 22 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,31 @@
11
---
2-
description: Guidelines for working with the SqlServerDsc PowerShell module.
2+
description: SqlServerDsc-specific guidelines for AI development.
33
applyTo: "**"
44
---
55

6-
# SqlServerDsc Module Guidelines
6+
# SqlServerDsc Guidelines
77

8-
This file contains specific guidelines for working with the SqlServerDsc PowerShell module project.
8+
## Naming
9+
- Public commands: `{Verb}-SqlDsc{Noun}` format
910

10-
## Public Command Naming
11+
## Resources
12+
- Database Engine resources: inherit `SqlResourceBase`
13+
- `SqlResourceBase` provides: `InstanceName`, `ServerName`, `Credential`, `Reasons`, `GetServerObject()`
1114

12-
All public command names must have the noun prefixed with 'SqlDsc', e.g.
13-
{Verb}-SqlDsc{Noun}.
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
1419

15-
## DSC Resource Base Classes
20+
## Testing CI Environment
21+
- Database Engine: instance `DSCSQLTEST`
22+
- Reporting Services: instance `SSRS`
23+
- Power BI Report Server: instance `PBIRS`
1624

17-
### SqlResourceBase
18-
19-
Derived resources should inherit `SqlResourceBase` (which inherits `ResourceBase`)
20-
when they need to connect to the SQL Server Database Engine.
21-
22-
`SqlResourceBase` provides the DSC properties `InstanceName`, `ServerName`,
23-
`Credential`, and `Reasons`, and the `GetServerObject` method used to connect
24-
to a SQL Server Database Engine instance.
25-
26-
## SQL Server
27-
28-
### SQL Server Management Objects (SMO)
29-
30-
When developing commands, private functions, class-based resources, or making
31-
modifications to existing functionality, always prefer using SQL Server
32-
Management Objects (SMO) as the primary method for interacting with SQL Server.
33-
Only use T-SQL when it is not possible to achieve the desired functionality
34-
with SMO.
35-
36-
Do not mock SMO types in unit tests, use SMO stub types from SMO.cs.
37-
Always run tests in a new session after changing stub types in SMO.cs.
38-
39-
## Integration Testing Environment
40-
41-
### SQL Server Database Engine
42-
43-
Integration tests that depend on an SQL Server Database Engine instance
44-
will run in environments in CI/CD pipelines where an instance DSCSQLTEST
45-
is already installed. Each environment will have SQL Server 2016, 2017,
46-
2019, or 2022.
47-
48-
### SQL Server Reporting Services
49-
50-
Integration tests that depend on an SQL Server Reporting Services instance
51-
will run in environments in CI/CD pipelines where an instance SSRS is already
52-
installed. Each environment will have SQL Server Reporting Services 2016,
53-
2017, 2019, or 2022.
54-
55-
### Power BI Report Server
56-
57-
Integration tests that depend on a Power BI Report Server instance
58-
will run in one environment in CI/CD pipeline where an instance PBIRS is
59-
already installed. The environment will always have the latest Power BI
60-
Report Server version.
61-
62-
## Integration Test Configuration
63-
64-
Integration test script files for public commands must be added to a group
65-
within the 'Integration_Test_Commands_SqlServer' stage in ./azure-pipelines.yml.
66-
Choose the appropriate group number based on the command’s dependencies
67-
(for example, commands that require Database Engine should be in Group 2
68-
or later, after the Database Engine installation tests).
69-
70-
For integration testing commands, use the information in
71-
tests/Integration/Commands/README.md, which describes the testing environment,
72-
including available instances, users, credentials, and other configuration
73-
details.
74-
75-
## Testing
76-
77-
### Unit Tests
78-
79-
For every unit test the following must be added to the top level `BeforeAll`- and `AfterAll`-blocks in the test file:
80-
81-
```powershell
82-
BeforeAll {
83-
$env:SqlServerDscCI = $true
84-
}
85-
86-
AfterAll {
87-
Remove-Item -Path 'env:SqlServerDscCI'
88-
}
89-
```
90-
91-
### Integration tests
92-
93-
When using command `Connect-SqlDscDatabaseEngine` always use `Disconnect-SqlDscDatabaseEngine` when connection is no longer needed.
94-
95-
Instances and credentials to use in integration tests are available for:
96-
- Commands: tests/Integration/Commands/README.md
97-
- Resources: tests/Integration/Resources/README.md
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

.github/instructions/dsc-community-style-guidelines-changelog.instructions.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@ description: Guidelines for maintaining a clear and consistent changelog.
33
applyTo: "CHANGELOG.md"
44
---
55

6-
# Changelog Style Guidelines
7-
8-
Always update the Unreleased section in CHANGELOG.md with every change.
9-
Use the Keep a Changelog format and provide concrete release notes that
10-
describe the main changes. Include new commands, private functions,
11-
class-based resources, or significant modifications to existing
12-
functionality.
13-
14-
Reference related issues using the format #<issue_number>.
15-
16-
Do not leave empty lines between list items in the same section.
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

.github/instructions/dsc-community-style-guidelines-class-resource.instructions.md

Lines changed: 28 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,100 +3,65 @@ description: Guidelines for implementing Desired State Configuration (DSC) class
33
applyTo: "source/[cC]lasses/**/*.ps1"
44
---
55

6-
# Desired State Configuration (DSC) class-based resource Style Guidelines
6+
# DSC Class-Based Resource Guidelines
77

8-
Only use this instruction when the class is decorated with `[DscResource(...)]`.
8+
**Applies to:** Classes with `[DscResource(...)]` decoration only.
99

10-
Each DSC class-based resource must have its own script file named after the
11-
resource class (with the .ps1 extension). Place these files in source/Classes.
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
1215

13-
## Parent classes
14-
15-
### ResourceBase
16-
17-
A derived class should inherit the parent class `ResourceBase`.
18-
19-
The parent class `ResourceBase` will set up `$this.localizedData` and provide
20-
logic to compare the desired state against the current state. To get the
21-
current state it will call the overridable method `GetCurrentState`. If not
22-
in desired state it will call the overridable method `Modify`. It will also
23-
call the overridable methods `AssertProperties` and `NormalizeProperties` to
24-
validate and normalize the provided values of the desired state.
25-
26-
## Derived class
27-
28-
The derived class should use the decoration `[DscResource(RunAsCredential = 'Optional')]`.
29-
30-
The derived class should always inherit from a parent class.
31-
32-
The derived class should override the methods `Get`, `Test`, `Set`, `GetCurrentState`,
33-
`Modify`, `AssertProperties`, and `NormalizeProperties` using this pattern
34-
(and replace MyResourceName with actual resource name):
16+
## Required Method Pattern
3517

3618
```powershell
3719
[MyResourceName] Get()
3820
{
39-
# Call the base method to return the properties.
40-
return ([ResourceBase] $this).Get()
21+
$currentState = ([ResourceBase] $this).Get()
22+
23+
# If needed, post-processing based on returned current state before returning to user
24+
25+
return $currentState
4126
}
4227
4328
[System.Boolean] Test()
4429
{
45-
# Call the base method to test all of the properties that should be enforced.
46-
return ([ResourceBase] $this).Test()
30+
$inDesiredState = ([ResourceBase] $this).Test()
31+
32+
# If needed, post-processing based on returned test result before returning to user
33+
34+
return $inDesiredState
4735
}
4836
4937
[void] Set()
5038
{
51-
# Call the base method to enforce the properties.
5239
([ResourceBase] $this).Set()
40+
41+
# If needed, additional state changes that could not be handled by Modify()
5342
}
5443
55-
<#
56-
Base method Get() calls this method to get the current state as a hashtable.
57-
The parameter properties will contain the key properties.
58-
#>
5944
hidden [System.Collections.Hashtable] GetCurrentState([System.Collections.Hashtable] $properties)
6045
{
61-
# Add code to return the current state as a hashtable.
46+
# Return current state as hashtable
47+
# Variable $properties contains the key properties (key-value pairs).
6248
}
6349
64-
<#
65-
Base method Set() calls this method with the properties that are not in
66-
the desired state and must be enforced. It is not called if all properties
67-
are in the desired state. The $properties variable contains only the
68-
properties that are not in the desired state.
69-
#>
7050
hidden [void] Modify([System.Collections.Hashtable] $properties)
7151
{
72-
# Add code to set the desired state based on the properties that are not in desired state.
52+
# Set desired state for non-compliant properties only
53+
# Variable $properties contains the properties (key-value pairs) that are not in desired state.
7354
}
7455
75-
<#
76-
Base method Assert() calls this method with the properties that were assigned
77-
a value.
78-
#>
7956
hidden [void] AssertProperties([System.Collections.Hashtable] $properties)
8057
{
81-
# Add code to validate class properties that the user passed values to.
58+
# Validate user-provided properties
59+
# Variable $properties contains properties user assigned values.
8260
}
8361
84-
<#
85-
Base method Normalize() calls this method with the properties that were assigned
86-
a value.
87-
#>
8862
hidden [void] NormalizeProperties([System.Collections.Hashtable] $properties)
8963
{
90-
# Add code to normalize class properties that the user passed values to.
64+
# Normalize user-provided properties
65+
# Variable $properties contains properties user assigned values.
9166
}
9267
```
93-
94-
## Localization
95-
96-
For class-based resources, add a localized strings file in the folder
97-
source/en-US. Name the file exactly after the resource class with the suffix
98-
`.strings.psd1`.
99-
Localized string key names should use underscores as word separators if the key
100-
name has more than one word. Always assume that all localized string keys for a
101-
class-based resource have already been assigned to `$this.localizedData` by the
102-
parent class.

.github/instructions/dsc-community-style-guidelines-integration-tests.instructions.md

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
---
22
description: Guidelines for implementing integration tests for commands.
3-
applyTo: "**/*.[iI]ntegration.[tT]ests.ps1"
3+
applyTo: "tests/[iI]ntegration/**/*.[iI]ntegration.[tT]ests.ps1"
44
---
55

6-
# Command Integration Tests Style Guidelines
6+
# Integration Tests Guidelines
77

8-
Every public command must have an integration test. Integration tests must
9-
never mock any command; they run in a real environment. Place all integration
10-
tests in the folder `tests/Integration/Commands`. Name each test after the
11-
public command it verifies and suffix it with `.Integration.Tests.ps1`.
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.
1215

13-
Write tests to cover all scenarios and code paths, including common cases
14-
and edge cases. Tests should exercise the command in a real environment,
15-
using real resources and dependencies.
16-
17-
When integration tests need the computer name in CI, use [`Get-ComputerName`](https://github.com/dsccommunity/DscResource.Common/wiki/Get%E2%80%91ComputerName).
18-
This helper is provided in the build pipeline and is not required locally.
19-
20-
All integration tests must use the code block below before the first
21-
`Describe` block. The following code sets up the integration test
22-
environment and ensures the module under test is available:
16+
## Required Setup Block
2317

2418
```powershell
2519
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Suppressing this rule because Script Analyzer does not understand Pester syntax.')]
@@ -53,9 +47,3 @@ BeforeAll {
5347
Import-Module -Name $script:dscModuleName -Force -ErrorAction 'Stop'
5448
}
5549
```
56-
57-
The DscResource.Test module is used by the pipeline and its commands are
58-
typically not used when testing public functions, private functions, or
59-
class-based resources.
60-
61-
Do not run integration tests locally unless explicitly instructed.

.github/instructions/dsc-community-style-guidelines-localization.instructions.md

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,34 @@ description: Guidelines for implementing localization.
33
applyTo: "source/**/*.ps1"
44
---
55

6-
# Localization Style Guidelines
6+
# Localization Guidelines
77

8-
For public commands and private functions, you should always add all localized
9-
strings in the source/en-US/SqlServerDsc.strings.psd1 file, reusing the
10-
same pattern for new string keys. Localized string key names should always
11-
be prefixed with the function name but use underscores as word separators.
12-
Always assume that all localized string keys have already been assigned to
13-
the variable $script:localizedData.
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
1412

15-
All message strings for Write-Debug, Write-Verbose, Write-Error, Write-Warning,
16-
and other error messages in classes, public commands, and private functions should
17-
be localized using localized string keys.
13+
## String Files
14+
- Commands/functions: `source/en-US/SqlServerDsc.strings.psd1`
15+
- Class resources: `source/en-US/{ResourceClassName}.strings.psd1`
1816

19-
## String File Locations
17+
## Key Naming
18+
- Format: `FunctionName_Description` (underscore separators)
19+
- Example: `Get_SqlDscDatabase_ConnectingToDatabase`
2020

21-
- Public commands and private functions: source/en-US/SqlServerDsc.strings.psd1
22-
- Class-based resources: source/en-US/<ResourceClassName>.strings.psd1
23-
24-
## String File Format
21+
## String Format
2522
```powershell
26-
# Localized resources for <ResourceName>
2723
ConvertFrom-StringData @'
2824
KeyName = Message with {0} placeholder. (PREFIX0001)
2925
'@
3026
```
3127

32-
## String ID Format
33-
Use unique IDs: `(PREFIX####)`
34-
- PREFIX: First letter of each word in resource name or function name
35-
- ####: Sequential number starting 0001
36-
- Examples: SqlSetup → SS0001, SqlAGDatabase → SAGD0001, Get-SqlDscSqlDatabase → GSDSD0001
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
3732

38-
## Usage Patterns
33+
## Usage
3934
```powershell
40-
# Verbose/Warning messages
41-
Write-Verbose -Message ($script:localizedData.KeyName -f $value)
42-
Write-Warning -Message ($script:localizedData.KeyName -f $value)
43-
44-
# Error messages
45-
New-InvalidOperationException -Message ($script:localizedData.KeyName -f $value1, $value2)
46-
New-InvalidOperationException -ErrorRecord $_ -Message ($script:localizedData.KeyName -f $value1)
35+
Write-Verbose -Message ($script:localizedData.KeyName -f $value1)
4736
```

0 commit comments

Comments
 (0)