Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
* A failed object deployment now stops `Publish-AdfV2FromJson` whatever `$ErrorActionPreference` is, instead of being skipped and the object marked as deployed #295
* Starting and stopping triggers now catches Az errors whatever `$ErrorActionPreference` is, so retries and warnings work; a failed start is a warning and the deployment carries on #508
* `Export-AdfToArmTemplate` calls `npm.cmd` on Windows (avoids npm.ps1 failing on Windows PowerShell 5.1) and stops when an npm command fails #462

## [1.19.0] - 2026-10-16
### Added
Expand Down
21 changes: 21 additions & 0 deletions private/Invoke-AdfNpm.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function Get-AdfNpmCommand {
# On Windows, 'npm' resolves to npm.ps1, which fails on Windows PowerShell 5.1 in some npm versions
# ($MyInvocation.Statement under strict mode) #462. npm.cmd does the same without PowerShell.
if ($env:OS -eq 'Windows_NT') { 'npm.cmd' } else { 'npm' }
}

function Invoke-AdfNpm {
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[String[]] $Arguments
)

$npm = Get-AdfNpmCommand
Write-Verbose "$npm $($Arguments -join ' ')"
& $npm @Arguments
if ($global:LASTEXITCODE -ne 0) {
throw "Command 'npm $($Arguments -join ' ')' failed with exit code $($global:LASTEXITCODE)."
}
}
7 changes: 3 additions & 4 deletions public/Export-AdfToArmTemplate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,18 @@ function Export-AdfToArmTemplate {

# Validate and export ARM Template using @microsoft/azure-data-factory-utilities module
Write-Host "=== Check NPM Version..."
npm version
Invoke-AdfNpm -Arguments 'version'
Write-Host "=== Check finished."

Write-Host "=== Installing NPM azure-data-factory-utilities..."
npm i @microsoft/azure-data-factory-utilities
Invoke-AdfNpm -Arguments 'i', '@microsoft/azure-data-factory-utilities'
Write-Host "=== Installation finished."

$AdfName = Split-Path -Path $RootFolder -Leaf
$adfAzurePath = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.DataFactory/factories/$AdfName"

Write-Host "=== Validating & exporting ARM Template..."
Write-Verbose "npm run build export $RootFolder $adfAzurePath ""$OutputFolder"""
npm run build export $RootFolder $adfAzurePath "$OutputFolder"
Invoke-AdfNpm -Arguments 'run', 'build', 'export', $RootFolder, $adfAzurePath, $OutputFolder
Write-Host "=== Export finished."

}
94 changes: 94 additions & 0 deletions test/Export-AdfToArmTemplate-Npm.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
BeforeDiscovery {
$ModuleRootPath = $PSScriptRoot | Split-Path -Parent
$moduleManifestName = 'azure.datafactory.tools.psd1'
$moduleManifestPath = Join-Path -Path $ModuleRootPath -ChildPath $moduleManifestName

Import-Module -Name $moduleManifestPath -Force -Verbose:$false
}

InModuleScope azure.datafactory.tools {

# Issue #462: on Windows, 'npm' runs npm.ps1, which fails on Windows PowerShell 5.1
Describe 'Get-AdfNpmCommand' -Tag 'Unit' {

BeforeAll {
$script:origOS = $env:OS
}

AfterEach {
$env:OS = $script:origOS
}

It 'Should return npm.cmd on Windows' {
$env:OS = 'Windows_NT'
Get-AdfNpmCommand | Should -Be 'npm.cmd'
}

It 'Should return npm on other systems' {
$env:OS = $null
Get-AdfNpmCommand | Should -Be 'npm'
}
}

Describe 'Invoke-AdfNpm' -Tag 'Unit' {

BeforeAll {
function Invoke-FakeNpm { $global:LASTEXITCODE = $script:fakeExitCode; $script:fakeArgs = $args }
}

BeforeEach {
$ErrorActionPreference = 'Continue'
$script:fakeExitCode = 0
$script:fakeArgs = $null
Mock Get-AdfNpmCommand { 'Invoke-FakeNpm' }
}

AfterEach {
$global:LASTEXITCODE = 0
}

It 'Should pass the arguments to npm' {
Invoke-AdfNpm -Arguments 'i', '@microsoft/azure-data-factory-utilities'
$script:fakeArgs | Should -Be @('i', '@microsoft/azure-data-factory-utilities')
}

It 'Should throw when npm fails' {
$script:fakeExitCode = 1
{ Invoke-AdfNpm -Arguments 'i', 'pkg' } | Should -Throw "*'npm i pkg' failed with exit code 1*"
}
}

Describe 'Export-AdfToArmTemplate calls npm' -Tag 'Unit' {

BeforeAll {
$script:origLocation = Get-Location
}

BeforeEach {
$ErrorActionPreference = 'Continue'
$script:RootFolder = Join-Path $TestDrive 'adf1'
New-Item -Path $script:RootFolder -ItemType Directory -Force | Out-Null
Mock Invoke-AdfNpm { }
}

AfterEach {
Set-Location $script:origLocation
}

It 'Should check the version, install the utilities and export' {
Export-AdfToArmTemplate -RootFolder $script:RootFolder -SubscriptionId 'sub1' -ResourceGroup 'rg1' -OutputFolder 'out'
Should -Invoke Invoke-AdfNpm -Times 3 -Exactly
Should -Invoke Invoke-AdfNpm -Times 1 -Exactly -ParameterFilter { ($Arguments -join ' ') -eq 'version' }
Should -Invoke Invoke-AdfNpm -Times 1 -Exactly -ParameterFilter { ($Arguments -join ' ') -eq 'i @microsoft/azure-data-factory-utilities' }
Should -Invoke Invoke-AdfNpm -Times 1 -Exactly -ParameterFilter {
($Arguments -join ' ') -eq "run build export $($script:RootFolder) /subscriptions/sub1/resourceGroups/rg1/providers/Microsoft.DataFactory/factories/adf1 out"
}
}

It 'Should stop when npm install fails' {
Mock Invoke-AdfNpm { throw 'npm failed' } -ParameterFilter { $Arguments[0] -eq 'i' }
{ Export-AdfToArmTemplate -RootFolder $script:RootFolder } | Should -Throw 'npm failed'
Should -Invoke Invoke-AdfNpm -Times 0 -Exactly -ParameterFilter { $Arguments[0] -eq 'run' }
}
}
}
Loading