Skip to content

Commit b273a4b

Browse files
feat(scripts): add Get-StandardTimestamp utility to CIHelpers module (#1126)
## Description Added a `Get-StandardTimestamp` function to `CIHelpers.psm1` that returns the current UTC time as an ISO 8601 string (`2025-01-15T18:30:00.0000000Z`). Five different timestamp expressions existed across linting and security scripts with no shared utility, making cross-script log correlation unreliable. This function provides a single, authoritative source for consistent, timezone-unambiguous timestamps across all scripts. ## Related Issue(s) Closes #993 ## Type of Change Select all that apply: **Code & Documentation:** * [ ] Bug fix (non-breaking change fixing an issue) * [x] New feature (non-breaking change adding functionality) * [ ] Breaking change (fix or feature causing existing functionality to change) * [ ] Documentation update **Infrastructure & Configuration:** * [ ] GitHub Actions workflow * [ ] Linting configuration (markdown, PowerShell, etc.) * [ ] Security configuration * [ ] DevContainer configuration * [ ] Dependency update **Other:** * [x] Script/automation (`.ps1`, `.sh`, `.py`) * [ ] Other (please describe): ## Testing All validation was performed: * `npm run lint:ps` — Passed. All PowerShell files pass PSScriptAnalyzer checks with no issues. * `npm run test:ps` — Passed. 73/73 Pester tests pass, including all 4 new `Get-StandardTimestamp` tests: * `Returns a string` * `Returns a non-empty value` * `Matches ISO 8601 UTC format ending in Z` * `Returns monotonically increasing timestamps on consecutive calls` * Security analysis: No sensitive data, new dependencies, or privilege scope changes detected. * No manual testing required for this change; the function has no external side effects or I/O. ## Checklist ### Required Checks * [x] Documentation is updated (if applicable) * [x] Files follow existing naming conventions * [x] Changes are backwards compatible (if applicable) * [x] Tests added for new functionality (if applicable) ### Required Automated Checks The following validation commands must pass before merging: * [x] Markdown linting: `npm run lint:md` * [x] Spell checking: `npm run spell-check` * [x] Frontmatter validation: `npm run lint:frontmatter` * [x] Skill structure validation: `npm run validate:skills` * [x] Link validation: `npm run lint:md-links` * [x] PowerShell analysis: `npm run lint:ps` * [x] Plugin freshness: `npm run plugin:generate` ## Security Considerations <!-- ⚠️ WARNING: Do not commit sensitive information such as API keys, passwords, or personal data --> * [x] This PR does not contain any sensitive or NDA information * [x] Any new dependencies have been reviewed for security issues (N/A — no new dependencies) * [x] Security-related scripts follow the principle of least privilege (N/A — no security script changes) ## Additional Notes This function is a prerequisite for issue #1000 (`Standardize timestamp in SecurityHelpers.psm1 to use Get-StandardTimestamp`), which will be addressed in a follow-up PR. --------- Co-authored-by: Bill Berry <wberry@microsoft.com> Co-authored-by: Bill Berry <WilliamBerryiii@users.noreply.github.com>
1 parent fdf1bcf commit b273a4b

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

scripts/lib/Modules/CIHelpers.psm1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,29 @@ function Publish-CIArtifact {
550550
}
551551
}
552552

553+
function Get-StandardTimestamp {
554+
<#
555+
.SYNOPSIS
556+
Returns the current UTC time as an ISO 8601 string.
557+
558+
.DESCRIPTION
559+
Returns the current UTC time formatted with the round-trip specifier ("o"),
560+
producing a string such as "2025-01-15T18:30:00.0000000Z". Use this
561+
function wherever a timestamp is needed to ensure consistent, timezone-
562+
unambiguous log output across all scripts.
563+
564+
.OUTPUTS
565+
System.String - UTC timestamp in ISO 8601 round-trip format ending in Z.
566+
#>
567+
[CmdletBinding()]
568+
[OutputType([string])]
569+
param()
570+
571+
return (Get-Date).ToUniversalTime().ToString('o')
572+
}
573+
553574
Export-ModuleMember -Function @(
575+
'Get-StandardTimestamp',
554576
'ConvertTo-GitHubActionsEscaped',
555577
'ConvertTo-AzureDevOpsEscaped',
556578
'Get-CIPlatform',

scripts/tests/lib/CIHelpers.Tests.ps1

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,33 @@ BeforeAll {
1515
Import-Module $mockPath -Force
1616
}
1717

18+
Describe 'Get-StandardTimestamp' -Tag 'Unit' {
19+
It 'Returns a string' {
20+
Get-StandardTimestamp | Should -BeOfType [string]
21+
}
22+
23+
It 'Returns a non-empty value' {
24+
Get-StandardTimestamp | Should -Not -BeNullOrEmpty
25+
}
26+
27+
It 'Matches ISO 8601 UTC format ending in Z' {
28+
Get-StandardTimestamp | Should -Match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z$'
29+
}
30+
31+
It 'Returns monotonically increasing timestamps on consecutive calls' {
32+
$earlier = [datetime]::new(2025, 1, 15, 18, 30, 0, [System.DateTimeKind]::Utc)
33+
$later = $earlier.AddSeconds(1)
34+
35+
Mock Get-Date { $earlier } -ModuleName CIHelpers
36+
$first = [datetime]::Parse((Get-StandardTimestamp))
37+
38+
Mock Get-Date { $later } -ModuleName CIHelpers
39+
$second = [datetime]::Parse((Get-StandardTimestamp))
40+
41+
$second | Should -BeGreaterThan $first
42+
}
43+
}
44+
1845
Describe 'Get-CIPlatform' -Tag 'Unit' {
1946
BeforeAll {
2047
Save-CIEnvironment

0 commit comments

Comments
 (0)