Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
58e68d9
This yml should only starts when file changes on `private` or `public…
NowinskiK May 27, 2026
5f1f07f
Fixed #480 (preview)
NowinskiK May 27, 2026
4f6d8a7
Initial fix #472
NowinskiK May 27, 2026
7393958
All in one CI/CD
NowinskiK Jun 9, 2026
16f2fd7
Login to run correct tests
NowinskiK Jun 10, 2026
bcbdc34
deploy preview module version only from `develop` branch
NowinskiK Jun 10, 2026
c4bc7b7
Refactor Get-AdfObjectsFromServiceRestAPI to handle pagination and im…
NowinskiK Jun 30, 2026
3e6cf73
Add tests for handling non-terminating errors in Get-AdfFromService
NowinskiK Jun 30, 2026
ba7dd15
changelog update - 1.17.0
NowinskiK Jun 30, 2026
516ae68
Fixed simple error in unit test
NowinskiK Jun 30, 2026
cd2bd4e
Fix unit test issue c.d.
NowinskiK Jun 30, 2026
917160c
Merge pull request #489 from Azure-Player/issue-480
NowinskiK Jun 30, 2026
51605b9
Merge branch 'develop' into issue-472
NowinskiK Jun 30, 2026
ea3b24d
Merge pull request #490 from Azure-Player/issue-472
NowinskiK Jun 30, 2026
1f66fe1
Merge branch 'develop' into issue-492
NowinskiK Jun 30, 2026
26f2659
ver.1.17.0
NowinskiK Jun 30, 2026
4aa4afc
Merge pull request #494 from Azure-Player/issue-492
NowinskiK Jun 30, 2026
bca0ad1
Added unit test for #475
NowinskiK Jul 1, 2026
4a43a49
ci-cd is active
NowinskiK Jul 1, 2026
8a7a465
Merge pull request #495 from Azure-Player/issue-475
NowinskiK Jul 1, 2026
66182d3
Bump module version to 1.17.1 and update changelog for timezone handl…
NowinskiK Jul 1, 2026
f5477a0
Update documentation: IgnoreLackOfReferencedObject option #198
NowinskiK Jul 1, 2026
bc4eebe
Merge pull request #496 from Azure-Player/issue-402-timezone
NowinskiK Jul 1, 2026
fd78700
DryRun shows deployment plan in terraform-like format
NowinskiK Jul 1, 2026
7906ec4
Documentation about DryRun/Plan feature to preview deployment changes…
NowinskiK Jul 1, 2026
26edcf1
Bump module version to 1.18.0 and update changelog for new DryRun/Pla…
NowinskiK Jul 1, 2026
7b5ed81
Refactor Get-DryRunPlan to use List<T> for collection management
NowinskiK Jul 6, 2026
c2829e2
Merge pull request #497 from Azure-Player/issue-360-dryrun
NowinskiK Jul 7, 2026
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
72 changes: 72 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: CI/CD

on:
push:
branches: [ develop ]
paths:
- 'private/**'
- 'public/**'
- 'test/**'
pull_request:
branches: [ develop ]
paths:
- 'private/**'
- 'public/**'
- 'test/**'
workflow_dispatch:

permissions:
contents: read
checks: write # required by dorny/test-reporter

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
name: Run Unit Tests
runs-on: windows-latest

steps:
- uses: actions/checkout@v4

- name: Login via Az module
uses: azure/login@v3
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true

- name: Run Unit Tests
uses: azure/powershell@v3
with:
inlineScript: |
test/!RunAllTests.ps1 -folder '${{ github.workspace }}/' -TestFilenameFilter "*" -InstallModules:$false -ResultOutputFormat "JUnitXml"
azPSVersion: "latest"

- name: Publish Test Results
uses: dorny/test-reporter@v3
if: ${{ !cancelled() }}
with:
name: Pester Tests
path: '**/TEST-*.xml'
reporter: java-junit
collapsed: 'auto'

publish:
name: Publish to PS Gallery
runs-on: windows-latest
needs: test
if: ${{ github.event_name != 'pull_request' && (github.ref_name == 'master' || github.ref_name == 'develop') }}

steps:
- uses: actions/checkout@v4

- name: Publish module to PowerShell Gallery
shell: pwsh
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY_API_KEY }}
run: |
$isPreview = '${{ github.ref_name }}' -ne 'master'
Write-Host "Branch: ${{ github.ref_name }} | Preview: $isPreview"
./tools/Publish-ToGallery.ps1 -IsPreview:$isPreview -NuGetApiKey $env:PSGALLERY_API_KEY
16 changes: 12 additions & 4 deletions .github/workflows/develop-ci.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
name: CI

on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
# push:
# branches: [ develop ]
# paths:
# - 'private/**'
# - 'public/**'
# - 'test/**'
# pull_request:
# branches: [ develop ]
# paths:
# - 'private/**'
# - 'public/**'
# - 'test/**'
workflow_dispatch:

permissions:
Expand Down
50 changes: 47 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ The main advantage of the module is the ability to publish all the Azure Data Fa
- [Stage value as full path to CSV config file](#stage-value-as-full-path-to-csv-config-file)
- [JSON format of Config file](#json-format-of-config-file)
- [Step: Deployment Plan](#step-deployment-plan)
- [Step: Stoping triggers](#step-stoping-triggers)
- [DryRun / Plan output and CI usage](#dryrun--plan-output-and-ci-usage)
- [Step: Stopping triggers](#step-stopping-triggers)
- [Step: Deployment of ADF objects](#step-deployment-of-adf-objects)
- [Step: Save deployment state](#step-save-deployment-state)
- [Step: Deleting objects not in source](#step-deleting-objects-not-in-source)
Expand Down Expand Up @@ -185,6 +186,7 @@ Publish-AdfV2FromJson
[-Option] <AdfPublishOption>
[-Method] <String>
[-DryRun] <Switch>
[-Plan] <Switch>
```

Assuming your ADF is named ```SQLPlayerDemo``` and the code is located in ```c:\GitHub\AdfName\```, replace the values for *SubscriptionName*, *ResourceGroupName*, *DataFactoryName* and run the following command using PowerShell CLI:
Expand Down Expand Up @@ -221,6 +223,7 @@ $opt = New-AdfPublishOption
* [Boolean] **DeployGlobalParams** - indicates whether deploy Global Parameters of ADF. Nothing happens when parameters are not defined. (default: *true*)
* [Boolean] **FailsWhenConfigItemNotFound** - indicates whether configuration items not found fails the script. (default: *true*)
* [Boolean] **FailsWhenPathNotFound** - indicates whether missing paths fails the script. (default: *true*)
* [Boolean] **IgnoreLackOfReferencedObject** - indicates whether missing referenced objects should only raise warnings. (default: *false*)
* [Boolean] **DoNotStopStartExcludedTriggers** - specifies whether excluded triggers will be stopped before deployment (default: *false*)
* [Boolean] **DoNotDeleteExcludedObjects** - specifies whether excluded objects can be removed. Applies when `DeleteNotInSource` is set to *True* only. (default: *true*)
* [Boolean] **IncrementalDeployment** - specifies whether Incremental Deployment mode is enabled (default: *false*)
Expand Down Expand Up @@ -265,7 +268,11 @@ $opt.FailsWhenConfigItemNotFound = $false
$opt = New-AdfPublishOption
$opt.FailsWhenPathNotFound = $false

# Example 7: Exclude Infrastructure-type of objects from deployment
# Example 7: Ignore missing referenced objects (will just write warning to standard output instead)
$opt = New-AdfPublishOption
$opt.IgnoreLackOfReferencedObject = $true

# Example 8: Exclude Infrastructure-type of objects from deployment
$opt = New-AdfPublishOption
$opt.CreateNewInstance = $false
$opt.Excludes.Add("integrationruntime.*", "")
Expand Down Expand Up @@ -617,8 +624,45 @@ If you prefer using JSON rather than CSV for setting up configuration - JSON fil
This step identifies objects to be deployed using `Includes` and `Excludes` list provided in *Publish Options*.
Afterwards, if `IncrementalDeployment = true`, it excludes objects by comparing hashes from **Deployment State** to hashed of awaiting objects.

### DryRun / Plan output and CI usage

Use `-DryRun` or `-Plan` to preview intended changes without deploying. The process prints a terraform-like summary:

```text
Terraform-like plan (DryRun):
Plan: 0 to add, 1 to change, 1 to destroy.

~ Update
~ pipeline.PL_ExecSparkJob

- Delete
- pipeline.PL_Obsolete

= Unchanged / skipped
= dataset.DS_Json
```

The returned object contains a `DryRunPlan` property, so CI can enforce policy checks before deployment:

```powershell
$result = Publish-AdfV2FromJson `
-RootFolder $RootFolder `
-ResourceGroupName $ResourceGroupName `
-DataFactoryName $DataFactoryName `
-Location $Location `
-Option $opt `
-Plan

if ($result.DryRunPlan.Delete.Count -gt 0) {
Write-Error "Plan contains destroy actions. Review required before deployment."
exit 1
}

Write-Host "Plan accepted. Add=$($result.DryRunPlan.Create.Count); Change=$($result.DryRunPlan.Update.Count); Destroy=$($result.DryRunPlan.Delete.Count)"
```


## Step: Stoping triggers
## Step: Stopping triggers

💬 In log you'll see line: `STEP: Stopping triggers...`

Expand Down
2 changes: 1 addition & 1 deletion azure.datafactory.tools.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'azure.datafactory.tools.psm1'

# Version number of this module.
ModuleVersion = '1.16.0'
ModuleVersion = '1.18.0'

# Supported PSEditions
# CompatiblePSEditions = @()
Expand Down
13 changes: 11 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,19 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [1.16.0] - 2026-06-06
## [1.18.0] - 2026-07-01
### Added
* `Publish-AdfV2FromJson` now supports terraform-like planning via `-DryRun`/`-Plan`, including structured `DryRunPlan` output (Create/Update/Delete/Unchanged) #360

## [1.17.1] - 2026-07-01
### Fixed
* Further fixes of `DeleteNotInSource` with deserialization issue #480
* `Publish-AdfV2FromJson` no longer silently continues after errors: config path errors (ADFT0010) and deployment failures (e.g. Azure Policy blocks) now propagate as terminating errors to the caller #472
* Scheduled trigger recurrence times now preserve explicit timezone offsets during config-driven updates, preventing shifted deployment times #402

## [1.16.0] - 2026-06-06
### Fixed
* `DeleteNotInSource` no longer fails with "Unable to deserialize the response" when ADF contains object types unsupported by the installed Az.DataFactory module version - REST API fallback added to `Get-AdfFromService` #480 #473
* Fixed ClientAssertionCredential authentication failure for federated identity (OIDC) credentials by removing redundant `Get-AzAccessToken` calls in `Get-AzDFV2Credential` and `Remove-AdfObjectRestAPI` #492

## [1.15.0] - 2026-05-26
Expand All @@ -16,7 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
* Starting blob event trigger fails with 'Resource cannot be updated during provisioning' - now waits for provisioning to complete before retrying #484, #474, #463
* Fixed REST API calls failing with 401 Unauthorized due to Az.Accounts 5.x returning SecureString from Get-AzAccessToken
* Fixed DryRun not loading deployment state from storage for hash comparison #476
* Fixed DryRun not loading deployment state from storage for hash comparison #475
* README.md updated and new Structured Documentation created

## [1.14.0] - 2025-10-24
Expand Down
4 changes: 3 additions & 1 deletion docs/ADVANCED/CMDLET_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ Publish-AdfV2FromJson `
[-Stage <String>] `
[-Option <AdfPublishOption>] `
[-Method <String>] `
[-DryRun]
[-DryRun] `
[-Plan]
```

**Parameters:**
Expand All @@ -33,6 +34,7 @@ Publish-AdfV2FromJson `
| Option | AdfPublishOption | No | Publish options object (filtering, triggers, etc.) |
| Method | String | No | Publishing method: 'AzDataFactory' or 'AzResource' (default) |
| DryRun | Switch | No | Validate without deploying |
| Plan | Switch | No | Alias behavior of DryRun with terraform-like naming |

**Returns:** AdfPublishOption (deployment result)

Expand Down
5 changes: 4 additions & 1 deletion docs/GUIDE/PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ Publish-AdfV2FromJson `
[-Stage] <String> `
[-Option] <AdfPublishOption> `
[-Method] <String> `
[-DryRun]
[-DryRun] `
[-Plan]
```

`-Plan` is an alias behavior of `-DryRun` and prints a terraform-like plan without deploying.

### Complete Example

```powershell
Expand Down
17 changes: 15 additions & 2 deletions docs/GUIDE/PUBLISH_OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ $opt = New-AdfPublishOption
- **Default:** true
- **Purpose:** Fail deployment if config path doesn't exist (vs. warning only)

#### IgnoreLackOfReferencedObject
- **Type:** Boolean
- **Default:** false
- **Purpose:** Continue deployment when a referenced object is missing and emit a warning instead of failing

### Trigger Control Options

#### StopStartTriggers (see also: TriggerStopMethod, TriggerStartMethod)
Expand Down Expand Up @@ -155,15 +160,23 @@ $opt.FailsWhenConfigItemNotFound = $false
# Warnings will be printed instead of failing
```

### Example 6: Incremental Deployment
### Example 6: Ignore Missing Referenced Objects

```powershell
$opt = New-AdfPublishOption
$opt.IgnoreLackOfReferencedObject = $true
# Referenced objects that are not present will warn instead of failing
```

### Example 7: Incremental Deployment

```powershell
$opt = New-AdfPublishOption
$opt.IncrementalDeployment = $true
$opt.IncrementalDeploymentStorageUri = 'https://storageaccount.file.core.windows.net/adftools'
```

### Example 7: Selective Deployment with Smart Triggers
### Example 8: Selective Deployment with Smart Triggers

```powershell
$opt = New-AdfPublishOption
Expand Down
40 changes: 40 additions & 0 deletions private/AdfPSObjects.class.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

# Lightweight wrapper classes for ADF objects retrieved via REST API.
# Class names follow the AdfPS<SimplifiedType> pattern so that Get-SimplifiedType
# strips the "AdfPS" prefix and returns the correct simplified type (e.g. "Dataset").
# These are used as a fallback when Get-AzDataFactoryV2* cmdlets fail to deserialize
# objects whose types are not yet known to the installed Az.DataFactory module version.

class AdfPSDataset {
[String] $Name
AdfPSDataset([String] $name) { $this.Name = $name }
}

class AdfPSDataFlow {
[String] $Name
AdfPSDataFlow([String] $name) { $this.Name = $name }
}

class AdfPSPipeline {
[String] $Name
AdfPSPipeline([String] $name) { $this.Name = $name }
}

class AdfPSLinkedService {
[String] $Name
AdfPSLinkedService([String] $name) { $this.Name = $name }
}

class AdfPSIntegrationRuntime {
[String] $Name
AdfPSIntegrationRuntime([String] $name) { $this.Name = $name }
}

class AdfPSTrigger {
[String] $Name
[String] $RuntimeState
AdfPSTrigger([String] $name, [String] $runtimeState) {
$this.Name = $name
$this.RuntimeState = $runtimeState
}
}
Loading
Loading