Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add audit action for task.issue #1033

Merged
merged 9 commits into from Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions node/CHANGELOG.md
Expand Up @@ -2,6 +2,10 @@

## 4.x

### 4.11.0

- Added audit action for task.issue [#1033](https://github.com/microsoft/azure-pipelines-task-lib/pull/1033)

### 4.10.0

- Added `correlation ID` property for logging commands [#1021](https://github.com/microsoft/azure-pipelines-task-lib/pull/1021)
Expand Down
47 changes: 39 additions & 8 deletions node/internal.ts
Expand Up @@ -30,6 +30,11 @@ export enum IssueSource {
TaskInternal = 'TaskInternal'
}

export enum IssueAuditAction {
Unknown = 0,
ShellTasksValidation = 1,
}

//-----------------------------------------------------
// Validation Checks
//-----------------------------------------------------
Expand All @@ -52,11 +57,11 @@ export function _endsWith(str: string, end: string): boolean {
}

export function _truncateBeforeSensitiveKeyword(str: string, sensitiveKeywordsPattern: RegExp): string {
if(!str) {
if (!str) {
return str;
}

const index = str.search(sensitiveKeywordsPattern);
const index = str.search(sensitiveKeywordsPattern);

if (index <= 0) {
return str;
Expand Down Expand Up @@ -250,7 +255,7 @@ export function _loc(key: string, ...param: any[]): string {
* @param name name of the variable to get
* @returns string
*/
export function _getVariable(name: string): string | undefined {
export function _getVariable(name: string): string | undefined {
let varval: string | undefined;

// get the metadata
Expand Down Expand Up @@ -305,12 +310,38 @@ export function _command(command: string, properties: any, message: string) {
_writeLine(taskCmd.toString());
}

export function _warning(message: string, source: IssueSource = IssueSource.TaskInternal): void {
_command('task.issue', { 'type': 'warning', 'source': source, 'correlationId': _commandCorrelationId }, message);
export function _warning(
message: string,
source: IssueSource = IssueSource.TaskInternal,
auditAction?: IssueAuditAction
): void {
_command(
'task.issue',
{
'type': 'warning',
'source': source,
'correlationId': _commandCorrelationId,
'auditAction': auditAction
},
message
);
}

export function _error(message: string, source: IssueSource = IssueSource.TaskInternal): void {
_command('task.issue', { 'type': 'error', 'source': source, 'correlationId': _commandCorrelationId }, message);
export function _error(
message: string,
source: IssueSource = IssueSource.TaskInternal,
auditAction?: IssueAuditAction
): void {
_command(
'task.issue',
{
'type': 'error',
'source': source,
'correlationId': _commandCorrelationId,
'auditAction': auditAction
},
message
);
}

export function _debug(message: string): void {
Expand Down Expand Up @@ -801,7 +832,7 @@ export function _loadData(): void {
* @param path a path to a file.
* @returns true if path starts with double backslash, otherwise returns false.
*/
export function _isUncPath(path: string) {
export function _isUncPath(path: string) {
return /^\\\\[^\\]/.test(path);
}

Expand Down
2 changes: 1 addition & 1 deletion node/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 75 additions & 2 deletions node/test/taskissuecommandtests.ts
Expand Up @@ -4,7 +4,7 @@
import assert = require('assert');
import * as testutil from './testutil';
import * as tl from '../_build/task';
import { IssueSource, _loadData } from '../_build/internal';
import { IssueAuditAction, IssueSource, _loadData } from '../_build/internal';


describe('Task Issue command test without correlation ID', function () {
Expand Down Expand Up @@ -177,4 +177,77 @@ describe('Task Issue command test with correlation ID', function () {

done();
})
});
});

describe('Task Issue command, audit action tests', function () {
before(function (done) {
try {
testutil.initialize();
} catch (err) {
assert.fail('Failed to load task lib: ' + err.message);
}

done();
});

after(function (done) {
done();
});

it('Audit action is present in issue', function (done) {
this.timeout(1000);

const stdStream = testutil.createStringStream();
tl.setStdStream(stdStream);

const expected = testutil.buildOutput(
['##vso[task.issue type=error;auditAction=1;]Test error',
'##vso[task.issue type=warning;auditAction=1;]Test warning']);

tl.error("Test error", null, IssueAuditAction.ShellTasksValidation);
tl.warning("Test warning", null, IssueAuditAction.ShellTasksValidation);

const output = stdStream.getContents();

assert.strictEqual(output, expected);
done();
})

it('Audit action not present if unspecified', function (done) {
this.timeout(1000);

const stdStream = testutil.createStringStream();
tl.setStdStream(stdStream);

const expected = testutil.buildOutput(
['##vso[task.issue type=error;]Test error',
'##vso[task.issue type=warning;]Test warning']);

tl.error("Test error", null);
tl.warning("Test warning", null);

const output = stdStream.getContents();

assert.strictEqual(output, expected);
done();
})

it('Audit action is present when value is not from enum', function (done) {
this.timeout(1000);

const stdStream = testutil.createStringStream();
tl.setStdStream(stdStream);

const expected = testutil.buildOutput(
['##vso[task.issue type=error;auditAction=123;]Test error',
'##vso[task.issue type=warning;auditAction=321;]Test warning']);

tl.error("Test error", null, 123 as IssueAuditAction);
tl.warning("Test warning", null, 321 as IssueAuditAction);

const output = stdStream.getContents();

assert.strictEqual(output, expected);
done();
})
});
4 changes: 4 additions & 0 deletions powershell/Docs/ReleaseNotes.md
@@ -1,5 +1,9 @@
# Release Notes

## 0.21.0

- Added audit action for task.issue [#1033](https://github.com/microsoft/azure-pipelines-task-lib/pull/1033)

## 0.17.0

* Added `Invoke-VstsProcess` cmdlet (<https://github.com/microsoft/azure-pipelines-task-lib/pull/978>)
Expand Down
@@ -0,0 +1,23 @@
[CmdletBinding()]
param()

# Arrange.
. $PSScriptRoot\..\lib\Initialize-Test.ps1
Invoke-VstsTaskScript -ScriptBlock {
$vstsModule = Get-Module -Name VstsTaskSdk

# 1
$actual = & $vstsModule Write-TaskError -Message "test error" -AsOutput
$expected = "##vso[task.logissue type=error;source=TaskInternal]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "No audit action in issue if not specified."

# 2
$actual = & $vstsModule Write-TaskWarning -Message "test warning" -AuditAction '1' -AsOutput
$expected = "##vso[task.logissue type=warning;source=TaskInternal;auditAction=1]test warning"
Assert-TaskIssueMessagesAreEqual $expected $actual "String audit action."

#3
$actual = & $vstsModule Write-TaskError -Message "test error" -AuditAction 1 -AsOutput
$expected = "##vso[task.logissue type=error;source=TaskInternal;auditAction=1]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "Int audit action."
}
Expand Up @@ -8,21 +8,21 @@ Invoke-VstsTaskScript -ScriptBlock {

# 1
$actual = & $vstsModule Write-TaskError -Message "test error" -AsOutput
$expected = "##vso[task.logissue source=TaskInternal;type=error]test error"
$expected = "##vso[task.logissue type=error;source=TaskInternal]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "The default 'TastInternal' source was added for errors."

# 2
$actual = & $vstsModule Write-TaskWarning -Message "test warning" -AsOutput
$expected = "##vso[task.logissue source=TaskInternal;type=warning]test warning"
$expected = "##vso[task.logissue type=warning;source=TaskInternal]test warning"
Assert-TaskIssueMessagesAreEqual $expected $actual "The default 'TastInternal' source was added for warnings."

#3
$actual = & $vstsModule Write-TaskError -Message "test error" -IssueSource $IssueSources.CustomerScript -AsOutput
$expected = "##vso[task.logissue source=CustomerScript;type=error]test error"
$expected = "##vso[task.logissue type=error;source=CustomerScript]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "Adds the specified issue source for errors."

#4
$actual = & $vstsModule Write-TaskWarning -Message "test warning" -IssueSource $IssueSources.CustomerScript -AsOutput
$expected = "##vso[task.logissue source=CustomerScript;type=warning]test warning"
$expected = "##vso[task.logissue type=warning;source=CustomerScript]test warning"
Assert-TaskIssueMessagesAreEqual $expected $actual "Adds the specified issue source for warnings."
}
Expand Up @@ -17,21 +17,21 @@ Invoke-VstsTaskScript -ScriptBlock {

# 3
$actual = & $vstsModule Write-TaskError -Message "test error" -AsOutput
$expected = "##vso[task.logissue correlationId=test_id123;source=TaskInternal;type=error]test error"
$expected = "##vso[task.logissue type=error;source=TaskInternal;correlationId=test_id123]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "The default 'TastInternal' source and the correlation ID were added for errors."

# 4
$actual = & $vstsModule Write-TaskWarning -Message "test warning" -AsOutput
$expected = "##vso[task.logissue correlationId=test_id123;source=TaskInternal;type=warning]test warning"
$expected = "##vso[task.logissue type=warning;source=TaskInternal;correlationId=test_id123]test warning"
Assert-TaskIssueMessagesAreEqual $expected $actual "The default 'TastInternal' source and the correlation ID were added for warnings."

# 5
$actual = & $vstsModule Write-TaskError -Message "test error" -IssueSource $IssueSources.CustomerScript -AsOutput
$expected = "##vso[task.logissue correlationId=test_id123;source=CustomerScript;type=error]test error"
$expected = "##vso[task.logissue type=error;source=CustomerScript;correlationId=test_id123]test error"
Assert-TaskIssueMessagesAreEqual $expected $actual "Adds the specified issue source and the correlation ID for errors."

# 6
$actual = & $vstsModule Write-TaskWarning -Message "test warning" -IssueSource $IssueSources.CustomerScript -AsOutput
$expected = "##vso[task.logissue correlationId=test_id123;source=CustomerScript;type=warning]test warning"
$expected = "##vso[task.logissue type=warning;source=CustomerScript;correlationId=test_id123]test warning"
Assert-TaskIssueMessagesAreEqual $expected $actual "Adds the specified issue source and the correlation ID for warnings."
}
Expand Up @@ -22,6 +22,7 @@ function Assert-TaskIssueMessagesAreEqual {
[CmdletBinding()]
param([string]$Expected, [string]$Actual, [string]$Message)

Write-Verbose "Asserting Task issue messages are equal. Expected: '$Expected' ; Actual: '$Actual'."
if ($Expected -ne $Actual) {
throw ("Assert are equal failed. Expected: '$Expected' ; Actual: '$Actual'. $Message".Trim())
}
Expand Down
36 changes: 22 additions & 14 deletions powershell/VstsTaskSdk/LoggingCommandFunctions.ps1
Expand Up @@ -298,7 +298,9 @@ function Write-TaskError {
[string]$LineNumber,
[string]$ColumnNumber,
[switch]$AsOutput,
[string]$IssueSource)
[string]$IssueSource,
[string]$AuditAction
)

Write-LogIssue -Type error @PSBoundParameters
}
Expand Down Expand Up @@ -335,7 +337,9 @@ function Write-TaskWarning {
[string]$LineNumber,
[string]$ColumnNumber,
[switch]$AsOutput,
[string]$IssueSource)
[string]$IssueSource,
[string]$AuditAction
)

Write-LogIssue -Type warning @PSBoundParameters
}
Expand Down Expand Up @@ -517,7 +521,7 @@ function Format-LoggingCommand {
[Parameter(Mandatory = $true)]
[string]$Event,
[string]$Data,
[hashtable]$Properties)
[System.Collections.IDictionary]$Properties)

# Append the preamble.
[System.Text.StringBuilder]$sb = New-Object -TypeName System.Text.StringBuilder
Expand Down Expand Up @@ -560,17 +564,21 @@ function Write-LogIssue {
[switch]$AsOutput,
[AllowNull()]
[ValidateSet('CustomerScript', 'TaskInternal')]
[string]$IssueSource = $IssueSources.TaskInternal)

$command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties @{
'type' = $Type
'code' = $ErrCode
'sourcepath' = $SourcePath
'linenumber' = $LineNumber
'columnnumber' = $ColumnNumber
'source' = $IssueSource
'correlationId' = $commandCorrelationId
}
[string]$IssueSource = $IssueSources.TaskInternal,
[string]$AuditAction
)

$properties = [ordered]@{
'type' = $Type
'code' = $ErrCode
'sourcepath' = $SourcePath
'linenumber' = $LineNumber
'columnnumber' = $ColumnNumber
'source' = $IssueSource
'correlationId' = $commandCorrelationId
'auditAction' = $AuditAction
}
$command = Format-LoggingCommand -Area 'task' -Event 'logissue' -Data $Message -Properties $properties
if ($AsOutput) {
return $command
}
Expand Down
6 changes: 6 additions & 0 deletions powershell/VstsTaskSdk/VstsTaskSdk.psm1
Expand Up @@ -95,8 +95,14 @@ Export-ModuleMember -Function @(
'Get-ClientCertificate'
)

$IssueAuditActions = @{
Unknown = '0'
ShellTasksValidation = '1'
}

Export-ModuleMember -Variable @(
'IssueSources'
$IssueAuditActions
)

# Override Out-Default globally.
Expand Down
2 changes: 1 addition & 1 deletion powershell/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion powershell/package.json
@@ -1,5 +1,5 @@
{
"version": "0.20.1",
"version": "0.21.0",
"private": true,
"scripts": {
"build": "node make.js build",
Expand Down