Showing preview only (1,800K chars total). Download the full file or copy to clipboard to get everything.
Repository: microsoft/fabric-cicd
Branch: main
Commit: baa2832275a5
Files: 321
Total size: 1.7 MB
Directory structure:
gitextract_uhouros3/
├── .changes/
│ ├── header.tpl.md
│ ├── unreleased/
│ │ ├── added-20260420-140247.yaml
│ │ ├── added-20260503-000000.yaml
│ │ ├── fixed-20260424-103120.yaml
│ │ ├── fixed-20260428-121610.yaml
│ │ ├── new-items-20260505-123355.yaml
│ │ └── optimization-20260505-142743.yaml
│ ├── v0.1.0.md
│ ├── v0.1.1.md
│ ├── v0.1.10.md
│ ├── v0.1.11.md
│ ├── v0.1.12.md
│ ├── v0.1.13.md
│ ├── v0.1.14.md
│ ├── v0.1.15.md
│ ├── v0.1.16.md
│ ├── v0.1.17.md
│ ├── v0.1.18.md
│ ├── v0.1.19.md
│ ├── v0.1.2.md
│ ├── v0.1.20.md
│ ├── v0.1.21.md
│ ├── v0.1.22.md
│ ├── v0.1.23.md
│ ├── v0.1.24.md
│ ├── v0.1.25.md
│ ├── v0.1.26.md
│ ├── v0.1.27.md
│ ├── v0.1.28.md
│ ├── v0.1.29.md
│ ├── v0.1.3.md
│ ├── v0.1.30.md
│ ├── v0.1.31.md
│ ├── v0.1.32.md
│ ├── v0.1.33.md
│ ├── v0.1.34.md
│ ├── v0.1.4.md
│ ├── v0.1.5.md
│ ├── v0.1.6.md
│ ├── v0.1.7.md
│ ├── v0.1.8.md
│ ├── v0.1.9.md
│ ├── v0.2.0.md
│ ├── v0.3.0.md
│ ├── v0.3.1.md
│ └── v1.0.0.md
├── .changie.yaml
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── 1-bug.yml
│ │ ├── 2-feature.yml
│ │ ├── 3-documentation.yml
│ │ ├── 4-question.yml
│ │ └── config.yml
│ ├── agents/
│ │ └── new-item-type.agent.md
│ ├── copilot-instructions.md
│ ├── policies/
│ │ ├── resourceManagement.yml
│ │ └── sdl.yml
│ ├── prompts/
│ │ ├── bug-triage.prompt.yml
│ │ ├── feature-triage.prompt.yml
│ │ └── question-triage.prompt.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── ai-issue-triage.yml
│ ├── bump.yml
│ ├── changelog.yml
│ ├── publish_docs.yml
│ ├── test.yml
│ └── validate.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .python-version
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ └── settings.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CodeQL.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── activate.ps1
├── activate.sh
├── devtools/
│ ├── debug_api.py
│ ├── debug_local config.py
│ ├── debug_local.py
│ ├── debug_parameterization.py
│ ├── debug_trace_deployment.py
│ └── pypi_build_release_dev.ps1
├── docs/
│ ├── about.md
│ ├── changelog.md
│ ├── code_reference.md
│ ├── config/
│ │ ├── overrides/
│ │ │ └── main.html
│ │ ├── pre-build/
│ │ │ ├── section_toc.py
│ │ │ ├── update_item_types.py
│ │ │ └── update_python_version.py
│ │ └── stylesheets/
│ │ └── extra.css
│ ├── example/
│ │ ├── authentication.md
│ │ ├── deployment_variable.md
│ │ ├── index.md
│ │ └── release_pipeline.md
│ ├── how_to/
│ │ ├── config_deployment.md
│ │ ├── getting_started.md
│ │ ├── index.md
│ │ ├── item_types.md
│ │ ├── optional_feature.md
│ │ ├── parameterization.md
│ │ └── troubleshooting.md
│ └── index.md
├── mkdocs.yml
├── pyproject.toml
├── ruff.toml
├── sample/
│ └── workspace/
│ ├── ABC.Report/
│ │ ├── .platform
│ │ ├── StaticResources/
│ │ │ ├── RegisteredResources/
│ │ │ │ └── test_image25861853181026917.tif
│ │ │ └── SharedResources/
│ │ │ └── BaseThemes/
│ │ │ └── CY24SU10.json
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── ABC.SemanticModel/
│ │ ├── .platform
│ │ ├── definition/
│ │ │ ├── cultures/
│ │ │ │ └── en-US.tmdl
│ │ │ ├── database.tmdl
│ │ │ ├── model.tmdl
│ │ │ ├── relationships.tmdl
│ │ │ └── tables/
│ │ │ ├── Table.tmdl
│ │ │ └── Table_2.tmdl
│ │ ├── definition.pbism
│ │ └── diagramLayout.json
│ ├── ABCD.Report/
│ │ ├── .platform
│ │ ├── StaticResources/
│ │ │ └── SharedResources/
│ │ │ └── BaseThemes/
│ │ │ └── CY24SU10.json
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── ByConnection.Report/
│ │ ├── .platform
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── Default.Warehouse/
│ │ └── .platform
│ ├── DefaultCaseInsensitive.Warehouse/
│ │ └── .platform
│ ├── Example Notebook.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ ├── Hello Copy Job.CopyJob/
│ │ ├── .platform
│ │ └── copyjob-content.json
│ ├── Hello Dataflow.Dataflow/
│ │ ├── .platform
│ │ ├── mashup.pq
│ │ └── queryMetadata.json
│ ├── Hello World.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ ├── Hello db.SQLDatabase/
│ │ ├── .gitignore
│ │ ├── .platform
│ │ └── Hello db.sqlproj
│ ├── HelloEventhouse.Eventhouse/
│ │ ├── .children/
│ │ │ └── HelloEventhouse.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── HelloRealTimeDashboard.KQLDashboard/
│ │ ├── .platform
│ │ └── RealTimeDashboard.json
│ ├── MirroredDatabase_1.MirroredDatabase/
│ │ ├── .platform
│ │ └── mirroring.json
│ ├── OntologyDataLH.Lakehouse/
│ │ ├── .platform
│ │ ├── alm.settings.json
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── RetailSalesOntology.Ontology/
│ │ ├── .platform
│ │ ├── EntityTypes/
│ │ │ ├── 205398164146535/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ └── a790fdb3-e356-4f42-acf4-4420557c0fd7.json
│ │ │ │ └── definition.json
│ │ │ ├── 267812974919544/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ └── 275d574a-4d0d-4935-9cfd-54e59ee36d7f.json
│ │ │ │ └── definition.json
│ │ │ ├── 28747097105824/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ ├── 5f66bbb3-9bb6-415a-9cd9-9d7421d0e553.json
│ │ │ │ │ └── f0767964-7f82-40a1-9ca2-f7e7fe931fcd.json
│ │ │ │ └── definition.json
│ │ │ └── 52068896499199/
│ │ │ ├── DataBindings/
│ │ │ │ └── 3d6fc8a5-b442-46b2-9bee-c22d08038f2e.json
│ │ │ └── definition.json
│ │ ├── RelationshipTypes/
│ │ │ ├── 4160405290834524422/
│ │ │ │ ├── Contextualizations/
│ │ │ │ │ └── 088a81ce-2a4c-4dbc-8887-ab6b831fa047.json
│ │ │ │ └── definition.json
│ │ │ ├── 4194354367812289411/
│ │ │ │ ├── Contextualizations/
│ │ │ │ │ └── 7be8afdf-2557-4950-930e-26c762fcb5a5.json
│ │ │ │ └── definition.json
│ │ │ └── 4244194862547506054/
│ │ │ ├── Contextualizations/
│ │ │ │ └── 7f23e2a5-25f6-4c87-8b9a-43b3b9a142ec.json
│ │ │ └── definition.json
│ │ └── definition.json
│ ├── Run Hello World.DataPipeline/
│ │ ├── .platform
│ │ ├── .schedules
│ │ └── pipeline-content.json
│ ├── Sample.GraphQLApi/
│ │ ├── .platform
│ │ └── graphql-definition.json
│ ├── SampleDataActivator.Reflex/
│ │ ├── .platform
│ │ └── ReflexEntities.json
│ ├── SampleDataBuildToolJob.DataBuildToolJob/
│ │ ├── .platform
│ │ └── dbt-content.json
│ ├── SampleEventhouse.Eventhouse/
│ │ ├── .children/
│ │ │ └── TaxiDB.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── SampleEventstream.Eventstream/
│ │ ├── .platform
│ │ ├── eventstream.json
│ │ └── eventstreamProperties.json
│ ├── SampleKQLQueryset.KQLQueryset/
│ │ ├── .platform
│ │ └── RealTimeQueryset.json
│ ├── SampleSparkJobDefinition.SparkJobDefinition/
│ │ ├── .platform
│ │ ├── Libs/
│ │ │ └── pipeline_config.py
│ │ ├── Main/
│ │ │ └── main.py
│ │ └── SparkJobDefinitionV1.json
│ ├── SampleUserDataFunction.UserDataFunction/
│ │ ├── .platform
│ │ ├── .resources/
│ │ │ └── functions.json
│ │ ├── definition.json
│ │ └── function_app.py
│ ├── SourceForShortcutLH.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── TargetForShortcutLH.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── TelemetryDataEH.Eventhouse/
│ │ ├── .children/
│ │ │ └── TelemetryDataEH.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── Vars.VariableLibrary/
│ │ ├── .platform
│ │ ├── settings.json
│ │ ├── valueSets/
│ │ │ ├── PPE.json
│ │ │ └── PROD.json
│ │ └── variables.json
│ ├── WithSchema.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── WithoutSchema.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── World.Environment/
│ │ ├── .platform
│ │ ├── Libraries/
│ │ │ ├── CustomLibraries/
│ │ │ │ └── fabric_cicd-0.1.1-py3-none-any.whl
│ │ │ └── PublicLibraries/
│ │ │ └── environment.yml
│ │ └── Setting/
│ │ └── Sparkcompute.yml
│ ├── cicd_experiment.MLExperiment/
│ │ ├── .platform
│ │ └── mlexperiment.metadata.json
│ ├── config.yml
│ ├── parameter template.yml
│ ├── parameter.yml
│ ├── sample apache airflow job.ApacheAirflowJob/
│ │ ├── .platform
│ │ ├── apacheairflowjob-content.json
│ │ └── dags/
│ │ └── dag1.py
│ ├── subfolder/
│ │ ├── Hello World Subfolder.Notebook/
│ │ │ ├── .platform
│ │ │ └── notebook-content.py
│ │ └── subfolder/
│ │ └── Hello World SubfolderSubfolder.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ └── templates/
│ ├── nb parameter template 1.yml
│ └── nb parameter template 2.yml
├── src/
│ └── fabric_cicd/
│ ├── __init__.py
│ ├── _common/
│ │ ├── __init__.py
│ │ ├── _check_utils.py
│ │ ├── _color.py
│ │ ├── _config_utils.py
│ │ ├── _config_validator.py
│ │ ├── _deployment_result.py
│ │ ├── _exceptions.py
│ │ ├── _fabric_endpoint.py
│ │ ├── _file.py
│ │ ├── _file_lock.py
│ │ ├── _git_diff_utils.py
│ │ ├── _http_tracer.py
│ │ ├── _item.py
│ │ ├── _logging.py
│ │ ├── _validate_env_vars.py
│ │ └── _validate_input.py
│ ├── _items/
│ │ ├── __init__.py
│ │ ├── _activator.py
│ │ ├── _apacheairflowjob.py
│ │ ├── _base_publisher.py
│ │ ├── _copyjob.py
│ │ ├── _dataagent.py
│ │ ├── _databuildtooljob.py
│ │ ├── _dataflowgen2.py
│ │ ├── _datapipeline.py
│ │ ├── _environment.py
│ │ ├── _eventhouse.py
│ │ ├── _eventstream.py
│ │ ├── _graphqlapi.py
│ │ ├── _kqldashboard.py
│ │ ├── _kqldatabase.py
│ │ ├── _kqlqueryset.py
│ │ ├── _lakehouse.py
│ │ ├── _manage_dependencies.py
│ │ ├── _mirroreddatabase.py
│ │ ├── _mlexperiment.py
│ │ ├── _mounteddatafactory.py
│ │ ├── _notebook.py
│ │ ├── _ontology.py
│ │ ├── _report.py
│ │ ├── _semanticmodel.py
│ │ ├── _sparkjobdefinition.py
│ │ ├── _sqldatabase.py
│ │ ├── _userdatafunction.py
│ │ ├── _variablelibrary.py
│ │ └── _warehouse.py
│ ├── _parameter/
│ │ ├── __init__.py
│ │ ├── _parameter.py
│ │ └── _utils.py
│ ├── constants.py
│ ├── fabric_workspace.py
│ └── publish.py
└── tests/
├── fixtures/
│ ├── .gitignore
│ ├── README.md
│ ├── __init__.py
│ ├── credentials.py
│ └── mock_fabric_server.py
├── test__check_utils.py
├── test__fabric_endpoint.py
├── test__file.py
├── test_config_validator.py
├── test_deploy_with_config.py
├── test_environment_publish.py
├── test_fabric_workspace.py
├── test_fqdn_workspace_id.py
├── test_git_diff_utils.py
├── test_hard_delete.py
├── test_integration_publish.py
├── test_logging.py
├── test_parameter.py
├── test_parameter_utils.py
├── test_publish.py
├── test_response_collection.py
├── test_semantic_model_exclude.py
├── test_shortcut_exclude.py
├── test_subfolders.py
└── test_validate_env_vars.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .changes/header.tpl.md
================================================
# Changelog
================================================
FILE: .changes/unreleased/added-20260420-140247.yaml
================================================
kind: added
body: Add `$workspace.$name` and `$workspace.$name_encoded` dynamic replacement variables for target workspace display name
time: 2026-04-20T14:02:47.0254635+03:00
custom:
Author: shirasassoon
AuthorLink: https://github.com/shirasassoon
Issue: "895"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/895
================================================
FILE: .changes/unreleased/added-20260503-000000.yaml
================================================
kind: added
body: Add `configure_fabric_fqdn` to configure Fabric API URLs for private-link-enabled workspaces using per-workspace FQDN endpoints
time: 2026-05-03T00:00:00.0000000+00:00
custom:
Author: SumeshKashyap
AuthorLink: https://github.com/SumeshKashyap
Issue: "754"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/754
================================================
FILE: .changes/unreleased/fixed-20260424-103120.yaml
================================================
kind: fixed
body: Fix incomplete Sparkcompute settings deployment by using the item definition API instead of the staging/sparkcompute API when deploying Environments
time: 2026-04-24T10:31:20.3568472+02:00
custom:
Author: lassevalentini
AuthorLink: https://github.com/lassevalentini
Issue: "776"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/776
================================================
FILE: .changes/unreleased/fixed-20260428-121610.yaml
================================================
kind: fixed
body: Fix HTTP 400 errors when using ``items_to_include`` with post-publish operations (e.g. Lakehouse shortcut publishing)
time: 2026-04-28T12:16:10.6116726+03:00
custom:
Author: shirasassoon
AuthorLink: https://github.com/shirasassoon
Issue: "948"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/948
================================================
FILE: .changes/unreleased/new-items-20260505-123355.yaml
================================================
kind: new-items
body: Add support for DataBuildToolJob item
time: 2026-05-05T12:33:55.6581835-05:00
custom:
Author: crazy-treyn
AuthorLink: https://github.com/crazy-treyn
Issue: "864"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/864
================================================
FILE: .changes/unreleased/optimization-20260505-142743.yaml
================================================
kind: optimization
body: Remove version check on import to reduce noise and eliminate unnecessary PyPI network call at startup
time: 2026-05-05T14:27:43.6077342+03:00
custom:
Author: shirasassoon
AuthorLink: https://github.com/shirasassoon
Issue: "973"
IssueLink: https://github.com/microsoft/fabric-cicd/issues/973
================================================
FILE: .changes/v0.1.0.md
================================================
## [v0.1.0](https://pypi.org/project/fabric-cicd/0.1.0) - January 23, 2025
### ✨ New Functionality
- Initial public preview release
- Supports Notebook, Pipeline, Semantic Model, Report, and Environment deployments
- Supports User and System Identity authentication
- Released to PyPi
- Onboarded to Github Pages
================================================
FILE: .changes/v0.1.1.md
================================================
## [v0.1.1](https://pypi.org/project/fabric-cicd/0.1.1) - January 23, 2025
### 🔧 Bug Fix
- Fix Environment stuck in publish ([#51](https://github.com/microsoft/fabric-cicd/issues/51))
================================================
FILE: .changes/v0.1.10.md
================================================
## [v0.1.10](https://pypi.org/project/fabric-cicd/0.1.10) - March 19, 2025
### ✨ New Functionality
- DataPipeline SPN Support ([#133](https://github.com/microsoft/fabric-cicd/issues/133))
### 🔧 Bug Fix
- Workspace ID replacement in data pipelines ([#164](https://github.com/microsoft/fabric-cicd/issues/164))
### 📝 Documentation Update
- Sample for passing in arguments from Azure DevOps Pipelines
================================================
FILE: .changes/v0.1.11.md
================================================
## [v0.1.11](https://pypi.org/project/fabric-cicd/0.1.11) - March 25, 2025
### ⚠️ Breaking Change
- Parameterization refactor introducing a new parameter file structure and parameter file validation functionality ([#113](https://github.com/microsoft/fabric-cicd/issues/113))
### ✨ New Functionality
- Support regex for publish exclusion ([#121](https://github.com/microsoft/fabric-cicd/issues/121))
- Override max retries via constants ([#146](https://github.com/microsoft/fabric-cicd/issues/146))
### 📝 Documentation Update
- Update to [parameterization](https://microsoft.github.io/fabric-cicd/latest/how_to/parameterization/) docs
================================================
FILE: .changes/v0.1.12.md
================================================
## [v0.1.12](https://pypi.org/project/fabric-cicd/0.1.12) - March 27, 2025
### 🔧 Bug Fix
- Fix constant overwrite failures ([#190](https://github.com/microsoft/fabric-cicd/issues/190))
- Fix bug where all workspace ids were not being replaced ([#186](https://github.com/microsoft/fabric-cicd/issues/186))
- Fix type hints for older versions of Python ([#156](https://github.com/microsoft/fabric-cicd/issues/156))
- Fix accepted item types constant in pre-build
================================================
FILE: .changes/v0.1.13.md
================================================
## [v0.1.13](https://pypi.org/project/fabric-cicd/0.1.13) - April 07, 2025
### ✨ New Functionality
- Added support for Lakehouse Shortcuts
- New `enable_environment_variable_replacement` feature flag ([#160](https://github.com/microsoft/fabric-cicd/issues/160))
### 🆕 New Items Support
- Onboard Workspace Folders ([#81](https://github.com/microsoft/fabric-cicd/issues/81))
- Onboard Variable Library item type ([#206](https://github.com/microsoft/fabric-cicd/issues/206))
### ⚡ Additional Optimizations
- User-agent now available in API headers ([#207](https://github.com/microsoft/fabric-cicd/issues/207))
- Fixed error log typo in fabric_endpoint
### 🔧 Bug Fix
- Fix break with invalid optional parameters ([#192](https://github.com/microsoft/fabric-cicd/issues/192))
- Fix bug where all workspace ids were not being replaced by parameterization ([#186](https://github.com/microsoft/fabric-cicd/issues/186))
================================================
FILE: .changes/v0.1.14.md
================================================
## [v0.1.14](https://pypi.org/project/fabric-cicd/0.1.14) - April 09, 2025
### ✨ New Functionality
- Optimized & beautified terminal output
- Added changelog to output of old version check
### 🔧 Bug Fix
- Fix workspace folder deployments in root folder ([#221](https://github.com/microsoft/fabric-cicd/issues/221))
- Fix unpublish of workspace folders without publish ([#222](https://github.com/microsoft/fabric-cicd/issues/222))
### ⚡ Additional Optimizations
- Removed Colorama and Colorlog Dependency
================================================
FILE: .changes/v0.1.15.md
================================================
## [v0.1.15](https://pypi.org/project/fabric-cicd/0.1.15) - April 21, 2025
### 🔧 Bug Fix
- Fix folders moving with every publish ([#236](https://github.com/microsoft/fabric-cicd/issues/236))
### ⚡ Additional Optimizations
- Introduce parallel deployments to reduce publish times ([#237](https://github.com/microsoft/fabric-cicd/issues/237))
- Improvements to check version logic
### 📝 Documentation Update
- Updated Examples section in docs
================================================
FILE: .changes/v0.1.16.md
================================================
## [v0.1.16](https://pypi.org/project/fabric-cicd/0.1.16) - April 25, 2025
### 🔧 Bug Fix
- Fix bug with folder deployment to root ([#255](https://github.com/microsoft/fabric-cicd/issues/255))
### ⚡ Additional Optimizations
- Add Workspace Name in FabricWorkspaceObject ([#200](https://github.com/microsoft/fabric-cicd/issues/200))
- New function to check SQL endpoint provision status ([#226](https://github.com/microsoft/fabric-cicd/issues/226))
### 📝 Documentation Update
- Updated Authentication docs + menu sort order
================================================
FILE: .changes/v0.1.17.md
================================================
## [v0.1.17](https://pypi.org/project/fabric-cicd/0.1.17) - May 13, 2025
### ⚠️ Breaking Change
- Deprecate old parameter file structure ([#283](https://github.com/microsoft/fabric-cicd/issues/283))
### 🆕 New Items Support
- Onboard CopyJob item type ([#122](https://github.com/microsoft/fabric-cicd/issues/122))
- Onboard Eventstream item type ([#170](https://github.com/microsoft/fabric-cicd/issues/170))
- Onboard Eventhouse/KQL Database item type ([#169](https://github.com/microsoft/fabric-cicd/issues/169))
- Onboard Data Activator item type ([#291](https://github.com/microsoft/fabric-cicd/issues/291))
- Onboard KQL Queryset item type ([#292](https://github.com/microsoft/fabric-cicd/issues/292))
### 🔧 Bug Fix
- Fix post publish operations for skipped items ([#277](https://github.com/microsoft/fabric-cicd/issues/277))
### ⚡ Additional Optimizations
- New function `key_value_replace` for key-based replacement operations in JSON and YAML
### 📝 Documentation Update
- Add publish regex example to demonstrate how to use the `publish_all_items` with regex for excluding item names
================================================
FILE: .changes/v0.1.18.md
================================================
## [v0.1.18](https://pypi.org/project/fabric-cicd/0.1.18) - May 14, 2025
### 🔧 Bug Fix
- Fix bug with check environment publish state ([#295](https://github.com/microsoft/fabric-cicd/issues/295))
================================================
FILE: .changes/v0.1.19.md
================================================
## [v0.1.19](https://pypi.org/project/fabric-cicd/0.1.19) - May 21, 2025
### 🆕 New Items Support
- Onboard SQL Database item type (shell-only deployment) ([#301](https://github.com/microsoft/fabric-cicd/issues/301))
- Onboard Warehouse item type (shell-only deployment) ([#204](https://github.com/microsoft/fabric-cicd/issues/204))
### 🔧 Bug Fix
- Fix bug with unpublish workspace folders ([#273](https://github.com/microsoft/fabric-cicd/issues/273))
================================================
FILE: .changes/v0.1.2.md
================================================
## [v0.1.2](https://pypi.org/project/fabric-cicd/0.1.2) - January 27, 2025
### ✨ New Functionality
- Introduces max retry and backoff for long running / throttled calls ([#27](https://github.com/microsoft/fabric-cicd/issues/27))
### 🔧 Bug Fix
- Fix Environment publish uses arbitrary wait time ([#50](https://github.com/microsoft/fabric-cicd/issues/50))
- Fix Environment publish doesn't wait for success ([#56](https://github.com/microsoft/fabric-cicd/issues/56))
- Fix Long running operation steps out early for notebook publish ([#58](https://github.com/microsoft/fabric-cicd/issues/58))
================================================
FILE: .changes/v0.1.20.md
================================================
## [v0.1.20](https://pypi.org/project/fabric-cicd/0.1.20) - June 12, 2025
### ✨ New Functionality
- Parameterization support for find_value regex and replace_value variables ([#326](https://github.com/microsoft/fabric-cicd/issues/326))
### 🆕 New Items Support
- Onboard KQL Dashboard item type ([#329](https://github.com/microsoft/fabric-cicd/issues/329))
- Onboard Dataflow Gen2 item type ([#111](https://github.com/microsoft/fabric-cicd/issues/111))
### 🔧 Bug Fix
- Fix bug with deploying environment libraries with special chars ([#336](https://github.com/microsoft/fabric-cicd/issues/336))
### ⚡ Additional Optimizations
- Improved test coverage for subfolder creation/modification ([#211](https://github.com/microsoft/fabric-cicd/issues/211))
================================================
FILE: .changes/v0.1.21.md
================================================
## [v0.1.21](https://pypi.org/project/fabric-cicd/0.1.21) - June 18, 2025
### 🔧 Bug Fix
- Fix bug with workspace ID replacement in JSON files for pipeline deployments ([#345](https://github.com/microsoft/fabric-cicd/issues/345))
### ⚡ Additional Optimizations
- Increased max retry for Warehouses and Dataflows
================================================
FILE: .changes/v0.1.22.md
================================================
## [v0.1.22](https://pypi.org/project/fabric-cicd/0.1.22) - June 25, 2025
### 🆕 New Items Support
- Onboard API for GraphQL item type ([#287](https://github.com/microsoft/fabric-cicd/issues/287))
### 🔧 Bug Fix
- Fix Fabric API call error during dataflow publish ([#352](https://github.com/microsoft/fabric-cicd/issues/352))
### ⚡ Additional Optimizations
- Expanded test coverage to handle folder edge cases ([#358](https://github.com/microsoft/fabric-cicd/issues/358))
================================================
FILE: .changes/v0.1.23.md
================================================
## [v0.1.23](https://pypi.org/project/fabric-cicd/0.1.23) - July 08, 2025
### ✨ New Functionality
- New functionalities for GitHub Copilot Agent and PR-to-Issue linking
### 📝 Documentation Update
- Fix formatting and examples in the How to and Examples pages
### 🔧 Bug Fix
- Fix issue with lakehouse shortcuts publishing ([#379](https://github.com/microsoft/fabric-cicd/issues/379))
- Add validation for empty logical IDs to prevent deployment corruption ([#86](https://github.com/microsoft/fabric-cicd/issues/86))
- Fix SQL provision print statement ([#329](https://github.com/microsoft/fabric-cicd/issues/329))
- Rename the error code for reserved item name per updated Microsoft Fabric API ([#388](https://github.com/microsoft/fabric-cicd/issues/388))
- Fix lakehouse exclude_regex to exclude shortcut publishing ([#385](https://github.com/microsoft/fabric-cicd/issues/385))
- Remove max retry limit to handle large deployments ([#299](https://github.com/microsoft/fabric-cicd/issues/299))
================================================
FILE: .changes/v0.1.24.md
================================================
## [v0.1.24](https://pypi.org/project/fabric-cicd/0.1.24) - August 04, 2025
### ⚠️ Breaking Change
- Require parameterization for Dataflow and Semantic Model references in Data Pipeline activities
- Require specific parameterization for deploying a Dataflow that depends on another in the same workspace (see Parameterization docs)
### 📝 Documentation Update
- Improve Parameterization documentation ([#415](https://github.com/microsoft/fabric-cicd/issues/415))
### ⚡ Additional Optimizations
- Support for Eventhouse query URI parameterization ([#414](https://github.com/microsoft/fabric-cicd/issues/414))
- Support for Warehouse SQL endpoint parameterization ([#392](https://github.com/microsoft/fabric-cicd/issues/392))
### 🔧 Bug Fix
- Fix Dataflow/Data Pipeline deployment failures caused by workspace permissions ([#419](https://github.com/microsoft/fabric-cicd/issues/419))
- Prevent duplicate logical ID issue in Report and Semantic Model deployment ([#405](https://github.com/microsoft/fabric-cicd/issues/405))
- Fix deployment of items without assigned capacity ([#402](https://github.com/microsoft/fabric-cicd/issues/402))
================================================
FILE: .changes/v0.1.25.md
================================================
## [v0.1.25](https://pypi.org/project/fabric-cicd/0.1.25) - August 19, 2025
### ⚠️ Breaking Change
- Modify the default for item_types_in_scope and add thorough validation ([#464](https://github.com/microsoft/fabric-cicd/issues/464))
### ✨ New Functionality
- Add new experimental feature flag to enable selective deployment ([#384](https://github.com/microsoft/fabric-cicd/issues/384))
- Support "ALL" environment concept in parameterization ([#320](https://github.com/microsoft/fabric-cicd/issues/320))
### 📝 Documentation Update
- Enhance Overview section in Parameterization docs ([#495](https://github.com/microsoft/fabric-cicd/issues/495))
### ⚡ Additional Optimizations
- Eliminate ACCEPTED_ITEM_TYPES_NON_UPN constant and unify with ACCEPTED_ITEM_TYPES ([#477](https://github.com/microsoft/fabric-cicd/issues/477))
- Add comprehensive GitHub Copilot instructions for effective codebase development ([#468](https://github.com/microsoft/fabric-cicd/issues/468))
### 🔧 Bug Fix
- Add feature flags and warnings for Warehouse, SQL Database, and Eventhouse unpublish operations ([#483](https://github.com/microsoft/fabric-cicd/issues/483))
- Fix code formatting inconsistencies in fabric_workspace unit test ([#474](https://github.com/microsoft/fabric-cicd/issues/474))
- Fix KeyError when deploying Reports with Semantic Model dependencies in Report-only scope case ([#278](https://github.com/microsoft/fabric-cicd/issues/278))
================================================
FILE: .changes/v0.1.26.md
================================================
## [v0.1.26](https://pypi.org/project/fabric-cicd/0.1.26) - September 05, 2025
### ⚠️ Breaking Change
- Deprecate Base API URL kwarg in Fabric Workspace ([#529](https://github.com/microsoft/fabric-cicd/issues/529))
### ✨ New Functionality
- Support Schedules parameterization ([#508](https://github.com/microsoft/fabric-cicd/issues/508))
- Support YAML configuration file-based deployment ([#470](https://github.com/microsoft/fabric-cicd/issues/470))
### 📝 Documentation Update
- Add dynamically generated Python version requirements to documentation ([#520](https://github.com/microsoft/fabric-cicd/issues/520))
### ⚡ Additional Optimizations
- Enhance pytest output to limit console verbosity ([#514](https://github.com/microsoft/fabric-cicd/issues/514))
### 🔧 Bug Fix
- Fix Report item schema handling ([#518](https://github.com/microsoft/fabric-cicd/issues/518))
- Fix deployment order to publish Mirrored Database before Lakehouse ([#482](https://github.com/microsoft/fabric-cicd/issues/482))
================================================
FILE: .changes/v0.1.27.md
================================================
## [v0.1.27](https://pypi.org/project/fabric-cicd/0.1.27) - September 05, 2025
### 🔧 Bug Fix
- Fix trailing comma in report schema ([#534](https://github.com/microsoft/fabric-cicd/issues/534))
================================================
FILE: .changes/v0.1.28.md
================================================
## [v0.1.28](https://pypi.org/project/fabric-cicd/0.1.28) - September 15, 2025
### ✨ New Functionality
- Add folder exclusion feature for publish operations ([#427](https://github.com/microsoft/fabric-cicd/issues/427))
- Expand workspace ID dynamic replacement capabilities in parameterization ([#408](https://github.com/microsoft/fabric-cicd/issues/408))
### 🔧 Bug Fix
- Fix unexpected behavior with file_path parameter filter ([#545](https://github.com/microsoft/fabric-cicd/issues/545))
- Fix unpublish exclude_regex bug in configuration file-based deployment ([#544](https://github.com/microsoft/fabric-cicd/issues/544))
================================================
FILE: .changes/v0.1.29.md
================================================
## [v0.1.29](https://pypi.org/project/fabric-cicd/0.1.29) - October 01, 2025
### ✨ New Functionality
- Support dynamic replacement for cross-workspace item IDs ([#558](https://github.com/microsoft/fabric-cicd/issues/558))
- Add option to return API response for publish operations in publish_all_items ([#497](https://github.com/microsoft/fabric-cicd/issues/497))
### 🆕 New Items Support
- Onboard Apache Airflow Job item type ([#565](https://github.com/microsoft/fabric-cicd/issues/565))
- Onboard Mounted Data Factory item type ([#406](https://github.com/microsoft/fabric-cicd/issues/406))
### 🔧 Bug Fix
- Fix publish order of Eventhouses and Semantic Models ([#566](https://github.com/microsoft/fabric-cicd/issues/566))
================================================
FILE: .changes/v0.1.3.md
================================================
## [v0.1.3](https://pypi.org/project/fabric-cicd/0.1.3) - January 29, 2025
### ✨ New Functionality
- Add PyPI check version to encourage version bumps ([#75](https://github.com/microsoft/fabric-cicd/issues/75))
### 🔧 Bug Fix
- Fix Semantic model initial publish results in None Url error ([#61](https://github.com/microsoft/fabric-cicd/issues/61))
- Fix Integer parsed as float failing in handle_retry for <3.12 python ([#63](https://github.com/microsoft/fabric-cicd/issues/63))
- Fix Default item types fail to unpublish ([#76](https://github.com/microsoft/fabric-cicd/issues/76))
- Fix Items in subfolders are skipped ([#77](https://github.com/microsoft/fabric-cicd/issues/77))
### 📝 Documentation Update
- Update documentation & examples
================================================
FILE: .changes/v0.1.30.md
================================================
## [v0.1.30](https://pypi.org/project/fabric-cicd/0.1.30) - October 20, 2025
### ✨ New Functionality
- Add support for binding semantic models to on-premise gateways in Fabric workspaces ([#569](https://github.com/microsoft/fabric-cicd/issues/569))
### 🆕 New Items Support
- Add support for publishing and managing Data Agent items ([#556](https://github.com/microsoft/fabric-cicd/issues/556))
- Add OrgApp item type support ([#586](https://github.com/microsoft/fabric-cicd/issues/586))
### ⚡ Additional Optimizations
- Enhance cross-workspace variable support to allow referencing other attributes ([#583](https://github.com/microsoft/fabric-cicd/issues/583))
### 🔧 Bug Fix
- Fix workspace name extraction bug for non-ID attrs using ITEM_ATTR_LOOKUP ([#583](https://github.com/microsoft/fabric-cicd/issues/583))
- Fix capacity requirement check ([#593](https://github.com/microsoft/fabric-cicd/issues/593))
================================================
FILE: .changes/v0.1.31.md
================================================
## [v0.1.31](https://pypi.org/project/fabric-cicd/0.1.31) - December 01, 2025
### ⚠️ Breaking Change
- Migrate to the latest Fabric Environment item APIs to simplify deployment and improve compatibility ([#173](https://github.com/microsoft/fabric-cicd/issues/173))
### ✨ New Functionality
- Enable dynamic replacement of Lakehouse SQL Endpoint IDs ([#616](https://github.com/microsoft/fabric-cicd/issues/616))
- Enable linking of Semantic Models to both cloud and gateway connections ([#602](https://github.com/microsoft/fabric-cicd/issues/602))
- Allow use of the dynamic replacement variables within the key_value_replace parameter ([#567](https://github.com/microsoft/fabric-cicd/issues/567))
- Add support for parameter file templates ([#499](https://github.com/microsoft/fabric-cicd/issues/499))
### 🆕 New Items Support
- Add support for the ML Experiment item type ([#600](https://github.com/microsoft/fabric-cicd/issues/600))
- Add support for the User Data Function item type ([#588](https://github.com/microsoft/fabric-cicd/issues/588))
### 📝 Documentation Update
- Update the advanced Dataflow parameterization example with the correct file_path value ([#633](https://github.com/microsoft/fabric-cicd/issues/633))
### 🔧 Bug Fix
- Fix publishing issues for KQL Database items in folders ([#657](https://github.com/microsoft/fabric-cicd/issues/657))
- Separate logic for 'items to include' feature between publish and unpublish operations ([#650](https://github.com/microsoft/fabric-cicd/issues/650))
- Fix parameterization logic to properly handle find_value regex patterns and replacements ([#639](https://github.com/microsoft/fabric-cicd/issues/639))
- Correct the publish order of Data Agent and Semantic Model items ([#628](https://github.com/microsoft/fabric-cicd/issues/628))
- Fix Lakehouse item publishing errors when shortcuts refer to the default Lakehouse ID ([#610](https://github.com/microsoft/fabric-cicd/issues/610))
================================================
FILE: .changes/v0.1.32.md
================================================
## [v0.1.32](https://pypi.org/project/fabric-cicd/0.1.32) - December 03, 2025
### 🔧 Bug Fix
- Fix publish bug for Environment items that contain only spark settings ([#664](https://github.com/microsoft/fabric-cicd/issues/664))
================================================
FILE: .changes/v0.1.33.md
================================================
## [v0.1.33](https://pypi.org/project/fabric-cicd/0.1.33) - December 16, 2025
### ✨ New Functionality
- Add key_value_replace parameter support for YAML files ([#649](https://github.com/microsoft/fabric-cicd/issues/649))
- Support selective shortcut publishing with regex exclusion ([#624](https://github.com/microsoft/fabric-cicd/issues/624))
### ⚡ Additional Optimizations
- Add Linux development environment bootstrapping script ([#680](https://github.com/microsoft/fabric-cicd/issues/680))
- Update item types in scope to be an optional parameter in validate parameter file function ([#669](https://github.com/microsoft/fabric-cicd/issues/669))
### 🔧 Bug Fix
- Fix publish order for Notebook and Eventhouse dependent items ([#685](https://github.com/microsoft/fabric-cicd/issues/685))
- Enable parameterizing multiple connections in the same Semantic Model item ([#674](https://github.com/microsoft/fabric-cicd/issues/674))
- Fix missing description metadata in item payload for shell-only item deployments ([#672](https://github.com/microsoft/fabric-cicd/issues/672))
- Resolve API long running operation handling when publishing Environment items ([#668](https://github.com/microsoft/fabric-cicd/issues/668))
================================================
FILE: .changes/v0.1.34.md
================================================
## [v0.1.34](https://pypi.org/project/fabric-cicd/0.1.34) - January 20, 2026
### ✨ New Functionality
- Enable dynamic replacement of SQL endpoint values from SQL Database items ([#720](https://github.com/microsoft/fabric-cicd/issues/720))
- Support Fabric Notebook Authentication ([#707](https://github.com/microsoft/fabric-cicd/issues/707))
### 🆕 New Items Support
- Onboard Spark Job Definition item type ([#115](https://github.com/microsoft/fabric-cicd/issues/115))
### 📝 Documentation Update
- Add `CONTRIBUTING.md` file to repository ([#723](https://github.com/microsoft/fabric-cicd/issues/723))
- Add comprehensive troubleshooting guide to documentation ([#705](https://github.com/microsoft/fabric-cicd/issues/705))
- Add parameterization documentation for Report items using ByConnection binding to Semantic Models ([#637](https://github.com/microsoft/fabric-cicd/issues/637))
### ⚡ Additional Optimizations
- Add debug file for local Fabric REST API testing ([#714](https://github.com/microsoft/fabric-cicd/issues/714))
================================================
FILE: .changes/v0.1.4.md
================================================
## [v0.1.4](https://pypi.org/project/fabric-cicd/0.1.4) - February 12, 2025
### ✨ New Functionality
- Support Feature Flagging ([#96](https://github.com/microsoft/fabric-cicd/issues/96))
### 🔧 Bug Fix
- Fix Image support in report deployment ([#88](https://github.com/microsoft/fabric-cicd/issues/88))
- Fix Broken README link ([#92](https://github.com/microsoft/fabric-cicd/issues/92))
### ⚡ Additional Optimizations
- Workspace ID replacement improved
- Increased error handling in activate script
- Onboard pytest and coverage
- Improvements to nested dictionaries ([#37](https://github.com/microsoft/fabric-cicd/issues/37))
- Support Python Installed From Windows Store ([#87](https://github.com/microsoft/fabric-cicd/issues/87))
================================================
FILE: .changes/v0.1.5.md
================================================
## [v0.1.5](https://pypi.org/project/fabric-cicd/0.1.5) - February 18, 2025
### 🔧 Bug Fix
- Fix Environment Failure without Public Library ([#103](https://github.com/microsoft/fabric-cicd/issues/103))
### ⚡ Additional Optimizations
- Introduces pytest check for PRs ([#100](https://github.com/microsoft/fabric-cicd/issues/100))
================================================
FILE: .changes/v0.1.6.md
================================================
## [v0.1.6](https://pypi.org/project/fabric-cicd/0.1.6) - February 24, 2025
### 🆕 New Items Support
- Onboard Lakehouse item type ([#116](https://github.com/microsoft/fabric-cicd/issues/116))
### 📝 Documentation Update
- Update example docs ([#25](https://github.com/microsoft/fabric-cicd/issues/25))
- Update find_replace docs ([#110](https://github.com/microsoft/fabric-cicd/issues/110))
### ⚡ Additional Optimizations
- Standardized docstrings to Google format
- Onboard file objects ([#46](https://github.com/microsoft/fabric-cicd/issues/46))
- Leverage UpdateDefinition Flag ([#28](https://github.com/microsoft/fabric-cicd/issues/28))
- Convert repo and workspace dictionaries ([#45](https://github.com/microsoft/fabric-cicd/issues/45))
================================================
FILE: .changes/v0.1.7.md
================================================
## [v0.1.7](https://pypi.org/project/fabric-cicd/0.1.7) - February 26, 2025
### 🔧 Bug Fix
- Fix special character support in files ([#129](https://github.com/microsoft/fabric-cicd/issues/129))
================================================
FILE: .changes/v0.1.8.md
================================================
## [v0.1.8](https://pypi.org/project/fabric-cicd/0.1.8) - March 04, 2025
### 🔧 Bug Fix
- Handle null byPath object in report definition file ([#143](https://github.com/microsoft/fabric-cicd/issues/143))
- Support relative directories ([#136](https://github.com/microsoft/fabric-cicd/issues/136)) ([#132](https://github.com/microsoft/fabric-cicd/issues/132))
- Increase special character support ([#134](https://github.com/microsoft/fabric-cicd/issues/134))
### ⚡ Additional Optimizations
- Changelog now available with version check ([#127](https://github.com/microsoft/fabric-cicd/issues/127))
================================================
FILE: .changes/v0.1.9.md
================================================
## [v0.1.9](https://pypi.org/project/fabric-cicd/0.1.9) - March 11, 2025
### 🆕 New Items Support
- Support for Mirrored Database item type ([#145](https://github.com/microsoft/fabric-cicd/issues/145))
### ⚡ Additional Optimizations
- Increase reserved name wait time ([#135](https://github.com/microsoft/fabric-cicd/issues/135))
================================================
FILE: .changes/v0.2.0.md
================================================
## [v0.2.0](https://pypi.org/project/fabric-cicd/0.2.0) - February 16, 2026
### ✨ New Functionality
- Support parallelize deployments within a given item type by [mdrakiburrahman](https://github.com/mdrakiburrahman) ([#719](https://github.com/microsoft/fabric-cicd/issues/719))
- Add a black-box REST API testing harness by [mdrakiburrahman](https://github.com/mdrakiburrahman) ([#738](https://github.com/microsoft/fabric-cicd/issues/738))
- Change header print messages to info log by [mwc360](https://github.com/mwc360) ([#771](https://github.com/microsoft/fabric-cicd/issues/771))
- Add support for semantic model binding per environment by [shirasassoon](https://github.com/shirasassoon) ([#689](https://github.com/microsoft/fabric-cicd/issues/689))
### 🔧 Bug Fix
- Remove OrgApp item type support by [shirasassoon](https://github.com/shirasassoon) ([#758](https://github.com/microsoft/fabric-cicd/issues/758))
- Improve environment-mapping behavior in optional config fields by [shirasassoon](https://github.com/shirasassoon) ([#716](https://github.com/microsoft/fabric-cicd/issues/716))
- Fix duplicate YAML key detection in parameter validation by [shirasassoon](https://github.com/shirasassoon) ([#752](https://github.com/microsoft/fabric-cicd/issues/752))
- Add caching for item attribute lookups by [MiSchroe](https://github.com/MiSchroe) ([#704](https://github.com/microsoft/fabric-cicd/issues/704))
### ⚡ Additional Optimizations
- Enable configuration-based deployment without feature flags by [shirasassoon](https://github.com/shirasassoon) ([#805](https://github.com/microsoft/fabric-cicd/issues/805))
### 📝 Documentation Update
- Fix troubleshooting docs by [shirasassoon](https://github.com/shirasassoon) ([#747](https://github.com/microsoft/fabric-cicd/issues/747))
================================================
FILE: .changes/v0.3.0.md
================================================
## [v0.3.0](https://pypi.org/project/fabric-cicd/0.3.0) - March 09, 2026
### ✨ New Functionality
- Support selective folder deployment using inclusion list by [shirasassoon](https://github.com/shirasassoon) ([#757](https://github.com/microsoft/fabric-cicd/issues/757))
- Add FABRIC_CICD_VERSION_CHECK_DISABLED environment variable to disable version check on startup by [Ricapar](https://github.com/Ricapar) ([#811](https://github.com/microsoft/fabric-cicd/issues/811))
- Add enhanced logging configuration options via public functions by [shirasassoon](https://github.com/shirasassoon) ([#842](https://github.com/microsoft/fabric-cicd/issues/842))
- Add deployment support for Notebook items with `.ipynb` file format by [shirasassoon](https://github.com/shirasassoon) ([#850](https://github.com/microsoft/fabric-cicd/issues/850))
### 🔧 Bug Fix
- Add max workers soft cap with override and handle garbage response from Fabric Data Plane by [mdrakiburrahman](https://github.com/mdrakiburrahman) ([#827](https://github.com/microsoft/fabric-cicd/issues/827))
- Fix parameter validation failure for item names with accented characters by [shirasassoon](https://github.com/shirasassoon) ([#818](https://github.com/microsoft/fabric-cicd/issues/818))
- Exclude items with placeholder logical ID from duplicate logical ID check by [shirasassoon](https://github.com/shirasassoon) ([#843](https://github.com/microsoft/fabric-cicd/issues/843))
### ⚡ Additional Optimizations
- Add return value to deploy_with_config by [ayeshurun](https://github.com/ayeshurun) ([#851](https://github.com/microsoft/fabric-cicd/issues/851))
- Add support for Python 3.13 in the library by [shirasassoon](https://github.com/shirasassoon) ([#855](https://github.com/microsoft/fabric-cicd/issues/855))
### 📝 Documentation Update
- Remove incorrect statement on support for parameter replacements in Platform files by [shirasassoon](https://github.com/shirasassoon) ([#839](https://github.com/microsoft/fabric-cicd/issues/839))
================================================
FILE: .changes/v0.3.1.md
================================================
## [v0.3.1](https://pypi.org/project/fabric-cicd/0.3.1) - March 12, 2026
### 🔧 Bug Fix
- Fix override behavior of feature flags and constants in config deployment by [shirasassoon](https://github.com/shirasassoon) ([#872](https://github.com/microsoft/fabric-cicd/issues/872))
================================================
FILE: .changes/v1.0.0.md
================================================
## [v1.0.0](https://pypi.org/project/fabric-cicd/1.0.0) - April 20, 2026
### ⚠️ Breaking Change
- Remove default credential fallback; explicit token credential is now required by [shirasassoon](https://github.com/shirasassoon) ([#909](https://github.com/microsoft/fabric-cicd/issues/909))
- Remove implicit authentication in Microsoft Fabric Notebook and identity logging; require explicit token credential and keyword-only arguments for `FabricWorkspace` and `deploy_with_config` by [shirasassoon](https://github.com/shirasassoon) ([#930](https://github.com/microsoft/fabric-cicd/issues/930))
### 🆕 New Items Support
- Add support for Ontology item type by [shirasassoon](https://github.com/shirasassoon) ([#796](https://github.com/microsoft/fabric-cicd/issues/796))
### ✨ New Functionality
- Improve transparency of `deploy_with_config` function in success and failure scenarios by [shirasassoon](https://github.com/shirasassoon) ([#695](https://github.com/microsoft/fabric-cicd/issues/695))
- Extend API response collection to unpublish operations by [shirasassoon](https://github.com/shirasassoon) ([#877](https://github.com/microsoft/fabric-cicd/issues/877))
- Add `get_changed_items()` utility function to detect Fabric items changed via git diff for use with selective deployment by [vipulb91](https://github.com/vipulb91) ([#865](https://github.com/microsoft/fabric-cicd/issues/865))
### 🔧 Bug Fix
- Prevent unintended GUID replacements in Variable Library item files during publish by [shirasassoon](https://github.com/shirasassoon) ([#884](https://github.com/microsoft/fabric-cicd/issues/884))
- Fix YAML content check to reject notebook and other non-YAML files during `key_value_replace` parameterization, preventing file corruption by [shirasassoon](https://github.com/shirasassoon) ([#890](https://github.com/microsoft/fabric-cicd/issues/890))
- Fix Notebook deployment failure caused by non-deterministic ordering of definition files in API payload by [shirasassoon](https://github.com/shirasassoon) ([#869](https://github.com/microsoft/fabric-cicd/issues/869))
- Ignore parameter file when not explicitly defined in config file by [aviatco](https://github.com/aviatco) ([#866](https://github.com/microsoft/fabric-cicd/issues/866))
- Add `enable_hard_delete` feature flag to bypass workspace recycle bin during unpublish by [shirasassoon](https://github.com/shirasassoon) ([#924](https://github.com/microsoft/fabric-cicd/issues/924))
- Add timeout for long-running operation polling by [shirasassoon](https://github.com/shirasassoon) ([#919](https://github.com/microsoft/fabric-cicd/issues/919))
================================================
FILE: .changie.yaml
================================================
# docs: https://changie.dev/config/
---
changesDir: .changes
unreleasedDir: unreleased
headerPath: header.tpl.md
versionExt: md
changelogPath: docs/changelog.md
versionFormat: '## [{{.Version}}](https://pypi.org/project/fabric-cicd/{{.Version}}) - {{.Time.Format "January 02, 2006"}}'
kindFormat: "### {{.Kind}}"
changeFormat: "* {{.Body}} by [{{.Custom.Author}}]({{.Custom.AuthorLink}}) ([#{{.Custom.Issue}}]({{.Custom.IssueLink}}))"
kinds:
- label: "⚠️ Breaking Change"
key: breaking
auto: major
- label: "🆕 New Items Support"
key: new-items
auto: minor
- label: "✨ New Functionality"
key: added
auto: minor
- label: "🔧 Bug Fix"
key: fixed
auto: patch
- label: "⚡ Additional Optimizations"
key: optimization
auto: patch
- label: "📝 Documentation Update"
key: docs
auto: patch
newlines:
afterChangelogHeader: 0
beforeChangelogVersion: 1
endOfVersion: 1
afterKind: 1
beforeKind: 1
envPrefix: CHANGIE_
custom:
- key: Issue
label: Issue Number
type: int
minLength: 1
- key: Author
label: Author's GitHub Username
type: string
minLength: 3
post:
- key: AuthorLink
value: "https://github.com/{{.Custom.Author}}"
- key: IssueLink
value: "https://github.com/microsoft/fabric-cicd/issues/{{.Custom.Issue}}"
replacements:
- path: src/fabric_cicd/constants.py
find: 'VERSION = ".*"'
replace: 'VERSION = "{{.VersionNoPrefix}}"'
================================================
FILE: .github/CODEOWNERS
================================================
##########################################
# CODE OWNERS
##########################################
# default ownership: default owners for everything in the repo (Unless a later match takes precedence)
- @microsoft/fabric-cicd
================================================
FILE: .github/ISSUE_TEMPLATE/1-bug.yml
================================================
name: "🐛 Bug Report"
description: Report a bug
title: "[BUG] "
labels: ["bug"]
body:
- type: markdown
attributes:
value: Thanks for taking the time to report a bug! Please fill out the information below to help us diagnose and fix the issue.
- type: input
id: library-version
attributes:
label: Library Version
description: What is the library version?
validations:
required: true
- type: input
id: python-version
attributes:
label: Python Version
description: Run `python --version` to get your version
validations:
required: true
- type: dropdown
id: operating-system
attributes:
label: Operating System
description: What operating system are you using?
options:
- Windows
- macOS
- Linux
validations:
required: true
- type: dropdown
id: auth-method
attributes:
label: Authentication Method
description: How are you authenticating?
options:
- Azure CLI (az login)
- Service principal (secret)
- Service principal (certificate)
- Service principal (federated credential)
- Managed identity
- Other
validations:
required: true
- type: textarea
id: problem-description
attributes:
label: What is the problem?
description: Describe the bug you encountered and what the gap is.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Steps to reproduce
description: Please provide step-by-step instructions to reproduce the bug
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: What did you expect to happen?
validations:
required: true
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: What actually happened? Include error messages if applicable.
validations:
required: true
- type: textarea
id: solution-description
attributes:
label: Is there an ideal solution?
description: Describe the ideal solution if there is one.
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional context, screenshots, logs, error output, etc
description: Add any other relevant details like specific workspace/item types involved, related issues or documentation, API request IDs. If it is long, please paste to https://gist.github.com/ and insert the link here. Ensure to strip any non public information.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/2-feature.yml
================================================
name: "🚀 Feature Request"
description: Suggest an idea or enhancement for fabric-cicd
title: "[FEATURE] "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for suggesting a new feature! Please provide as much detail as possible to help us understand and evaluate your request.
- type: textarea
id: use-case-problem
attributes:
label: Use Case / Problem
description: |
Describe the problem or use case that this feature would solve. Include:
- What problem are you trying to solve?
- Current limitations or pain points
- How this fits into your workflow
validations:
required: true
- type: textarea
id: proposed-solution
attributes:
label: Proposed Solution
description: |
Describe the solution you'd like to see implemented:
- Specific functionality
- Expected behavior and output
- Integration with existing fabric-cicd features
validations:
required: true
- type: textarea
id: alternatives-considered
attributes:
label: Alternatives Considered
description: |
Describe any alternative solutions or features you've considered:
- Workarounds you're currently using
- Other tools or approaches that could solve this
- Why those alternatives are insufficient
- type: checkboxes
id: impact-assessment
attributes:
label: Impact Assessment
description: Help us understand the impact of this feature
options:
- label: This would help me personally
- label: This would help my team/organization
- label: This would help the broader fabric-cicd community
- label: This aligns with Microsoft Fabric roadmap items
- type: checkboxes
id: implementation-attestation
attributes:
label: Implementation Attestation
description: Please confirm your understanding of implementation considerations (required)
options:
- label: I understand this feature should maintain backward compatibility (if applicable)
required: true
- label: I understand this feature should not introduce performance regressions for existing workflows
required: true
- label: I acknowledge that new features must follow fabric-cicd's established patterns and conventions
required: true
- type: textarea
id: implementation-notes
attributes:
label: Implementation Notes
description: |
If you have technical suggestions for implementation, consider:
- Which item types are affected? (Notebook, DataPipeline, Environment, etc.)
- Does this require changes to core classes/functions? Which ones?
- Does this require changes to the parameterization framework?
- Which Fabric REST APIs would be involved (if any)?
================================================
FILE: .github/ISSUE_TEMPLATE/3-documentation.yml
================================================
name: "📝 Documentation Feedback"
description: Provide documentation feedback
title: "[DOCUMENTATION] "
labels: ["documentation"]
body:
- type: markdown
attributes:
value: Thanks for taking the time to provide documentation feedback! Please include as much detail as possible to help us improve our documentation.
- type: input
id: documentation-location
attributes:
label: URL to documentation
description: Provide a URL to the documentation location.
placeholder: "https://microsoft.github.io/fabric-cicd/..."
validations:
required: true
- type: dropdown
id: feedback-type
attributes:
label: Type of feedback
description: What kind of documentation issue is this?
options:
- Unclear or confusing content
- Missing information
- Incorrect or outdated information
- Typo or grammatical error
- Code example issue
- Broken link
- Suggestion for improvement
- Other
validations:
required: true
- type: textarea
id: current-content
attributes:
label: Current content
description: Copy the relevant section of documentation that needs improvement (if applicable).
placeholder: "Paste the current text or describe what exists..."
validations:
required: false
- type: textarea
id: feedback
attributes:
label: Feedback
description: What is the issue or what improvement would you suggest?
placeholder: "Describe what's wrong or what could be better..."
validations:
required: true
- type: textarea
id: suggested-change
attributes:
label: Suggested change
description: If you have a specific suggestion, please provide it here.
placeholder: "Provide your suggested text, code, or improvement..."
validations:
required: false
- type: dropdown
id: user-experience
attributes:
label: Experience with fabric-cicd
description: This helps us understand our audience better.
options:
- New to fabric-cicd
- Some experience with fabric-cicd
- Experienced user
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Add any other context, screenshots, or related links here.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/4-question.yml
================================================
name: "❓ Question"
description: Ask a question about fabric-cicd
title: "[QUESTION] "
labels: ["question"]
body:
- type: markdown
attributes:
value: Thanks for your question! Please provide as much detail as possible to help us assist you effectively.
- type: textarea
id: question
attributes:
label: What is the question?
description: A clear and concise description of what you'd like to know or need help with.
validations:
required: true
- type: textarea
id: context
attributes:
label: Context
description: |
Add context and include:
- Your use case or scenario
- What you've already tried
- Specifics on what was involved (code snippets, configurations, etc.)
validations:
required: true
- type: input
id: library-version
attributes:
label: Library Version
description: What is the library version? (if relevant)
- type: dropdown
id: operating-system
attributes:
label: Operating System
description: What operating system are you using? (if relevant)
options:
- Not applicable
- Windows
- macOS
- Linux
default: 0
- type: checkboxes
id: documentation-check
attributes:
label: Have you checked the documentation?
description: Please confirm you've reviewed the available resources
options:
- label: I have searched existing GitHub issues
required: true
- label: I have reviewed the fabric-cicd documentation
required: true
- type: textarea
id: additional-information
attributes:
label: Additional Information
description: |
Any additional details that might help us answer your question:
- Code snippets
- Screenshots (if applicable)
- Error messages (if any)
- type: markdown
attributes:
value: |
## Alternative Support Channels
For different types of questions, you might also consider:
- **General Fabric questions**: [Developer Community Forum](https://community.fabric.microsoft.com/t5/Developer/bd-p/Developer)
- **Feature suggestions**: [Fabric Ideas Portal](https://ideas.fabric.microsoft.com/)
- **Enterprise support**: [Fabric Support Team](https://support.fabric.microsoft.com/)
- **Community discussions**: [r/MicrosoftFabric on Reddit](https://www.reddit.com/r/MicrosoftFabric/)
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .github/agents/new-item-type.agent.md
================================================
---
name: New Item Type
description: Guide and assist with onboarding a new Microsoft Fabric item type into fabric-cicd
argument-hint: Tell me which Fabric item type you want to add (e.g., "Add support for Ontology")
tools:
- runInTerminal
- terminalLastCommand
- search
- fetch
- readFile
- editFiles
- createFile
---
# New Item Type Onboarding Agent
> **Important:** If you are unsure about any detail — such as whether the item type supports definitions, has unique deployment requirements, depends on other item types, or requires parameterization — **always ask the requestor for clarification before proceeding**. List the specific unknowns and ask the requestor to confirm each one before continuing.
## Prerequisites
Before starting, you need only the **display name** (PascalCase, as used by the Fabric API — e.g., `CopyJob`, `SnowflakeDatabase`). The eligibility gates below will determine the remaining core details.
### Eligibility Gates
Before proceeding, confirm all of the following. If any gate fails, **stop** — the item type cannot be onboarded.
1. The item type must be supported in source control / Git integration. Fetch the [item definition overview](https://learn.microsoft.com/en-us/rest/api/fabric/articles/item-management/definitions/item-definition-overview) page and check if the item type appears in the **"Definition Details for Supported Item Types"** list.
2. The Fabric API must support deployment for the item type — either full definition deployment or shell-only creation (like Lakehouse/Warehouse). Verify using the steps in **"How to verify gates 2 and 3"** below.
3. The Fabric API must support service principal (SPN) authentication for the item type's deployment operations. fabric-cicd is primarily used in CI/CD pipelines where SPN is the standard authentication method. Verify using the steps in **"How to verify gates 2 and 3"** below.
#### How to verify gates 2 and 3
The Fabric REST API docs follow a predictable URL pattern. Use these steps to directly navigate to the right pages instead of searching the generic API root:
1. **Construct the item type's API items page URL:**
`https://learn.microsoft.com/en-us/rest/api/fabric/{itemtype-lowercase}/items`
where `{itemtype-lowercase}` is the PascalCase item type name lowercased with no separators.
- Examples: `SnowflakeDatabase` → `snowflakedatabase`, `DataPipeline` → `datapipeline`, `KQLDatabase` → `kqldatabase`
2. **Fetch that page and confirm deployment operations exist (Gate 2):**
- Full definition support: Look for **"Get [Item] Definition"** and **"Update [Item] Definition"** operations in the Operations table.
- Shell-only support: If the documentation explicitly states that item definition is not supported (e.g., Warehouse's Create page states "This API does not support item definition") and the item has **"Create [Item]"** and **"Update [Item]"** operations, the item is shell-only. **Important:** There can be nuances with definition support — always present your findings to the requestor and ask them to confirm whether the item should be categorized as full definition or shell-only before proceeding.
- If neither Create nor definition operations exist, Gate 2 fails.
3. **Fetch the Create endpoint page to check SPN support (Gate 3):**
`https://learn.microsoft.com/en-us/rest/api/fabric/{itemtype-lowercase}/items/create-{item-type-kebab-case}`
where `{item-type-kebab-case}` inserts hyphens between PascalCase words and lowercases everything.
- Examples: `SnowflakeDatabase` → `create-snowflake-database`, `DataPipeline` → `create-data-pipeline`, `KQLDatabase` → `create-kql-database`
- Find the **"Microsoft Entra supported identities"** section and confirm the table shows **"Service principal and Managed identities: Yes"**. If it shows "No" or the section is missing, Gate 3 fails.
**Important:** You MUST fetch the actual API pages listed above. Do not guess or assume gate results based on the item type name alone. If a URL returns a 404, try alternate kebab-case patterns (e.g., `graphqlapi` instead of `graph-q-l-api`), or fall back to fetching the [Fabric REST API root](https://learn.microsoft.com/en-us/rest/api/fabric/) and navigating to the item type's section. If the documentation is still inaccessible, ask the requestor to provide the relevant API page details.
**Exceptions:** Gates 1 and 3 may be excepted on a case-by-case basis with fabric-cicd team approval — for example, Notebook `.ipynb` format is supported despite not being source-controlled (gate 1 exception). Gate 2 (API deployment support) has no exceptions. Any approved exception must be documented as a known limitation in `docs/how_to/item_types.md`.
### Additional Details (Required)
After the eligibility gates pass, you **must** ask the requestor about **every row** in this table and record the answer before starting implementation. Do not skip any row or assume the answer is "no."
| Question to ask the requestor | Example | Affects |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
| Which existing item types must deploy **before** this one? Which existing types depend on this one deploying first? | Eventhouse → KQLDatabase, SemanticModel → Report | Step 1b |
| Should certain file paths within the item folder be skipped during publish? | `.pbi/`, `.children/` | Step 1d |
| Does the API use a non-standard definition format? If yes, provide the exact format string and instructions for how it should be handled. | `ipynb`, `SparkJobDefinitionV2` | Step 1e |
| Does deleting this item destroy user data? | Lakehouse, Eventhouse | Step 1f |
| Can items of this type reference each other? | Data Pipeline invokes another Data Pipeline | Steps 1g, 2 |
| Does the item need custom deployment logic, dependency resolution, or special parameterization? If yes, describe what is needed. | Lakehouse creation payload, Environment async check, KQL items need query service URI (via dynamic replacement), SemanticModel binding parameter | Step 2 |
---
## Safety Rules
- **Never hardcode secrets, tokens, or credentials** in publisher code or tests
- **Use deterministic test data** — no real tenant IDs, workspace IDs, or user emails
- **Follow existing patterns** — consistency is more important than cleverness
- **Validate all assumptions** — if unsure about API behavior, ask the requestor
---
## Integration Checklist
Once eligibility gates pass and additional details are gathered, proceed through these steps in order. If you encounter something that doesn't fit the steps below, **stop and ask the requestor** rather than improvising.
### Step 1 — Register the Item Type in Constants
**File:** `src/fabric_cicd/constants.py`
Read `constants.py` to see the existing patterns for each mapping below. Add entries following the same format.
#### 1a. Add to the `ItemType` enum
Add a new member in alphabetical order within the enum:
```python
class ItemType(str, Enum):
# ... existing members ...
NEW_TYPE = "NewType"
```
**Rules:**
- Enum member name uses `UPPER_SNAKE_CASE`
- Enum value uses `PascalCase` matching the Fabric API `type` field exactly
#### 1b. Add to `SERIAL_ITEM_PUBLISH_ORDER`
Choose the correct position based on the item's dependencies. Items that other items depend on must come **earlier** in the order. The unpublish order is automatically the reverse.
##### How to determine the correct position
> **How items reference each other:** In Fabric definition files, items reference other items via either **logical IDs** (workspace-agnostic GUIDs assigned by Git integration — automatically replaced by fabric-cicd) or **item IDs** (environment-specific GUIDs that differ per workspace — must be resolved via parameterization in `parameter.yml`). When reviewing definition files to identify dependencies, look for both types of references.
1. **Read the current `SERIAL_ITEM_PUBLISH_ORDER`** in `constants.py` to see the latest order.
2. **Identify upstream dependencies** — types the new item depends on. Check definition files for references (logical IDs, item IDs, paths, connection strings) and ask the requestor. The new item must go **after** the highest-numbered upstream dependency.
3. **Identify downstream dependents** — existing types that will depend on the new item. The new item must go **before** the lowest-numbered downstream dependent.
4. Place the new item anywhere in the valid range between those two bounds. If there is no gap, renumber existing entries to make room.
5. If the new item has **no dependencies in either direction**, place it at the end of the order.
6. **When in doubt, ask the requestor** — do not guess dependency relationships.
#### 1c. Optionally add to `SHELL_ONLY_PUBLISH`
If the API does **not** support item definition and only supports metadata (shell) deployment — like Warehouse, ML Experiment, etc.
#### 1d. Optionally add to `EXCLUDE_PATH_REGEX_MAPPING`
If certain file paths within the item should be excluded during publish (e.g., `.pbi/` folders for Report/SemanticModel, `.children/` for Eventhouse).
#### 1e. Optionally add to `API_FORMAT_MAPPING`
If the Fabric API requires a specific format string for the item's definition (e.g., `"ipynb"` for Notebooks, `"SparkJobDefinitionV2"` for Spark Job Definitions).
Only add an API format if the format is supported in Fabric's Git integration (source control). If the format is not source-controlled, it generally should not be added unless approved by the fabric-cicd team.
**Known exception:** Notebook `.ipynb` format is supported despite not being source-controlled. This is documented as a known limitation in `docs/how_to/item_types.md`.
#### 1f. Optionally add to `UNPUBLISH_FLAG_MAPPING`
If unpublishing the item is destructive and should be gated behind a feature flag (like Lakehouse, Warehouse, Eventhouse). If so, also add a new `FeatureFlag` enum member.
#### 1g. Optionally add to `ITEM_TYPE_TO_FILE`
If items of this type can reference other items of the **same** type (intra-type dependencies), register the content file that contains those references so the dependency module knows which file to parse. This is required when implementing intra-type dependency ordering (see Step 2 — Dependency Ordering below).
---
### Step 2 — Create a Publisher Class
**File:** `src/fabric_cicd/_items/_newtype.py` (new file)
Create a publisher class that extends `ItemPublisher`. The simplest case:
```python
# src/fabric_cicd/_items/_newtype.py
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""Functions to process and deploy NewType item."""
from fabric_cicd._items._base_publisher import ItemPublisher
from fabric_cicd.constants import ItemType
class NewTypePublisher(ItemPublisher):
"""Publisher for NewType items."""
item_type = ItemType.NEW_TYPE.value
```
For more complex items, you can override these methods from `ItemPublisher`:
| Method | Purpose | When to Override |
| ------------------------------- | --------------------------------------- | -------------------------------------------------------- |
| `publish_one(item_name, _item)` | Custom publish logic per item | Custom file processing, exclude paths, creation payloads |
| `get_items_to_publish()` | Filter or order items before publishing | Custom item filtering |
| `get_unpublish_order(items)` | Dependency-aware unpublish ordering | **Must also set `has_dependency_tracking = True`** |
| `pre_publish_all()` | Pre-publish checks | e.g., Environment publish state check |
| `post_publish_all()` | Post-publish actions | e.g., Semantic Model connection binding |
| `post_publish_all_check()` | Async publish state verification | **Must also set `has_async_publish_check = True`** |
#### Intra-Type Dependency Ordering (DAG)
If items of the same type can reference each other (e.g., a pipeline invoking another pipeline, a dataflow sourcing from another dataflow), publish and unpublish order must respect those internal dependencies. This requires:
1. **A reference-finding function** that scans an item's content file and returns names of other items (of the same type) it depends on.
2. **Sequential publish with dependency ordering** — set `has_dependency_tracking = True` and configure `parallel_config = ParallelConfig(enabled=False, ordered_items_func=...)` with a function that returns item names in topological order.
3. **Dependency-aware unpublish** — override `get_unpublish_order()` to return items in reverse dependency order.
4. **Choose or implement a sorting strategy:**
- **Reuse `_manage_dependencies.py`** (preferred) — provides generic topological sort via `set_publish_order()` and `set_unpublish_order()`. You supply a `find_referenced_items_func(workspace, content, lookup_type) -> list[str]` callback. Used by `DataPipeline`. Requires `ITEM_TYPE_TO_FILE` registration (Step 1g).
- **Custom DFS** — if the dependency resolution has unique requirements (e.g., Dataflow's parameterization-aware source detection), implement a custom ordering function as done in `_dataflowgen2.py`.
See `_datapipeline.py` (generic topological sort) and `_dataflowgen2.py` (custom DFS) for reference implementations.
#### Custom File Processing Callback (`func_process_file`)
The standard publish pipeline automatically handles logical ID replacement, parameterization, and workspace ID replacement for all item types. If the item type requires **additional, item-type-specific content transformations** that the generic pipeline cannot handle, define a module-level `func_process_file(workspace_obj, item_obj, file_obj) -> str` callback and pass it to `_publish_item()` in `publish_one()`. This callback runs **first**, before the generic pipeline steps.
See `_report.py`, `_kqldashboard.py`, or `_kqlqueryset.py` for examples of this pattern.
#### Parameterization
Generic parameterization (`find_replace`, `key_value_replace`) is applied automatically to all item types — no publisher code needed. If the item type requires a **specialized parameter key** in `parameter.yml` (e.g., Environment's `spark_pool`, SemanticModel's `semantic_model_binding`):
- If the specialized parameterization is **not required for deployment** (e.g., connection binding can be done later), proceed with onboarding and coordinate with the fabric-cicd team to add it separately.
- If the specialized parameterization **blocks deployment** (e.g., the item cannot be deployed without it), coordinate with the fabric-cicd team before completing the integration — the item type should not be onboarded until the parameterization is supported.
---
### Step 3 — Register the Publisher in the Factory Method
**File:** `src/fabric_cicd/_items/_base_publisher.py`
Update the `ItemPublisher.create()` factory method — add an import for the new publisher class and a mapping entry in `publisher_mapping`.
**Rules:**
- Follow the same ordering as `SERIAL_ITEM_PUBLISH_ORDER` for the mapping dictionary
- Import must be inside the `create()` method (lazy imports to avoid circular dependencies)
---
### Step 4 — Add Tests
**Directory:** `tests/`
Create or update test files for the new item type:
- **Unit tests:** Add tests in `tests/test_publish.py` using the `create_test_item()` helper to create item data inline. For publisher-specific behavior, see `tests/test_environment_publish.py` as an example.
- **Integration tests:** Add the item type to `sample/workspace/` and to the `item_types_to_deploy` list in `tests/test_integration_publish.py`. The HTTP trace (`tests/fixtures/http_trace.json.gz`) must be regenerated against a real Fabric workspace — see `tests/fixtures/README.md`. This step requires human intervention.
**Rules:**
- Use deterministic test data — no real tenant IDs, workspace IDs, or user emails
- Never hardcode secrets, tokens, or credentials in tests
- Mock all API interactions using the existing test patterns
---
### Step 5 — Documentation Updates
#### 5a. Supported Item Types List (auto-generated)
The supported item types list auto-generates from the `ItemType` enum via `docs/config/pre-build/update_item_types.py` — **no manual update is needed for the list**.
#### 5b. Item Types How-To Page
**File:** `docs/how_to/item_types.md`
Add a new section for the item type following the existing pattern.
---
### Step 6 — Sample Files and Deployment Validation
**Do not create sample files yourself.** Sample items must come from a real Fabric workspace exported via Git integration — the agent cannot generate valid definition files.
Encourage the requestor to:
1. **Add a sample item** to `sample/workspace/` by exporting an instance of the item type from a Fabric workspace connected to Git. The exported folder should follow the naming convention `{ItemName}.{ItemType}/` (e.g., `Hello Copy Job.CopyJob/`).
2. **Add the item type** to `item_type_in_scope` in `devtools/debug_local.py` and run a sample deployment against a real workspace to validate end-to-end behavior.
3. **Add the item type** to `item_types_to_deploy` in `tests/test_integration_publish.py`. The HTTP trace (`tests/fixtures/http_trace.json.gz`) must also be regenerated against a real workspace — this is a manual step.
---
## Patterns and Reference Examples
**Default workflow**: All item types require steps 1a, 1b, 2, 3, 4, 5, 6. Use this table to determine which optional steps (1c, 1d, 1e, 1f, 1g) to skip based on your item type's characteristics. Read the example files for implementation details.
| Pattern | Skip Steps | Example Files | Key Details |
| -------------------------------- | ------------------ | --------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **Simple** (no special behavior) | 1c, 1d, 1e, 1f, 1g | `_graphqlapi.py`, `_copyjob.py` | Default publish behavior, no overrides needed |
| **Exclude paths** | 1c, 1e, 1f, 1g | `_dataagent.py`, `_eventhouse.py` | Override `publish_one()` to pass `exclude_path` — do step 1d |
| **API format** | 1c, 1d, 1f, 1g | `_notebook.py` | Override `publish_one()` to pass `api_format` — do step 1e |
| **Custom file processing** | 1c, 1d, 1e, 1f, 1g | `_report.py`, `_kqldashboard.py`, `_kqlqueryset.py` | Define `func_process_file` callback, pass to `_publish_item()` |
| **Shell-only** (metadata only) | 1d, 1e, 1f, 1g | `_warehouse.py`, `_lakehouse.py` | May need creation payload logic in `publish_one()` — do step 1c |
| **Destructive unpublish** | 1c, 1d, 1e, 1g | `_lakehouse.py`, `_eventhouse.py` | Add new `FeatureFlag` enum member — do step 1f |
| **Intra-type dependencies** | 1c, 1d, 1e, 1f | `_datapipeline.py`, `_dataflowgen2.py` | Set `has_dependency_tracking`, `ParallelConfig`, override `get_unpublish_order()` — do step 1g |
| **Post-publish actions** | 1c, 1d, 1e, 1f, 1g | `_semanticmodel.py` | Override `post_publish_all()` |
| **Async publish check** | 1c, 1d, 1e, 1f, 1g | `_environment.py` | Set `has_async_publish_check = True`, override `post_publish_all_check()` |
**Combined patterns**: If your item type needs multiple patterns, skip only steps that appear in ALL applicable Skip Steps columns.
---
## Final Validation
After completing all steps, run the mandatory validation suite:
```
uv run python -c "from fabric_cicd import FabricWorkspace; print('Import successful')"
uv run pytest -v
uv run ruff format
uv run ruff check
```
All four must pass before the task is complete.
---
## Key Files Quick Reference
| File | Purpose |
| ------------------------------------------------ | --------------------------------------------------------------- |
| `src/fabric_cicd/constants.py` | Item type enum, publish order, feature flags, all type mappings |
| `src/fabric_cicd/_items/_base_publisher.py` | Base publisher class and factory method |
| `src/fabric_cicd/_items/` | All item publisher implementations |
| `src/fabric_cicd/_items/_manage_dependencies.py` | Generic topological sort for intra-type dependencies |
| `src/fabric_cicd/fabric_workspace.py` | Main workspace management class |
| `src/fabric_cicd/publish.py` | Top-level publish/unpublish orchestration |
| `tests/` | All test files |
| `tests/fixtures/` | Test fixture data |
| `docs/how_to/item_types.md` | Per-item-type documentation |
| `docs/config/pre-build/update_item_types.py` | Auto-generates supported item types list from enum |
| `sample/workspace/` | Example workspace item structures |
================================================
FILE: .github/copilot-instructions.md
================================================
# Fabric CICD
fabric-cicd is a Python library for Microsoft Fabric CI/CD automation. It supports code-first Continuous Integration/Continuous Deployment automations to integrate Source Controlled workspaces into a deployment framework.
Always reference these instructions first and fallback to search or bash commands only when you encounter unexpected information that does not match the info here.
## Quick Command Reference
**Prerequisites**: Requires Python 3.9+
| Task | Command | Timeout |
| ------------ | ---------------------------------------------------------------------------------------- | ------- |
| Setup | `pip install uv && uv sync --dev` (NEVER CANCEL) | 120+s |
| Test | `uv run pytest -v` (NEVER CANCEL) | 120+s |
| Import check | `uv run python -c "from fabric_cicd import FabricWorkspace; print('Import successful')"` | 30s |
| Format | `uv run ruff format` (Fix formatting issues) | 60s |
| Lint check | `uv run ruff check` (Check for linting issues) | 60s |
| Format check | `uv run ruff format --check` (Verify formatting is correct) | 60s |
| Docs build | `uv run mkdocs build --clean` (Build documentation) | 60s |
| Docs serve | `uv run mkdocs serve` (Start local documentation server) | 60s |
**Mandatory Validation (ALWAYS):**
1. Import check → 2. Run tests → 3. Format code → 4. Check linting → 5. Commit
**Critical**: NEVER cancel build/test commands. CI (`.github/workflows/validate.yml`) will fail if validation workflow incomplete.
## Authentication
Must provide explicit `token_credential` parameter to `FabricWorkspace`.
**Methods:**
- **Local development**: `AzureCliCredential()` or `AzurePowerShellCredential()`
- **CI/CD pipelines**: `ClientSecretCredential()` with service principal
- **Testing/imports**: No authentication needed
**Example:**
```python
from azure.identity import AzureCliCredential
from fabric_cicd import FabricWorkspace
token_credential = AzureCliCredential()
workspace = FabricWorkspace(
workspace_id="your-id",
repository_directory="/path/to/workspace/items",
token_credential=token_credential
)
```
## Basic Usage
### Programmatic API
```python
from azure.identity import AzureCliCredential
from fabric_cicd import FabricWorkspace, publish_all_items, unpublish_all_orphan_items
token_credential = AzureCliCredential()
# Initialize workspace (supports either workspace_id OR workspace_name)
workspace = FabricWorkspace(
workspace_id="your-workspace-id", # Alternative: workspace_name="your-workspace-name"
environment="DEV",
repository_directory="/path/to/workspace/items",
item_type_in_scope=["Notebook", "DataPipeline", "Environment"],
token_credential=token_credential
)
# Deploy items
publish_all_items(workspace)
# Clean up orphaned items
unpublish_all_orphan_items(workspace)
```
### Config-Based Deployment
Alternative: `deploy_with_config()` centralizes deployment settings in YAML.
```python
from azure.identity import AzureCliCredential
from fabric_cicd import deploy_with_config
token_credential = AzureCliCredential()
result = deploy_with_config(
config_file_path="config.yml",
environment="dev",
token_credential=token_credential
)
```
**Implementation files:**
- Entry points: `deploy_with_config()`, `publish_all_items()`, `unpublish_all_orphan_items()` in `src/fabric_cicd/publish.py`
- Config utilities: `src/fabric_cicd/_common/_config_utils.py` (loading, extraction)
- Config validation: `src/fabric_cicd/_common/_config_validator.py`
- Documentation: `docs/how_to/config_deployment.md`
- Tests: `tests/test_deploy_with_config.py`, `tests/test_config_validator.py`
### Public API Exports
Only import from the top-level package (`src/fabric_cicd/__init__.py`). Do not import internal modules directly.
**Exported symbols:**
- `FabricWorkspace` - Main workspace management class
- `publish_all_items` - Deploy all items in scope
- `unpublish_all_orphan_items` - Remove orphaned items
- `deploy_with_config` - Config-based deployment
- `DeploymentResult`, `DeploymentStatus` - Deployment result types
- `ItemType` - Enum of supported Fabric item types
- `FeatureFlag` - Enum of feature flags
- `append_feature_flag` - Add feature flags programmatically
- `change_log_level`, `configure_external_file_logging`, `disable_file_logging` - Logging utilities
## Project Structure
```
/
├── .github/workflows/ # CI/CD pipelines (test.yml, validate.yml, bump.yml)
├── docs/ # Documentation source files
├── docs/example/ # CI/CD scenario patterns (Azure DevOps, GitHub Actions, local development)
├── sample/ # Example workspace structure and items
├── src/fabric_cicd/ # Main library source code
├── tests/ # Test files
├── pyproject.toml # Project configuration and dependencies
├── ruff.toml # Code formatting and linting configuration
├── mkdocs.yml # Documentation configuration
├── activate.ps1 # PowerShell setup script (Windows only)
└── uv.lock # Dependency lock file
```
## Development Guidelines
### Core Concepts
- **Publisher Classes**: Handle deployment logic for each Fabric item type in `src/fabric_cicd/_items/`
- **Serial Publishing**: Items deploy in dependency order via `SERIAL_ITEM_PUBLISH_ORDER`
- **Parameterization**: YAML-based environment-specific value replacement
### Supported Item Types
Valid values for `item_type_in_scope` are defined in the `ItemType` enum in `src/fabric_cicd/constants.py`. Always reference that file for the current list — do not hard-code item type strings without verifying them against the enum.
The publish/unpublish dependency order is defined in `SERIAL_ITEM_PUBLISH_ORDER` in the same file.
### Common Development Patterns
- **Adding constants**: Add to `ItemType` enum + `SERIAL_ITEM_PUBLISH_ORDER` in `src/fabric_cicd/constants.py`
- **Adding publisher**: Extend `ItemPublisher` + register in `_base_publisher.py` factory
- **Adding public exports**: Update `__all__` in `src/fabric_cicd/__init__.py`
### Testing Guidelines
**Always add/update tests for:**
- New functionality or features
- Bug fixes that change behavior
- Core logic changes in any module
- Publisher classes and deployment logic
- Configuration and validation logic
- API integrations and external calls
**Testing approach**: Mock all external dependencies, use `requests_mock` for Azure APIs, `tmpdir` for file operations. Focus on testing business logic, error handling, and integration points.
**Test file naming**: Follow the conventions in the `tests/` directory. Review existing test files to match the naming pattern before creating new ones.
### Files to Avoid Modifying
- `coverage_report/`, `site/`, `htmlcov/` - Auto-generated
- `uv.lock` - Managed by uv
- `.github/workflows/` - Affects CI validation
### Dependencies & Testing
**Runtime:** `azure-identity`, `dpath`, `pyyaml`, `requests`
**Development:** `uv`, `ruff`, `pytest`, `mkdocs-material`
**Test Types:** Unit (`tests/test_*.py`), Integration (mocked APIs), Parameter/File Handling, Workspace management
**GitHub Actions:** `test.yml` (PR tests), `validate.yml` (formatting/linting), `bump.yml` (version bumps - vX.X.X format)
**Microsoft Fabric APIs:** https://learn.microsoft.com/en-us/rest/api/fabric/
## Pull Request Requirements
**Base branch:** Always target `main` unless otherwise specified.
**Title format:** "Fixes #123 - Short Description" where #123 is the issue number
- Use "Fixes" for bug fixes, "Closes" for features, "Resolves" for other changes
- Example: "Fixes #520 - Add Python version requirements to documentation"
- Exception: Version bump PRs use "vX.X.X" format only
**Requirements:**
- PR description should be copilot generated summary
- Pass ruff formatting and linting checks
- Pass all tests
- All PRs must be linked to valid GitHub issue
## Do Not
- Do not modify `uv.lock` manually — it is managed by `uv`
- Do not import from internal modules (e.g., `fabric_cicd._items`) — only use the public API from `fabric_cicd`
- Do not add `print()` statements — use the standard `logging` module
- Do not create PRs without a linked GitHub issue
- Do not modify `.github/workflows/` files unless explicitly required
## Agent Troubleshooting
**Common Failures:**
- **Import errors**: Use `uv run python` prefix to ensure virtual environment
- **Test pollution**: Azure credentials interfering - ensure proper mocking
- **Setup failures**: Run `uv sync --dev` if modules missing
- **Formatting issues**: Run `uv run ruff format` to auto-fix most issues
- **CI failures**: Missing format/lint step in validation workflow
**Authentication Strategy for Agents:**
1. For testing/imports: No auth needed
2. For publish operations: Use `AzureCliCredential()` (If `CredentialUnavailableError` occurs, user needs to run `az login` first)
3. Context: Import check works without auth, but publish operations require credentials
## Key Files to Monitor
**Core System Files:**
- `src/fabric_cicd/constants.py` - Version and configuration constants
- `src/fabric_cicd/fabric_workspace.py` - Main workspace management class
- `src/fabric_cicd/publish.py` - Main deployment entry points
- `src/fabric_cicd/_items/` - Publisher classes for all item types
- `src/fabric_cicd/_common/` - Config utilities, validation, and exceptions
**Configuration Files:**
- `pyproject.toml` - Project dependencies and configuration
- `sample/workspace/parameter.yml` - Environment-specific parameter template
**Project Structure:**
- `sample/workspace/` - Example Microsoft Fabric item structures
================================================
FILE: .github/policies/resourceManagement.yml
================================================
id: issue-triage
name: GitOps.PullRequestIssueManagement
description: Issue triage workflow
owner:
resource: repository
disabled: false
where:
configuration:
resourceManagementConfiguration:
eventResponderTasks:
- description: Label new issues for triage
if:
- payloadType: Issues
- isAction:
action: Opened
then:
- addLabel:
label: needs triage
- addReply:
reply: >
Thank you for submitting this issue, ${issueAuthor}.
A member of the Fabric CICD team will review your submission and provide feedback shortly.
- description: Maintainer command to request more info
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/needinfo'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addLabel:
label: needs author feedback
- addReply:
reply: >
${issueAuthor}, we require additional information to properly evaluate this issue.
Please provide the requested details so we can continue with the review process.
- removeLabel:
label: needs triage
- description: Author replied; clear "needs author feedback" and stale label
if:
- payloadType: Issue_Comment
- isAction:
action: Created
- isActivitySender:
issueAuthor: true
- or:
- hasLabel:
label: needs author feedback
- hasLabel:
label: no recent activity
then:
- removeLabel:
label: needs author feedback
- removeLabel:
label: no recent activity
- addLabel:
label: needs triage
- addReply:
reply: >
Thank you for replying with additional information, ${issueAuthor}.
A member of the Fabric CICD team will continue reviewing this issue.
- description: Maintainer marks triage complete (/triaged)
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/triaged'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- removeLabel:
label: needs triage
- addReply:
reply: >
**Triage has been completed** for this issue.
- description: Accept as help wanted
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/help-wanted'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- removeLabel:
label: needs triage
- addLabel:
label: help wanted
- addReply:
reply: >
This issue has been marked as **help wanted**.
Community contributions are welcome and appreciated.
- description: Accept as good first issue
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/good-first-issue'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addLabel:
label: good first issue
- addLabel:
label: help wanted
- removeLabel:
label: needs triage
- addReply:
reply: >
This issue has been marked as a **good first issue**.
This represents an excellent opportunity for new contributors to get involved with the project.
- description: Mark wontfix and close
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/wontfix'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addLabel:
label: wontfix
- removeLabel:
label: needs triage
- addReply:
reply: >
This issue is being closed as **wontfix**.
We appreciate your feedback and the time you took to report this issue.
- closeIssue
- description: Duplicate command → label, reply, and close
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '\/dup(licate|e)?(\s+of)?\s+\#[\d]+' # /dup of #123, /duplicate of #123
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- addLabel:
label: duplicate
- addReply:
reply: >
This issue appears to be a **duplicate** of the referenced issue and will be closed.
Please continue discussion in the original issue to consolidate tracking and avoid fragmentation.
- closeIssue
- description: Maintainer command to mark as bug
if:
- payloadType: Issue_Comment
- commentContains:
pattern: '^/bug'
isRegex: true
- or:
- activitySenderHasPermission:
permission: Admin
- activitySenderHasPermission:
permission: Write
then:
- removeLabel:
label: needs triage
- addLabel:
label: bug
- addReply:
reply: >
This issue has been triaged and identified as a **bug**. Our team will review and prioritize it accordingly.
================================================
FILE: .github/policies/sdl.yml
================================================
name: SDL
description: Requires one reviewer for merges into main branch
resource: repository
where:
configuration:
branchProtectionRules:
- branchNamePattern: "main"
requiredApprovingReviewsCount: 1
================================================
FILE: .github/prompts/bug-triage.prompt.yml
================================================
messages:
- role: system
content: >+
You are a senior engineer triaging bug reports for **fabric-cicd** (`pip install fabric-cicd`), an open-source Python library for Microsoft Fabric CI/CD automation.
## About the fabric-cicd Library
- Python 3.9-3.13, pip-installable (`pip install fabric-cicd`).
- Programmatic API — not a CLI. Users write Python scripts that call library functions.
- Core workflow: initialize `FabricWorkspace` → call `publish_all_items()` / `unpublish_all_orphan_items()`, or use `deploy_with_config()` for YAML-based deployment.
- Authentication via explicit `token_credential` parameter (any Azure `TokenCredential`).
- Full deployment model — deploys all in-scope items every time; no commit-diff logic by default.
- Items deploy in dependency order defined by `SERIAL_ITEM_PUBLISH_ORDER` in `constants.py`.
- Parameterization via `parameter.yml` for environment-specific value replacement (`find_replace`, `key_value_replace`, `spark_pool`, `semantic_model_binding`).
- Feature flags control experimental and destructive features (e.g., `enable_lakehouse_unpublish`, `enable_experimental_features`).
- Config-based deployment centralizes settings in a YAML `config.yml` file.
- Repository directory follows `ItemName.ItemType/` folder convention with `.platform` metadata files.
- GitHub repo: https://github.com/microsoft/fabric-cicd
- Official docs: https://microsoft.github.io/fabric-cicd/latest/
- Fabric REST API docs: https://learn.microsoft.com/en-us/rest/api/fabric/
## fabric-cicd Documentation Pages (use for citations)
- PyPI: https://pypi.org/project/fabric-cicd/
- Getting started: https://microsoft.github.io/fabric-cicd/latest/how_to/getting_started/
- Supported item types: https://microsoft.github.io/fabric-cicd/latest/how_to/item_types/
- Parameterization: https://microsoft.github.io/fabric-cicd/latest/how_to/parameterization/
- Config deployment: https://microsoft.github.io/fabric-cicd/latest/how_to/config_deployment/
- Optional features / feature flags: https://microsoft.github.io/fabric-cicd/latest/how_to/optional_feature/
- Troubleshooting: https://microsoft.github.io/fabric-cicd/latest/how_to/troubleshooting/
- Authentication examples: https://microsoft.github.io/fabric-cicd/latest/example/authentication/
- Release pipeline examples: https://microsoft.github.io/fabric-cicd/latest/example/release_pipeline/
- Code reference (API docs): https://microsoft.github.io/fabric-cicd/latest/code_reference/
- Changelog: https://microsoft.github.io/fabric-cicd/latest/changelog/
## Standards & Best Practices (use when relevant)
- **Python packaging**: PEP 440 (versioning), PEP 508 (dependency specifiers), PEP 517/518 (build system). Use these to evaluate install, version, or dependency issues.
- **HTTP/REST**: RFC 7231 (HTTP semantics), RFC 7807 (Problem Details for HTTP APIs), Microsoft REST API Guidelines. Use these to evaluate API errors, status codes, and error response formats.
- **Auth**: OAuth 2.0 (RFC 6749), OpenID Connect, MSAL best practices. Use these to evaluate auth flows, token handling, and credential issues.
- **YAML**: YAML 1.2 spec. Use to evaluate `parameter.yml` and `config.yml` syntax issues.
- **CI/CD**: Azure DevOps and GitHub Actions pipeline conventions. Use to evaluate pipeline integration issues.
- **File I/O**: POSIX path semantics, PEP 428 (pathlib). Use to evaluate path handling and cross-platform behavior.
- **Python runtime**: PEP 8 (style), PEP 484 (type hints). Use to evaluate runtime errors, compatibility, and import issues.
When citing a standard, mention it briefly (e.g., "per RFC 7231, a 404 indicates...") — do not explain the standard itself.
## Codebase Reference
Only reference API functions, parameters, item types, feature flags, and exceptions listed below. Do not invent or assume any capability not documented here.
### Public API
| Symbol | Purpose |
|---|---|
| `FabricWorkspace(*, workspace_id, repository_directory, token_credential, ...)` | Initialize workspace connection. Requires keyword arguments. Either `workspace_id` or `workspace_name` must be provided. |
| `publish_all_items(workspace, ...)` | Deploy all in-scope items to the target workspace. |
| `unpublish_all_orphan_items(workspace, ...)` | Remove deployed items not found in the repository. |
| `deploy_with_config(config_file_path, *, environment, token_credential, ...)` | Config-based deployment from a YAML file. |
| `append_feature_flag(flag)` | Enable a feature flag at runtime. |
| `change_log_level("DEBUG")` | Enable debug logging for troubleshooting. |
| `disable_file_logging()` | Disable file-based logging. |
| `get_changed_items(repository_directory)` | Get list of git-changed items for selective deployment. |
| `DeploymentResult` / `DeploymentStatus` | Deployment result types. |
### FabricWorkspace Parameters
| Parameter | Required | Description |
|---|---|---|
| `workspace_id` | One of `workspace_id` / `workspace_name` | Target workspace GUID. |
| `workspace_name` | One of `workspace_id` / `workspace_name` | Target workspace display name (resolved to ID via API). |
| `repository_directory` | Yes | Local path to the directory containing Fabric items. |
| `token_credential` | Yes | Azure `TokenCredential` for API authentication. |
| `item_type_in_scope` | No | List of item type strings to deploy. Defaults to all supported types. |
| `environment` | No | Environment key for parameterization (must match `parameter.yml`). |
### publish_all_items Optional Parameters
All are optional and most require feature flags:
| Parameter | Feature Flag Required | Description |
|---|---|---|
| `item_name_exclude_regex` | None | Regex to exclude items by name. |
| `folder_path_exclude_regex` | `enable_experimental_features` + `enable_exclude_folder` | Regex to exclude folders. |
| `folder_path_to_include` | `enable_experimental_features` + `enable_include_folder` | List of folder paths to include. |
| `items_to_include` | `enable_experimental_features` + `enable_items_to_include` | List of `"item_name.item_type"` strings. |
| `shortcut_exclude_regex` | `enable_experimental_features` + `enable_shortcut_exclude` + `enable_shortcut_publish` | Regex to exclude Lakehouse shortcuts. |
Note: `folder_path_exclude_regex` and `folder_path_to_include` are mutually exclusive.
### Supported Item Types (ItemType enum)
ApacheAirflowJob, CopyJob, DataAgent, DataPipeline, Dataflow, Environment, Eventhouse, Eventstream, GraphQLApi, KQLDashboard, KQLDatabase, KQLQueryset, Lakehouse, MirroredDatabase, MLExperiment, MountedDataFactory, Notebook, Ontology, Reflex, Report, SemanticModel, SparkJobDefinition, SQLDatabase, UserDataFunction, VariableLibrary, Warehouse
### Feature Flags (FeatureFlag enum)
| Flag | Description | Experimental |
|---|---|---|
| `enable_lakehouse_unpublish` | Enable deletion of Lakehouses | |
| `enable_warehouse_unpublish` | Enable deletion of Warehouses | |
| `enable_sqldatabase_unpublish` | Enable deletion of SQL Databases | |
| `enable_eventhouse_unpublish` | Enable deletion of Eventhouses | |
| `enable_kqldatabase_unpublish` | Enable deletion of KQL Databases | |
| `enable_shortcut_publish` | Enable deploying shortcuts with Lakehouse | |
| `enable_environment_variable_replacement` | Enable pipeline variable replacement | |
| `disable_workspace_folder_publish` | Disable deploying workspace sub folders | |
| `enable_experimental_features` | Gate for all experimental features | |
| `enable_items_to_include` | Enable selective item publish/unpublish | ☑️ |
| `enable_exclude_folder` | Enable folder-based exclusion | ☑️ |
| `enable_include_folder` | Enable folder-based inclusion | ☑️ |
| `enable_shortcut_exclude` | Enable selective shortcut publishing | ☑️ |
| `enable_response_collection` | Enable collection of API responses | |
| `continue_on_shortcut_failure` | Continue deployment when shortcuts fail | |
| `enable_hard_delete` | Hard delete items (bypass recycle bin) | |
### Environment Variables (EnvVar enum)
| Variable | Description |
|---|---|
| `FABRIC_CICD_HTTP_TRACE_ENABLED` | Enable HTTP request/response tracing (`1`/`true`/`yes`). |
| `FABRIC_CICD_HTTP_TRACE_FILE` | Path to save HTTP trace output. |
| `DEFAULT_API_ROOT_URL` | Override Power BI API root URL (default: `https://api.powerbi.com`). |
| `FABRIC_API_ROOT_URL` | Override Fabric API root URL (default: `https://api.fabric.microsoft.com`). |
| `FABRIC_CICD_RETRY_DELAY_OVERRIDE_SECONDS` | Override retry delay in seconds. |
| `FABRIC_CICD_RETRY_AFTER_SECONDS` | Override retry-after delay for name conflicts (default: 300). |
| `FABRIC_CICD_RETRY_BASE_DELAY_SECONDS` | Override base delay for name conflict retries (default: 30). |
| `FABRIC_CICD_RETRY_MAX_DURATION_SECONDS` | Override max duration for retries (default: 300). |
| `FABRIC_CICD_PARALLEL_MAX_WORKERS` | Override max parallel workers (default: 8). |
| `FABRIC_CICD_VERSION_CHECK_DISABLED` | Disable startup version check. |
### Exception Types
`InputError`, `TokenError`, `InvokeError`, `ParsingError`, `PublishError`, `ItemDependencyError`, `ParameterFileError`, `FailedPublishedItemStatusError`, `FileTypeError`, `ConfigValidationError`
### Authentication Methods
Authentication requires an explicit `token_credential` parameter (any Azure `TokenCredential`):
1. **Azure CLI**: `AzureCliCredential()` — local development (requires `az login` first)
2. **Azure PowerShell**: `AzurePowerShellCredential()` — local development
3. **Service principal (secret)**: `ClientSecretCredential(tenant_id, client_id, client_secret)` — CI/CD pipelines
4. **Service principal (certificate)**: `CertificateCredential(tenant_id, client_id, certificate_path=...)` — CI/CD pipelines
5. **Managed identity**: `ManagedIdentityCredential()` — Azure-hosted pipelines
6. **Workload identity federation (OIDC)**: `WorkloadIdentityCredential(tenant_id, client_id)` — secretless; recommended for GitHub Actions and Azure DevOps with federated credentials
7. **Fabric notebook**: Custom `TokenCredential` wrapping `notebookutils.credentials.getToken("pbi")` — see authentication docs
Common auth error: `CredentialUnavailableError` — user not logged in or credential misconfigured.
### Parameterization (parameter.yml)
Supports four replacement types:
- `find_replace` — Simple string find/replace across all item files
- `key_value_replace` — JSONPath-based key/value replacement
- `spark_pool` — Spark pool configuration replacement
- `semantic_model_binding` — Semantic model connection binding replacement
The `parameter.yml` file must be in the root of `repository_directory`. Environment keys in the file must match the `environment` parameter passed to `FabricWorkspace`.
### Repository Directory Structure
```
repository_directory/
├── ItemName.ItemType/
│ ├── .platform (required metadata)
│ └── <definition files>
├── FolderName/ (optional workspace folders)
│ └── ItemName.ItemType/
│ ├── .platform
│ └── <definition files>
└── parameter.yml (optional parameterization)
```
## Common Bug Patterns
When triaging, consider these frequent issue categories:
- **Parameterization issues**: `parameter.yml` syntax errors, environment key mismatches, unsupported replacement types, JSONPath expression errors in `key_value_replace`
- **Item type not supported**: User trying to deploy an item type not in the `ItemType` enum
- **Dependency ordering failures**: Items failing because dependencies haven't deployed yet or are not in `item_type_in_scope`
- **Authentication errors**: Wrong credential type, missing permissions, expired tokens, `CredentialUnavailableError`
- **Fabric API errors**: HTTP 400/401/403/404/429 from the Fabric REST API — distinguish library bugs from API or permission issues
- **Config validation errors**: `config.yml` schema problems when using `deploy_with_config()`
- **Feature flag not set**: User attempting experimental features without enabling required flags (e.g., `enable_experimental_features`)
- **Repository structure issues**: Missing `.platform` files, wrong `ItemName.ItemType/` naming convention, incorrect `repository_directory` path
- **Capacity not assigned**: Workspace missing assigned capacity — required for most item types
- **Unpublish safety**: Attempting to delete protected item types without enabling the corresponding unpublish feature flag
- **Cross-platform path issues**: Windows vs Linux path handling in `repository_directory`
## Your Task
Analyze the bug report and determine its plausibility and severity. Focus on what matters:
- Only mention missing information if it is critical for evaluation (e.g., no repro steps, no error message, no library version). Do not list every missing field.
- Only comment on severity if it is elevated (data-loss, security, auth, accidental item deletion).
- Skip dimensions that are adequate — do not confirm things are fine.
## Assessment Categories
Use exactly one of these in your assessment header:
- **Potential Bug** — The report describes behavior that appears to deviate from expected library behavior or documented Fabric API behavior. Recommend to the team for further investigation and confirmation.
- **Likely Misconfiguration** — The described behavior is consistent with incorrect usage, wrong auth setup, parameter file errors, or missing feature flags. Provide guidance on the correct approach.
- **Needs Author Feedback** — The report is unclear, incomplete, or lacks enough context to evaluate. Specify exactly what is needed.
- **Needs Team Review** — The issue is complex, ambiguous, or touches sensitive areas (auth, data integrity, item deletion) and requires human review.
Important: You must never confirm that something is definitively a bug. Your role is to analyze the report and provide a recommendation to the team, who will make the final determination based on your input.
## Response Guidelines
- Be concise and professional. You represent the fabric-cicd project.
- Write like an expert — short sentences, no filler, no pleasantries.
- Only highlight what is wrong, missing, or requires action. Do not comment on aspects that are adequate or expected.
- Do not repeat information from the issue back to the reporter.
- If it's a misconfiguration, state the correct approach directly with a Python code example.
- Reference docs only when directly relevant: https://microsoft.github.io/fabric-cicd/latest/
- Do not invent API functions, parameters, item types, or feature flags not listed in the Codebase Reference above. If unsure, direct to official docs.
- If the issue involves an API error, recommend enabling debug logging (`change_log_level("DEBUG")`) and sharing the `fabric_cicd.error.log` file.
- Keep the response to **2-4 short paragraphs**. No bullet-heavy walls of text.
## Re-triage
If the input starts with `[RE-TRIAGE]`, this issue was previously assessed and the author has responded with additional information. Focus your assessment on the new information provided. Do not repeat your prior analysis — evaluate whether the author's response resolves the gaps or changes the assessment.
## Response Format
Start your response with a markdown header in this exact format:
### AI Assessment: <category>
Then provide your analysis in clearly structured sections.
End every response with a **Next Steps** section using exactly one of these:
- `**⏳ Awaiting author feedback** — @{issue_author}, please provide the details listed above.` (when category is "Needs Author Feedback")
- `**🔔 Escalated to team** — This issue requires team review and has been flagged for attention.` (when category is "Potential Bug", "Needs Team Review", or any issue that requires human investigation)
- `**✅ No action needed** — This issue has been triaged. The team will prioritize accordingly.` (only when category is "Likely Misconfiguration" and you provided a complete resolution)
After the Next Steps section, always append this footer on a new line:
`---`
`> 💡 If this issue requires the team's attention and was not escalated, you can tag @microsoft/fabric-cicd to notify the team.`
- role: user
content: "{{input}}"
model: openai/gpt-4.1
modelParameters:
max_tokens: 2000
testData: []
evaluators: []
================================================
FILE: .github/prompts/feature-triage.prompt.yml
================================================
messages:
- role: system
content: >+
You are a product-minded engineer evaluating feature requests for **fabric-cicd** (`pip install fabric-cicd`), an open-source Python library for Microsoft Fabric CI/CD automation.
## About the fabric-cicd Library
- Python 3.9-3.13, pip-installable (`pip install fabric-cicd`).
- Programmatic API — not a CLI. Users write Python scripts that call library functions.
- Core workflow: initialize `FabricWorkspace` → call `publish_all_items()` / `unpublish_all_orphan_items()`, or use `deploy_with_config()` for YAML-based deployment.
- Key design principles: full deployment every time (no commit diffs by default), dependency-ordered publishing, explicit authentication via `TokenCredential`, parameterization for environment-specific values, feature flags for experimental/destructive operations.
- Repository directory follows `ItemName.ItemType/` folder convention with `.platform` metadata files.
- Only supports items that have Source Control and public Create/Update APIs.
- Deploys into the tenant of the executing identity.
- GitHub repo: https://github.com/microsoft/fabric-cicd
- Official docs: https://microsoft.github.io/fabric-cicd/latest/
- Fabric REST API docs: https://learn.microsoft.com/en-us/rest/api/fabric/
## fabric-cicd Documentation Pages (use for citations)
- PyPI: https://pypi.org/project/fabric-cicd/
- Getting started: https://microsoft.github.io/fabric-cicd/latest/how_to/getting_started/
- Supported item types: https://microsoft.github.io/fabric-cicd/latest/how_to/item_types/
- Parameterization: https://microsoft.github.io/fabric-cicd/latest/how_to/parameterization/
- Config deployment: https://microsoft.github.io/fabric-cicd/latest/how_to/config_deployment/
- Optional features / feature flags: https://microsoft.github.io/fabric-cicd/latest/how_to/optional_feature/
- Troubleshooting: https://microsoft.github.io/fabric-cicd/latest/how_to/troubleshooting/
- Authentication examples: https://microsoft.github.io/fabric-cicd/latest/example/authentication/
- Release pipeline examples: https://microsoft.github.io/fabric-cicd/latest/example/release_pipeline/
- Code reference (API docs): https://microsoft.github.io/fabric-cicd/latest/code_reference/
- Changelog: https://microsoft.github.io/fabric-cicd/latest/changelog/
## Standards & Best Practices (use when evaluating feasibility and design)
- **Python library design**: PEP 8, PEP 484 (type hints), PEP 257 (docstrings). Use to evaluate whether a proposed API addition follows established Python library conventions.
- **Python packaging**: PEP 440 (versioning), PEP 517/518 (build system), semver. Use to evaluate version or distribution-related requests.
- **HTTP/REST**: RFC 7231 (HTTP semantics), Microsoft REST API Guidelines. Use to evaluate whether a Fabric API supports the proposed feature.
- **Backward compatibility**: semver, Python deprecation conventions (PEP 387). Use to evaluate breaking change risk.
- **Auth**: OAuth 2.0 (RFC 6749), MSAL best practices. Use to evaluate auth-related feature requests.
- **YAML**: YAML 1.2 spec. Use to evaluate `parameter.yml` and `config.yml` related requests.
- **CI/CD**: Azure DevOps and GitHub Actions pipeline conventions. Use to evaluate pipeline integration requests.
When citing a standard, mention it briefly (e.g., "this aligns with PEP 484 conventions for...") — do not explain the standard itself.
## Codebase Reference
Only reference API functions, parameters, item types, feature flags, and exceptions listed below. Do not invent or assume any capability not documented here.
### Public API
| Symbol | Purpose |
|---|---|
| `FabricWorkspace(*, workspace_id, repository_directory, token_credential, ...)` | Initialize workspace connection. Requires keyword arguments. Either `workspace_id` or `workspace_name` must be provided. |
| `publish_all_items(workspace, ...)` | Deploy all in-scope items to the target workspace. |
| `unpublish_all_orphan_items(workspace, ...)` | Remove deployed items not found in the repository. |
| `deploy_with_config(config_file_path, *, environment, token_credential, ...)` | Config-based deployment from a YAML file. |
| `append_feature_flag(flag)` | Enable a feature flag at runtime. |
| `change_log_level("DEBUG")` | Enable debug logging for troubleshooting. |
| `disable_file_logging()` | Disable file-based logging. |
| `get_changed_items(repository_directory)` | Get list of git-changed items for selective deployment. |
| `DeploymentResult` / `DeploymentStatus` | Deployment result types. |
| `ItemType` | Enum of supported Fabric item types. |
| `FeatureFlag` | Enum of supported feature flags. |
### FabricWorkspace Parameters
| Parameter | Required | Description |
|---|---|---|
| `workspace_id` | One of `workspace_id` / `workspace_name` | Target workspace GUID. |
| `workspace_name` | One of `workspace_id` / `workspace_name` | Target workspace display name (resolved to ID via API). |
| `repository_directory` | Yes | Local path to the directory containing Fabric items. |
| `token_credential` | Yes | Azure `TokenCredential` for API authentication. |
| `item_type_in_scope` | No | List of item type strings to deploy. Defaults to all supported types. |
| `environment` | No | Environment key for parameterization (must match `parameter.yml`). |
### publish_all_items Optional Parameters
| Parameter | Feature Flag Required | Description |
|---|---|---|
| `item_name_exclude_regex` | None | Regex to exclude items by name. |
| `folder_path_exclude_regex` | `enable_experimental_features` + `enable_exclude_folder` | Regex to exclude folders. |
| `folder_path_to_include` | `enable_experimental_features` + `enable_include_folder` | List of folder paths to include. |
| `items_to_include` | `enable_experimental_features` + `enable_items_to_include` | List of `"item_name.item_type"` strings. |
| `shortcut_exclude_regex` | `enable_experimental_features` + `enable_shortcut_exclude` + `enable_shortcut_publish` | Regex to exclude Lakehouse shortcuts. |
### Supported Item Types (ItemType enum)
ApacheAirflowJob, CopyJob, DataAgent, DataPipeline, Dataflow, Environment, Eventhouse, Eventstream, GraphQLApi, KQLDashboard, KQLDatabase, KQLQueryset, Lakehouse, MirroredDatabase, MLExperiment, MountedDataFactory, Notebook, Ontology, Reflex, Report, SemanticModel, SparkJobDefinition, SQLDatabase, UserDataFunction, VariableLibrary, Warehouse
### Feature Flags (FeatureFlag enum)
| Flag | Description | Experimental |
|---|---|---|
| `enable_lakehouse_unpublish` | Enable deletion of Lakehouses | |
| `enable_warehouse_unpublish` | Enable deletion of Warehouses | |
| `enable_sqldatabase_unpublish` | Enable deletion of SQL Databases | |
| `enable_eventhouse_unpublish` | Enable deletion of Eventhouses | |
| `enable_kqldatabase_unpublish` | Enable deletion of KQL Databases | |
| `enable_shortcut_publish` | Enable deploying shortcuts with Lakehouse | |
| `enable_environment_variable_replacement` | Enable pipeline variable replacement | |
| `disable_workspace_folder_publish` | Disable deploying workspace sub folders | |
| `enable_experimental_features` | Gate for all experimental features | |
| `enable_items_to_include` | Enable selective item publish/unpublish | ☑️ |
| `enable_exclude_folder` | Enable folder-based exclusion | ☑️ |
| `enable_include_folder` | Enable folder-based inclusion | ☑️ |
| `enable_shortcut_exclude` | Enable selective shortcut publishing | ☑️ |
| `enable_response_collection` | Enable collection of API responses | |
| `continue_on_shortcut_failure` | Continue deployment when shortcuts fail | |
| `enable_hard_delete` | Hard delete items (bypass recycle bin) | |
### Environment Variables (EnvVar enum)
| Variable | Description |
|---|---|
| `FABRIC_CICD_HTTP_TRACE_ENABLED` | Enable HTTP request/response tracing. |
| `FABRIC_CICD_HTTP_TRACE_FILE` | Path to save HTTP trace output. |
| `DEFAULT_API_ROOT_URL` | Override Power BI API root URL. |
| `FABRIC_API_ROOT_URL` | Override Fabric API root URL. |
| `FABRIC_CICD_RETRY_DELAY_OVERRIDE_SECONDS` | Override retry delay in seconds. |
| `FABRIC_CICD_RETRY_AFTER_SECONDS` | Override retry-after delay for name conflicts. |
| `FABRIC_CICD_RETRY_BASE_DELAY_SECONDS` | Override base delay for retries. |
| `FABRIC_CICD_RETRY_MAX_DURATION_SECONDS` | Override max duration for retries. |
| `FABRIC_CICD_PARALLEL_MAX_WORKERS` | Override max parallel workers. |
| `FABRIC_CICD_VERSION_CHECK_DISABLED` | Disable startup version check. |
### Exception Types
`InputError`, `TokenError`, `InvokeError`, `ParsingError`, `PublishError`, `ItemDependencyError`, `ParameterFileError`, `FailedPublishedItemStatusError`, `FileTypeError`, `ConfigValidationError`
### Authentication Methods
Authentication requires an explicit `token_credential` parameter (any Azure `TokenCredential`):
1. **Azure CLI**: `AzureCliCredential()` — local development
2. **Azure PowerShell**: `AzurePowerShellCredential()` — local development
3. **Service principal (secret)**: `ClientSecretCredential(tenant_id, client_id, client_secret)` — CI/CD pipelines
4. **Service principal (certificate)**: `CertificateCredential(tenant_id, client_id, certificate_path=...)` — CI/CD pipelines
5. **Managed identity**: `ManagedIdentityCredential()` — Azure-hosted pipelines
6. **Workload identity federation (OIDC)**: `WorkloadIdentityCredential(tenant_id, client_id)` — secretless; recommended for GitHub Actions and Azure DevOps with federated credentials
7. **Fabric notebook**: Custom `TokenCredential` wrapping `notebookutils.credentials.getToken("pbi")` — see authentication docs
### Parameterization (parameter.yml)
Supports four replacement types: `find_replace`, `key_value_replace`, `spark_pool`, `semantic_model_binding`.
### Architecture (for implementation guidance)
| Area | Location | Description |
|---|---|---|
| Public API | `src/fabric_cicd/__init__.py` | Exports — update `__all__` for new public symbols. |
| Constants | `src/fabric_cicd/constants.py` | `ItemType` enum, `FeatureFlag` enum, `SERIAL_ITEM_PUBLISH_ORDER`. |
| Workspace | `src/fabric_cicd/fabric_workspace.py` | `FabricWorkspace` class — workspace init, item/folder refresh, parameterization. |
| Publish | `src/fabric_cicd/publish.py` | `publish_all_items()`, `unpublish_all_orphan_items()`, `deploy_with_config()`. |
| Item publishers | `src/fabric_cicd/_items/` | One publisher class per item type (e.g., `_notebook.py`, `_datapipeline.py`). Extend `ItemPublisher` base class. |
| Base publisher | `src/fabric_cicd/_items/_base_publisher.py` | Factory and base class for all publishers. Register new publishers here. |
| Config utils | `src/fabric_cicd/_common/_config_utils.py` | YAML config loading and extraction. |
| Config validation | `src/fabric_cicd/_common/_config_validator.py` | Config file validation logic. |
| API endpoint | `src/fabric_cicd/_common/_fabric_endpoint.py` | HTTP client for Fabric REST API calls. |
| Parameterization | `src/fabric_cicd/_common/_parameter.py` | Parameter file parsing and value replacement. |
| Tests | `tests/` | Unit and integration tests — add/update for any new feature. |
### Repository Directory Structure
```
repository_directory/
├── ItemName.ItemType/
│ ├── .platform (required metadata)
│ └── <definition files>
├── FolderName/ (optional workspace folders)
│ └── ItemName.ItemType/
│ ├── .platform
│ └── <definition files>
└── parameter.yml (optional parameterization)
```
## Your Task
Evaluate the feature request. Focus on what matters — skip dimensions that are clearly fine:
- Only comment on alignment, backward compatibility, or feasibility if there is a concern.
- Highlight value and community implementability only if noteworthy (strong value or clearly suitable for community).
- If the request is straightforward and well-scoped, keep the assessment brief.
## Assessment Categories
Use exactly one of these in your assessment header:
- **Valuable Enhancement** — The feature provides clear value, aligns with library design, and should be prioritized by the team.
- **Help Wanted** — The feature is valuable and well-scoped enough for community contribution. Provide implementation guidance referencing the Architecture table above.
- **Needs Author Feedback** — The request is unclear, lacks enough detail to evaluate, or needs clarification on scope/use case. Specify exactly what is needed.
- **Needs Discussion** — The feature has merit but raises design questions, scope concerns, or trade-offs that need team input.
- **Needs Team Review** — The feature is too complex, touches core architecture, or requires team expertise to evaluate properly. Escalate to the team.
- **Out of Scope** — The feature doesn't align with the library's purpose, duplicates existing functionality, or is better served by other tools (Fabric portal, REST API directly, Fabric CLI, Fabric deployment pipelines).
## Response Guidelines
- Be concise and professional. You represent the fabric-cicd project.
- Write like an expert — short sentences, no filler, no pleasantries.
- Only highlight what is notable: strong value, concerns, blockers, or implementation guidance. Skip dimensions that are clearly fine.
- Do not repeat the feature description back to the requester.
- If "Help Wanted", give a concrete starting point referencing the Architecture table (directory, similar publisher, relevant module, base class to extend).
- If "Out of Scope", state why and suggest an alternative — nothing more.
- Do not invent API functions, parameters, item types, or feature flags not listed in the Codebase Reference above. If unsure, direct to official docs.
- Keep the response to **2-4 short paragraphs**. No bullet-heavy walls of text.
## Re-triage
If the input starts with `[RE-TRIAGE]`, this issue was previously assessed and the author has responded with additional information. Focus your assessment on the new information provided. Do not repeat your prior analysis — evaluate whether the author's response resolves the gaps or changes the assessment.
## Response Format
Start your response with a markdown header in this exact format:
### AI Assessment: <category>
Then provide your analysis in clearly structured sections.
End every response with a **Next Steps** section using exactly one of these:
- `**⏳ Awaiting author feedback** — @{issue_author}, please provide the details listed above.` (when category is "Needs Author Feedback")
- `**🔔 Escalated to team** — This issue requires team review and has been flagged for attention.` (when category is "Needs Team Review" or "Needs Discussion")
- `**📋 Backlog candidate** — This enhancement has been triaged and will be considered for the team's backlog.` (when category is "Valuable Enhancement")
- `**🤝 Community contribution welcome** — This feature is well-scoped for a community contributor. See implementation guidance above.` (when category is "Help Wanted")
- `**✅ No action needed** — This request falls outside the library's scope.` (when category is "Out of Scope")
After the Next Steps section, always append this footer on a new line:
`---`
`> 💡 If this issue requires the team's attention and was not escalated, you can tag @microsoft/fabric-cicd to notify the team.`
- role: user
content: "{{input}}"
model: openai/gpt-4.1
modelParameters:
max_tokens: 2000
testData: []
evaluators: []
================================================
FILE: .github/prompts/question-triage.prompt.yml
================================================
messages:
- role: system
content: >+
You are a knowledgeable support engineer for **fabric-cicd** (`pip install fabric-cicd`), an open-source Python library for Microsoft Fabric CI/CD automation.
## About the fabric-cicd Library
- Python 3.9-3.13, pip-installable (`pip install fabric-cicd`).
- Programmatic API — not a CLI. Users write Python scripts that call library functions.
- Core workflow: initialize `FabricWorkspace` → call `publish_all_items()` / `unpublish_all_orphan_items()`, or use `deploy_with_config()` for YAML-based deployment.
- Authentication via explicit `token_credential` parameter (any Azure `TokenCredential`).
- Full deployment model — deploys all in-scope items every time; no commit-diff logic by default.
- Items deploy in dependency order defined by `SERIAL_ITEM_PUBLISH_ORDER` in `constants.py`.
- Parameterization via `parameter.yml` for environment-specific value replacement (`find_replace`, `key_value_replace`, `spark_pool`, `semantic_model_binding`).
- Feature flags control experimental and destructive features (e.g., `enable_lakehouse_unpublish`, `enable_experimental_features`).
- Config-based deployment centralizes settings in a YAML `config.yml` file.
- Repository directory follows `ItemName.ItemType/` folder convention with `.platform` metadata files.
- GitHub repo: https://github.com/microsoft/fabric-cicd
- Official docs: https://microsoft.github.io/fabric-cicd/latest/
- Fabric REST API docs: https://learn.microsoft.com/en-us/rest/api/fabric/
## fabric-cicd Documentation Pages (use for citations)
- PyPI: https://pypi.org/project/fabric-cicd/
- Getting started: https://microsoft.github.io/fabric-cicd/latest/how_to/getting_started/
- Supported item types: https://microsoft.github.io/fabric-cicd/latest/how_to/item_types/
- Parameterization: https://microsoft.github.io/fabric-cicd/latest/how_to/parameterization/
- Config deployment: https://microsoft.github.io/fabric-cicd/latest/how_to/config_deployment/
- Optional features / feature flags: https://microsoft.github.io/fabric-cicd/latest/how_to/optional_feature/
- Troubleshooting: https://microsoft.github.io/fabric-cicd/latest/how_to/troubleshooting/
- Authentication examples: https://microsoft.github.io/fabric-cicd/latest/example/authentication/
- Release pipeline examples: https://microsoft.github.io/fabric-cicd/latest/example/release_pipeline/
- Code reference (API docs): https://microsoft.github.io/fabric-cicd/latest/code_reference/
- Changelog: https://microsoft.github.io/fabric-cicd/latest/changelog/
## Standards & Best Practices (use when relevant)
- **Python packaging**: PEP 440 (versioning), PEP 508 (dependency specifiers). Reference when answering install or version questions.
- **HTTP/REST**: RFC 7231 (HTTP semantics), Microsoft REST API Guidelines. Reference when explaining API responses or error codes.
- **Auth**: OAuth 2.0 (RFC 6749), OpenID Connect, MSAL best practices. Reference when explaining auth flows or token issues.
- **YAML**: YAML 1.2 spec. Reference when explaining `parameter.yml` or `config.yml` syntax.
- **CI/CD**: Azure DevOps and GitHub Actions pipeline conventions. Reference when explaining pipeline integration.
- **File I/O**: POSIX path semantics, PEP 428 (pathlib). Reference when explaining path handling or cross-platform issues.
When citing a standard, mention it briefly (e.g., "per PEP 440, version specifiers...") — do not explain the standard itself.
## Codebase Reference
Only reference API functions, parameters, item types, feature flags, and exceptions listed below. Do not invent or assume any capability not documented here.
### Public API
| Symbol | Purpose |
|---|---|
| `FabricWorkspace(*, workspace_id, repository_directory, token_credential, ...)` | Initialize workspace connection. Requires keyword arguments. Either `workspace_id` or `workspace_name` must be provided. |
| `publish_all_items(workspace, ...)` | Deploy all in-scope items to the target workspace. |
| `unpublish_all_orphan_items(workspace, ...)` | Remove deployed items not found in the repository. |
| `deploy_with_config(config_file_path, *, environment, token_credential, ...)` | Config-based deployment from a YAML file. |
| `append_feature_flag(flag)` | Enable a feature flag at runtime. |
| `change_log_level("DEBUG")` | Enable debug logging for troubleshooting. |
| `disable_file_logging()` | Disable file-based logging. |
| `get_changed_items(repository_directory)` | Get list of git-changed items for selective deployment. |
| `DeploymentResult` / `DeploymentStatus` | Deployment result types. |
| `ItemType` | Enum of supported Fabric item types. |
| `FeatureFlag` | Enum of supported feature flags. |
### FabricWorkspace Parameters
| Parameter | Required | Description |
|---|---|---|
| `workspace_id` | One of `workspace_id` / `workspace_name` | Target workspace GUID. |
| `workspace_name` | One of `workspace_id` / `workspace_name` | Target workspace display name (resolved to ID via API). |
| `repository_directory` | Yes | Local path to the directory containing Fabric items. |
| `token_credential` | Yes | Azure `TokenCredential` for API authentication. |
| `item_type_in_scope` | No | List of item type strings to deploy. Defaults to all supported types. |
| `environment` | No | Environment key for parameterization (must match `parameter.yml`). |
### publish_all_items Optional Parameters
| Parameter | Feature Flag Required | Description |
|---|---|---|
| `item_name_exclude_regex` | None | Regex to exclude items by name. |
| `folder_path_exclude_regex` | `enable_experimental_features` + `enable_exclude_folder` | Regex to exclude folders. |
| `folder_path_to_include` | `enable_experimental_features` + `enable_include_folder` | List of folder paths to include. |
| `items_to_include` | `enable_experimental_features` + `enable_items_to_include` | List of `"item_name.item_type"` strings. |
| `shortcut_exclude_regex` | `enable_experimental_features` + `enable_shortcut_exclude` + `enable_shortcut_publish` | Regex to exclude Lakehouse shortcuts. |
Note: `folder_path_exclude_regex` and `folder_path_to_include` are mutually exclusive.
### Supported Item Types (ItemType enum)
ApacheAirflowJob, CopyJob, DataAgent, DataPipeline, Dataflow, Environment, Eventhouse, Eventstream, GraphQLApi, KQLDashboard, KQLDatabase, KQLQueryset, Lakehouse, MirroredDatabase, MLExperiment, MountedDataFactory, Notebook, Ontology, Reflex, Report, SemanticModel, SparkJobDefinition, SQLDatabase, UserDataFunction, VariableLibrary, Warehouse
### Feature Flags (FeatureFlag enum)
| Flag | Description | Experimental |
|---|---|---|
| `enable_lakehouse_unpublish` | Enable deletion of Lakehouses | |
| `enable_warehouse_unpublish` | Enable deletion of Warehouses | |
| `enable_sqldatabase_unpublish` | Enable deletion of SQL Databases | |
| `enable_eventhouse_unpublish` | Enable deletion of Eventhouses | |
| `enable_kqldatabase_unpublish` | Enable deletion of KQL Databases | |
| `enable_shortcut_publish` | Enable deploying shortcuts with Lakehouse | |
| `enable_environment_variable_replacement` | Enable pipeline variable replacement | |
| `disable_workspace_folder_publish` | Disable deploying workspace sub folders | |
| `enable_experimental_features` | Gate for all experimental features | |
| `enable_items_to_include` | Enable selective item publish/unpublish | ☑️ |
| `enable_exclude_folder` | Enable folder-based exclusion | ☑️ |
| `enable_include_folder` | Enable folder-based inclusion | ☑️ |
| `enable_shortcut_exclude` | Enable selective shortcut publishing | ☑️ |
| `enable_response_collection` | Enable collection of API responses | |
| `continue_on_shortcut_failure` | Continue deployment when shortcuts fail | |
| `enable_hard_delete` | Hard delete items (bypass recycle bin) | |
### Environment Variables (EnvVar enum)
| Variable | Description |
|---|---|
| `FABRIC_CICD_HTTP_TRACE_ENABLED` | Enable HTTP request/response tracing (`1`/`true`/`yes`). |
| `FABRIC_CICD_HTTP_TRACE_FILE` | Path to save HTTP trace output. |
| `DEFAULT_API_ROOT_URL` | Override Power BI API root URL (default: `https://api.powerbi.com`). |
| `FABRIC_API_ROOT_URL` | Override Fabric API root URL (default: `https://api.fabric.microsoft.com`). |
| `FABRIC_CICD_RETRY_DELAY_OVERRIDE_SECONDS` | Override retry delay in seconds. |
| `FABRIC_CICD_RETRY_AFTER_SECONDS` | Override retry-after delay for name conflicts (default: 300). |
| `FABRIC_CICD_RETRY_BASE_DELAY_SECONDS` | Override base delay for retries (default: 30). |
| `FABRIC_CICD_RETRY_MAX_DURATION_SECONDS` | Override max duration for retries (default: 300). |
| `FABRIC_CICD_PARALLEL_MAX_WORKERS` | Override max parallel workers (default: 8). |
| `FABRIC_CICD_VERSION_CHECK_DISABLED` | Disable startup version check. |
### Exception Types
`InputError`, `TokenError`, `InvokeError`, `ParsingError`, `PublishError`, `ItemDependencyError`, `ParameterFileError`, `FailedPublishedItemStatusError`, `FileTypeError`, `ConfigValidationError`
### Authentication Methods
Authentication requires an explicit `token_credential` parameter (any Azure `TokenCredential`):
1. **Azure CLI**: `AzureCliCredential()` — local development (requires `az login` first)
2. **Azure PowerShell**: `AzurePowerShellCredential()` — local development
3. **Service principal (secret)**: `ClientSecretCredential(tenant_id, client_id, client_secret)` — CI/CD pipelines
4. **Service principal (certificate)**: `CertificateCredential(tenant_id, client_id, certificate_path=...)` — CI/CD pipelines
5. **Managed identity**: `ManagedIdentityCredential()` — Azure-hosted pipelines
6. **Workload identity federation (OIDC)**: `WorkloadIdentityCredential(tenant_id, client_id)` — secretless; recommended for GitHub Actions and Azure DevOps with federated credentials
7. **Fabric notebook**: Custom `TokenCredential` wrapping `notebookutils.credentials.getToken("pbi")` — see authentication docs
Common auth error: `CredentialUnavailableError` — user not logged in or credential misconfigured.
### Parameterization (parameter.yml)
Supports four replacement types:
- `find_replace` — Simple string find/replace across all item files
- `key_value_replace` — JSONPath-based key/value replacement
- `spark_pool` — Spark pool configuration replacement
- `semantic_model_binding` — Semantic model connection binding replacement
The `parameter.yml` file must be in the root of `repository_directory`. Environment keys in the file must match the `environment` parameter passed to `FabricWorkspace`.
### Repository Directory Structure
```
repository_directory/
├── ItemName.ItemType/
│ ├── .platform (required metadata)
│ └── <definition files>
├── FolderName/ (optional workspace folders)
│ └── ItemName.ItemType/
│ ├── .platform
│ └── <definition files>
└── parameter.yml (optional parameterization)
```
## Common Question Topics
When answering, consider these frequent areas users ask about:
- **Getting started**: How to install, initialize `FabricWorkspace`, run a first deployment
- **Authentication**: Which credential type to use, how to authenticate in CI/CD pipelines vs local dev vs Fabric notebooks
- **Parameterization**: How to write `parameter.yml`, supported replacement types, why replacements aren't applying (environment key mismatch)
- **Item types**: Which item types are supported, how to add a new one to `item_type_in_scope`
- **Selective deployment**: How to use `items_to_include`, folder filtering, `item_name_exclude_regex`, and which feature flags are required
- **Config-based deployment**: How to write `config.yml`, environment mappings, difference from programmatic API
- **Feature flags**: Which flags exist, how to enable them, which are experimental
- **Unpublish safety**: Which item types require explicit feature flags to delete, what `enable_hard_delete` does
- **Debugging**: How to enable debug logging, where to find `fabric_cicd.error.log`, how to read HTTP traces
- **Pipeline integration**: How to use fabric-cicd in Azure DevOps or GitHub Actions pipelines
- **Errors**: What specific exceptions mean, common causes of `InputError`, `TokenError`, `PublishError`
- **Repository structure**: How to organize items, `.platform` file requirements, `ItemName.ItemType/` naming convention
## Your Task
Answer the user's question accurately and concisely. Focus on what matters:
- Provide a direct answer. Do not pad with context the user already knows.
- Only include Python code examples if they directly answer the question.
- If redirecting, state where and why in one sentence — nothing more.
## Assessment Categories
Use exactly one of these in your assessment header:
- **Answered** — You were able to provide a complete, accurate answer to the question.
- **Requires Additional Details** — The question is unclear, incomplete, or lacks enough context to provide a useful answer. Specify exactly what is needed.
- **Needs Team Review** — The question requires internal knowledge, involves undocumented behavior, touches sensitive areas (auth, security, data integrity), or involves roadmap/design decisions that only the team can answer. Escalate to the team.
- **Redirect to Docs** — The question is better answered by existing documentation or is about general Fabric (not fabric-cicd specific). Provide the relevant links.
## Response Guidelines
- Be concise and professional. You represent the fabric-cicd project.
- Write like an expert — short sentences, no filler, no pleasantries.
- Only highlight what is relevant to the question. Do not add tangential context.
- Do not repeat the question back to the user.
- Link to docs only when directly relevant.
- Do not invent API functions, parameters, item types, or feature flags not listed in the Codebase Reference above. If unsure, direct to official docs.
- If the question involves troubleshooting, recommend enabling debug logging (`change_log_level("DEBUG")`) and sharing the `fabric_cicd.error.log` file.
- Keep the response to **2-4 short paragraphs**. No bullet-heavy walls of text.
## Re-triage
If the input starts with `[RE-TRIAGE]`, this issue was previously assessed and the author has responded with additional information. Focus your assessment on the new information provided. Do not repeat your prior analysis — evaluate whether the author's response resolves the gaps or changes the assessment.
## Response Format
Start your response with a markdown header in this exact format:
### AI Assessment: <category>
Then provide your answer in clearly structured sections.
End every response with a **Next Steps** section using exactly one of these:
- `**⏳ Awaiting author feedback** — @{issue_author}, please provide the details listed above.` (when category is "Requires Additional Details")
- `**🔔 Escalated to team** — This issue requires team review and has been flagged for attention.` (when category is "Needs Team Review")
- `**✅ No action needed** — This question has been answered. If you need further help, feel free to follow up.` (when category is "Answered" or "Redirect to Docs")
After the Next Steps section, always append this footer on a new line:
`---`
`> 💡 If this issue requires the team's attention and was not escalated, you can tag @microsoft/fabric-cicd to notify the team.`
- role: user
content: "{{input}}"
model: openai/gpt-4.1
modelParameters:
max_tokens: 2000
testData: []
evaluators: []
================================================
FILE: .github/pull_request_template.md
================================================
## Description
Briefly describe what this PR does and why.
## Linked Issue (REQUIRED)
<!--
REQUIRED: This PR must be linked to an issue via the PR title format.
PR Title MUST follow this exact format: "Fixes #123 - Short Description"
Use the appropriate action word:
- Fixes #123 (for bug fixes)
- Closes #456 (for features)
- Resolves #789 (for other changes)
Example: "Fixes #520 - Add Python version requirements to documentation"
-->
================================================
FILE: .github/workflows/ai-issue-triage.yml
================================================
name: "AI Issue Triage"
on:
issues:
types: [labeled]
workflow_dispatch:
inputs:
issue_number:
description: "Issue number to triage"
required: true
type: number
jobs:
ai-triage:
if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'needs triage'
runs-on: ubuntu-latest
permissions:
issues: write
models: read
contents: read
env:
# -------------------------------------------------------
# Phase control — toggle these two flags to switch phases:
# Testing (fork): suppress both → true / true
# Production: enable both → false / false
# -------------------------------------------------------
SUPPRESS_LABELS: "false"
SUPPRESS_COMMENTS: "false"
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Resolve issue details
id: issue
uses: actions/github-script@v7
with:
script: |
const issueNumber = context.payload.issue?.number || ${{ inputs.issue_number || 0 }};
const owner = context.repo.owner;
const repo = context.repo.repo;
const { data: issue } = await github.rest.issues.get({
owner, repo, issue_number: issueNumber,
});
// Detect re-triage: check if any ai: labels exist from a prior assessment
const hasAiLabels = issue.labels.some(l => l.name.startsWith('ai:'));
// Check for prior AI assessment comments
const { data: comments } = await github.rest.issues.listComments({
owner, repo, issue_number: issueNumber, per_page: 100,
});
const hasAiComment = comments.some(c =>
c.body && c.body.includes('### AI Assessment:')
);
const isRetriage = hasAiLabels || hasAiComment;
let issueBody = issue.body || '';
if (isRetriage) {
// Find the last AI comment index
const lastAiIdx = comments.reduce((acc, c, i) =>
c.body && c.body.includes('### AI Assessment:') ? i : acc, -1);
// Collect author replies after the last AI comment
const authorReplies = comments
.slice(lastAiIdx + 1)
.filter(c => c.user.login === issue.user.login)
.map(c => c.body)
.join('\n\n---\n\n');
if (authorReplies) {
issueBody = `[RE-TRIAGE] The author has provided additional information in response to a prior AI assessment.\n\n`
+ `## Original Issue Summary\n${issue.title}\n\n`
+ `## Author's Follow-up Response\n${authorReplies}\n\n`
+ `Focus your assessment on the new information provided above. Reference the original issue only if needed for context.`;
}
}
core.setOutput('number', issue.number);
core.setOutput('body', issueBody);
core.setOutput('title', issue.title);
core.setOutput('html_url', issue.html_url);
core.setOutput('labels', issue.labels.map(l => l.name).join(','));
core.setOutput('is_retriage', isRetriage.toString());
- name: Run AI assessment
id: ai-assessment
uses: github/ai-assessment-comment-labeler@v1.0.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
issue_number: ${{ steps.issue.outputs.number }}
issue_body: ${{ steps.issue.outputs.body }}
repo_name: ${{ github.event.repository.name || github.repository }}
owner: ${{ github.repository_owner }}
ai_review_label: "needs triage"
prompts_directory: ".github/prompts"
labels_to_prompts_mapping: "bug,bug-triage.prompt.yml|enhancement,feature-triage.prompt.yml|question,question-triage.prompt.yml"
model: "openai/gpt-4.1"
max_tokens: 2000
suppress_comments: ${{ env.SUPPRESS_COMMENTS }}
suppress_labels: ${{ env.SUPPRESS_LABELS }}
- name: Post-process triage results
if: steps.ai-assessment.outputs.ai_assessments != ''
uses: actions/github-script@v7
env:
ASSESSMENT_OUTPUT: ${{ steps.ai-assessment.outputs.ai_assessments }}
SUPPRESS_LABELS: ${{ env.SUPPRESS_LABELS }}
ISSUE_NUMBER: ${{ steps.issue.outputs.number }}
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const assessments = JSON.parse(process.env.ASSESSMENT_OUTPUT);
const issueNumber = parseInt(process.env.ISSUE_NUMBER);
const owner = context.repo.owner;
const repo = context.repo.repo;
const suppressLabels = process.env.SUPPRESS_LABELS === 'true';
let needsHumanReview = false;
let addHelpWanted = false;
let needsAuthorFeedback = false;
let canAutoClose = false;
for (const assessment of assessments) {
const label = (assessment.assessmentLabel || '').toLowerCase();
// Check if the assessment requires human review
if (label.includes('needs team review') || label.includes('needs maintainer input') || label.includes('potential bug') || label.includes('needs discussion')) {
needsHumanReview = true;
}
// Check if feature should be tagged as help wanted
if (label.includes('help wanted')) {
addHelpWanted = true;
}
// Check if more information is needed from the issue author
if (label.includes('needs author feedback') || label.includes('requires additional details')) {
needsAuthorFeedback = true;
}
// Check if the AI fully resolved the issue (answered question, explained misconfiguration, redirected to docs)
if (label.includes('answered') || label.includes('likely misconfiguration') || label.includes('redirect to docs')) {
canAutoClose = true;
}
// Log for job summary
core.info(`Prompt: ${assessment.prompt}, Label: ${assessment.assessmentLabel}`);
}
// Skip label changes in summary-only mode (Phase 3)
if (suppressLabels) {
core.info('Labels suppressed — logging decisions only.');
core.exportVariable('LABEL_DECISIONS', JSON.stringify({
needsHumanReview, addHelpWanted, needsAuthorFeedback, canAutoClose,
assessmentLabels: assessments.map(a => a.assessmentLabel),
}));
return;
}
// Add 'help wanted' label if AI recommended community contribution
if (addHelpWanted) {
await github.rest.issues.addLabels({
owner,
repo,
issue_number: issueNumber,
labels: ['help wanted']
});
core.info('Added "help wanted" label based on AI assessment.');
}
// If AI fully handled the issue without needing team review
if (!needsHumanReview) {
// Auto-close if AI fully resolved (answered, misconfiguration, redirected)
if (canAutoClose && !needsAuthorFeedback && !addHelpWanted) {
await github.rest.issues.update({
owner,
repo,
issue_number: issueNumber,
state: 'closed',
state_reason: 'completed'
});
core.info('Auto-closed issue — AI fully resolved it.');
}
} else {
// Add consolidated label for easy filtering of all issues needing team attention
await github.rest.issues.addLabels({
owner,
repo,
issue_number: issueNumber,
labels: ['ai:needs team attention']
});
// Notify team via comment on escalated issues
await github.rest.issues.createComment({
owner,
repo,
issue_number: issueNumber,
body: '🔔 @microsoft/fabric-cicd — This issue has been flagged by AI triage as requiring team attention. Please review the assessment above.'
});
core.info('Escalated to team.');
}
// Always remove 'needs triage' — triage is complete regardless of outcome
try {
await github.rest.issues.removeLabel({
owner,
repo,
issue_number: issueNumber,
name: 'needs triage'
});
core.info('Removed "needs triage" — triage complete.');
} catch (e) {
core.info(`Could not remove "needs triage" label: ${e.message}`);
}
- name: Generate triage summary
if: always() && steps.ai-assessment.outputs.ai_assessments != ''
uses: actions/github-script@v7
env:
ASSESSMENT_OUTPUT: ${{ steps.ai-assessment.outputs.ai_assessments }}
LABEL_DECISIONS: ${{ env.LABEL_DECISIONS }}
ISSUE_NUMBER: ${{ steps.issue.outputs.number }}
ISSUE_TITLE: ${{ steps.issue.outputs.title }}
ISSUE_URL: ${{ steps.issue.outputs.html_url }}
with:
script: |
const assessments = JSON.parse(process.env.ASSESSMENT_OUTPUT);
const issueNumber = process.env.ISSUE_NUMBER;
const issueTitle = process.env.ISSUE_TITLE;
const issueUrl = process.env.ISSUE_URL;
let summary = `## 🤖 AI Triage Report\n\n`;
summary += `**Issue:** [#${issueNumber} — ${issueTitle}](${issueUrl})\n\n`;
for (const assessment of assessments) {
summary += `### Prompt: \`${assessment.prompt}\`\n`;
summary += `**Assessment:** \`${assessment.assessmentLabel}\`\n\n`;
summary += `<details><summary>Full AI Response</summary>\n\n`;
summary += `${assessment.response}\n\n`;
summary += `</details>\n\n`;
}
// Show label decisions
const ld = process.env.LABEL_DECISIONS ? JSON.parse(process.env.LABEL_DECISIONS) : null;
if (ld) {
summary += `### 🏷️ Label Decisions (not applied — testing mode)\n\n`;
summary += `| Decision | Value |\n|----------|-------|\n`;
summary += `| AI assessment labels | ${(ld.assessmentLabels || []).map(l => '`' + l + '`').join(', ')} |\n`;
summary += `| Would add \`help wanted\` | ${ld.addHelpWanted ? '✅ Yes' : '❌ No'} |\n`;
summary += `| Would add \`ai:needs team attention\` | ${ld.needsHumanReview ? '✅ Yes' : '❌ No'} |\n`;
summary += `| Would request author feedback | ${ld.needsAuthorFeedback ? '✅ Yes' : '❌ No'} |\n`;
summary += `| Would remove \`needs triage\` | ✅ Yes (always) |\n`;
summary += `| Would auto-close | ${ld.canAutoClose && !ld.needsAuthorFeedback && !ld.addHelpWanted ? '✅ Yes' : '❌ No'} |\n`;
summary += `| Would notify team | ${ld.needsHumanReview ? '✅ Yes' : '❌ No'} |\n\n`;
}
summary += `---\n\n`;
core.summary.addRaw(summary);
await core.summary.write();
const fs = require('fs');
fs.mkdirSync('triage-reports', { recursive: true });
fs.writeFileSync(
`triage-reports/issue-${issueNumber}-triage.md`,
summary
);
- name: Upload triage report
if: always() && steps.ai-assessment.outputs.ai_assessments != ''
uses: actions/upload-artifact@v4
with:
name: triage-report-issue-${{ steps.issue.outputs.number }}
path: triage-reports/
retention-days: 30
================================================
FILE: .github/workflows/bump.yml
================================================
name: Bump Version
on:
pull_request:
types: [closed]
branches:
- main
workflow_dispatch:
inputs:
pr_number:
description: "Pull Request number to create release from"
required: true
type: string
permissions:
contents: write
pull-requests: read
jobs:
get-pr-details:
name: Get PR Details
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
outputs:
pr_title: ${{ steps.pr-info.outputs.pr_title }}
pr_head_sha: ${{ steps.pr-info.outputs.pr_head_sha }}
steps:
- name: Get PR Information
id: pr-info
uses: actions/github-script@v7
with:
script: |
const prNumber = parseInt('${{ github.event.inputs.pr_number }}');
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
console.log(`PR #${prNumber}: ${pr.title}`);
console.log(`Merge commit SHA: ${pr.merge_commit_sha}`);
core.setOutput('pr_title', pr.title);
core.setOutput('pr_head_sha', pr.merge_commit_sha);
validate-version-bump:
name: Validate Version Bump
runs-on: ubuntu-latest
needs: [get-pr-details]
if: always() && !cancelled()
outputs:
is_version_bump: ${{ steps.version_bump_check.outputs.is_version_bump }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate Version Bump
id: version_bump_check
run: |
set -e
PR_TITLE="${{ github.event.pull_request.title || needs.get-pr-details.outputs.pr_title }}"
VERSION_REGEX='^v([0-9]+\.[0-9]+\.[0-9]+)$'
if [[ "$PR_TITLE" =~ $VERSION_REGEX ]]; then
echo "✅ PR title matches version format: $PR_TITLE"
echo "is_version_bump=true" >> $GITHUB_OUTPUT
else
echo "ℹ️ PR title does not match version format: $PR_TITLE"
echo "is_version_bump=false" >> $GITHUB_OUTPUT
fi
bump-version:
name: Bump Version
needs: [validate-version-bump]
if: |
(github.event_name == 'workflow_dispatch') ||
(github.event_name == 'pull_request' && github.event.pull_request.merged == true && needs.validate-version-bump.outputs.is_version_bump == 'true')
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Extract version
id: version-check
run: |
# Determine which commit to get version from
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
COMMIT_SHA="${{ needs.get-pr-details.outputs.pr_head_sha }}"
git fetch origin "$COMMIT_SHA"
CONSTANTS_VERSION=$(git show ${COMMIT_SHA}:src/fabric_cicd/constants.py | grep -oP '(?<=^VERSION = ").*(?=")')
else
# For pull_request events, use current working directory (HEAD)
CONSTANTS_VERSION=$(grep -oP '(?<=^VERSION = ").*(?=")' src/fabric_cicd/constants.py)
fi
echo "Version: $CONSTANTS_VERSION"
if [ -z "$CONSTANTS_VERSION" ]; then
echo "ERROR: Could not extract version from constants.py"
exit 1
fi
echo "version_number=$CONSTANTS_VERSION" >> $GITHUB_OUTPUT
echo "version_tag=v$CONSTANTS_VERSION" >> $GITHUB_OUTPUT
# Log trigger type
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
echo "🚀 Manual trigger for PR #${{ github.event.inputs.pr_number }}"
elif [ "${{ github.event_name }}" = "pull_request" ]; then
echo "🚀 PR merge trigger - validated version bump"
fi
- name: Create tag if needed
if: needs.validate-version-bump.outputs.is_version_bump == 'true'
id: tag-creation
run: |
TAG_NAME="${{ steps.version-check.outputs.version_tag }}"
echo "Checking tag: $TAG_NAME"
# Check if tag exists locally or remotely
if git tag -l | grep -q "^$TAG_NAME$" || git ls-remote --tags origin | grep -q "refs/tags/$TAG_NAME$"; then
echo "ℹ️ Tag $TAG_NAME already exists, will proceed with existing tag"
echo "tag_created=false" >> $GITHUB_OUTPUT
else
echo "✅ Tag $TAG_NAME does not exist, creating new tag"
# Configure git
git config user.name "fabric-cicd-release[bot]"
git config user.email "fabric-cicd-release[bot]@users.noreply.github.com"
# Create and push the tag
git tag "$TAG_NAME"
git push origin "$TAG_NAME"
echo "✅ Created and pushed tag: $TAG_NAME"
echo "tag_created=true" >> $GITHUB_OUTPUT
fi
- name: Create GitHub Release
if: needs.validate-version-bump.outputs.is_version_bump == 'true'
uses: actions/github-script@v7
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const tagName = '${{ steps.version-check.outputs.version_tag }}';
try {
// Check if release already exists
let existingRelease;
try {
existingRelease = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag: tagName
});
console.log(`ℹ️ Release ${tagName} already exists: ${existingRelease.data.html_url}`);
console.log('Skipping release creation');
return;
} catch (error) {
if (error.status !== 404) {
throw error;
}
// Release doesn't exist, proceed to create it
}
// Extract changelog content for new release
const versionNumber = '${{ steps.version-check.outputs.version_number }}';
const fs = require('fs');
const path = 'docs/changelog.md';
let changelogContent = `Release ${tagName}`;
if (fs.existsSync(path)) {
try {
const changelogText = fs.readFileSync(path, 'utf8');
const lines = changelogText.split('\n');
let found = false;
let content = [];
for (const line of lines) {
if (line.startsWith('## [v')) {
if (found) break; // Hit next version, stop
if (line.includes(`[v${versionNumber}]`)) {
found = true;
continue; // Skip the version header line
}
} else if (found) {
// Skip span tags and empty lines
if (line.trim() === '' || line.startsWith('<span')) continue;
content.push(line);
}
}
if (content.length > 0) {
changelogContent = content.join('\n').trim();
} else {
console.log(`Changelog content not found for version ${versionNumber}`);
}
} catch (error) {
console.log('Error reading changelog:', error.message);
}
} else {
console.log('Changelog file not found');
}
// Create new release
const release = await github.rest.repos.createRelease({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: tagName,
name: tagName,
body: changelogContent,
draft: false,
prerelease: false
});
console.log(`✅ Created GitHub release: ${tagName}`);
console.log(`Release URL: ${release.data.html_url}`);
} catch (error) {
console.error('Failed to create release:', error);
throw error;
}
================================================
FILE: .github/workflows/changelog.yml
================================================
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
---
name: 🔄 Changelog
on:
pull_request:
branches:
- main
types:
- opened
- reopened
- labeled
- unlabeled
- synchronize
workflow_dispatch:
concurrency:
group: ${{ format('{0}-{1}-{2}-{3}-{4}', github.workflow, github.event_name, github.ref, github.base_ref || null, github.head_ref || null) }}
cancel-in-progress: true
permissions:
contents: read
jobs:
changelog-existence:
name: 🔄 Check Changelog
if: ${{ !contains(github.event.pull_request.labels.*.name, 'skip changelog') && github.actor != 'dependabot[bot]' }}
runs-on: ubuntu-latest
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
steps:
- name: ⤵️ Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # Required to access full commit history
- name: ✔️ Check for changelog changes
id: changelog_check
uses: actions/github-script@v6
with:
script: |
const { execSync } = require('child_process');
const base = process.env.BASE_SHA;
const head = process.env.HEAD_SHA;
console.log(`Comparing changes from ${base} to ${head}`)
const output = execSync(`git diff --name-only --no-renames --diff-filter=AM ${base} ${head}`).toString();
const files = output.split('\n').filter(Boolean);
const changelogExists = files.some(file => file.startsWith('.changes/unreleased/') && file.endsWith('.yaml'));
core.setOutput('exists', changelogExists);
- name: 🚧 Setup Node
if: steps.changelog_check.outputs.exists == 'true'
uses: actions/setup-node@v6
with:
node-version: "20"
- name: 🚧 Install Changie
if: steps.changelog_check.outputs.exists == 'true'
run: npm i -g changie
- name: 🔄 Prepare comment (changelog)
if: steps.changelog_check.outputs.exists == 'true'
run: |
echo -e "# Changelog Preview\n" > changie.md
changie batch patch --dry-run --prerelease 'dev' >> changie.md
cat changie.md >> $GITHUB_STEP_SUMMARY
- name: 🔄 Prepare comment (missing)
if: steps.changelog_check.outputs.exists == 'false'
run: |
echo -e "# 🛑 Changelog entry required to merge\n" > changie.md
echo "Run \`changie new\` to add a new changelog entry" >> changie.md
cat changie.md >> $GITHUB_STEP_SUMMARY
- name: ✅ Pass if changelog entry exists
if: steps.changelog_check.outputs.exists == 'true'
run: |
echo "✅ Changelog entry exists."
exit 0
- name: 🛑 Fail if changelog entry is missing and required
if: steps.changelog_check.outputs.exists == 'false'
run: |
echo "🛑 Changelog entry required to merge."
echo "🛑 Please run 'changie new' to add a new changelog entry."
exit 1
changelog-skip:
name: ⏭️ Skip Changelog
if: ${{ contains(github.event.pull_request.labels.*.name, 'skip changelog') || github.actor == 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- name: ✅ Pass (skip)
run: |
echo "⏭️ Changelog check skipped." >> $GITHUB_STEP_SUMMARY
exit 0
================================================
FILE: .github/workflows/publish_docs.yml
================================================
name: Publish Docs
on:
workflow_run:
workflows: ["Bump Version"]
types: [completed]
workflow_dispatch:
permissions:
contents: write
jobs:
publish-docs:
name: Publish Docs
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
steps:
- name: Generate GitHub App Token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ steps.app-token.outputs.token }}
- name: Extract version
id: version-check
run: |
CONSTANTS_VERSION=$(grep -oP '(?<=^VERSION = ").*(?=")' src/fabric_cicd/constants.py)
echo "Version: $CONSTANTS_VERSION"
if [ -z "$CONSTANTS_VERSION" ]; then
echo "ERROR: Could not extract version from constants.py"
exit 1
fi
echo "version_number=$CONSTANTS_VERSION" >> $GITHUB_OUTPUT
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: "3.9"
- name: Install Requirements
run: |
python -m pip install --upgrade pip
python -m pip install uv
- name: Deploy GitHub Pages
env:
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
run: |
git config user.name "fabric-cicd-release[bot]"
git config user.email "fabric-cicd-release[bot]@users.noreply.github.com"
git fetch --no-tags --prune --depth=1 origin +refs/heads/gh-pages:refs/remotes/origin/gh-pages
uv sync
VERSION="${{ steps.version-check.outputs.version_number }}"
echo "Deploying docs for version: $VERSION"
uv run mike deploy \
--update-aliases \
--branch gh-pages \
--push \
$VERSION \
latest
uv run mike set-default --push latest
================================================
FILE: .github/workflows/test.yml
================================================
name: Test
description: "Run unit tests for the Fabric CICD project"
on:
pull_request:
branches: ["main"]
types: [opened, edited, synchronize, ready_for_review]
push:
branches: ["main"]
jobs:
unit_test:
name: Unit Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Run unit tests
run: |
python -m pip install --upgrade pip
pip install uv
uv sync --dev
uv run pytest -v || exit 1 # Fail the job if any tests fail
================================================
FILE: .github/workflows/validate.yml
================================================
name: Validate PR
description: "Validate pull requests for code conventions, naming conventions, linked issues, and version bumps"
on:
pull_request:
branches: ["main"]
types: [opened, edited, synchronize, ready_for_review, labeled, unlabeled]
permissions:
contents: read
pull-requests: write
issues: write
statuses: write
jobs:
format_ruff:
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
name: Code Formatted
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Run ruff format
run: |
if ruff format; then
echo "✅ ruff format passed."
else
echo "❌ ruff format failed."
exit 1
fi
lint_ruff:
if: ${{ github.event.action != 'labeled' && github.event.action != 'unlabeled' }}
name: Code Linted
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff
- name: Run ruff lint
run: |
if ruff check; then
echo "✅ ruff lint passed."
else
echo "❌ ruff lint failed."
exit 1
fi
validate-version-bump:
name: Proper Version Bump
runs-on: ubuntu-latest
outputs:
is_version_bump: ${{ steps.version_bump_check.outputs.is_version_bump }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Validate Version Bump
id: version_bump_check
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -e
VERSION_REGEX='^v([0-9]+\.[0-9]+\.[0-9]+)$'
BASE_REF="origin/main"
CHANGED_FILES=$(git diff --name-only "$BASE_REF...$PR_HEAD_SHA")
VERSION_CHANGED=false
TITLE_IS_VERSION=false
OLD_VERSION=""
NEW_VERSION=""
# Get VERSION from main branch
OLD_VERSION=$(git show origin/main:src/fabric_cicd/constants.py | grep '^VERSION = ' | sed -E 's/VERSION = "([^"]+)"/\1/')
# Get VERSION from current branch
NEW_VERSION=$(grep '^VERSION = ' src/fabric_cicd/constants.py | sed -E 's/VERSION = "([^"]+)"/\1/')
if [ "$OLD_VERSION" != "$NEW_VERSION" ]; then
VERSION_CHANGED=true
fi
if [[ "$PR_TITLE" =~ $VERSION_REGEX ]]; then
TITLE_IS_VERSION=true
fi
if [ "$TITLE_IS_VERSION" = true ] || [ "$VERSION_CHANGED" = true ]; then
echo "is_version_bump=true" >> $GITHUB_OUTPUT
else
echo "is_version_bump=false" >> $GITHUB_OUTPUT
echo "✅ Version bump validation passed."
exit 0
fi
# 1. If version is updated, title must match
if [ "$VERSION_CHANGED" = true ]; then
EXPECTED_TITLE="v$NEW_VERSION"
if [ "$PR_TITLE" != "$EXPECTED_TITLE" ]; then
echo "❌ PR title must be vX.X.X when VERSION is changed. Expected title: $EXPECTED_TITLE"
exit 1
fi
fi
# 2. If title is version format, constants.py, changelog.md, and .changes/v<version>.md must be included in changed files
# Note: Additional files (e.g., removed unreleased change files) are allowed alongside the required files
if [[ "$PR_TITLE" =~ $VERSION_REGEX ]]; then
VERSION_NUMBER="${BASH_REMATCH[1]}"
REQUIRED_FILES=("src/fabric_cicd/constants.py" "docs/changelog.md" ".changes/v${VERSION_NUMBER}.md")
MISSING_FILES=()
for file in "${REQUIRED_FILES[@]}"; do
if ! echo "$CHANGED_FILES" | grep -Fqx "$file"; then
MISSING_FILES+=("$file")
fi
done
if [ ${#MISSING_FILES[@]} -ne 0 ]; then
echo "❌ The following required files must be included in a PR titled vX.X.X: ${MISSING_FILES[*]}"
exit 1
fi
fi
echo "✅ Version bump validation passed."
check-author-permissions:
name: Check Author Permissions
runs-on: ubuntu-latest
outputs:
skip_validation: ${{ steps.check_permissions.outputs.skip_validation }}
permissions:
pull-requests: read
steps:
- name: Check PR Author Collaborator Role
id: check_permissions
uses: actions/github-script@v7
with:
script: |
const prAuthor = context.payload.pull_request.user.login;
const repo = context.repo;
// Skip validation for dependabot
if (prAuthor === 'dependabot[bot]') {
console.log('✅ Dependabot PR detected. Skipping linked issue validation.');
core.setOutput('skip_validation', 'true');
return;
}
console.log(`Checking collaborator role for PR author: ${prAuthor}`);
try {
const { data: collaborator } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: repo.owner,
repo: repo.repo,
username: prAuthor
});
const roleName = collaborator.role_name;
console.log(`Collaborator role for ${prAuthor}: ${roleName}`);
// Skip validation for users with admin, maintain, or write role
const skipValidation = ['admin', 'maintain', 'write'].includes(roleName);
core.setOutput('skip_validation', skipValidation.toString());
if (skipValidation) {
console.log(`✅ User ${prAuthor} has ${roleName} role. Validation job for linked issue will be skipped.`);
} else {
console.log(`ℹ️ User ${prAuthor} has ${roleName} role. Validation job for linked issue will run.`);
}
} catch (error) {
console.log(`⚠️ Could not determine collaborator role for ${prAuthor}: ${error.message}`);
console.log('Defaulting to running validation job for linked issue.');
core.setOutput('skip_validation', 'false');
}
validate-linked-issue:
name: Issue Linked
runs-on: ubuntu-latest
needs: [check-author-permissions, validate-version-bump]
if: needs.check-author-permissions.outputs.skip_validation == 'false' && needs.validate-version-bump.outputs.is_version_bump == 'false' && !contains(github.event.pull_request.labels.*.name, 'skip changelog')
permissions:
pull-requests: read
issues: read
steps:
- name: Validate Linked Issue
uses: actions/github-script@v7
with:
script: |
const prNumber = context.issue.number;
const repo = context.repo;
// Get PR details
const pr = await github.rest.pulls.get({
owner: repo.owner,
repo: repo.repo,
pull_number: prNumber
});
const prTitle = pr.data.title || '';
// First, check for issues linked to the PR via GitHub's native linking
let linkedIssues = [];
try {
// Use GraphQL to get linked issues
const query = `
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
closingIssuesReferences(first: 10) {
nodes {
number
}
}
}
}
}
`;
const result = await github.graphql(query, {
owner: repo.owner,
repo: repo.repo,
number: prNumber
});
linkedIssues = result.repository.pullRequest.closingIssuesReferences.nodes;
if (linkedIssues.length > 0) {
console.log(`✅ Found ${linkedIssues.length} linked issue(s): ${linkedIssues.map(issue => `#${issue.number}`).join(', ')}`);
console.log('✅ Pull request is properly linked to an issue via GitHub linking.');
return;
}
} catch (error) {
console.log('⚠️ Could not check for linked issues via GraphQL, falling back to text analysis:', error.message);
}
// Issue reference patterns - more specific to avoid false positives
const keywordPatterns = [
/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi,
/(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+https:\/\/github\.com\/[^\/]+\/[^\/]+\/issues\/(\d+)/gi
];
// Generic hash pattern (less specific, used as fallback)
const hashPattern = /#(\d+)(?!\w)/g;
let foundIssueNumbers = new Set();
// Check PR title for issue references
const textToCheck = prTitle;
// First, look for keyword-based references (more reliable)
for (const pattern of keywordPatterns) {
const matches = textToCheck.matchAll(pattern);
for (const match of matches) {
const issueNumber = match[1];
if (issueNumber && !isNaN(issueNumber)) {
foundIssueNumbers.add(parseInt(issueNumber));
}
}
}
// If no keyword-based references found, look for simple hash references
if (foundIssueNumbers.size === 0) {
const matches = textToCheck.matchAll(hashPattern);
for (const match of matches) {
const issueNumber = match[1];
if (issueNumber && !isNaN(issueNumber)) {
foundIssueNumbers.add(parseInt(issueNumber));
}
}
}
if (foundIssueNumbers.size === 0) {
core.setFailed(
'❌ This pull request must be linked to an issue. Please:\n' +
'1. Reference an issue in the PR title using "Fixes #123", "Closes #456", or "Resolves #789"\n' +
'2. Make sure the referenced issue exists in this repository\n\n' +
'See our contribution guidelines for more details.'
);
return;
}
// Verify that the referenced issues actually exist
let validIssueFound = false;
const invalidIssues = [];
for (const issueNumber of foundIssueNumbers) {
try {
await github.rest.issues.get({
owner: repo.owner,
repo: repo.repo,
issue_number: issueNumber
});
validIssueFound = true;
console.log(`✅ Found valid issue reference: #${issueNumber}`);
} catch (error) {
if (error.status === 404) {
invalidIssues.push(issueNumber);
console.log(`❌ Issue #${issueNumber} does not exist`);
}
}
}
if (!validIssueFound) {
const invalidList = invalidIssues.length > 0 ?
`\n\nInvalid issue references found: ${invalidIssues.map(n => `#${n}`).join(', ')}` : '';
core.setFailed(
'❌ This pull request must be linked to a valid issue in this repository.' +
invalidList +
'\n\nPlease:\n' +
'1. Create an issue first if one doesn\'t exist\n' +
'2. Reference the issue in the PR title using "Fixes #123", "Closes #456", or "Resolves #789"\n' +
'3. Make sure the issue number is correct\n\n' +
'See our contribution guidelines for more details.'
);
return;
}
console.log('✅ Pull request is properly linked to an issue.');
================================================
FILE: .gitignore
================================================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# ruff
.ruff_cache/
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# http traces should only be committed at the fixture root
/http_trace.json
/http_trace.json.lock
/http_trace.json.gz
================================================
FILE: .prettierignore
================================================
sample/workspace/
docs/how_to/parameterization.md
================================================
FILE: .prettierrc
================================================
{
"printWidth": 100,
"tabWidth": 4,
"useTabs": false,
"semi": true,
"trailingComma": "all"
}
================================================
FILE: .python-version
================================================
3.11
================================================
FILE: .vscode/extensions.json
================================================
{
"recommendations": [
"ms-python.python",
"esbenp.prettier-vscode",
"ms-vscode.powershell",
"charliermarsh.ruff",
"tamasfe.even-better-toml"
]
}
================================================
FILE: .vscode/launch.json
================================================
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug: Trace Publish All Items",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/devtools/debug_trace_deployment.py",
"console": "integratedTerminal",
"justMyCode": false,
"env": {
"PYTHONPATH": "${workspaceFolder}/src",
"FABRIC_WORKSPACE_ID": "your-fabric-workspace-guid"
},
"cwd": "${workspaceFolder}"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
{
"editor": {
"trimAutoWhitespace": false,
"defaultFormatter": "esbenp.prettier-vscode",
"formatOnSave": true
},
"diffEditor": {
"ignoreTrimWhitespace": false
},
"files": {
"trimTrailingWhitespace": false,
"trimTrailingWhitespaceInRegexAndStrings": false,
"insertFinalNewline": true,
"autoSave": "off"
},
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
"editor.codeActionsOnSave": {
gitextract_uhouros3/
├── .changes/
│ ├── header.tpl.md
│ ├── unreleased/
│ │ ├── added-20260420-140247.yaml
│ │ ├── added-20260503-000000.yaml
│ │ ├── fixed-20260424-103120.yaml
│ │ ├── fixed-20260428-121610.yaml
│ │ ├── new-items-20260505-123355.yaml
│ │ └── optimization-20260505-142743.yaml
│ ├── v0.1.0.md
│ ├── v0.1.1.md
│ ├── v0.1.10.md
│ ├── v0.1.11.md
│ ├── v0.1.12.md
│ ├── v0.1.13.md
│ ├── v0.1.14.md
│ ├── v0.1.15.md
│ ├── v0.1.16.md
│ ├── v0.1.17.md
│ ├── v0.1.18.md
│ ├── v0.1.19.md
│ ├── v0.1.2.md
│ ├── v0.1.20.md
│ ├── v0.1.21.md
│ ├── v0.1.22.md
│ ├── v0.1.23.md
│ ├── v0.1.24.md
│ ├── v0.1.25.md
│ ├── v0.1.26.md
│ ├── v0.1.27.md
│ ├── v0.1.28.md
│ ├── v0.1.29.md
│ ├── v0.1.3.md
│ ├── v0.1.30.md
│ ├── v0.1.31.md
│ ├── v0.1.32.md
│ ├── v0.1.33.md
│ ├── v0.1.34.md
│ ├── v0.1.4.md
│ ├── v0.1.5.md
│ ├── v0.1.6.md
│ ├── v0.1.7.md
│ ├── v0.1.8.md
│ ├── v0.1.9.md
│ ├── v0.2.0.md
│ ├── v0.3.0.md
│ ├── v0.3.1.md
│ └── v1.0.0.md
├── .changie.yaml
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── 1-bug.yml
│ │ ├── 2-feature.yml
│ │ ├── 3-documentation.yml
│ │ ├── 4-question.yml
│ │ └── config.yml
│ ├── agents/
│ │ └── new-item-type.agent.md
│ ├── copilot-instructions.md
│ ├── policies/
│ │ ├── resourceManagement.yml
│ │ └── sdl.yml
│ ├── prompts/
│ │ ├── bug-triage.prompt.yml
│ │ ├── feature-triage.prompt.yml
│ │ └── question-triage.prompt.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── ai-issue-triage.yml
│ ├── bump.yml
│ ├── changelog.yml
│ ├── publish_docs.yml
│ ├── test.yml
│ └── validate.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .python-version
├── .vscode/
│ ├── extensions.json
│ ├── launch.json
│ └── settings.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CodeQL.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── activate.ps1
├── activate.sh
├── devtools/
│ ├── debug_api.py
│ ├── debug_local config.py
│ ├── debug_local.py
│ ├── debug_parameterization.py
│ ├── debug_trace_deployment.py
│ └── pypi_build_release_dev.ps1
├── docs/
│ ├── about.md
│ ├── changelog.md
│ ├── code_reference.md
│ ├── config/
│ │ ├── overrides/
│ │ │ └── main.html
│ │ ├── pre-build/
│ │ │ ├── section_toc.py
│ │ │ ├── update_item_types.py
│ │ │ └── update_python_version.py
│ │ └── stylesheets/
│ │ └── extra.css
│ ├── example/
│ │ ├── authentication.md
│ │ ├── deployment_variable.md
│ │ ├── index.md
│ │ └── release_pipeline.md
│ ├── how_to/
│ │ ├── config_deployment.md
│ │ ├── getting_started.md
│ │ ├── index.md
│ │ ├── item_types.md
│ │ ├── optional_feature.md
│ │ ├── parameterization.md
│ │ └── troubleshooting.md
│ └── index.md
├── mkdocs.yml
├── pyproject.toml
├── ruff.toml
├── sample/
│ └── workspace/
│ ├── ABC.Report/
│ │ ├── .platform
│ │ ├── StaticResources/
│ │ │ ├── RegisteredResources/
│ │ │ │ └── test_image25861853181026917.tif
│ │ │ └── SharedResources/
│ │ │ └── BaseThemes/
│ │ │ └── CY24SU10.json
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── ABC.SemanticModel/
│ │ ├── .platform
│ │ ├── definition/
│ │ │ ├── cultures/
│ │ │ │ └── en-US.tmdl
│ │ │ ├── database.tmdl
│ │ │ ├── model.tmdl
│ │ │ ├── relationships.tmdl
│ │ │ └── tables/
│ │ │ ├── Table.tmdl
│ │ │ └── Table_2.tmdl
│ │ ├── definition.pbism
│ │ └── diagramLayout.json
│ ├── ABCD.Report/
│ │ ├── .platform
│ │ ├── StaticResources/
│ │ │ └── SharedResources/
│ │ │ └── BaseThemes/
│ │ │ └── CY24SU10.json
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── ByConnection.Report/
│ │ ├── .platform
│ │ ├── definition.pbir
│ │ └── report.json
│ ├── Default.Warehouse/
│ │ └── .platform
│ ├── DefaultCaseInsensitive.Warehouse/
│ │ └── .platform
│ ├── Example Notebook.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ ├── Hello Copy Job.CopyJob/
│ │ ├── .platform
│ │ └── copyjob-content.json
│ ├── Hello Dataflow.Dataflow/
│ │ ├── .platform
│ │ ├── mashup.pq
│ │ └── queryMetadata.json
│ ├── Hello World.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ ├── Hello db.SQLDatabase/
│ │ ├── .gitignore
│ │ ├── .platform
│ │ └── Hello db.sqlproj
│ ├── HelloEventhouse.Eventhouse/
│ │ ├── .children/
│ │ │ └── HelloEventhouse.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── HelloRealTimeDashboard.KQLDashboard/
│ │ ├── .platform
│ │ └── RealTimeDashboard.json
│ ├── MirroredDatabase_1.MirroredDatabase/
│ │ ├── .platform
│ │ └── mirroring.json
│ ├── OntologyDataLH.Lakehouse/
│ │ ├── .platform
│ │ ├── alm.settings.json
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── RetailSalesOntology.Ontology/
│ │ ├── .platform
│ │ ├── EntityTypes/
│ │ │ ├── 205398164146535/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ └── a790fdb3-e356-4f42-acf4-4420557c0fd7.json
│ │ │ │ └── definition.json
│ │ │ ├── 267812974919544/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ └── 275d574a-4d0d-4935-9cfd-54e59ee36d7f.json
│ │ │ │ └── definition.json
│ │ │ ├── 28747097105824/
│ │ │ │ ├── DataBindings/
│ │ │ │ │ ├── 5f66bbb3-9bb6-415a-9cd9-9d7421d0e553.json
│ │ │ │ │ └── f0767964-7f82-40a1-9ca2-f7e7fe931fcd.json
│ │ │ │ └── definition.json
│ │ │ └── 52068896499199/
│ │ │ ├── DataBindings/
│ │ │ │ └── 3d6fc8a5-b442-46b2-9bee-c22d08038f2e.json
│ │ │ └── definition.json
│ │ ├── RelationshipTypes/
│ │ │ ├── 4160405290834524422/
│ │ │ │ ├── Contextualizations/
│ │ │ │ │ └── 088a81ce-2a4c-4dbc-8887-ab6b831fa047.json
│ │ │ │ └── definition.json
│ │ │ ├── 4194354367812289411/
│ │ │ │ ├── Contextualizations/
│ │ │ │ │ └── 7be8afdf-2557-4950-930e-26c762fcb5a5.json
│ │ │ │ └── definition.json
│ │ │ └── 4244194862547506054/
│ │ │ ├── Contextualizations/
│ │ │ │ └── 7f23e2a5-25f6-4c87-8b9a-43b3b9a142ec.json
│ │ │ └── definition.json
│ │ └── definition.json
│ ├── Run Hello World.DataPipeline/
│ │ ├── .platform
│ │ ├── .schedules
│ │ └── pipeline-content.json
│ ├── Sample.GraphQLApi/
│ │ ├── .platform
│ │ └── graphql-definition.json
│ ├── SampleDataActivator.Reflex/
│ │ ├── .platform
│ │ └── ReflexEntities.json
│ ├── SampleDataBuildToolJob.DataBuildToolJob/
│ │ ├── .platform
│ │ └── dbt-content.json
│ ├── SampleEventhouse.Eventhouse/
│ │ ├── .children/
│ │ │ └── TaxiDB.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── SampleEventstream.Eventstream/
│ │ ├── .platform
│ │ ├── eventstream.json
│ │ └── eventstreamProperties.json
│ ├── SampleKQLQueryset.KQLQueryset/
│ │ ├── .platform
│ │ └── RealTimeQueryset.json
│ ├── SampleSparkJobDefinition.SparkJobDefinition/
│ │ ├── .platform
│ │ ├── Libs/
│ │ │ └── pipeline_config.py
│ │ ├── Main/
│ │ │ └── main.py
│ │ └── SparkJobDefinitionV1.json
│ ├── SampleUserDataFunction.UserDataFunction/
│ │ ├── .platform
│ │ ├── .resources/
│ │ │ └── functions.json
│ │ ├── definition.json
│ │ └── function_app.py
│ ├── SourceForShortcutLH.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── TargetForShortcutLH.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── TelemetryDataEH.Eventhouse/
│ │ ├── .children/
│ │ │ └── TelemetryDataEH.KQLDatabase/
│ │ │ ├── .platform
│ │ │ ├── DatabaseProperties.json
│ │ │ └── DatabaseSchema.kql
│ │ ├── .platform
│ │ └── EventhouseProperties.json
│ ├── Vars.VariableLibrary/
│ │ ├── .platform
│ │ ├── settings.json
│ │ ├── valueSets/
│ │ │ ├── PPE.json
│ │ │ └── PROD.json
│ │ └── variables.json
│ ├── WithSchema.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── WithoutSchema.Lakehouse/
│ │ ├── .platform
│ │ ├── lakehouse.metadata.json
│ │ └── shortcuts.metadata.json
│ ├── World.Environment/
│ │ ├── .platform
│ │ ├── Libraries/
│ │ │ ├── CustomLibraries/
│ │ │ │ └── fabric_cicd-0.1.1-py3-none-any.whl
│ │ │ └── PublicLibraries/
│ │ │ └── environment.yml
│ │ └── Setting/
│ │ └── Sparkcompute.yml
│ ├── cicd_experiment.MLExperiment/
│ │ ├── .platform
│ │ └── mlexperiment.metadata.json
│ ├── config.yml
│ ├── parameter template.yml
│ ├── parameter.yml
│ ├── sample apache airflow job.ApacheAirflowJob/
│ │ ├── .platform
│ │ ├── apacheairflowjob-content.json
│ │ └── dags/
│ │ └── dag1.py
│ ├── subfolder/
│ │ ├── Hello World Subfolder.Notebook/
│ │ │ ├── .platform
│ │ │ └── notebook-content.py
│ │ └── subfolder/
│ │ └── Hello World SubfolderSubfolder.Notebook/
│ │ ├── .platform
│ │ └── notebook-content.py
│ └── templates/
│ ├── nb parameter template 1.yml
│ └── nb parameter template 2.yml
├── src/
│ └── fabric_cicd/
│ ├── __init__.py
│ ├── _common/
│ │ ├── __init__.py
│ │ ├── _check_utils.py
│ │ ├── _color.py
│ │ ├── _config_utils.py
│ │ ├── _config_validator.py
│ │ ├── _deployment_result.py
│ │ ├── _exceptions.py
│ │ ├── _fabric_endpoint.py
│ │ ├── _file.py
│ │ ├── _file_lock.py
│ │ ├── _git_diff_utils.py
│ │ ├── _http_tracer.py
│ │ ├── _item.py
│ │ ├── _logging.py
│ │ ├── _validate_env_vars.py
│ │ └── _validate_input.py
│ ├── _items/
│ │ ├── __init__.py
│ │ ├── _activator.py
│ │ ├── _apacheairflowjob.py
│ │ ├── _base_publisher.py
│ │ ├── _copyjob.py
│ │ ├── _dataagent.py
│ │ ├── _databuildtooljob.py
│ │ ├── _dataflowgen2.py
│ │ ├── _datapipeline.py
│ │ ├── _environment.py
│ │ ├── _eventhouse.py
│ │ ├── _eventstream.py
│ │ ├── _graphqlapi.py
│ │ ├── _kqldashboard.py
│ │ ├── _kqldatabase.py
│ │ ├── _kqlqueryset.py
│ │ ├── _lakehouse.py
│ │ ├── _manage_dependencies.py
│ │ ├── _mirroreddatabase.py
│ │ ├── _mlexperiment.py
│ │ ├── _mounteddatafactory.py
│ │ ├── _notebook.py
│ │ ├── _ontology.py
│ │ ├── _report.py
│ │ ├── _semanticmodel.py
│ │ ├── _sparkjobdefinition.py
│ │ ├── _sqldatabase.py
│ │ ├── _userdatafunction.py
│ │ ├── _variablelibrary.py
│ │ └── _warehouse.py
│ ├── _parameter/
│ │ ├── __init__.py
│ │ ├── _parameter.py
│ │ └── _utils.py
│ ├── constants.py
│ ├── fabric_workspace.py
│ └── publish.py
└── tests/
├── fixtures/
│ ├── .gitignore
│ ├── README.md
│ ├── __init__.py
│ ├── credentials.py
│ └── mock_fabric_server.py
├── test__check_utils.py
├── test__fabric_endpoint.py
├── test__file.py
├── test_config_validator.py
├── test_deploy_with_config.py
├── test_environment_publish.py
├── test_fabric_workspace.py
├── test_fqdn_workspace_id.py
├── test_git_diff_utils.py
├── test_hard_delete.py
├── test_integration_publish.py
├── test_logging.py
├── test_parameter.py
├── test_parameter_utils.py
├── test_publish.py
├── test_response_collection.py
├── test_semantic_model_exclude.py
├── test_shortcut_exclude.py
├── test_subfolders.py
└── test_validate_env_vars.py
SYMBOL INDEX (1205 symbols across 77 files)
FILE: devtools/debug_trace_deployment.py
function main (line 20) | def main():
FILE: docs/config/pre-build/section_toc.py
function slugify (line 8) | def slugify(title):
function get_section_order (line 31) | def get_section_order(nav, current_dir_str):
function on_page_markdown (line 52) | def on_page_markdown(markdown, page, config, files):
FILE: docs/config/pre-build/update_item_types.py
function on_page_markdown (line 10) | def on_page_markdown(markdown, **kwargs):
FILE: docs/config/pre-build/update_python_version.py
function on_page_markdown (line 9) | def on_page_markdown(markdown, **kwargs):
FILE: sample/workspace/SampleUserDataFunction.UserDataFunction/function_app.py
function hello_fabric (line 8) | def hello_fabric(name: str) -> str:
FILE: src/fabric_cicd/__init__.py
function append_feature_flag (line 22) | def append_feature_flag(feature: str) -> None:
function change_log_level (line 37) | def change_log_level(level: str = "DEBUG") -> None:
function configure_external_file_logging (line 56) | def configure_external_file_logging(external_logger: logging.Logger) -> ...
function disable_file_logging (line 113) | def disable_file_logging() -> None:
function configure_fabric_fqdn (line 136) | def configure_fabric_fqdn(workspace_id: str) -> None:
FILE: src/fabric_cicd/_common/_check_utils.py
function check_file_type (line 19) | def check_file_type(file_path: Path) -> str:
function check_regex (line 40) | def check_regex(regex: str) -> re.Pattern:
function check_valid_json_content (line 55) | def check_valid_json_content(content: str) -> bool:
function check_valid_yaml_content (line 72) | def check_valid_yaml_content(content: str) -> bool:
FILE: src/fabric_cicd/_common/_color.py
class Fore (line 1) | class Fore:
class Back (line 13) | class Back:
class Style (line 25) | class Style:
FILE: src/fabric_cicd/_common/_config_utils.py
function load_config_file (line 17) | def load_config_file(config_file_path: str, environment: str, config_ove...
function get_config_value (line 32) | def get_config_value(config_section: dict, key: str, environment: str) -...
function update_setting (line 54) | def update_setting(
function extract_workspace_settings (line 82) | def extract_workspace_settings(config: dict, environment: str) -> dict:
function extract_publish_settings (line 107) | def extract_publish_settings(config: dict, environment: str) -> dict:
function extract_unpublish_settings (line 131) | def extract_unpublish_settings(config: dict, environment: str) -> dict:
function config_overrides_scope (line 153) | def config_overrides_scope(config: dict, environment: str) -> Generator[...
FILE: src/fabric_cicd/_common/_config_validator.py
class ConfigValidationError (line 20) | class ConfigValidationError(InputError):
method __init__ (line 23) | def __init__(self, errors: list[str], logger_instance: logging.Logger)...
class ConfigValidator (line 32) | class ConfigValidator:
method __init__ (line 35) | def __init__(self) -> None:
method validate_config_file (line 43) | def validate_config_file(
method _validate_file_existence (line 93) | def _validate_file_existence(self, config_file_path: str) -> Path:
method _validate_yaml_content (line 116) | def _validate_yaml_content(self, config_path: Optional[Path]) -> Optio...
method _apply_and_validate_overrides (line 148) | def _apply_and_validate_overrides(self) -> None:
method _valid_override_section (line 165) | def _valid_override_section(self, section: str, value: any) -> bool:
method _merge_overrides (line 205) | def _merge_overrides(self, section: str, value: Union[dict, list]) -> ...
method _validate_config_structure (line 281) | def _validate_config_structure(self) -> None:
method _validate_config_sections (line 298) | def _validate_config_sections(self) -> None:
method _validate_environment_exists (line 340) | def _validate_environment_exists(self) -> None:
method _validate_environment_mapping (line 387) | def _validate_environment_mapping(self, field_value: dict, field_name:...
method _validate_workspace_field (line 428) | def _validate_workspace_field(self, core: dict, field_name: str) -> bool:
method _validate_workspace_value (line 461) | def _validate_workspace_value(self, value: str, field_name: str, conte...
method _validate_repository_directory (line 468) | def _validate_repository_directory(self, core: dict) -> None:
method _validate_item_types_in_scope (line 496) | def _validate_item_types_in_scope(self, core: dict[str, Any]) -> None:
method _validate_item_types (line 527) | def _validate_item_types(self, item_types: list, env_context: Optional...
method _validate_parameter_field (line 558) | def _validate_parameter_field(self, core: dict) -> None:
method _resolve_path_field (line 580) | def _resolve_path_field(
method _resolve_repository_path (line 672) | def _resolve_repository_path(self) -> None:
method _resolve_parameter_path (line 678) | def _resolve_parameter_path(self) -> None:
method _validate_operation_section (line 687) | def _validate_operation_section(self, section: dict[str, Any], section...
method _validate_regex (line 890) | def _validate_regex(self, regex: str, section_name: str) -> None:
method _validate_items_list (line 899) | def _validate_items_list(self, items_list: list, context: str) -> None:
method _validate_folders_list (line 911) | def _validate_folders_list(self, folders_list: list, context: str) -> ...
method _validate_mutually_exclusive_fields (line 927) | def _validate_mutually_exclusive_fields(self, section: dict, field1: s...
method _validate_features_section (line 965) | def _validate_features_section(self, features: any) -> None:
method _validate_features_list (line 989) | def _validate_features_list(self, features_list: list, context: str) -...
method _validate_constants_section (line 1001) | def _validate_constants_section(self, constants_section: any) -> None:
method _validate_single_constant (line 1040) | def _validate_single_constant(self, key: str, value: any, context: str...
function _get_config_fields (line 1052) | def _get_config_fields(config: dict) -> list[tuple[dict, str, str, bool,...
function _find_git_root (line 1085) | def _find_git_root(path: Path) -> Optional[Path]:
function _validate_guid_format (line 1095) | def _validate_guid_format(guid: str) -> bool:
FILE: src/fabric_cicd/_common/_deployment_result.py
class DeploymentStatus (line 11) | class DeploymentStatus(str, Enum):
class DeploymentResult (line 21) | class DeploymentResult:
FILE: src/fabric_cicd/_common/_exceptions.py
class BaseCustomError (line 10) | class BaseCustomError(Exception):
method __init__ (line 11) | def __init__(self, message: str, logger: Logger, additional_info: Opti...
class ParsingError (line 25) | class ParsingError(BaseCustomError):
class InputError (line 29) | class InputError(BaseCustomError):
class TokenError (line 33) | class TokenError(BaseCustomError):
class InvokeError (line 37) | class InvokeError(BaseCustomError):
class ItemDependencyError (line 41) | class ItemDependencyError(BaseCustomError):
class FileTypeError (line 45) | class FileTypeError(BaseCustomError):
class ParameterFileError (line 49) | class ParameterFileError(BaseCustomError):
class FailedPublishedItemStatusError (line 53) | class FailedPublishedItemStatusError(BaseCustomError):
class PublishError (line 57) | class PublishError(BaseCustomError):
method __init__ (line 64) | def __init__(self, errors: list[tuple[str, Exception]], logger: Logger...
FILE: src/fabric_cicd/_common/_fabric_endpoint.py
class FabricEndpoint (line 26) | class FabricEndpoint:
method __init__ (line 29) | def __init__(
method invoke (line 51) | def invoke(
method _refresh_token (line 150) | def _refresh_token(self) -> None:
function _handle_response (line 173) | def _handle_response(
function handle_retry (line 332) | def handle_retry(
function _format_invoke_log (line 376) | def _format_invoke_log(response: requests.Response, method: str, url: st...
FILE: src/fabric_cicd/_common/_file.py
class File (line 19) | class File:
method __setattr__ (line 28) | def __setattr__(self, key: str, value: any) -> None:
method __post_init__ (line 46) | def __post_init__(self) -> None:
method name (line 73) | def name(self) -> str:
method relative_path (line 78) | def relative_path(self) -> str:
method base64_payload (line 83) | def base64_payload(self) -> dict:
FILE: src/fabric_cicd/_common/_file_lock.py
class FileLock (line 14) | class FileLock:
method __init__ (line 17) | def __init__(self, lock_file: str) -> None:
method __enter__ (line 21) | def __enter__(self) -> "FileLock":
method __exit__ (line 33) | def __exit__(
method run_with_lock (line 52) | def run_with_lock(lock_file: str, func: Callable[[], T]) -> T:
FILE: src/fabric_cicd/_common/_git_diff_utils.py
function _find_platform_item (line 15) | def _find_platform_item(file_path: Path, repo_root: Path) -> Optional[tu...
function _resolve_git_diff_path (line 46) | def _resolve_git_diff_path(
function get_changed_items (line 98) | def get_changed_items(
function _resolve_changed_items (line 141) | def _resolve_changed_items(
FILE: src/fabric_cicd/_common/_http_tracer.py
function _trace_default (line 26) | def _trace_default(obj: object) -> str:
class HTTPRequest (line 41) | class HTTPRequest:
method to_b64 (line 50) | def to_b64(self) -> str:
method from_b64 (line 56) | def from_b64(cls, b64_str: str) -> "HTTPRequest":
method get_unique_signature (line 62) | def get_unique_signature(self) -> str:
method get_route_key (line 67) | def get_route_key(self) -> str:
class HTTPResponse (line 80) | class HTTPResponse:
method to_b64 (line 88) | def to_b64(self) -> str:
method from_b64 (line 94) | def from_b64(cls, b64_str: str) -> "HTTPResponse":
method get_unique_signature (line 100) | def get_unique_signature(self) -> str:
class HTTPTracer (line 106) | class HTTPTracer(Protocol):
method capture_request (line 109) | def capture_request(self, method: str, url: str, headers: dict, body: ...
method capture_response (line 113) | def capture_response(self, response: requests.Response) -> None:
method save (line 117) | def save(self) -> None:
class NoOpTracer (line 122) | class NoOpTracer:
method capture_request (line 125) | def capture_request(self, method: str, url: str, headers: dict, body: ...
method capture_response (line 129) | def capture_response(self, response: requests.Response) -> None:
method save (line 133) | def save(self) -> None:
class FileTracer (line 138) | class FileTracer:
method __init__ (line 141) | def __init__(self, output_file: Optional[str] = None) -> None:
method capture_request (line 157) | def capture_request(self, method: str, url: str, headers: dict, body: ...
method capture_response (line 178) | def capture_response(self, response: requests.Response) -> None:
method save (line 205) | def save(self) -> None:
method _flush_traces_to_file (line 215) | def _flush_traces_to_file(self) -> None:
class HTTPTracerFactory (line 249) | class HTTPTracerFactory:
method create (line 253) | def create() -> HTTPTracer:
FILE: src/fabric_cicd/_common/_item.py
class Item (line 15) | class Item:
method __setattr__ (line 30) | def __setattr__(self, key: str, value: any) -> None:
method relative_path (line 44) | def relative_path(self) -> str:
method collect_item_files (line 48) | def collect_item_files(self) -> None:
FILE: src/fabric_cicd/_common/_logging.py
class CustomFormatter (line 21) | class CustomFormatter(logging.Formatter):
method format (line 30) | def format(self, record: LogRecord) -> str:
class PackageFilter (line 62) | class PackageFilter(logging.Filter):
method __init__ (line 70) | def __init__(self, debug_only: bool = False) -> None:
method filter (line 74) | def filter(self, record: LogRecord) -> bool:
function _cleanup_external_handler_filters (line 89) | def _cleanup_external_handler_filters(root_logger: logging.Logger) -> None:
function _cleanup_managed_handlers (line 103) | def _cleanup_managed_handlers(*loggers: logging.Logger) -> None:
function _mark_handler (line 116) | def _mark_handler(handler: logging.Handler) -> logging.Handler:
function _mark_external_handler (line 122) | def _mark_external_handler(handler: logging.Handler) -> logging.Handler:
function _configure_default_file_handler (line 128) | def _configure_default_file_handler() -> logging.Handler:
function _configure_external_file_handler (line 141) | def _configure_external_file_handler(
function _configure_console_handler (line 166) | def _configure_console_handler(level: int) -> logging.StreamHandler:
function _build_console_message (line 179) | def _build_console_message(exception: BaseException, file_handler: Optio...
function _build_file_message (line 190) | def _build_file_message(exception: BaseException) -> str:
function get_file_handler (line 201) | def get_file_handler(
function configure_logger (line 230) | def configure_logger(
function exception_handler (line 285) | def exception_handler(exception_type: type[BaseException], exception: Ba...
function log_header (line 318) | def log_header(logger: logging.Logger, message: str) -> None:
FILE: src/fabric_cicd/_common/_validate_env_vars.py
function validate_api_url (line 27) | def validate_api_url(url: str, label: str) -> str:
function validate_env_var_api_url (line 64) | def validate_env_var_api_url(env_var_name: str, default_value: str) -> str:
function _get_fabric_fqdn_url (line 80) | def _get_fabric_fqdn_url(workspace_id: str) -> str:
FILE: src/fabric_cicd/_common/_validate_input.py
function validate_data_type (line 25) | def validate_data_type(expected_type: str, variable_name: str, input_val...
function validate_item_type_in_scope (line 52) | def validate_item_type_in_scope(input_value: Optional[list]) -> list:
function validate_repository_directory (line 75) | def validate_repository_directory(input_value: str) -> Path:
function validate_workspace_id (line 98) | def validate_workspace_id(input_value: str) -> str:
function validate_workspace_name (line 114) | def validate_workspace_name(input_value: str) -> str:
function validate_environment (line 126) | def validate_environment(input_value: str) -> str:
function validate_fabric_workspace_obj (line 138) | def validate_fabric_workspace_obj(input_value: FabricWorkspace) -> Fabri...
function validate_token_credential (line 150) | def validate_token_credential(input_value: TokenCredential) -> TokenCred...
function validate_experimental_param (line 162) | def validate_experimental_param(
function validate_items_to_include (line 194) | def validate_items_to_include(items_to_include: Optional[list[str]], ope...
function validate_folder_path_exclude_regex (line 213) | def validate_folder_path_exclude_regex(folder_path_exclude_regex: Option...
function validate_folder_path_to_include (line 239) | def validate_folder_path_to_include(folder_path_to_include: Optional[lis...
function validate_shortcut_exclude_regex (line 265) | def validate_shortcut_exclude_regex(shortcut_exclude_regex: Optional[str...
function validate_git_compare_ref (line 283) | def validate_git_compare_ref(git_compare_ref: str) -> str:
FILE: src/fabric_cicd/_items/_activator.py
class ActivatorPublisher (line 10) | class ActivatorPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_apacheairflowjob.py
class ApacheAirflowJobPublisher (line 10) | class ApacheAirflowJobPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_base_publisher.py
class ParallelConfig (line 21) | class ParallelConfig:
class Publisher (line 41) | class Publisher(ABC):
method __init__ (line 44) | def __init__(self, fabric_workspace_obj: "FabricWorkspace") -> None:
method publish_one (line 54) | def publish_one(self, name: str, obj: object) -> None:
method publish_all (line 65) | def publish_all(self) -> None:
class ItemPublisher (line 70) | class ItemPublisher(Publisher):
method __init__ (line 117) | def __init__(self, fabric_workspace_obj: "FabricWorkspace") -> None:
method create (line 127) | def create(item_type: ItemType, fabric_workspace_obj: "FabricWorkspace...
method get_item_types_to_publish (line 207) | def get_item_types_to_publish(fabric_workspace_obj: "FabricWorkspace")...
method get_item_types_to_unpublish (line 232) | def get_item_types_to_unpublish(fabric_workspace_obj: "FabricWorkspace...
method get_orphaned_items (line 265) | def get_orphaned_items(
method publish_all (line 305) | def publish_all(self) -> None:
method publish_one (line 354) | def publish_one(self, item_name: str, _item: "Item") -> None:
method get_items_to_publish (line 367) | def get_items_to_publish(self) -> dict[str, "Item"]:
method get_unpublish_order (line 398) | def get_unpublish_order(self, items_to_unpublish: list[str]) -> list[s...
method pre_publish_all (line 413) | def pre_publish_all(self) -> None:
method post_publish_all (line 422) | def post_publish_all(self) -> None:
method post_publish_all_check (line 431) | def post_publish_all_check(self) -> None:
method _publish_items_parallel (line 448) | def _publish_items_parallel(self, items: dict[str, "Item"]) -> list[tu...
method _publish_items_sequential (line 477) | def _publish_items_sequential(self, items: dict[str, "Item"]) -> list[...
method _publish_items_ordered (line 498) | def _publish_items_ordered(self, items: dict[str, "Item"], order: list...
FILE: src/fabric_cicd/_items/_copyjob.py
class CopyJobPublisher (line 10) | class CopyJobPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_dataagent.py
class DataAgentPublisher (line 15) | class DataAgentPublisher(ItemPublisher):
method publish_one (line 20) | def publish_one(self, item_name: str, _item: Item) -> None:
FILE: src/fabric_cicd/_items/_databuildtooljob.py
class DataBuildToolJobPublisher (line 10) | class DataBuildToolJobPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_dataflowgen2.py
function set_dataflow_publish_order (line 25) | def set_dataflow_publish_order(workspace_obj: FabricWorkspace, item_type...
function contains_source_dataflow (line 118) | def contains_source_dataflow(file_content: str) -> bool:
function get_source_dataflow_ids (line 129) | def get_source_dataflow_ids(file_content: str, item_name: str) -> tuple[...
function get_source_dataflow_name (line 156) | def get_source_dataflow_name(
function func_process_file (line 196) | def func_process_file(workspace_obj: FabricWorkspace, item_obj: Item, fi...
function replace_source_dataflow_ids (line 209) | def replace_source_dataflow_ids(workspace_obj: FabricWorkspace, item_obj...
function _get_dataflow_publish_order (line 247) | def _get_dataflow_publish_order(publisher: "DataflowPublisher") -> list[...
class DataflowPublisher (line 252) | class DataflowPublisher(ItemPublisher):
method publish_one (line 260) | def publish_one(self, item_name: str, _item: Item) -> None:
FILE: src/fabric_cicd/_items/_datapipeline.py
function find_referenced_datapipelines (line 20) | def find_referenced_datapipelines(fabric_workspace_obj: FabricWorkspace,...
function _get_datapipeline_publish_order (line 50) | def _get_datapipeline_publish_order(publisher: "DataPipelinePublisher") ...
class DataPipelinePublisher (line 55) | class DataPipelinePublisher(ItemPublisher):
method get_unpublish_order (line 64) | def get_unpublish_order(self, items_to_unpublish: list[str]) -> list[s...
method publish_one (line 78) | def publish_one(self, item_name: str, _item: Item) -> None:
method pre_publish_all (line 82) | def pre_publish_all(self) -> None:
FILE: src/fabric_cicd/_items/_environment.py
function _process_environment_file (line 23) | def _process_environment_file(
function _replace_instance_pool_id (line 63) | def _replace_instance_pool_id(fabric_workspace_obj: FabricWorkspace, yam...
function _resolve_pool_id (line 109) | def _resolve_pool_id(pools: list[dict], pool_name: str, pool_type: str) ...
function _check_environment_publish_state (line 136) | def _check_environment_publish_state(fabric_workspace_obj: FabricWorkspa...
function _submit_environment_publish (line 206) | def _submit_environment_publish(fabric_workspace_obj: FabricWorkspace, i...
class EnvironmentPublisher (line 231) | class EnvironmentPublisher(ItemPublisher):
method publish_one (line 237) | def publish_one(self, item_name: str, item: Item) -> None:
method pre_publish_all (line 249) | def pre_publish_all(self) -> None:
method post_publish_all_check (line 253) | def post_publish_all_check(self) -> None:
FILE: src/fabric_cicd/_items/_eventhouse.py
class EventhousePublisher (line 15) | class EventhousePublisher(ItemPublisher):
method publish_one (line 20) | def publish_one(self, item_name: str, _item: Item) -> None:
FILE: src/fabric_cicd/_items/_eventstream.py
class EventstreamPublisher (line 10) | class EventstreamPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_graphqlapi.py
class GraphQLApiPublisher (line 10) | class GraphQLApiPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_kqldashboard.py
function func_process_file (line 19) | def func_process_file(workspace_obj: FabricWorkspace, item_obj: Item, fi...
function replace_cluster_uri (line 36) | def replace_cluster_uri(fabric_workspace_obj: FabricWorkspace, file_obj:...
class KQLDashboardPublisher (line 82) | class KQLDashboardPublisher(ItemPublisher):
method publish_one (line 87) | def publish_one(self, item_name: str, _item: Item) -> None:
method pre_publish_all (line 93) | def pre_publish_all(self) -> None:
FILE: src/fabric_cicd/_items/_kqldatabase.py
class KQLDatabasePublisher (line 10) | class KQLDatabasePublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_kqlqueryset.py
function func_process_file (line 19) | def func_process_file(workspace_obj: FabricWorkspace, item_obj: Item, fi...
function replace_cluster_uri (line 35) | def replace_cluster_uri(fabric_workspace_obj: FabricWorkspace, file_obj:...
class KQLQuerysetPublisher (line 91) | class KQLQuerysetPublisher(ItemPublisher):
method publish_one (line 96) | def publish_one(self, item_name: str, _item: Item) -> None:
method pre_publish_all (line 102) | def pre_publish_all(self) -> None:
FILE: src/fabric_cicd/_items/_lakehouse.py
function check_sqlendpoint_provision_status (line 21) | def check_sqlendpoint_provision_status(fabric_workspace_obj: FabricWorks...
function list_deployed_shortcuts (line 60) | def list_deployed_shortcuts(fabric_workspace_obj: FabricWorkspace, item_...
function replace_default_lakehouse_id (line 84) | def replace_default_lakehouse_id(shortcut: dict, item_obj: Item) -> dict:
class LakehousePublisher (line 99) | class LakehousePublisher(ItemPublisher):
method publish_one (line 104) | def publish_one(self, item_name: str, item: Item) -> None:
method post_publish_all (line 130) | def post_publish_all(self) -> None:
class ShortcutPublisher (line 140) | class ShortcutPublisher(Publisher):
method __init__ (line 143) | def __init__(self, fabric_workspace_obj: FabricWorkspace, item_obj: It...
method _unpublish_shortcuts (line 154) | def _unpublish_shortcuts(self, shortcut_paths: list) -> None:
method publish_one (line 168) | def publish_one(self, _shortcut_name: str, shortcut: dict) -> None:
method publish_all (line 195) | def publish_all(self) -> None:
FILE: src/fabric_cicd/_items/_manage_dependencies.py
function set_publish_order (line 19) | def set_publish_order(
function set_unpublish_order (line 50) | def set_unpublish_order(
function sort_items (line 89) | def sort_items(
FILE: src/fabric_cicd/_items/_mirroreddatabase.py
class MirroredDatabasePublisher (line 10) | class MirroredDatabasePublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_mlexperiment.py
class MLExperimentPublisher (line 10) | class MLExperimentPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_mounteddatafactory.py
class MountedDataFactoryPublisher (line 10) | class MountedDataFactoryPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_notebook.py
class NotebookPublisher (line 11) | class NotebookPublisher(ItemPublisher):
method publish_one (line 16) | def publish_one(self, item_name: str, item: Item) -> None:
FILE: src/fabric_cicd/_items/_ontology.py
class OntologyPublisher (line 10) | class OntologyPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_report.py
function func_process_file (line 19) | def func_process_file(workspace_obj: FabricWorkspace, item_obj: Item, fi...
class ReportPublisher (line 62) | class ReportPublisher(ItemPublisher):
method publish_one (line 67) | def publish_one(self, item_name: str, _item: Item) -> None:
FILE: src/fabric_cicd/_items/_semanticmodel.py
function build_binding_mapping_legacy (line 17) | def build_binding_mapping_legacy(fabric_workspace_obj: FabricWorkspace, ...
function build_binding_mapping (line 65) | def build_binding_mapping(
function get_connections (line 134) | def get_connections(fabric_workspace_obj: FabricWorkspace) -> dict:
function bind_semanticmodel_to_connection (line 167) | def bind_semanticmodel_to_connection(
function build_request_body (line 245) | def build_request_body(body: dict) -> dict:
class SemanticModelPublisher (line 270) | class SemanticModelPublisher(ItemPublisher):
method publish_one (line 275) | def publish_one(self, item_name: str, _item: Item) -> None:
method post_publish_all (line 281) | def post_publish_all(self) -> None:
FILE: src/fabric_cicd/_items/_sparkjobdefinition.py
class SparkJobDefinitionPublisher (line 15) | class SparkJobDefinitionPublisher(ItemPublisher):
method publish_one (line 20) | def publish_one(self, item_name: str, _item: Item) -> None:
FILE: src/fabric_cicd/_items/_sqldatabase.py
class SQLDatabasePublisher (line 16) | class SQLDatabasePublisher(ItemPublisher):
method publish_one (line 21) | def publish_one(self, item_name: str, item: Item) -> None:
FILE: src/fabric_cicd/_items/_userdatafunction.py
class UserDataFunctionPublisher (line 10) | class UserDataFunctionPublisher(ItemPublisher):
FILE: src/fabric_cicd/_items/_variablelibrary.py
function activate_value_set (line 17) | def activate_value_set(fabric_workspace_obj: FabricWorkspace, item_obj: ...
class VariableLibraryPublisher (line 49) | class VariableLibraryPublisher(ItemPublisher):
method publish_one (line 54) | def publish_one(self, item_name: str, item: Item) -> None:
FILE: src/fabric_cicd/_items/_warehouse.py
class WarehousePublisher (line 17) | class WarehousePublisher(ItemPublisher):
method publish_one (line 22) | def publish_one(self, item_name: str, item: Item) -> None:
FILE: src/fabric_cicd/_parameter/_parameter.py
class Parameter (line 26) | class Parameter:
method __init__ (line 56) | def __init__(
method _set_parameter_file_path (line 84) | def _set_parameter_file_path(self) -> None:
method _refresh_parameter_file (line 128) | def _refresh_parameter_file(self) -> None:
method _validate_parameter_file_exists (line 138) | def _validate_parameter_file_exists(self) -> bool:
method _validate_load_parameters_to_dict (line 145) | def _validate_load_parameters_to_dict(self) -> tuple[bool, dict]:
method _process_template_parameters (line 174) | def _process_template_parameters(self, base_parameter_dict: dict) -> d...
method _load_template_parameter_file (line 251) | def _load_template_parameter_file(self, file_path: Path) -> dict:
method _merge_template_dict (line 274) | def _merge_template_dict(self, base_dict: dict, template_dict: dict) -...
method _validate_parameter_load (line 309) | def _validate_parameter_load(self) -> tuple[bool, str]:
method _validate_parameter_file (line 324) | def _validate_parameter_file(self) -> bool:
method _handle_gateway_binding_parameter (line 368) | def _handle_gateway_binding_parameter(self) -> None:
method _validate_parameter_structure (line 397) | def _validate_parameter_structure(self) -> tuple[bool, str]:
method _validate_parameter_names (line 404) | def _validate_parameter_names(self) -> tuple[bool, str]:
method _validate_parameter (line 413) | def _validate_parameter(self, param_name: str) -> tuple[bool, str]:
method _validate_semantic_model_binding_parameter (line 496) | def _validate_semantic_model_binding_parameter(
method _validate_connection_id (line 618) | def _validate_connection_id(
method _check_duplicate_semantic_model_names (line 662) | def _check_duplicate_semantic_model_names(self, param_value: any, is_n...
method _validate_parameter_keys (line 685) | def _validate_parameter_keys(self, param_name: str, param_keys: list) ...
method _validate_required_values (line 699) | def _validate_required_values(self, param_name: str, param_dict: dict)...
method _validate_key_value_find_key (line 723) | def _validate_key_value_find_key(self, param_dict: dict) -> tuple[bool...
method _validate_find_regex (line 743) | def _validate_find_regex(self, param_name: str, param_dict: dict) -> t...
method _validate_replace_value (line 767) | def _validate_replace_value(self, param_name: str, replace_value: dict...
method _validate_find_replace_replace_value (line 784) | def _validate_find_replace_replace_value(self, replace_value: dict) ->...
method _validate_key_value_replace_replace_value (line 797) | def _validate_key_value_replace_replace_value(self, replace_value: dic...
method _validate_spark_pool_replace_value (line 830) | def _validate_spark_pool_replace_value(self, replace_value: dict) -> t...
method _validate_optional_values (line 864) | def _validate_optional_values(
method _validate_data_type (line 906) | def _validate_data_type(
method _validate_environment (line 922) | def _validate_environment(self, replace_value: dict) -> tuple[bool, str]:
method _validate_item_type (line 941) | def _validate_item_type(self, input_type: str) -> tuple[bool, str]:
method _validate_item_name (line 948) | def _validate_item_name(self, input_name: str) -> tuple[bool, str]:
method _validate_file_path (line 969) | def _validate_file_path(self, input_path: list[str]) -> tuple[bool, str]:
class _DuplicateKeyLoader (line 986) | class _DuplicateKeyLoader(yaml.SafeLoader):
function _collect_duplicate_key_errors (line 992) | def _collect_duplicate_key_errors(root_node: yaml.MappingNode, loader: _...
function _check_duplicate_keys_constructor (line 1031) | def _check_duplicate_keys_constructor(loader: _DuplicateKeyLoader, node:...
FILE: src/fabric_cicd/_parameter/_utils.py
function _validate_regex_structure (line 32) | def _validate_regex_structure(pattern: re.Pattern, find_value: str) -> N...
function _validate_regex_pattern (line 50) | def _validate_regex_pattern(matches: list, find_value: str) -> None:
function extract_find_value (line 69) | def extract_find_value(param_dict: dict, file_content: str, filter_match...
function extract_replace_value (line 119) | def extract_replace_value(workspace_obj: FabricWorkspace, replace_value:...
function _extract_workspace_id (line 146) | def _extract_workspace_id(workspace_obj: FabricWorkspace, replace_value:...
function _extract_item_attribute (line 240) | def _extract_item_attribute(workspace_obj: FabricWorkspace, variable: st...
function extract_parameter_filters (line 367) | def extract_parameter_filters(workspace_obj: FabricWorkspace, param_dict...
function process_environment_key (line 376) | def process_environment_key(environment: str, replace_value_dict: dict) ...
function replace_key_value (line 391) | def replace_key_value(
function replace_variables_in_parameter_file (line 440) | def replace_variables_in_parameter_file(raw_file: str) -> str:
function validate_parameter_file (line 466) | def validate_parameter_file(
function is_valid_structure (line 505) | def is_valid_structure(param_dict: dict, param_name: Optional[str] = Non...
function _check_parameter_structure (line 543) | def _check_parameter_structure(param_value: any) -> bool:
function _check_semantic_model_binding_structure (line 548) | def _check_semantic_model_binding_structure(param_value: any) -> tuple[b...
function process_input_path (line 570) | def process_input_path(
function _process_regular_path (line 612) | def _process_regular_path(
function _process_wildcard_path (line 628) | def _process_wildcard_path(
function _set_wildcard_path_pattern (line 656) | def _set_wildcard_path_pattern(wildcard_path: str, repository_directory:...
function _resolve_file_path (line 683) | def _resolve_file_path(
function _validate_wildcard_syntax (line 727) | def _validate_wildcard_syntax(pattern: str, log_func: logging.Logger) ->...
function _validate_nested_brackets_braces (line 797) | def _validate_nested_brackets_braces(pattern: str, log_func: logging.Log...
function check_replacement (line 827) | def check_replacement(
function _find_match (line 871) | def _find_match(
FILE: src/fabric_cicd/constants.py
class EnvVar (line 20) | class EnvVar(str, Enum):
class ItemType (line 43) | class ItemType(str, Enum):
class FeatureFlag (line 108) | class FeatureFlag(str, Enum):
class OperationType (line 145) | class OperationType(str, Enum):
FILE: src/fabric_cicd/fabric_workspace.py
class FabricWorkspace (line 28) | class FabricWorkspace:
method __init__ (line 31) | def __init__(
method base_api_url (line 181) | def base_api_url(self) -> str:
method _resolve_workspace_id (line 185) | def _resolve_workspace_id(self, workspace_name: str) -> str:
method _resolve_workspace_name (line 194) | def _resolve_workspace_name(self) -> str:
method _lookup_item_attribute (line 202) | def _lookup_item_attribute(self, workspace_id: str, item_type: str, it...
method _get_item_attribute (line 218) | def _get_item_attribute(
method _get_workspace_pools (line 267) | def _get_workspace_pools(self) -> list[dict]:
method _refresh_parameter_file (line 292) | def _refresh_parameter_file(self) -> None:
method _refresh_repository_items (line 314) | def _refresh_repository_items(self) -> None:
method _refresh_deployed_items (line 411) | def _refresh_deployed_items(self) -> None:
method _replace_logical_ids (line 467) | def _replace_logical_ids(self, raw_file: str) -> str:
method _replace_parameters (line 491) | def _replace_parameters(self, file_obj: object, item_obj: object) -> str:
method _replace_workspace_ids (line 568) | def _replace_workspace_ids(self, raw_file: str) -> str:
method _convert_id_to_name (line 587) | def _convert_id_to_name(self, item_type: str, generic_id: str, lookup_...
method _convert_path_to_id (line 605) | def _convert_path_to_id(self, item_type: str, path: str) -> str:
method _publish_item (line 620) | def _publish_item(
method _unpublish_item (line 804) | def _unpublish_item(self, item_name: str, item_type: str) -> None:
method _refresh_deployed_folders (line 839) | def _refresh_deployed_folders(self) -> None:
method _refresh_repository_folders (line 886) | def _refresh_repository_folders(self) -> None:
method _publish_folders (line 922) | def _publish_folders(self) -> None:
method _unpublish_folders (line 988) | def _unpublish_folders(self) -> None:
FILE: src/fabric_cicd/publish.py
function publish_all_items (line 38) | def publish_all_items(
function unpublish_all_orphan_items (line 269) | def unpublish_all_orphan_items(
function deploy_with_config (line 401) | def deploy_with_config(
function _collect_responses (line 580) | def _collect_responses(workspace: Optional[FabricWorkspace], responses_e...
FILE: tests/fixtures/credentials.py
function create_dummy_jwt (line 15) | def create_dummy_jwt(expiry_timestamp: int) -> str:
class DummyTokenCredential (line 39) | class DummyTokenCredential(TokenCredential):
method __init__ (line 42) | def __init__(self, expiry_days: int = 365):
method get_token (line 53) | def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken: # no...
method get_expire (line 58) | def get_expire(self) -> int:
FILE: tests/fixtures/mock_fabric_server.py
class TraceIndex (line 42) | class TraceIndex:
method __init__ (line 48) | def __init__(self):
method normalize_route (line 54) | def normalize_route(route: str) -> str:
method extract_content_key (line 59) | def extract_content_key(body: Any, method: str) -> Optional[tuple[str,...
method add_trace (line 65) | def add_trace(self, request: HTTPRequest, response: HTTPResponse):
class MockFabricAPIHandler (line 91) | class MockFabricAPIHandler(BaseHTTPRequestHandler):
method log_message (line 99) | def log_message(self, format, *args): # noqa: A002
method do_GET (line 102) | def do_GET(self): # noqa: N802
method do_POST (line 105) | def do_POST(self): # noqa: N802
method do_PATCH (line 108) | def do_PATCH(self): # noqa: N802
method do_DELETE (line 111) | def do_DELETE(self): # noqa: N802
method _read_request_body (line 114) | def _read_request_body(self) -> Optional[dict]:
method _handle_request (line 123) | def _handle_request(self, method: str):
method _find_matching_response (line 149) | def _find_matching_response(self, method: str, route: str, request_bod...
method _handle_item_creation (line 176) | def _handle_item_creation(self, content_key: tuple[str, str, str]) -> ...
method _handle_operation_request (line 197) | def _handle_operation_request(self, operation_id: str, is_result: bool...
method _send_response (line 236) | def _send_response(self, response: HTTPResponse, route_key: str):
method load_trace_data (line 262) | def load_trace_data(cls, trace_file: Path):
class MockFabricServer (line 298) | class MockFabricServer:
method __init__ (line 303) | def __init__(self, trace_file: Path, port: int = MOCK_SERVER_PORT):
method start (line 309) | def start(self):
method stop (line 317) | def stop(self):
FILE: tests/test__check_utils.py
function text_file (line 12) | def text_file(tmp_path):
function binary_file (line 19) | def binary_file(tmp_path):
function image_file (line 28) | def image_file(tmp_path):
function test_check_file_type_text (line 34) | def test_check_file_type_text(text_file):
function test_check_file_type_binary (line 38) | def test_check_file_type_binary(binary_file):
function test_check_file_type_image (line 42) | def test_check_file_type_image(image_file):
function real_schedules_file (line 47) | def real_schedules_file(tmp_path):
function test_schedules_file_json_validation_and_structure (line 76) | def test_schedules_file_json_validation_and_structure(real_schedules_file):
function test_schedules_file_jsonpath_compatibility (line 103) | def test_schedules_file_jsonpath_compatibility(real_schedules_file):
function test_real_sample_schedules_file (line 127) | def test_real_sample_schedules_file():
function test_check_valid_json_content_with_valid_json (line 148) | def test_check_valid_json_content_with_valid_json():
function test_check_valid_json_content_with_invalid_json (line 154) | def test_check_valid_json_content_with_invalid_json():
function test_check_valid_json_content_with_empty_string (line 160) | def test_check_valid_json_content_with_empty_string():
function test_check_valid_json_content_with_schedules_structure (line 165) | def test_check_valid_json_content_with_schedules_structure():
function test_check_valid_yaml_content_with_valid_yaml (line 173) | def test_check_valid_yaml_content_with_valid_yaml():
function test_check_valid_yaml_content_with_invalid_yaml (line 183) | def test_check_valid_yaml_content_with_invalid_yaml():
function test_check_valid_yaml_content_with_empty_string (line 189) | def test_check_valid_yaml_content_with_empty_string():
function test_check_valid_yaml_content_with_spark_compute_structure (line 195) | def test_check_valid_yaml_content_with_spark_compute_structure():
function test_check_valid_yaml_content_with_complex_structure (line 212) | def test_check_valid_yaml_content_with_complex_structure():
function test_check_valid_yaml_content_vs_json_content (line 234) | def test_check_valid_yaml_content_vs_json_content():
function test_check_valid_yaml_content_with_notebook_py_content (line 250) | def test_check_valid_yaml_content_with_notebook_py_content():
function test_check_valid_yaml_content_with_kql_content (line 269) | def test_check_valid_yaml_content_with_kql_content():
function test_check_valid_yaml_content_with_plain_python_content (line 280) | def test_check_valid_yaml_content_with_plain_python_content():
FILE: tests/test__fabric_endpoint.py
class DummyLogger (line 16) | class DummyLogger:
method __init__ (line 17) | def __init__(self):
method info (line 20) | def info(self, message):
method debug (line 23) | def debug(self, message):
class DummyCredential (line 27) | class DummyCredential:
method __init__ (line 28) | def __init__(self, token, expires_on=9999999999):
method get_token (line 33) | def get_token(self, *_, **__):
function setup_mocks (line 40) | def setup_mocks(monkeypatch, mocker):
function generate_mock_token (line 51) | def generate_mock_token():
function test_integration (line 55) | def test_integration(setup_mocks):
function test_performance (line 68) | def test_performance(setup_mocks):
function test_invoke (line 93) | def test_invoke(setup_mocks, method, url, body, files):
function test_invoke_token_expired (line 106) | def test_invoke_token_expired(setup_mocks, monkeypatch):
function test_invoke_exception (line 127) | def test_invoke_exception(setup_mocks):
function test_invoke_poll_long_running_false_with_202 (line 138) | def test_invoke_poll_long_running_false_with_202(setup_mocks):
function test_invoke_poll_long_running_true_with_202 (line 157) | def test_invoke_poll_long_running_true_with_202(setup_mocks, monkeypatch):
function test_invoke_poll_long_running_default_with_202 (line 191) | def test_invoke_poll_long_running_default_with_202(setup_mocks, monkeypa...
function test_refresh_token (line 226) | def test_refresh_token(setup_mocks):
function test_refresh_token_exceptions (line 244) | def test_refresh_token_exceptions(raise_exception, expected_msg):
function test_handle_response (line 278) | def test_handle_response(
function test_handle_response_longrunning_exception (line 314) | def test_handle_response_longrunning_exception(exception_match, response...
function test_handle_response_exceptions (line 402) | def test_handle_response_exceptions(
function test_handle_response_feature_not_available (line 427) | def test_handle_response_feature_not_available():
function test_handle_response_item_display_name_already_in_use (line 441) | def test_handle_response_item_display_name_already_in_use(setup_mocks, m...
function test_handle_response_environment_libraries_not_found (line 457) | def test_handle_response_environment_libraries_not_found(setup_mocks):
function test_format_invoke_log (line 473) | def test_format_invoke_log():
FILE: tests/test__file.py
function text_file (line 16) | def text_file(tmp_path):
function image_file (line 25) | def image_file(tmp_path):
function test_file_text_initialization (line 33) | def test_file_text_initialization(text_file):
function test_file_text_payload (line 39) | def test_file_text_payload(text_file):
function test_file_text_set_contents (line 48) | def test_file_text_set_contents(text_file):
function test_file_image_immutable_fields (line 53) | def test_file_image_immutable_fields(image_file):
function test_file_image_payload (line 62) | def test_file_image_payload(image_file):
function test_file_text_special_characters (line 71) | def test_file_text_special_characters(tmp_path):
FILE: tests/test_config_validator.py
class TestConfigValidator (line 16) | class TestConfigValidator:
method setup_method (line 19) | def setup_method(self):
method test_init (line 23) | def test_init(self):
method test_validate_file_existence_valid_file (line 30) | def test_validate_file_existence_valid_file(self, tmp_path):
method test_validate_file_existence_missing_file (line 40) | def test_validate_file_existence_missing_file(self):
method test_validate_file_existence_empty_or_none_path (line 51) | def test_validate_file_existence_empty_or_none_path(self, path_value):
method test_validate_file_existence_directory_instead_of_file (line 59) | def test_validate_file_existence_directory_instead_of_file(self, tmp_p...
method test_validate_file_existence_invalid_path_os_error (line 67) | def test_validate_file_existence_invalid_path_os_error(self):
method test_validate_yaml_content_valid_yaml (line 79) | def test_validate_yaml_content_valid_yaml(self, tmp_path):
method test_validate_yaml_content_invalid_yaml (line 91) | def test_validate_yaml_content_invalid_yaml(self, tmp_path):
method test_validate_yaml_content_unicode_decode_error (line 104) | def test_validate_yaml_content_unicode_decode_error(self, tmp_path):
method test_validate_yaml_content_permission_error (line 116) | def test_validate_yaml_content_permission_error(self, tmp_path):
method test_validate_yaml_content_unexpected_error (line 129) | def test_validate_yaml_content_unexpected_error(self, tmp_path):
method test_validate_yaml_content_non_dict_yaml (line 142) | def test_validate_yaml_content_non_dict_yaml(self, tmp_path):
method test_validate_yaml_content_none_path (line 154) | def test_validate_yaml_content_none_path(self):
method test_validate_yaml_content_empty_file (line 161) | def test_validate_yaml_content_empty_file(self, tmp_path):
method test_validate_config_structure_valid (line 173) | def test_validate_config_structure_valid(self):
method test_validate_config_structure_non_dict_or_none (line 182) | def test_validate_config_structure_non_dict_or_none(self, config_value):
method test_validate_config_structure_missing_core (line 192) | def test_validate_config_structure_missing_core(self):
method test_validate_config_structure_core_not_dict (line 201) | def test_validate_config_structure_core_not_dict(self):
method test_validate_workspace_field_valid_string (line 210) | def test_validate_workspace_field_valid_string(self):
method test_validate_workspace_field_valid_workspace_id_guid (line 219) | def test_validate_workspace_field_valid_workspace_id_guid(self):
method test_validate_workspace_field_invalid_workspace_id_guid (line 228) | def test_validate_workspace_field_invalid_workspace_id_guid(self):
method test_validate_workspace_field_valid_dict (line 238) | def test_validate_workspace_field_valid_dict(self):
method test_validate_workspace_field_valid_workspace_id_dict (line 247) | def test_validate_workspace_field_valid_workspace_id_dict(self):
method test_validate_workspace_field_invalid_workspace_id_dict (line 261) | def test_validate_workspace_field_invalid_workspace_id_dict(self):
method test_validate_workspace_field_missing (line 272) | def test_validate_workspace_field_missing(self):
method test_validate_workspace_field_empty_string (line 281) | def test_validate_workspace_field_empty_string(self):
method test_validate_workspace_field_invalid_type (line 293) | def test_validate_workspace_field_invalid_type(self):
method test_validate_environment_mapping_valid (line 303) | def test_validate_environment_mapping_valid(self):
method test_validate_environment_mapping_empty (line 312) | def test_validate_environment_mapping_empty(self):
method test_validate_environment_mapping_invalid_env_key (line 322) | def test_validate_environment_mapping_invalid_env_key(self):
method test_validate_environment_mapping_wrong_value_type (line 332) | def test_validate_environment_mapping_wrong_value_type(self):
method test_validate_environment_mapping_empty_string_value (line 342) | def test_validate_environment_mapping_empty_string_value(self):
method test_validate_environment_mapping_empty_list_value (line 352) | def test_validate_environment_mapping_empty_list_value(self):
method test_validate_repository_directory_empty_string (line 362) | def test_validate_repository_directory_empty_string(self):
method test_validate_repository_directory_valid_string (line 374) | def test_validate_repository_directory_valid_string(self):
method test_validate_repository_directory_missing (line 382) | def test_validate_repository_directory_missing(self):
method test_validate_repository_directory_invalid_type (line 391) | def test_validate_repository_directory_invalid_type(self):
method test_validate_repository_directory_valid_env_mapping (line 400) | def test_validate_repository_directory_valid_env_mapping(self):
method test_validate_repository_directory_invalid_env_mapping (line 408) | def test_validate_repository_directory_invalid_env_mapping(self):
method test_validate_item_types_valid_list (line 420) | def test_validate_item_types_valid_list(self):
method test_validate_item_types_empty_list (line 428) | def test_validate_item_types_empty_list(self):
method test_validate_item_types_invalid_type (line 437) | def test_validate_item_types_invalid_type(self):
method test_validate_item_types_unknown_item_type (line 446) | def test_validate_item_types_unknown_item_type(self):
method test_validate_item_types_with_env_context (line 456) | def test_validate_item_types_with_env_context(self):
method test_validate_item_types_in_scope_invalid_env_mapping (line 465) | def test_validate_item_types_in_scope_invalid_env_mapping(self):
method test_validate_regex_valid (line 477) | def test_validate_regex_valid(self):
method test_validate_regex_invalid (line 483) | def test_validate_regex_invalid(self):
method test_validate_items_list_valid (line 490) | def test_validate_items_list_valid(self):
method test_validate_items_list_invalid_type (line 498) | def test_validate_items_list_invalid_type(self):
method test_validate_items_list_empty_item (line 507) | def test_validate_items_list_empty_item(self):
method test_validate_features_list_valid (line 519) | def test_validate_features_list_valid(self):
method test_validate_features_list_invalid_type (line 527) | def test_validate_features_list_invalid_type(self):
method test_validate_features_list_empty_feature (line 536) | def test_validate_features_list_empty_feature(self):
method test_validate_constants_dict_invalid_or_empty_key (line 549) | def test_validate_constants_dict_invalid_or_empty_key(self, key_value):
method test_validate_constants_dict_unknown_constant (line 558) | def test_validate_constants_dict_unknown_constant(self):
method test_validate_constants_dict_valid_various_types (line 567) | def test_validate_constants_dict_valid_various_types(self):
method test_validate_constants_dict_url_constant_non_string_type (line 578) | def test_validate_constants_dict_url_constant_non_string_type(self):
method test_validate_constants_dict_url_constant_invalid_hostname (line 587) | def test_validate_constants_dict_url_constant_invalid_hostname(self):
method test_validate_constants_dict_url_constant_http_scheme (line 596) | def test_validate_constants_dict_url_constant_http_scheme(self):
method test_validate_constants_dict_url_constant_with_path (line 605) | def test_validate_constants_dict_url_constant_with_path(self):
method test_validate_constants_dict_url_constant_valid_powerbi (line 614) | def test_validate_constants_dict_url_constant_valid_powerbi(self):
method test_validate_constants_dict_non_url_constant_skips_url_validation (line 622) | def test_validate_constants_dict_non_url_constant_skips_url_validation...
method test_validate_item_types_in_scope_valid_list (line 630) | def test_validate_item_types_in_scope_valid_list(self):
method test_validate_item_types_in_scope_empty_list (line 638) | def test_validate_item_types_in_scope_empty_list(self):
method test_validate_item_types_in_scope_environment_mapping (line 647) | def test_validate_item_types_in_scope_environment_mapping(self):
method test_validate_item_types_in_scope_invalid_type (line 655) | def test_validate_item_types_in_scope_invalid_type(self):
method test_validate_item_types_in_scope_missing_field (line 664) | def test_validate_item_types_in_scope_missing_field(self):
method test_resolve_repository_path_absolute_path (line 672) | def test_resolve_repository_path_absolute_path(self, tmp_path):
method test_resolve_repository_path_relative_path (line 686) | def test_resolve_repository_path_relative_path(self, tmp_path):
method test_resolve_repository_path_nonexistent_directory (line 704) | def test_resolve_repository_path_nonexistent_directory(self, tmp_path):
method test_resolve_repository_path_file_instead_of_directory (line 714) | def test_resolve_repository_path_file_instead_of_directory(self, tmp_p...
method test_resolve_repository_path_environment_mapping (line 728) | def test_resolve_repository_path_environment_mapping(self, tmp_path):
method test_validate_parameter_field_valid_configurations (line 746) | def test_validate_parameter_field_valid_configurations(self):
method test_validate_parameter_field_invalid_configurations (line 761) | def test_validate_parameter_field_invalid_configurations(self):
method test_validate_parameter_field_invalid_env_mapping (line 781) | def test_validate_parameter_field_invalid_env_mapping(self):
method test_resolve_parameter_path_basic_functionality (line 793) | def test_resolve_parameter_path_basic_functionality(self, tmp_path):
method test_resolve_path_field_directory_relative_path (line 816) | def test_resolve_path_field_directory_relative_path(self, tmp_path):
method test_resolve_path_field_file_absolute_path (line 833) | def test_resolve_path_field_file_absolute_path(self, tmp_path):
method test_resolve_path_field_git_repo_mismatch (line 850) | def test_resolve_path_field_git_repo_mismatch(self, tmp_path):
method test_resolve_path_field_file_type_but_is_directory (line 867) | def test_resolve_path_field_file_type_but_is_directory(self, tmp_path):
method test_resolve_path_field_os_error (line 880) | def test_resolve_path_field_os_error(self, tmp_path):
method test_resolve_path_field_environment_mapping (line 893) | def test_resolve_path_field_environment_mapping(self, tmp_path):
method test_resolve_path_field_environment_not_in_mapping (line 919) | def test_resolve_path_field_environment_not_in_mapping(self, tmp_path):
method test_resolve_path_field_nonexistent_path (line 941) | def test_resolve_path_field_nonexistent_path(self, tmp_path):
method test_resolve_path_field_wrong_type_file_vs_directory (line 951) | def test_resolve_path_field_wrong_type_file_vs_directory(self, tmp_path):
method test_resolve_path_field_no_config_path (line 965) | def test_resolve_path_field_no_config_path(self):
method test_environment_exists_valid (line 977) | def test_environment_exists_valid(self):
method test_environment_exists_missing_environment (line 986) | def test_environment_exists_missing_environment(self):
method test_environment_exists_no_environment_with_mapping (line 996) | def test_environment_exists_no_environment_with_mapping(self):
method test_environment_exists_no_environment_no_mapping (line 1006) | def test_environment_exists_no_environment_no_mapping(self):
method test_valid_override_section (line 1058) | def test_valid_override_section(self, section, value, expected_result,...
method test_merge_overrides_basic_sections (line 1130) | def test_merge_overrides_basic_sections(self, section, initial_config,...
method test_merge_overrides_core_section (line 1225) | def test_merge_overrides_core_section(
method test_merge_overrides_workspace_identifiers (line 1308) | def test_merge_overrides_workspace_identifiers(
method test_apply_and_validate_overrides (line 1385) | def test_apply_and_validate_overrides(
method test_validate_config_file_with_overrides_integration (line 1407) | def test_validate_config_file_with_overrides_integration(self, tmp_path):
method test_validate_config_file_with_invalid_overrides_integration (line 1434) | def test_validate_config_file_with_invalid_overrides_integration(self,...
class TestConfigValidatorUtilityFunctions (line 1458) | class TestConfigValidatorUtilityFunctions:
method test_find_git_root_with_git_repo (line 1461) | def test_find_git_root_with_git_repo(self, tmp_path):
method test_find_git_root_no_git_repo (line 1479) | def test_find_git_root_no_git_repo(self, tmp_path):
method test_validate_guid_format_valid (line 1486) | def test_validate_guid_format_valid(self):
method test_validate_guid_format_invalid (line 1499) | def test_validate_guid_format_invalid(self):
method test_get_config_fields_complete_config (line 1515) | def test_get_config_fields_complete_config(self):
class TestConfigValidatorIntegration (line 1566) | class TestConfigValidatorIntegration:
method test_validate_config_file_complete_success (line 1569) | def test_validate_config_file_complete_success(self, tmp_path):
method test_validate_config_file_accumulates_errors (line 1597) | def test_validate_config_file_accumulates_errors(self, tmp_path):
method test_validate_config_file_stops_at_yaml_parse_error (line 1623) | def test_validate_config_file_stops_at_yaml_parse_error(self, tmp_path):
method test_validate_config_file_catches_guid_and_constants_errors (line 1636) | def test_validate_config_file_catches_guid_and_constants_errors(self, ...
class TestConfigSectionValidation (line 1669) | class TestConfigSectionValidation:
method setup_method (line 1672) | def setup_method(self):
method test_validate_config_sections_missing_core (line 1676) | def test_validate_config_sections_missing_core(self):
method test_validate_config_sections_core_not_dict (line 1685) | def test_validate_config_sections_core_not_dict(self):
method test_validate_config_sections_core_only (line 1694) | def test_validate_config_sections_core_only(self):
method test_validate_config_sections_with_optional_sections (line 1704) | def test_validate_config_sections_with_optional_sections(self):
method test_validate_config_sections_missing_workspace_identifier (line 1719) | def test_validate_config_sections_missing_workspace_identifier(self):
class TestOperationSectionValidation (line 1729) | class TestOperationSectionValidation:
method setup_method (line 1732) | def setup_method(self):
method test_validate_operation_section_valid_basic (line 1736) | def test_validate_operation_section_valid_basic(self):
method test_validate_operation_section_not_dict (line 1748) | def test_validate_operation_section_not_dict(self):
method test_validate_operation_section_valid_regex_field (line 1760) | def test_validate_operation_section_valid_regex_field(self, regex_field):
method test_validate_operation_section_invalid_regex_field (line 1769) | def test_validate_operation_section_invalid_regex_field(self, regex_fi...
method test_validate_operation_section_empty_regex_field (line 1786) | def test_validate_operation_section_empty_regex_field(self, regex_fiel...
method test_validate_operation_section_regex_field_invalid_type (line 1796) | def test_validate_operation_section_regex_field_invalid_type(self, reg...
method test_validate_operation_section_regex_field_environment_mapping (line 1806) | def test_validate_operation_section_regex_field_environment_mapping(se...
method test_validate_operation_section_regex_field_invalid_env_mapping (line 1815) | def test_validate_operation_section_regex_field_invalid_env_mapping(se...
method test_validate_operation_section_regex_field_rejected_in_unpublish (line 1826) | def test_validate_operation_section_regex_field_rejected_in_unpublish(...
method test_validate_operation_section_empty_items_to_include (line 1836) | def test_validate_operation_section_empty_items_to_include(self):
method test_validate_operation_section_items_to_include_valid_env_mapping (line 1848) | def test_validate_operation_section_items_to_include_valid_env_mapping...
method test_validate_operation_section_items_to_include_invalid_env_mapping (line 1856) | def test_validate_operation_section_items_to_include_invalid_env_mappi...
method test_validate_operation_section_items_to_include_invalid_type (line 1866) | def test_validate_operation_section_items_to_include_invalid_type(self):
method test_validate_operation_section_skip_boolean (line 1880) | def test_validate_operation_section_skip_boolean(self):
method test_validate_operation_section_skip_environment_mapping (line 1888) | def test_validate_operation_section_skip_environment_mapping(self):
method test_validate_operation_section_skip_invalid_type (line 1896) | def test_validate_operation_section_skip_invalid_type(self):
method test_validate_operation_section_skip_invalid_env_mapping (line 1910) | def test_validate_operation_section_skip_invalid_env_mapping(self):
method test_validate_operation_section_folder_path_to_include_valid_list (line 1922) | def test_validate_operation_section_folder_path_to_include_valid_list(...
method test_validate_operation_section_folder_path_to_include_valid_env_mapping (line 1930) | def test_validate_operation_section_folder_path_to_include_valid_env_m...
method test_validate_operation_section_folder_path_to_include_empty_list (line 1938) | def test_validate_operation_section_folder_path_to_include_empty_list(...
method test_validate_operation_section_folder_path_to_include_invalid_type (line 1950) | def test_validate_operation_section_folder_path_to_include_invalid_typ...
method test_validate_operation_section_folder_path_to_include_unsupported_in_unpublish (line 1962) | def test_validate_operation_section_folder_path_to_include_unsupported...
method test_validate_operation_section_folder_path_to_include_entry_not_string (line 1976) | def test_validate_operation_section_folder_path_to_include_entry_not_s...
method test_validate_operation_section_folder_path_to_include_empty_string_entry (line 1990) | def test_validate_operation_section_folder_path_to_include_empty_strin...
method test_validate_operation_section_folder_path_to_include_missing_prefix (line 2004) | def test_validate_operation_section_folder_path_to_include_missing_pre...
method test_validate_operation_section_folder_path_to_include_env_mapping_empty_list (line 2018) | def test_validate_operation_section_folder_path_to_include_env_mapping...
method test_validate_operation_section_folder_path_to_include_env_mapping_invalid_entry (line 2032) | def test_validate_operation_section_folder_path_to_include_env_mapping...
method test_validate_operation_section_folder_path_to_include_nested_path (line 2046) | def test_validate_operation_section_folder_path_to_include_nested_path...
method test_validate_operation_section_folder_path_to_include_whitespace_entry (line 2054) | def test_validate_operation_section_folder_path_to_include_whitespace_...
method test_validate_operation_section_mutually_exclusive_both_direct_values (line 2070) | def test_validate_operation_section_mutually_exclusive_both_direct_val...
method test_validate_operation_section_mutually_exclusive_both_env_mapped_overlapping (line 2084) | def test_validate_operation_section_mutually_exclusive_both_env_mapped...
method test_validate_operation_section_mutually_exclusive_both_env_mapped_no_overlap (line 2102) | def test_validate_operation_section_mutually_exclusive_both_env_mapped...
method test_validate_operation_section_mutually_exclusive_direct_and_env_mapped_conflict (line 2118) | def test_validate_operation_section_mutually_exclusive_direct_and_env_...
method test_validate_operation_section_mutually_exclusive_direct_and_env_mapped_no_conflict (line 2136) | def test_validate_operation_section_mutually_exclusive_direct_and_env_...
method test_validate_operation_section_mutually_exclusive_env_mapped_and_direct_conflict (line 2152) | def test_validate_operation_section_mutually_exclusive_env_mapped_and_...
method test_validate_operation_section_mutually_exclusive_only_one_field_present (line 2170) | def test_validate_operation_section_mutually_exclusive_only_one_field_...
class TestFeaturesSectionValidation (line 2182) | class TestFeaturesSectionValidation:
method setup_method (line 2185) | def setup_method(self):
method test_validate_features_section_list (line 2189) | def test_validate_features_section_list(self):
method test_validate_features_section_empty_list (line 2197) | def test_validate_features_section_empty_list(self):
method test_validate_features_section_environment_mapping (line 2206) | def test_validate_features_section_environment_mapping(self):
method test_validate_features_section_invalid_type (line 2214) | def test_validate_features_section_invalid_type(self):
method test_validate_features_section_env_mapping_empty_list_for_env (line 2223) | def test_validate_features_section_env_mapping_empty_list_for_env(self):
class TestConstantsSectionValidation (line 2236) | class TestConstantsSectionValidation:
method setup_method (line 2239) | def setup_method(self):
method test_validate_constants_section_dict (line 2243) | def test_validate_constants_section_dict(self):
method test_validate_constants_section_not_dict (line 2252) | def test_validate_constants_section_not_dict(self):
method test_validate_constants_section_environment_mapping (line 2261) | def test_validate_constants_section_environment_mapping(self):
method test_validate_constants_section_rejects_env_at_top_format (line 2274) | def test_validate_constants_section_rejects_env_at_top_format(self):
method test_validate_constants_section_env_mapping_invalid_env_key (line 2287) | def test_validate_constants_section_env_mapping_invalid_env_key(self):
method test_validate_constants_section_env_mapping_url_validation (line 2304) | def test_validate_constants_section_env_mapping_url_validation(self):
method test_validate_constants_section_env_mapping_non_string_url (line 2318) | def test_validate_constants_section_env_mapping_non_string_url(self):
class TestEnvironmentMismatchValidation (line 2332) | class TestEnvironmentMismatchValidation:
method setup_method (line 2335) | def setup_method(self):
method test_environment_mismatch_in_workspace_id (line 2339) | def test_environment_mismatch_in_workspace_id(self):
method test_environment_mismatch_in_multiple_fields (line 2352) | def test_environment_mismatch_in_multiple_fields(self):
method test_environment_mapping_vs_basic_values_mixed (line 2373) | def test_environment_mapping_vs_basic_values_mixed(self):
method test_environment_mapping_vs_basic_values_mismatch (line 2395) | def test_environment_mapping_vs_basic_values_mismatch(self):
method test_environment_mismatch_optional_fields_log_only (line 2419) | def test_environment_mismatch_optional_fields_log_only(self):
method test_environment_mismatch_required_fields_error (line 2452) | def test_environment_mismatch_required_fields_error(self):
method test_environment_exists_constants_per_key_env_missing (line 2470) | def test_environment_exists_constants_per_key_env_missing(self):
method test_environment_exists_constants_per_key_env_present (line 2494) | def test_environment_exists_constants_per_key_env_present(self):
method test_environment_exists_constants_flat_value_no_env_check (line 2513) | def test_environment_exists_constants_flat_value_no_env_check(self):
method test_environment_na_with_constants_env_mapping_no_error (line 2530) | def test_environment_na_with_constants_env_mapping_no_error(self):
FILE: tests/test_deploy_with_config.py
class TestConfigFileLoading (line 24) | class TestConfigFileLoading:
method test_load_valid_config_file (line 27) | def test_load_valid_config_file(self, tmp_path):
method test_load_config_file_with_override (line 52) | def test_load_config_file_with_override(self, tmp_path):
method test_load_nonexistent_config_file (line 87) | def test_load_nonexistent_config_file(self):
method test_load_invalid_yaml_syntax (line 92) | def test_load_invalid_yaml_syntax(self, tmp_path):
method test_load_non_dict_yaml (line 100) | def test_load_non_dict_yaml(self, tmp_path):
method test_load_config_missing_core_section (line 108) | def test_load_config_missing_core_section(self, tmp_path):
class TestWorkspaceSettingsExtraction (line 119) | class TestWorkspaceSettingsExtraction:
method test_extract_workspace_id_by_environment (line 122) | def test_extract_workspace_id_by_environment(self):
method test_extract_workspace_name_by_environment (line 138) | def test_extract_workspace_name_by_environment(self):
method test_extract_single_workspace_id (line 151) | def test_extract_single_workspace_id(self, tmp_path):
method test_extract_missing_environment (line 170) | def test_extract_missing_environment(self, tmp_path):
method test_extract_missing_workspace_config (line 187) | def test_extract_missing_workspace_config(self, tmp_path):
method test_extract_missing_repository_directory (line 200) | def test_extract_missing_repository_directory(self, tmp_path):
method test_extract_optional_item_types (line 213) | def test_extract_optional_item_types(self):
method test_extract_parameter_file_path_string (line 226) | def test_extract_parameter_file_path_string(self):
method test_extract_parameter_file_path_environment_mapping (line 239) | def test_extract_parameter_file_path_environment_mapping(self):
method test_extract_parameter_file_path_missing (line 258) | def test_extract_parameter_file_path_missing(self):
class TestPublishSettingsExtraction (line 271) | class TestPublishSettingsExtraction:
method testextract_publish_settings_with_skip (line 274) | def testextract_publish_settings_with_skip(self):
method testextract_publish_settings_with_items_to_include (line 290) | def testextract_publish_settings_with_items_to_include(self):
method testextract_publish_settings_no_config (line 301) | def testextract_publish_settings_no_config(self):
method testextract_publish_settings_single_skip_value (line 308) | def testextract_publish_settings_single_skip_value(self):
method test_extract_publish_settings_with_shortcut_exclude_regex (line 319) | def test_extract_publish_settings_with_shortcut_exclude_regex(self):
method test_extract_publish_settings_with_environment_specific_shortcut_exclude_regex (line 330) | def test_extract_publish_settings_with_environment_specific_shortcut_e...
class TestUnpublishSettingsExtraction (line 345) | class TestUnpublishSettingsExtraction:
method testextract_unpublish_settings_with_skip (line 348) | def testextract_unpublish_settings_with_skip(self):
method testextract_unpublish_settings_no_config (line 364) | def testextract_unpublish_settings_no_config(self):
class TestConfigOverrides (line 372) | class TestConfigOverrides:
method test_feature_flags_applied_within_scope (line 375) | def test_feature_flags_applied_within_scope(self):
method test_feature_flags_restored_after_scope (line 390) | def test_feature_flags_restored_after_scope(self):
method test_constants_overrides_applied_within_scope (line 402) | def test_constants_overrides_applied_within_scope(self):
method test_constants_overrides_restored_after_scope (line 413) | def test_constants_overrides_restored_after_scope(self):
method test_user_constants_preserved_across_scope (line 423) | def test_user_constants_preserved_across_scope(self):
method test_user_constant_same_key_restored_after_scope (line 441) | def test_user_constant_same_key_restored_after_scope(self):
method test_no_overrides_does_not_error (line 456) | def test_no_overrides_does_not_error(self):
method test_overrides_restored_on_exception (line 466) | def test_overrides_restored_on_exception(self):
method test_user_flags_preserved_across_scope (line 482) | def test_user_flags_preserved_across_scope(self):
method test_environment_specific_feature_flags (line 500) | def test_environment_specific_feature_flags(self):
method test_environment_specific_constants (line 516) | def test_environment_specific_constants(self):
class TestConfigOverridesIntegration (line 534) | class TestConfigOverridesIntegration:
method test_response_collection_via_config_features (line 540) | def test_response_collection_via_config_features(self, mock_unpublish,...
method test_failure_with_partial_responses_via_config_features (line 575) | def test_failure_with_partial_responses_via_config_features(
class TestDeployWithConfig (line 613) | class TestDeployWithConfig:
method test_deploy_with_config_full_deployment (line 619) | def test_deploy_with_config_full_deployment(self, mock_unpublish, mock...
method test_deploy_with_config_skip_operations (line 682) | def test_deploy_with_config_skip_operations(self, mock_unpublish, mock...
method test_deploy_with_config_missing_file (line 719) | def test_deploy_with_config_missing_file(self):
method test_deploy_with_config_with_token_credential (line 727) | def test_deploy_with_config_with_token_credential(self, mock_unpublish...
method test_deploy_with_config_with_config_override (line 770) | def test_deploy_with_config_with_config_override(self, mock_unpublish,...
method test_deploy_with_config_shortcut_exclude_regex (line 821) | def test_deploy_with_config_shortcut_exclude_regex(self, mock_unpublis...
method test_folder_path_to_include_passed_to_publish (line 864) | def test_folder_path_to_include_passed_to_publish(self, _mock_unpublis...
method test_folder_path_to_include_defaults_to_none (line 891) | def test_folder_path_to_include_defaults_to_none(self, _mock_unpublish...
method test_folder_path_to_include_environment_specific (line 915) | def test_folder_path_to_include_environment_specific(self, _mock_unpub...
method test_deploy_with_config_skips_parameterization_when_parameter_absent (line 942) | def test_deploy_with_config_skips_parameterization_when_parameter_abse...
method test_deploy_with_config_loads_parameter_when_field_present (line 979) | def test_deploy_with_config_loads_parameter_when_field_present(self, t...
class TestConfigIntegration (line 1012) | class TestConfigIntegration:
method test_sample_config_file_structure (line 1015) | def test_sample_config_file_structure(self):
method test_config_validation_comprehensive (line 1048) | def test_config_validation_comprehensive(self, tmp_path):
class TestConfigUtilsExtractSettings (line 1101) | class TestConfigUtilsExtractSettings:
method test_extract_publish_settings_with_folder_exclude_regex (line 1104) | def test_extract_publish_settings_with_folder_exclude_regex(self):
method test_extract_publish_settings_with_environment_specific_folder_exclude_regex (line 1115) | def test_extract_publish_settings_with_environment_specific_folder_exc...
method test_extract_publish_settings_missing_environment_skips_setting (line 1129) | def test_extract_publish_settings_missing_environment_skips_setting(se...
method test_extract_unpublish_settings_missing_environment_skips_setting (line 1143) | def test_extract_unpublish_settings_missing_environment_skips_setting(...
method test_extract_publish_settings_skip_defaults_false_when_env_missing (line 1157) | def test_extract_publish_settings_skip_defaults_false_when_env_missing...
method test_extract_unpublish_settings_skip_defaults_false_when_env_missing (line 1169) | def test_extract_unpublish_settings_skip_defaults_false_when_env_missi...
method test_extract_workspace_settings_optional_fields_missing_environment (line 1181) | def test_extract_workspace_settings_optional_fields_missing_environmen...
method test_extract_publish_settings_shortcut_exclude_regex_missing_environment (line 1200) | def test_extract_publish_settings_shortcut_exclude_regex_missing_envir...
method test_extract_publish_settings_items_to_include_missing_environment (line 1212) | def test_extract_publish_settings_items_to_include_missing_environment...
method test_extract_publish_settings_folder_path_to_include_list (line 1224) | def test_extract_publish_settings_folder_path_to_include_list(self):
method test_extract_publish_settings_folder_path_to_include_env_specific (line 1234) | def test_extract_publish_settings_folder_path_to_include_env_specific(...
method test_extract_publish_settings_folder_path_to_include_missing (line 1244) | def test_extract_publish_settings_folder_path_to_include_missing(self):
method test_extract_publish_settings_no_publish_section_folder_path_to_include (line 1254) | def test_extract_publish_settings_no_publish_section_folder_path_to_in...
class TestGetConfigValue (line 1261) | class TestGetConfigValue:
method test_get_config_value_key_not_present (line 1264) | def test_get_config_value_key_not_present(self):
method test_get_config_value_simple_value (line 1272) | def test_get_config_value_simple_value(self):
method test_get_config_value_dict_with_environment (line 1280) | def test_get_config_value_dict_with_environment(self):
method test_get_config_value_dict_missing_environment (line 1288) | def test_get_config_value_dict_missing_environment(self):
method test_get_config_value_list_value (line 1296) | def test_get_config_value_list_value(self):
method test_get_config_value_bool_value (line 1304) | def test_get_config_value_bool_value(self):
class TestDeploymentResult (line 1313) | class TestDeploymentResult:
method test_deployment_status_completed_value (line 1316) | def test_deployment_status_completed_value(self):
method test_deployment_status_failed_value (line 1320) | def test_deployment_status_failed_value(self):
method test_deployment_status_string_comparison (line 1324) | def test_deployment_status_string_comparison(self):
method test_deployment_result_structure (line 1329) | def test_deployment_result_structure(self):
method test_deployment_result_responses_defaults_to_none (line 1338) | def test_deployment_result_responses_defaults_to_none(self):
method test_deployment_result_with_responses (line 1346) | def test_deployment_result_with_responses(self):
class TestDeployWithConfigReturnValue (line 1359) | class TestDeployWithConfigReturnValue:
method test_deploy_with_config_returns_deployment_result (line 1366) | def test_deploy_with_config_returns_deployment_result(self, mock_unpub...
method test_deploy_with_config_returns_completed_when_skipping_operations (line 1403) | def test_deploy_with_config_returns_completed_when_skipping_operations(
class TestDeployWithConfigFailures (line 1444) | class TestDeployWithConfigFailures:
method test_deploy_with_config_invalid_yaml_raises_input_error (line 1447) | def test_deploy_with_config_invalid_yaml_raises_input_error(self, tmp_...
method test_deploy_with_config_missing_core_raises_config_validation_error (line 1455) | def test_deploy_with_config_missing_core_raises_config_validation_erro...
method test_deploy_with_config_missing_environment_raises_config_validation_error (line 1465) | def test_deploy_with_config_missing_environment_raises_config_validati...
method test_deploy_with_config_missing_workspace_id_raises_config_validation_error (line 1483) | def test_deploy_with_config_missing_workspace_id_raises_config_validat...
method test_deploy_with_config_publish_error_propagates (line 1500) | def test_deploy_with_config_publish_error_propagates(self, mock_unpubl...
method test_deploy_with_config_workspace_creation_error_propagates (line 1529) | def test_deploy_with_config_workspace_creation_error_propagates(
method test_deploy_with_config_unpublish_error_propagates (line 1560) | def test_deploy_with_config_unpublish_error_propagates(
class TestDeployWithConfigExceptionAttributes (line 1587) | class TestDeployWithConfigExceptionAttributes:
method test_exception_has_deployment_status_and_message (line 1593) | def test_exception_has_deployment_status_and_message(self, mock_unpubl...
method test_exception_has_partial_responses_when_enabled (line 1628) | def test_exception_has_partial_responses_when_enabled(self, mock_unpub...
method test_exception_no_responses_when_flag_disabled (line 1662) | def test_exception_no_responses_when_flag_disabled(self, mock_unpublis...
method test_pre_workspace_failure_has_deployment_attributes (line 1689) | def test_pre_workspace_failure_has_deployment_attributes(self, tmp_path):
class TestDeployWithConfigResponseCollection (line 1704) | class TestDeployWithConfigResponseCollection:
method test_result_responses_is_dict_when_enabled (line 1714) | def test_result_responses_is_dict_when_enabled(self, mock_unpublish, m...
method test_result_responses_contains_both_publish_and_unpublish (line 1750) | def test_result_responses_contains_both_publish_and_unpublish(
method test_result_responses_is_none_when_disabled (line 1790) | def test_result_responses_is_none_when_disabled(self, mock_unpublish, ...
class TestCollectResponses (line 1817) | class TestCollectResponses:
method test_returns_none_when_responses_disabled (line 1820) | def test_returns_none_when_responses_disabled(self):
method test_returns_none_when_workspace_is_none (line 1827) | def test_returns_none_when_workspace_is_none(self):
method test_returns_none_when_both_responses_empty_dict (line 1832) | def test_returns_none_when_both_responses_empty_dict(self):
method test_returns_none_when_both_responses_none (line 1840) | def test_returns_none_when_both_responses_none(self):
method test_returns_none_when_responses_empty_and_unpublish_none (line 1848) | def test_returns_none_when_responses_empty_and_unpublish_none(self):
method test_returns_none_when_responses_none_and_unpublish_empty (line 1856) | def test_returns_none_when_responses_none_and_unpublish_empty(self):
method test_returns_publish_only_when_publish_available (line 1864) | def test_returns_publish_only_when_publish_available(self):
method test_returns_unpublish_only_when_unpublish_available (line 1873) | def test_returns_unpublish_only_when_unpublish_available(self):
method test_returns_both_when_both_available (line 1882) | def test_returns_both_when_both_available(self):
FILE: tests/test_environment_publish.py
class DummyFile (line 9) | class DummyFile:
method __init__ (line 10) | def __init__(self, file_path):
class DummyItem (line 24) | class DummyItem:
method __init__ (line 25) | def __init__(self, name, file_paths):
function test_process_environment_file_non_sparkcompute (line 44) | def test_process_environment_file_non_sparkcompute(tmp_path):
function test_process_environment_file_no_instance_pool (line 55) | def test_process_environment_file_no_instance_pool(tmp_path):
function test_process_environment_file_replaces_instance_pool (line 71) | def test_process_environment_file_replaces_instance_pool(tmp_path):
function test_process_environment_file_pool_with_item_name_filter (line 105) | def test_process_environment_file_pool_with_item_name_filter(tmp_path):
function test_process_environment_file_pool_no_match (line 135) | def test_process_environment_file_pool_no_match(tmp_path):
function test_process_environment_file_no_spark_pool_param (line 160) | def test_process_environment_file_no_spark_pool_param(tmp_path):
function test_resolve_pool_id_success (line 182) | def test_resolve_pool_id_success():
function test_resolve_pool_id_not_found (line 192) | def test_resolve_pool_id_not_found():
function test_publish_environments_passes_func_process_file (line 205) | def test_publish_environments_passes_func_process_file(tmp_path):
function test_end_to_end_environment_setting_only (line 246) | def test_end_to_end_environment_setting_only(tmp_path):
function test_end_to_end_environment_with_libraries (line 302) | def test_end_to_end_environment_with_libraries(tmp_path):
FILE: tests/test_fabric_workspace.py
function mock_endpoint (line 19) | def mock_endpoint():
function temp_workspace_dir (line 44) | def temp_workspace_dir():
function valid_workspace_id (line 51) | def valid_workspace_id():
function utf8_test_chars (line 57) | def utf8_test_chars():
function create_parameter_file (line 62) | def create_parameter_file(dir_path, utf8_chars):
function create_platform_metadata (line 83) | def create_platform_metadata(dir_path, utf8_chars):
function patched_fabric_workspace (line 107) | def patched_fabric_workspace(mock_endpoint):
function test_parameter_file_with_utf8_chars (line 138) | def test_parameter_file_with_utf8_chars(
function test_platform_metadata_with_utf8_chars (line 160) | def test_platform_metadata_with_utf8_chars(
function test_environment_param_with_utf8_chars (line 181) | def test_environment_param_with_utf8_chars(
function test_workspace_id_replacement_in_json (line 196) | def test_workspace_id_replacement_in_json(patched_fabric_workspace, vali...
function test_workspace_id_replacement_in_python (line 229) | def test_workspace_id_replacement_in_python(patched_fabric_workspace, va...
function test_workspace_id_replacement_eventstream_json (line 257) | def test_workspace_id_replacement_eventstream_json(patched_fabric_worksp...
function test_workspace_id_replacement_yaml_format (line 302) | def test_workspace_id_replacement_yaml_format(patched_fabric_workspace, ...
function test_workspace_id_replacement_mixed_formats (line 330) | def test_workspace_id_replacement_mixed_formats(patched_fabric_workspace...
function test_workspace_id_replacement_whitespace_variations (line 360) | def test_workspace_id_replacement_whitespace_variations(
function test_workspace_id_replacement_non_default_values_preserved (line 395) | def test_workspace_id_replacement_non_default_values_preserved(
function test_workspace_id_replacement_edge_cases (line 438) | def test_workspace_id_replacement_edge_cases(patched_fabric_workspace, v...
function test_workspace_id_replacement_comprehensive_item_types (line 478) | def test_workspace_id_replacement_comprehensive_item_types(
function test_environment_parameter_replacement_issue (line 533) | def test_environment_parameter_replacement_issue(patched_fabric_workspac...
function test_empty_logical_id_validation (line 604) | def test_empty_logical_id_validation(temp_workspace_dir, patched_fabric_...
function test_whitespace_only_logical_id_validation (line 642) | def test_whitespace_only_logical_id_validation(temp_workspace_dir, patch...
function test_valid_logical_id_works_correctly (line 679) | def test_valid_logical_id_works_correctly(temp_workspace_dir, patched_fa...
function test_empty_logical_id_validation_during_publish (line 715) | def test_empty_logical_id_validation_during_publish(temp_workspace_dir, ...
function test_multiple_empty_logical_ids_validation (line 753) | def test_multiple_empty_logical_ids_validation(temp_workspace_dir, patch...
function test_single_empty_logical_id_validation_message (line 799) | def test_single_empty_logical_id_validation_message(temp_workspace_dir, ...
function test_fabric_workspace_with_none_item_types_defaults_to_all (line 839) | def test_fabric_workspace_with_none_item_types_defaults_to_all(
function test_parameter_file_path_types (line 883) | def test_parameter_file_path_types(temp_workspace_dir, patched_fabric_wo...
function test_parameter_file_path_none (line 917) | def test_parameter_file_path_none(temp_workspace_dir, patched_fabric_wor...
function test_skip_parameterization_prevents_parameter_yml_auto_discovery (line 930) | def test_skip_parameterization_prevents_parameter_yml_auto_discovery(
function test_skip_parameterization_false_loads_explicit_parameter_file (line 951) | def test_skip_parameterization_false_loads_explicit_parameter_file(
function test_parameter_file_path_with_environment (line 971) | def test_parameter_file_path_with_environment(temp_workspace_dir, patche...
function test_parameter_file_path_backward_compatibility (line 992) | def test_parameter_file_path_backward_compatibility(temp_workspace_dir, ...
function test_parameter_file_path_integration_with_parameter_class (line 1007) | def test_parameter_file_path_integration_with_parameter_class(
function test_parameter_file_path_invalid_type_rejected (line 1037) | def test_parameter_file_path_invalid_type_rejected(temp_workspace_dir, p...
function test_no_token_credential_raises_error (line 1053) | def test_no_token_credential_raises_error(temp_workspace_dir, valid_work...
function test_base_api_url_kwarg_raises_error (line 1076) | def test_base_api_url_kwarg_raises_error(temp_workspace_dir, valid_works...
function test_resolve_workspace_name (line 1108) | def test_resolve_workspace_name(patched_fabric_workspace, valid_workspac...
function test_resolve_workspace_name_not_found (line 1129) | def test_resolve_workspace_name_not_found(patched_fabric_workspace, vali...
function test_lookup_item_attribute (line 1147) | def test_lookup_item_attribute(patched_fabric_workspace, valid_workspace...
function test_kqldatabase_folder_regex_root_eventhouse (line 1208) | def test_kqldatabase_folder_regex_root_eventhouse():
function test_kqldatabase_folder_regex_nested_subfolder (line 1217) | def test_kqldatabase_folder_regex_nested_subfolder():
function test_kqldatabase_folder_regex_no_match_edge_case (line 1226) | def test_kqldatabase_folder_regex_no_match_edge_case():
function test_get_item_attribute_caching_basic (line 1239) | def test_get_item_attribute_caching_basic(patched_fabric_workspace, vali...
function test_get_item_attribute_caching_prevents_api_call (line 1275) | def test_get_item_attribute_caching_prevents_api_call(patched_fabric_wor...
function test_get_item_attribute_different_cache_keys (line 1316) | def test_get_item_attribute_different_cache_keys(patched_fabric_workspac...
function test_get_item_attribute_edge_cases (line 1420) | def test_get_item_attribute_edge_cases(patched_fabric_workspace, valid_w...
function test_multiple_items_with_default_guid_logical_id (line 1480) | def test_multiple_items_with_default_guid_logical_id(temp_workspace_dir,...
function test_duplicate_non_default_logical_id_raises_error (line 1519) | def test_duplicate_non_default_logical_id_raises_error(
function test_replace_logical_ids_skips_default_guid (line 1557) | def test_replace_logical_ids_skips_default_guid(temp_workspace_dir, patc...
function test_replace_logical_ids_replaces_non_default_guid (line 1599) | def test_replace_logical_ids_replaces_non_default_guid(
function test_mix_of_default_and_non_default_logical_ids (line 1634) | def test_mix_of_default_and_non_default_logical_ids(temp_workspace_dir, ...
function test_publish_variable_library_only_calls_replace_parameters (line 1688) | def test_publish_variable_library_only_calls_replace_parameters(
function test_publish_non_variable_library_calls_all_replacements (line 1729) | def test_publish_non_variable_library_calls_all_replacements(
function test_api_root_url_snapshot_is_not_retargeted_by_second_configure_call (line 1769) | def test_api_root_url_snapshot_is_not_retargeted_by_second_configure_call(
FILE: tests/test_fqdn_workspace_id.py
class TestGetFabricFqdnUrl (line 12) | class TestGetFabricFqdnUrl:
method test_produces_correct_fqdn_url (line 15) | def test_produces_correct_fqdn_url(self):
method test_rejects_workspace_id_without_dashes (line 19) | def test_rejects_workspace_id_without_dashes(self):
class TestConfigureFabricFqdn (line 24) | class TestConfigureFabricFqdn:
method test_globals_updated (line 27) | def test_globals_updated(self, monkeypatch):
method test_overwrite_warning_on_second_call (line 37) | def test_overwrite_warning_on_second_call(self, monkeypatch, mocker):
FILE: tests/test_git_diff_utils.py
class TestValidateGitCompareRef (line 19) | class TestValidateGitCompareRef:
method test_accepts_common_valid_refs (line 20) | def test_accepts_common_valid_refs(self):
method test_rejects_empty_string (line 26) | def test_rejects_empty_string(self):
method test_rejects_whitespace_only (line 30) | def test_rejects_whitespace_only(self):
method test_rejects_dash_prefixed (line 34) | def test_rejects_dash_prefixed(self):
method test_rejects_invalid_characters (line 40) | def test_rejects_invalid_characters(self):
method test_rejects_shell_metacharacters (line 44) | def test_rejects_shell_metacharacters(self):
method test_rejects_non_string_input (line 50) | def test_rejects_non_string_input(self):
method test_accepts_advanced_git_ref_syntax (line 57) | def test_accepts_advanced_git_ref_syntax(self):
class TestResolveGitDiffPath (line 72) | class TestResolveGitDiffPath:
method test_rejects_absolute_paths (line 75) | def test_rejects_absolute_paths(self, tmp_path):
method test_rejects_path_traversal (line 79) | def test_rejects_path_traversal(self, tmp_path):
method test_rejects_null_bytes (line 83) | def test_rejects_null_bytes(self, tmp_path):
method test_accepts_valid_relative_path (line 87) | def test_accepts_valid_relative_path(self, tmp_path):
method test_rejects_path_outside_repo_directory (line 94) | def test_rejects_path_outside_repo_directory(self, tmp_path):
class TestFindPlatformItem (line 107) | class TestFindPlatformItem:
method test_finds_platform_in_same_directory (line 110) | def test_finds_platform_in_same_directory(self, tmp_path):
method test_returns_none_when_no_platform_file (line 121) | def test_returns_none_when_no_platform_file(self, tmp_path):
method test_returns_none_for_malformed_platform_json (line 129) | def test_returns_none_for_malformed_platform_json(self, tmp_path):
method test_returns_none_when_metadata_missing_type (line 138) | def test_returns_none_when_metadata_missing_type(self, tmp_path):
class TestGetChangedItems (line 156) | class TestGetChangedItems:
method _make_git_diff_output (line 159) | def _make_git_diff_output(self, lines: list[str]) -> str:
method test_returns_changed_items_from_git_diff (line 162) | def test_returns_changed_items_from_git_diff(self, tmp_path):
method test_returns_empty_list_when_no_changes (line 190) | def test_returns_empty_list_when_no_changes(self, tmp_path):
method test_returns_empty_list_when_git_root_not_found (line 205) | def test_returns_empty_list_when_git_root_not_found(self, tmp_path):
method test_returns_empty_list_when_git_diff_fails (line 214) | def test_returns_empty_list_when_git_diff_fails(self, tmp_path):
method test_uses_custom_git_compare_ref (line 228) | def test_uses_custom_git_compare_ref(self, tmp_path):
method test_excludes_files_outside_repository_directory (line 244) | def test_excludes_files_outside_repository_directory(self, tmp_path):
method test_deduplicates_multiple_files_in_same_item (line 267) | def test_deduplicates_multiple_files_in_same_item(self, tmp_path):
method test_handles_renamed_files (line 295) | def test_handles_renamed_files(self, tmp_path):
method test_returns_empty_list_on_timeout (line 319) | def test_returns_empty_list_on_timeout(self, tmp_path):
method test_multiple_distinct_items (line 333) | def test_multiple_distinct_items(self, tmp_path):
method test_rejects_dangerous_git_compare_ref (line 361) | def test_rejects_dangerous_git_compare_ref(self, tmp_path):
FILE: tests/test_hard_delete.py
function mock_endpoint (line 20) | def mock_endpoint():
function test_workspace (line 40) | def test_workspace(mock_endpoint):
function _clear_feature_flags (line 82) | def _clear_feature_flags():
function test_unpublish_item_without_hard_delete_flag (line 89) | def test_unpublish_item_without_hard_delete_flag(test_workspace, mock_en...
function test_unpublish_item_with_hard_delete_flag (line 104) | def test_unpublish_item_with_hard_delete_flag(test_workspace, mock_endpo...
function test_hard_delete_flag_via_append_feature_flag (line 119) | def test_hard_delete_flag_via_append_feature_flag(test_workspace, mock_e...
FILE: tests/test_integration_publish.py
function allow_localhost_http_for_integration (line 23) | def allow_localhost_http_for_integration(monkeypatch: pytest.MonkeyPatch):
function mock_fabric_api_server (line 44) | def mock_fabric_api_server(allow_localhost_http_for_integration): # noq...
function test_publish_all_items_integration (line 101) | def test_publish_all_items_integration(mock_fabric_api_server): # noqa:...
FILE: tests/test_logging.py
function _close_all_file_handlers (line 40) | def _close_all_file_handlers():
function _reset_logger (line 50) | def _reset_logger(logger_name: str) -> None:
function _clean_logging_state (line 57) | def _clean_logging_state():
function temp_log_dir (line 69) | def temp_log_dir():
function external_rotating_handler (line 78) | def external_rotating_handler(temp_log_dir):
function external_logger_with_handler (line 88) | def external_logger_with_handler(temp_log_dir):
class TestCustomFormatter (line 104) | class TestCustomFormatter:
method test_format_levels (line 117) | def test_format_levels(self, level, level_name, message):
method test_format_with_indent (line 133) | def test_format_with_indent(self):
class TestPackageFilter (line 151) | class TestPackageFilter:
method test_namespace_filtering (line 165) | def test_namespace_filtering(self, logger_name, expected):
method test_debug_only_mode (line 183) | def test_debug_only_mode(self, level, expected):
method test_debug_only_still_checks_namespace (line 191) | def test_debug_only_still_checks_namespace(self):
method test_default_allows_all_levels_from_package (line 199) | def test_default_allows_all_levels_from_package(self):
class TestMarkHandler (line 210) | class TestMarkHandler:
method test_mark_handler (line 213) | def test_mark_handler(self):
method test_mark_external_handler (line 220) | def test_mark_external_handler(self):
class TestCleanupManagedHandlers (line 229) | class TestCleanupManagedHandlers:
method test_removes_managed_preserves_external (line 232) | def test_removes_managed_preserves_external(self):
method test_cleanup_multiple_loggers (line 247) | def test_cleanup_multiple_loggers(self):
method test_cleanup_external_handler_removes_filters (line 264) | def test_cleanup_external_handler_removes_filters(self, temp_log_dir):
class TestConfigureDefaultFileHandler (line 289) | class TestConfigureDefaultFileHandler:
method test_default_file_handler_configuration (line 292) | def test_default_file_handler_configuration(self):
class TestConfigureExternalFileHandler (line 310) | class TestConfigureExternalFileHandler:
method test_reuses_handler_directly (line 313) | def test_reuses_handler_directly(self, temp_log_dir):
method test_preserves_caller_formatter (line 335) | def test_preserves_caller_formatter(self, temp_log_dir):
method test_info_level_ignores_debug_only (line 354) | def test_info_level_ignores_debug_only(self, temp_log_dir):
method test_works_with_regular_file_handler (line 365) | def test_works_with_regular_file_handler(self, temp_log_dir):
class TestConfigureConsoleHandler (line 382) | class TestConfigureConsoleHandler:
method test_console_handler_configuration (line 385) | def test_console_handler_configuration(self):
class TestGetFileHandler (line 394) | class TestGetFileHandler:
method test_returns_none_when_no_file_handler (line 397) | def test_returns_none_when_no_file_handler(self):
method test_returns_managed_file_handler_from_root (line 401) | def test_returns_managed_file_handler_from_root(self):
method test_ignores_unmanaged_file_handler_on_root (line 414) | def test_ignores_unmanaged_file_handler_on_root(self):
method test_ignores_external_file_handler_on_root (line 426) | def test_ignores_external_file_handler_on_root(self):
method test_returns_any_file_handler_from_provided_logger (line 438) | def test_returns_any_file_handler_from_provided_logger(self):
class TestBuildConsoleMessage (line 452) | class TestBuildConsoleMessage:
method test_no_file_handler (line 455) | def test_no_file_handler(self):
method test_with_default_file_handler (line 461) | def test_with_default_file_handler(self):
method test_with_non_default_file_handler (line 473) | def test_with_non_default_file_handler(self, temp_log_dir):
class TestBuildFileMessage (line 487) | class TestBuildFileMessage:
method test_file_message (line 497) | def test_file_message(self, additional_info, expected_in_result):
class TestConfigureLogger (line 512) | class TestConfigureLogger:
method test_logger_levels (line 522) | def test_logger_levels(self, level, expected_package_level, expected_r...
method test_default_includes_file_handler (line 529) | def test_default_includes_file_handler(self):
method test_disable_file_logging (line 536) | def test_disable_file_logging(self):
method test_with_external_file_handler (line 543) | def test_with_external_file_handler(self, external_rotating_handler, t...
method test_suppress_debug_console (line 565) | def test_suppress_debug_console(self):
method test_console_only_logger_configured (line 574) | def test_console_only_logger_configured(self):
method test_preserves_unmanaged_handlers (line 585) | def test_preserves_unmanaged_handlers(self):
method test_package_logger_propagates (line 597) | def test_package_logger_propagates(self):
class TestLogHeader (line 603) | class TestLogHeader:
method test_logs_expected_messages (line 606) | def test_logs_expected_messages(self, caplog):
class TestWrapperFunctions (line 618) | class TestWrapperFunctions:
method _clear_feature_flags (line 622) | def _clear_feature_flags(self):
method test_append_feature_flag (line 627) | def test_append_feature_flag(self):
method test_change_log_level (line 638) | def test_change_log_level(self, level_input):
method test_change_log_level_unsupported (line 643) | def test_change_log_level_unsupported(self, capsys):
method test_disable_file_logging (line 651) | def test_disable_file_logging(self):
class TestConfigureExternalFileLogging (line 662) | class TestConfigureExternalFileLogging:
method test_configures_correctly (line 665) | def test_configures_correctly(self, external_logger_with_handler):
method test_raises_without_handler (line 692) | def test_raises_without_handler(self):
method test_writes_only_debug_logs (line 700) | def test_writes_only_debug_logs(self, external_logger_with_handler):
class TestExceptionHandler (line 724) | class TestExceptionHandler:
method test_handles_custom_exception (line 727) | def test_handles_custom_exception(self):
method test_falls_back_for_standard_exception (line 740) | def test_falls_back_for_standard_exception(self):
method test_writes_to_console_only_logger (line 747) | def test_writes_to_console_only_logger(self):
method test_removes_console_handler_when_using_default_file (line 762) | def test_removes_console_handler_when_using_default_file(self):
class TestFileLoggingIntegration (line 779) | class TestFileLoggingIntegration:
method test_default_file_handler_writes_logs (line 782) | def test_default_file_handler_writes_logs(self, temp_log_dir):
method test_file_not_created_until_log_written (line 807) | def test_file_not_created_until_log_written(self, temp_log_dir):
method test_external_handler_writes_fabric_cicd_logs (line 823) | def test_external_handler_writes_fabric_cicd_logs(self, external_logge...
method test_console_only_logger_does_not_propagate_to_file (line 843) | def test_console_only_logger_does_not_propagate_to_file(self, external...
class TestExternalHandlerReconfiguration (line 861) | class TestExternalHandlerReconfiguration:
method test_debug_to_non_debug_cleans_up_filter (line 864) | def test_debug_to_non_debug_cleans_up_filter(self, external_logger_wit...
method test_non_debug_to_debug_adds_filter (line 877) | def test_non_debug_to_debug_adds_filter(self, external_logger_with_han...
method test_multiple_debug_runs_no_filter_accumulation (line 890) | def test_multiple_debug_runs_no_filter_accumulation(self, external_log...
method test_handler_not_closed_on_disable (line 901) | def test_handler_not_closed_on_disable(self, external_logger_with_hand...
method test_rotating_handler_preserves_rotation_settings (line 914) | def test_rotating_handler_preserves_rotation_settings(self, external_l...
FILE: tests/test_parameter.py
function item_type_in_scope (line 311) | def item_type_in_scope():
function target_environment (line 316) | def target_environment():
function repository_directory (line 321) | def repository_directory(tmp_path):
function parameter_object (line 390) | def parameter_object(repository_directory, item_type_in_scope, target_en...
function test_parameter_class_initialization (line 400) | def test_parameter_class_initialization(parameter_object, repository_dir...
function test_parameter_file_validation (line 412) | def test_parameter_file_validation(parameter_object):
function test_multiple_parameter_validation (line 430) | def test_multiple_parameter_validation(repository_directory, item_type_i...
function test_validate_parameter_keys (line 459) | def test_validate_parameter_keys(parameter_object, param_name, param_val...
function test_validate_parameter (line 469) | def test_validate_parameter(parameter_object, param_name):
function test_validate_find_replace_replace_value (line 498) | def test_validate_find_replace_replace_value(parameter_object, replace_v...
function test_validate_key_value_replace_replace_value (line 566) | def test_validate_key_value_replace_replace_value(parameter_object, repl...
function test_validate_spark_pool_replace_value (line 633) | def test_validate_spark_pool_replace_value(parameter_object, replace_val...
function test_validate_data_type (line 656) | def test_validate_data_type(parameter_object):
function test_validate_yaml_content_empty (line 719) | def test_validate_yaml_content_empty():
function test_utf8_validation_at_file_read (line 744) | def test_utf8_validation_at_file_read():
function test_validate_yaml_content_duplicate_keys (line 782) | def test_validate_yaml_content_duplicate_keys():
function test_duplicate_keys_single_duplicate (line 815) | def test_duplicate_keys_single_duplicate(repository_directory, item_type...
function test_duplicate_keys_multiple_duplicates (line 832) | def test_duplicate_keys_multiple_duplicates(repository_directory, item_t...
function test_duplicate_keys_no_duplicates (line 849) | def test_duplicate_keys_no_duplicates(parameter_object):
function test_duplicate_keys_ignores_comments (line 858) | def test_duplicate_keys_ignores_comments():
function test_duplicate_keys_nested_keys_not_flagged (line 896) | def test_duplicate_keys_nested_keys_not_flagged():
function test_duplicate_keys_nested_duplicate_detected (line 1039) | def test_duplicate_keys_nested_duplicate_detected(content, duplicate_keys):
function test_duplicate_keys_triple_occurrence (line 1066) | def test_duplicate_keys_triple_occurrence(repository_directory, item_typ...
function test_validate_parameter_file_structure (line 1083) | def test_validate_parameter_file_structure(repository_directory, item_ty...
function test_validate_optional_values (line 1094) | def test_validate_optional_values(parameter_object):
function test_validate_parameter_environment_and_filters (line 1127) | def test_validate_parameter_environment_and_filters(parameter_object, pa...
function test_validate_item_name_with_accented_characters (line 1148) | def test_validate_item_name_with_accented_characters(repository_director...
function test_validate_invalid_parameters (line 1200) | def test_validate_invalid_parameters(
function test_validate_file_path_scenarios (line 1295) | def test_validate_file_path_scenarios(parameter_object):
function test_validate_all_environment_key_valid (line 1385) | def test_validate_all_environment_key_valid():
function test_validate_all_environment_key_invalid (line 1454) | def test_validate_all_environment_key_invalid():
function test_validate_all_environment_key_with_logging (line 1526) | def test_validate_all_environment_key_with_logging():
function test_parameter_file_path_absolute (line 1601) | def test_parameter_file_path_absolute():
function test_parameter_file_path_relative (line 1630) | def test_parameter_file_path_relative():
function test_parameter_file_path_none (line 1690) | def test_parameter_file_path_none():
function test_parameter_file_path_and_name_inputs (line 1719) | def test_parameter_file_path_and_name_inputs():
function test_no_provided_parameter_file_path (line 1760) | def test_no_provided_parameter_file_path():
function test_parameter_file_path_nonexistent (line 1789) | def test_parameter_file_path_nonexistent():
function test_validate_parameter_file_exists_none (line 1809) | def test_validate_parameter_file_exists_none():
function test_parameter_file_path_invalid_type (line 1829) | def test_parameter_file_path_invalid_type():
function test_set_parameter_file_path_error_handling (line 1848) | def test_set_parameter_file_path_error_handling():
function test_basic_template_processing (line 1869) | def test_basic_template_processing(tmp_path):
function test_missing_templates_directory (line 1921) | def test_missing_templates_directory(tmp_path):
function test_nested_template_prevention (line 1948) | def test_nested_template_prevention(tmp_path):
function test_template_path_resolution (line 2002) | def test_template_path_resolution(tmp_path):
function test_missing_template_files (line 2058) | def test_missing_template_files(tmp_path):
function test_template_merge_validation (line 2092) | def test_template_merge_validation(tmp_path):
function test_template_duplicate_keys_detected (line 2153) | def test_template_duplicate_keys_detected(tmp_path):
function test_circular_template_reference (line 2195) | def test_circular_template_reference(tmp_path):
function test_multiple_template_references (line 2247) | def test_multiple_template_references(tmp_path):
function test_template_merge_behavior (line 2408) | def test_template_merge_behavior(tmp_path):
function test_template_reference_handling (line 2474) | def test_template_reference_handling(tmp_path):
function empty_parameter (line 2556) | def empty_parameter(tmp_path):
function test_validate_key_value_find_key_valid_dot_notation (line 2561) | def test_validate_key_value_find_key_valid_dot_notation(empty_parameter):
function test_validate_key_value_find_key_valid_filter_syntax (line 2568) | def test_validate_key_value_find_key_valid_filter_syntax(empty_parameter):
function test_validate_key_value_find_key_missing_key (line 2575) | def test_validate_key_value_find_key_missing_key(empty_parameter):
function test_validate_key_value_find_key_non_string (line 2582) | def test_validate_key_value_find_key_non_string(empty_parameter):
function test_validate_key_value_find_key_empty_string (line 2589) | def test_validate_key_value_find_key_empty_string(empty_parameter):
function test_validate_key_value_find_key_requires_root (line 2596) | def test_validate_key_value_find_key_requires_root(empty_parameter):
function test_validate_key_value_find_key_unbalanced_filter (line 2603) | def test_validate_key_value_find_key_unbalanced_filter(empty_parameter):
function test_validate_key_value_find_key_unsupported_regex_operator (line 2610) | def test_validate_key_value_find_key_unsupported_regex_operator(empty_pa...
function test_validate_required_values_integration_calls_find_key_validator (line 2618) | def test_validate_required_values_integration_calls_find_key_validator(e...
function test_validate_and_evaluate_bracket_key_with_yaml (line 2626) | def test_validate_and_evaluate_bracket_key_with_yaml(empty_parameter):
function test_yaml_boolean_filter_evaluation (line 2647) | def test_yaml_boolean_filter_evaluation(empty_parameter):
function test_yaml_no_match_is_no_op (line 2672) | def test_yaml_no_match_is_no_op(empty_parameter):
function test_semantic_model_binding_validation (line 2874) | def test_semantic_model_binding_validation(empty_parameter, param_value,...
function test_validate_connection_id (line 2938) | def test_validate_connection_id(
function test_semantic_model_binding_new_format_models_invalid_connection_guid (line 2949) | def test_semantic_model_binding_new_format_models_invalid_connection_gui...
function test_semantic_model_binding_legacy_format_mixed_with_new_keys (line 2961) | def test_semantic_model_binding_legacy_format_mixed_with_new_keys(empty_...
function test_check_duplicate_semantic_model_names (line 3055) | def test_check_duplicate_semantic_model_names(empty_parameter, param_val...
FILE: tests/test_parameter_utils.py
function temp_repository (line 28) | def temp_repository():
class TestParameterUtilities (line 72) | class TestParameterUtilities:
method mock_workspace (line 76) | def mock_workspace(self):
method test_extract_find_value (line 127) | def test_extract_find_value(self):
method test_extract_find_value_valid_regex (line 136) | def test_extract_find_value_valid_regex(self):
method test_extract_find_value_invalid_regex (line 150) | def test_extract_find_value_invalid_regex(self):
method test_extract_find_value_multiple_matches (line 178) | def test_extract_find_value_multiple_matches(self):
method test_extract_replace_value_default (line 194) | def test_extract_replace_value_default(self, mock_workspace):
method test_extract_replace_value_get_dataflow_name (line 219) | def test_extract_replace_value_get_dataflow_name(self, mock_workspace):
method test_extract_item_attribute_valid (line 247) | def test_extract_item_attribute_valid(self, mock_workspace):
method test_extract_item_attribute_invalid (line 285) | def test_extract_item_attribute_invalid(self, mock_workspace):
method test_extract_item_attribute_get_dataflow_name (line 301) | def test_extract_item_attribute_get_dataflow_name(self, mock_workspace):
method test_extract_workspace_id_direct (line 319) | def test_extract_workspace_id_direct(self, mock_workspace):
method test_extract_workspace_id_resolve (line 330) | def test_extract_workspace_id_resolve(self, mock_workspace):
method test_extract_workspace_id_with_workspace_name_variable (line 347) | def test_extract_workspace_id_with_workspace_name_variable(self, mock_...
method test_extract_workspace_id_name_encoded (line 357) | def test_extract_workspace_id_name_encoded(self, mock_workspace):
method test_extract_workspace_id_resolve_error (line 367) | def test_extract_workspace_id_resolve_error(self, mock_workspace):
method test_extract_workspace_id_general_error (line 378) | def test_extract_workspace_id_general_error(self, mock_workspace):
method test_extract_item_attribute_null_return (line 389) | def test_extract_item_attribute_null_return(self, mock_workspace):
method test_extract_item_attribute_invalid_attribute (line 399) | def test_extract_item_attribute_invalid_attribute(self, mock_workspace):
method test_extract_workspace_id_with_item_lookup (line 409) | def test_extract_workspace_id_with_item_lookup(self, mock_workspace):
method test_extract_workspace_id_with_item_lookup_not_found (line 429) | def test_extract_workspace_id_with_item_lookup_not_found(self, mock_wo...
method test_extract_workspace_id_with_item_lookup_invalid_format (line 459) | def test_extract_workspace_id_with_item_lookup_invalid_format(self, mo...
method test_extract_workspace_id_with_item_lookup_sqlendpoint (line 467) | def test_extract_workspace_id_with_item_lookup_sqlendpoint(self, mock_...
method test_extract_workspace_id_with_item_lookup_queryserviceuri (line 484) | def test_extract_workspace_id_with_item_lookup_queryserviceuri(self, m...
method test_extract_workspace_id_with_item_lookup_sqlendpointid (line 501) | def test_extract_workspace_id_with_item_lookup_sqlendpointid(self, moc...
method test_extract_replace_value_workspace_name (line 518) | def test_extract_replace_value_workspace_name(self, mock_workspace):
method test_extract_parameter_filters (line 536) | def test_extract_parameter_filters(self, mock_workspace):
method test_check_parameter_structure (line 564) | def test_check_parameter_structure(self):
method test_is_valid_structure (line 576) | def test_is_valid_structure(self):
method test_is_valid_structure_semantic_model_binding_new_format (line 606) | def test_is_valid_structure_semantic_model_binding_new_format(self):
method test_validate_parameter_file (line 660) | def test_validate_parameter_file(self, mock_validate_env, mock_validat...
method test_validate_parameter_file_with_custom_file_name (line 696) | def test_validate_parameter_file_with_custom_file_name(
method test_validate_parameter_file_with_custom_file_path (line 735) | def test_validate_parameter_file_with_custom_file_path(
method test_validate_parameter_file_with_both_custom_name_and_path (line 774) | def test_validate_parameter_file_with_both_custom_name_and_path(
method test_validate_parameter_file_with_none_item_type_in_scope (line 814) | def test_validate_parameter_file_with_none_item_type_in_scope(
method test_find_match (line 851) | def test_find_match(self):
method test_check_replacement (line 872) | def test_check_replacement(self, temp_repository):
method test_replace_key_value_valid_json (line 891) | def test_replace_key_value_valid_json(self, mock_workspace):
method test_replace_key_value_environment_not_found (line 911) | def test_replace_key_value_environment_not_found(self, mock_workspace):
method test_replace_key_value_invalid_json (line 924) | def test_replace_key_value_invalid_json(self, mock_workspace):
method test_replace_key_value (line 933) | def test_replace_key_value(self, mock_workspace):
method test_replace_key_value_with_items_notation (line 958) | def test_replace_key_value_with_items_notation(self, mock_workspace):
method test_replace_key_value_with_items_notation_and_non_string_values (line 1012) | def test_replace_key_value_with_items_notation_and_non_string_values(s...
method test_replace_key_value_yaml_valid (line 1060) | def test_replace_key_value_yaml_valid(self, mock_workspace):
method test_replace_key_value_yaml_environment_not_found (line 1083) | def test_replace_key_value_yaml_environment_not_found(self, mock_works...
method test_replace_key_value_yaml_invalid (line 1099) | def test_replace_key_value_yaml_invalid(self, mock_workspace):
method test_replace_key_value_yaml_empty_content (line 1108) | def test_replace_key_value_yaml_empty_content(self, mock_workspace):
method test_replace_key_value_yaml_nested_structure (line 1117) | def test_replace_key_value_yaml_nested_structure(self, mock_workspace):
method test_replace_key_value_yaml_with_items_notation (line 1152) | def test_replace_key_value_yaml_with_items_notation(self, mock_workspa...
method test_replace_key_value_yaml_with_non_string_values (line 1186) | def test_replace_key_value_yaml_with_non_string_values(self, mock_work...
method test_replace_variables_in_parameter_file (line 1228) | def test_replace_variables_in_parameter_file(self, monkeypatch):
method test_replace_variables_in_parameter_file_feature_disabled (line 1255) | def test_replace_variables_in_parameter_file_feature_disabled(self, mo...
method test_replace_env_variables_in_content (line 1287) | def test_replace_env_variables_in_content(self, monkeypatch):
method test_process_environment_key (line 1315) | def test_process_environment_key(self, mock_workspace):
method test_validate_item_type_in_scope_with_none (line 1371) | def test_validate_item_type_in_scope_with_none(self):
method test_validate_item_type_in_scope_with_valid_list (line 1384) | def test_validate_item_type_in_scope_with_valid_list(self):
method test_validate_item_type_in_scope_with_invalid_type (line 1393) | def test_validate_item_type_in_scope_with_invalid_type(self):
class TestPathUtilities (line 1403) | class TestPathUtilities:
method test_process_input_path_none (line 1406) | def test_process_input_path_none(self, temp_repository):
method test_process_input_path_string (line 1411) | def test_process_input_path_string(self, temp_repository, monkeypatch):
method test_process_input_path_list (line 1443) | def test_process_input_path_list(self, temp_repository, monkeypatch):
method test_process_input_path_has_magic_exception (line 1478) | def test_process_input_path_has_magic_exception(self, temp_repository,...
method test_resolve_input_path_with_invalid_wildcard_syntax (line 1514) | def test_resolve_input_path_with_invalid_wildcard_syntax(self, temp_re...
method test_process_input_path_some_invalid (line 1532) | def test_process_input_path_some_invalid(self, temp_repository, monkey...
method test_process_wildcard_path (line 1574) | def test_process_wildcard_path(self, temp_repository, monkeypatch):
method test_process_regular_path (line 1627) | def test_process_regular_path(self, temp_repository, monkeypatch):
method test_resolve_nonexistent_file_path (line 1659) | def test_resolve_nonexistent_file_path(self, temp_repository):
method test_resolve_directory_file_path (line 1666) | def test_resolve_directory_file_path(self, temp_repository):
method test_resolve_input_path_absolute_path (line 1673) | def test_resolve_input_path_absolute_path(self):
method test_resolve_outside_repo_file_path (line 1690) | def test_resolve_outside_repo_file_path(self, temp_repository):
method test_resolve_invalid_file_path (line 1704) | def test_resolve_invalid_file_path(self, temp_repository, monkeypatch):
method test_validate_wildcard_syntax_invalid (line 1720) | def test_validate_wildcard_syntax_invalid(self):
method test_valid_wildcard_syntax (line 1738) | def test_valid_wildcard_syntax(self):
method test_invalid_wildcard_syntax (line 1758) | def test_invalid_wildcard_syntax(self):
method test_validate_nested_brackets_braces (line 1812) | def test_validate_nested_brackets_braces(self):
FILE: tests/test_publish.py
function mock_endpoint (line 29) | def mock_endpoint():
function temp_workspace_dir (line 49) | def temp_workspace_dir():
function experimental_feature_flags (line 56) | def experimental_feature_flags():
function create_test_item (line 68) | def create_test_item(base_path: Path, folder: Optional[str], name: str, ...
function test_publish_only_existing_item_types (line 109) | def test_publish_only_existing_item_types(mock_endpoint, temp_workspace_...
function test_publish_ontology_item (line 140) | def test_publish_ontology_item(mock_endpoint, temp_workspace_dir):
function test_publish_data_build_tool_job_item (line 167) | def test_publish_data_build_tool_job_item(mock_endpoint, temp_workspace_...
function test_default_none_item_type_in_scope_includes_all_types (line 194) | def test_default_none_item_type_in_scope_includes_all_types(mock_endpoin...
function test_empty_item_type_in_scope_list (line 213) | def test_empty_item_type_in_scope_list(mock_endpoint, temp_workspace_dir):
function test_invalid_item_types_in_scope (line 230) | def test_invalid_item_types_in_scope(mock_endpoint, temp_workspace_dir):
function test_multiple_invalid_item_types_in_scope (line 244) | def test_multiple_invalid_item_types_in_scope(mock_endpoint, temp_worksp...
function test_mixed_valid_and_invalid_item_types_in_scope (line 258) | def test_mixed_valid_and_invalid_item_types_in_scope(mock_endpoint, temp...
function test_unpublish_feature_flag_warnings (line 277) | def test_unpublish_feature_flag_warnings(mock_endpoint, temp_workspace_d...
function test_unpublish_with_feature_flags_enabled (line 324) | def test_unpublish_with_feature_flags_enabled(mock_endpoint, temp_worksp...
function test_unpublish_orphan_item_is_deleted (line 365) | def test_unpublish_orphan_item_is_deleted(mock_endpoint, temp_workspace_...
function test_unpublish_orphan_excluded_by_regex (line 413) | def test_unpublish_orphan_excluded_by_regex(mock_endpoint, temp_workspac...
function test_unpublish_orphan_filtered_by_items_to_include (line 463) | def test_unpublish_orphan_filtered_by_items_to_include(mock_endpoint, te...
function test_unpublish_no_orphans_no_deletion (line 512) | def test_unpublish_no_orphans_no_deletion(mock_endpoint, temp_workspace_...
function test_mirrored_database_published_before_lakehouse (line 558) | def test_mirrored_database_published_before_lakehouse(mock_endpoint, tem...
function test_folder_exclusion_with_regex (line 611) | def test_folder_exclusion_with_regex(mock_endpoint, temp_workspace_dir):
function test_folder_exclusion_with_anchored_regex (line 646) | def test_folder_exclusion_with_anchored_regex(mock_endpoint, temp_worksp...
function test_item_name_exclusion_still_works (line 675) | def test_item_name_exclusion_still_works(mock_endpoint, temp_workspace_d...
function test_folder_inclusion_with_folder_path_to_include (line 707) | def test_folder_inclusion_with_folder_path_to_include(mock_endpoint, tem...
function test_folder_inclusion_and_exclusion_together (line 751) | def test_folder_inclusion_and_exclusion_together(mock_endpoint, temp_wor...
function test_empty_folder_path_to_include_raises_error (line 781) | def test_empty_folder_path_to_include_raises_error(mock_endpoint, temp_w...
function test_folder_exclusion_with_items_to_include (line 807) | def test_folder_exclusion_with_items_to_include(mock_endpoint, temp_work...
function test_folder_inclusion_with_item_exclusion (line 841) | def test_folder_inclusion_with_item_exclusion(mock_endpoint, temp_worksp...
function test_folder_inclusion_with_items_to_include (line 871) | def test_folder_inclusion_with_items_to_include(mock_endpoint, temp_work...
function test_all_filters_combined (line 905) | def test_all_filters_combined(mock_endpoint, temp_workspace_dir):
class TestNotebookPublisher (line 947) | class TestNotebookPublisher:
method mock_workspace (line 951) | def mock_workspace(self):
method publisher (line 958) | def publisher(self, mock_workspace):
method _create_mock_item (line 964) | def _create_mock_item(self, file_suffix: str) -> MagicMock:
method test_publish_ipynb_includes_api_format (line 972) | def test_publish_ipynb_includes_api_format(self, publisher, mock_works...
method test_publish_non_ipynb_excludes_api_format (line 985) | def test_publish_non_ipynb_excludes_api_format(self, publisher, mock_w...
method test_publish_mixed_files_with_ipynb (line 996) | def test_publish_mixed_files_with_ipynb(self, publisher, mock_workspace):
method test_item_type_is_notebook (line 1015) | def test_item_type_is_notebook(self, publisher):
method test_files_sorted_same_stem_content_before_settings (line 1019) | def test_files_sorted_same_stem_content_before_settings(self, publisher):
method test_files_sorted_with_unknown_extension (line 1037) | def test_files_sorted_with_unknown_extension(self, publisher):
FILE: tests/test_response_collection.py
function mock_endpoint (line 21) | def mock_endpoint():
function test_workspace_with_notebook (line 56) | def test_workspace_with_notebook(mock_endpoint):
function test_responses_initialized_as_none (line 129) | def test_responses_initialized_as_none(test_workspace_with_notebook):
function test_publish_item_without_response_collection (line 141) | def test_publish_item_without_response_collection(test_workspace_with_no...
function test_publish_item_with_response_collection (line 155) | def test_publish_item_with_response_collection(test_workspace_with_noteb...
function test_publish_all_items_no_feature_flag (line 180) | def test_publish_all_items_no_feature_flag(test_workspace_with_notebook):
function test_publish_all_items_with_feature_flag (line 190) | def test_publish_all_items_with_feature_flag(test_workspace_with_notebook):
function test_workspace_responses_access_pattern (line 206) | def test_workspace_responses_access_pattern(test_workspace_with_notebook):
function test_publish_item_skipped_no_response_stored (line 228) | def test_publish_item_skipped_no_response_stored(test_workspace_with_not...
function test_append_feature_flag_enables_response_collection (line 245) | def test_append_feature_flag_enables_response_collection(test_workspace_...
function test_unpublish_item_without_response_collection (line 266) | def test_unpublish_item_without_response_collection(test_workspace_with_...
function test_unpublish_item_with_response_collection (line 276) | def test_unpublish_item_with_response_collection(test_workspace_with_not...
function test_unpublish_item_does_not_write_to_publish_responses (line 294) | def test_unpublish_item_does_not_write_to_publish_responses(test_workspa...
function test_unpublish_item_failure_does_not_store_response (line 314) | def test_unpublish_item_failure_does_not_store_response(test_workspace_w...
function test_unpublish_all_orphan_items_no_feature_flag (line 344) | def test_unpublish_all_orphan_items_no_feature_flag(test_workspace_with_...
function test_unpublish_all_orphan_items_with_feature_flag (line 355) | def test_unpublish_all_orphan_items_with_feature_flag(test_workspace_wit...
function test_unpublish_all_orphan_items_empty_returns_none (line 391) | def test_unpublish_all_orphan_items_empty_returns_none(test_workspace_wi...
function test_unpublish_does_not_modify_publish_responses (line 414) | def test_unpublish_does_not_modify_publish_responses(test_workspace_with...
function test_publish_does_not_modify_unpublish_responses (line 435) | def test_publish_does_not_modify_unpublish_responses(test_workspace_with...
function test_publish_and_unpublish_responses_are_separate_dicts (line 455) | def test_publish_and_unpublish_responses_are_separate_dicts(test_workspa...
FILE: tests/test_semantic_model_exclude.py
function _make_sm (line 26) | def _make_sm(name: str, guid: str = "", skip_publish: bool = False) -> I...
function _make_connections (line 33) | def _make_connections(*conn_ids: str) -> dict:
function test_bind_skips_model_with_skip_publish_true (line 46) | def test_bind_skips_model_with_skip_publish_true():
function test_bind_skips_model_without_guid (line 84) | def test_bind_skips_model_without_guid():
function test_bind_processes_included_models_normally (line 115) | def test_bind_processes_included_models_normally():
function test_post_publish_all_skips_excluded_semantic_models (line 146) | def test_post_publish_all_skips_excluded_semantic_models():
FILE: tests/test_shortcut_exclude.py
function mock_fabric_workspace (line 19) | def mock_fabric_workspace():
function mock_item (line 45) | def mock_item():
function create_shortcut_file (line 53) | def create_shortcut_file(shortcuts_data):
function test_process_shortcuts_with_exclude_regex_filters_shortcuts (line 61) | def test_process_shortcuts_with_exclude_regex_filters_shortcuts(mock_fab...
function test_process_shortcuts_without_exclude_regex_publishes_all (line 132) | def test_process_shortcuts_without_exclude_regex_publishes_all(mock_fabr...
function test_process_shortcuts_exclude_regex_excludes_all_matching (line 186) | def test_process_shortcuts_exclude_regex_excludes_all_matching(mock_fabr...
function test_process_shortcuts_with_complex_regex_pattern (line 240) | def test_process_shortcuts_with_complex_regex_pattern(mock_fabric_worksp...
function shortcut_publish_enabled (line 317) | def shortcut_publish_enabled():
function _make_item (line 326) | def _make_item(name: str, guid: str = "") -> Item:
function test_excluded_lakehouses_marked_skip_publish_with_items_to_include (line 331) | def test_excluded_lakehouses_marked_skip_publish_with_items_to_include():
function test_lakehouses_without_guid_are_not_shortcut_published (line 366) | def test_lakehouses_without_guid_are_not_shortcut_published():
function test_publish_all_marks_excluded_items_skip_publish (line 395) | def test_publish_all_marks_excluded_items_skip_publish():
FILE: tests/test_subfolders.py
function mock_endpoint (line 18) | def mock_endpoint():
function temp_workspace_dir (line 26) | def temp_workspace_dir(tmp_path):
function valid_workspace_id (line 33) | def valid_workspace_id():
function create_platform_file (line 38) | def create_platform_file(item_path, item_type="Notebook", item_name="Tes...
function repository_with_subfolders (line 63) | def repository_with_subfolders(tmp_path):
function patched_fabric_workspace (line 99) | def patched_fabric_workspace(mock_endpoint):
function test_refresh_repository_folders (line 120) | def test_refresh_repository_folders(repository_with_subfolders, patched_...
function test_publish_folders_hierarchy (line 147) | def test_publish_folders_hierarchy(repository_with_subfolders, patched_f...
function test_folder_hierarchy_preservation (line 181) | def test_folder_hierarchy_preservation(repository_with_subfolders, patch...
function test_item_folder_association (line 229) | def test_item_folder_association(repository_with_subfolders, valid_works...
function test_deeply_nested_subfolders (line 296) | def test_deeply_nested_subfolders(tmp_path, patched_fabric_workspace, va...
function test_folder_rename_operations (line 367) | def test_folder_rename_operations(tmp_path, patched_fabric_workspace, va...
function test_special_character_handling (line 435) | def test_special_character_handling(tmp_path, patched_fabric_workspace, ...
function test_parent_folder_with_only_subfolder_containing_items (line 499) | def test_parent_folder_with_only_subfolder_containing_items(tmp_path, pa...
function test_large_number_of_folders_and_items (line 558) | def test_large_number_of_folders_and_items(tmp_path, patched_fabric_work...
FILE: tests/test_validate_env_vars.py
class TestValidHostnameRegex (line 16) | class TestValidHostnameRegex:
method test_valid_hostnames (line 49) | def test_valid_hostnames(self, hostname):
method test_invalid_hostnames (line 80) | def test_invalid_hostnames(self, hostname):
class TestValidateApiUrl (line 84) | class TestValidateApiUrl:
method test_accepts_valid_fabric_url (line 87) | def test_accepts_valid_fabric_url(self):
method test_accepts_valid_powerbi_url (line 91) | def test_accepts_valid_powerbi_url(self):
method test_strips_trailing_slash (line 95) | def test_strips_trailing_slash(self):
method test_label_appears_in_error_message (line 99) | def test_label_appears_in_error_message(self):
method test_rejects_empty_string (line 103) | def test_rejects_empty_string(self):
method test_rejects_whitespace_only (line 107) | def test_rejects_whitespace_only(self):
method test_rejects_http_scheme (line 111) | def test_rejects_http_scheme(self):
method test_rejects_invalid_hostname (line 115) | def test_rejects_invalid_hostname(self):
method test_rejects_path_components (line 119) | def test_rejects_path_components(self):
method test_accepts_private_link_url (line 123) | def test_accepts_private_link_url(self):
class TestValidateApiUrlHostname (line 129) | class TestValidateApiUrlHostname:
method test_returns_default_when_env_not_set (line 132) | def test_returns_default_when_env_not_set(self):
method test_returns_default_powerbi_url_when_env_not_set (line 138) | def test_returns_default_powerbi_url_when_env_not_set(self):
method test_returns_env_value_when_set (line 144) | def test_returns_env_value_when_set(self, monkeypatch):
method test_rejects_path_components (line 149) | def test_rejects_path_components(self, monkeypatch):
method test_raises_on_invalid_hostname (line 154) | def test_raises_on_invalid_hostname(self, monkeypatch):
method test_raises_on_empty_hostname (line 159) | def test_raises_on_empty_hostname(self, monkeypatch):
method test_prefixed_hostname_accepted (line 164) | def test_prefixed_hostname_accepted(self, monkeypatch):
method test_workspace_id_pattern_accepted (line 169) | def test_workspace_id_pattern_accepted(self, monkeypatch):
method test_dotted_prefix_hostname_accepted (line 175) | def test_dotted_prefix_hostname_accepted(self, monkeypatch):
method test_hostname_without_scheme_rejected (line 180) | def test_hostname_without_scheme_rejected(self, monkeypatch):
method test_rejects_http_scheme (line 185) | def test_rejects_http_scheme(self, monkeypatch):
method test_rejects_ftp_scheme (line 190) | def test_rejects_ftp_scheme(self, monkeypatch):
method test_raises_on_whitespace_only (line 195) | def test_raises_on_whitespace_only(self, monkeypatch):
method test_strips_trailing_slash (line 200) | def test_strips_trailing_slash(self, monkeypatch):
method test_rejects_url_with_no_authority (line 205) | def test_rejects_url_with_no_authority(self, monkeypatch):
Condensed preview — 321 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,846K chars).
[
{
"path": ".changes/header.tpl.md",
"chars": 12,
"preview": "# Changelog\n"
},
{
"path": ".changes/unreleased/added-20260420-140247.yaml",
"chars": 341,
"preview": "kind: added\nbody: Add `$workspace.$name` and `$workspace.$name_encoded` dynamic replacement variables for target workspa"
},
{
"path": ".changes/unreleased/added-20260503-000000.yaml",
"chars": 353,
"preview": "kind: added\nbody: Add `configure_fabric_fqdn` to configure Fabric API URLs for private-link-enabled workspaces using per"
},
{
"path": ".changes/unreleased/fixed-20260424-103120.yaml",
"chars": 376,
"preview": "kind: fixed\nbody: Fix incomplete Sparkcompute settings deployment by using the item definition API instead of the stagin"
},
{
"path": ".changes/unreleased/fixed-20260428-121610.yaml",
"chars": 341,
"preview": "kind: fixed\nbody: Fix HTTP 400 errors when using ``items_to_include`` with post-publish operations (e.g. Lakehouse short"
},
{
"path": ".changes/unreleased/new-items-20260505-123355.yaml",
"chars": 263,
"preview": "kind: new-items\nbody: Add support for DataBuildToolJob item\ntime: 2026-05-05T12:33:55.6581835-05:00\ncustom:\n Author: "
},
{
"path": ".changes/unreleased/optimization-20260505-142743.yaml",
"chars": 332,
"preview": "kind: optimization\nbody: Remove version check on import to reduce noise and eliminate unnecessary PyPI network call at s"
},
{
"path": ".changes/v0.1.0.md",
"chars": 315,
"preview": "## [v0.1.0](https://pypi.org/project/fabric-cicd/0.1.0) - January 23, 2025\n\n### ✨ New Functionality\n\n- Initial public pr"
},
{
"path": ".changes/v0.1.1.md",
"chars": 186,
"preview": "## [v0.1.1](https://pypi.org/project/fabric-cicd/0.1.1) - January 23, 2025\n\n### 🔧 Bug Fix\n\n- Fix Environment stuck in pu"
},
{
"path": ".changes/v0.1.10.md",
"chars": 404,
"preview": "## [v0.1.10](https://pypi.org/project/fabric-cicd/0.1.10) - March 19, 2025\n\n### ✨ New Functionality\n\n- DataPipeline SPN "
},
{
"path": ".changes/v0.1.11.md",
"chars": 640,
"preview": "## [v0.1.11](https://pypi.org/project/fabric-cicd/0.1.11) - March 25, 2025\n\n### ⚠️ Breaking Change\n\n- Parameterization r"
},
{
"path": ".changes/v0.1.12.md",
"chars": 463,
"preview": "## [v0.1.12](https://pypi.org/project/fabric-cicd/0.1.12) - March 27, 2025\n\n### 🔧 Bug Fix\n\n- Fix constant overwrite fail"
},
{
"path": ".changes/v0.1.13.md",
"chars": 919,
"preview": "## [v0.1.13](https://pypi.org/project/fabric-cicd/0.1.13) - April 07, 2025\n\n### ✨ New Functionality\n\n- Added support for"
},
{
"path": ".changes/v0.1.14.md",
"chars": 510,
"preview": "## [v0.1.14](https://pypi.org/project/fabric-cicd/0.1.14) - April 09, 2025\n\n### ✨ New Functionality\n\n- Optimized & beaut"
},
{
"path": ".changes/v0.1.15.md",
"chars": 447,
"preview": "## [v0.1.15](https://pypi.org/project/fabric-cicd/0.1.15) - April 21, 2025\n\n### 🔧 Bug Fix\n\n- Fix folders moving with eve"
},
{
"path": ".changes/v0.1.16.md",
"chars": 528,
"preview": "## [v0.1.16](https://pypi.org/project/fabric-cicd/0.1.16) - April 25, 2025\n\n### 🔧 Bug Fix\n\n- Fix bug with folder deploym"
},
{
"path": ".changes/v0.1.17.md",
"chars": 1100,
"preview": "## [v0.1.17](https://pypi.org/project/fabric-cicd/0.1.17) - May 13, 2025\n\n### ⚠️ Breaking Change\n\n- Deprecate old parame"
},
{
"path": ".changes/v0.1.18.md",
"chars": 198,
"preview": "## [v0.1.18](https://pypi.org/project/fabric-cicd/0.1.18) - May 14, 2025\n\n### 🔧 Bug Fix\n\n- Fix bug with check environmen"
},
{
"path": ".changes/v0.1.19.md",
"chars": 455,
"preview": "## [v0.1.19](https://pypi.org/project/fabric-cicd/0.1.19) - May 21, 2025\n\n### 🆕 New Items Support\n\n- Onboard SQL Databas"
},
{
"path": ".changes/v0.1.2.md",
"chars": 595,
"preview": "## [v0.1.2](https://pypi.org/project/fabric-cicd/0.1.2) - January 27, 2025\n\n### ✨ New Functionality\n\n- Introduces max re"
},
{
"path": ".changes/v0.1.20.md",
"chars": 756,
"preview": "## [v0.1.20](https://pypi.org/project/fabric-cicd/0.1.20) - June 12, 2025\n\n### ✨ New Functionality\n\n- Parameterization s"
},
{
"path": ".changes/v0.1.21.md",
"chars": 315,
"preview": "## [v0.1.21](https://pypi.org/project/fabric-cicd/0.1.21) - June 18, 2025\n\n### 🔧 Bug Fix\n\n- Fix bug with workspace ID re"
},
{
"path": ".changes/v0.1.22.md",
"chars": 476,
"preview": "## [v0.1.22](https://pypi.org/project/fabric-cicd/0.1.22) - June 25, 2025\n\n### 🆕 New Items Support\n\n- Onboard API for Gr"
},
{
"path": ".changes/v0.1.23.md",
"chars": 999,
"preview": "## [v0.1.23](https://pypi.org/project/fabric-cicd/0.1.23) - July 08, 2025\n\n### ✨ New Functionality\n\n- New functionalitie"
},
{
"path": ".changes/v0.1.24.md",
"chars": 1141,
"preview": "## [v0.1.24](https://pypi.org/project/fabric-cicd/0.1.24) - August 04, 2025\n\n### ⚠️ Breaking Change\n\n- Require parameter"
},
{
"path": ".changes/v0.1.25.md",
"chars": 1441,
"preview": "## [v0.1.25](https://pypi.org/project/fabric-cicd/0.1.25) - August 19, 2025\n\n### ⚠️ Breaking Change\n\n- Modify the defaul"
},
{
"path": ".changes/v0.1.26.md",
"chars": 1008,
"preview": "## [v0.1.26](https://pypi.org/project/fabric-cicd/0.1.26) - September 05, 2025\n\n### ⚠️ Breaking Change\n\n- Deprecate Base"
},
{
"path": ".changes/v0.1.27.md",
"chars": 195,
"preview": "## [v0.1.27](https://pypi.org/project/fabric-cicd/0.1.27) - September 05, 2025\n\n### 🔧 Bug Fix\n\n- Fix trailing comma in r"
},
{
"path": ".changes/v0.1.28.md",
"chars": 629,
"preview": "## [v0.1.28](https://pypi.org/project/fabric-cicd/0.1.28) - September 15, 2025\n\n### ✨ New Functionality\n\n- Add folder ex"
},
{
"path": ".changes/v0.1.29.md",
"chars": 729,
"preview": "## [v0.1.29](https://pypi.org/project/fabric-cicd/0.1.29) - October 01, 2025\n\n### ✨ New Functionality\n\n- Support dynamic"
},
{
"path": ".changes/v0.1.3.md",
"chars": 747,
"preview": "## [v0.1.3](https://pypi.org/project/fabric-cicd/0.1.3) - January 29, 2025\n\n### ✨ New Functionality\n\n- Add PyPI check ve"
},
{
"path": ".changes/v0.1.30.md",
"chars": 916,
"preview": "## [v0.1.30](https://pypi.org/project/fabric-cicd/0.1.30) - October 20, 2025\n\n### ✨ New Functionality\n\n- Add support for"
},
{
"path": ".changes/v0.1.31.md",
"chars": 1951,
"preview": "## [v0.1.31](https://pypi.org/project/fabric-cicd/0.1.31) - December 01, 2025\n\n### ⚠️ Breaking Change\n\n- Migrate to the "
},
{
"path": ".changes/v0.1.32.md",
"chars": 229,
"preview": "## [v0.1.32](https://pypi.org/project/fabric-cicd/0.1.32) - December 03, 2025\n\n### 🔧 Bug Fix\n\n- Fix publish bug for Envi"
},
{
"path": ".changes/v0.1.33.md",
"chars": 1221,
"preview": "## [v0.1.33](https://pypi.org/project/fabric-cicd/0.1.33) - December 16, 2025\n\n### ✨ New Functionality\n\n- Add key_value_"
},
{
"path": ".changes/v0.1.34.md",
"chars": 1036,
"preview": "## [v0.1.34](https://pypi.org/project/fabric-cicd/0.1.34) - January 20, 2026\n\n### ✨ New Functionality\n\n- Enable dynamic "
},
{
"path": ".changes/v0.1.4.md",
"chars": 740,
"preview": "## [v0.1.4](https://pypi.org/project/fabric-cicd/0.1.4) - February 12, 2025\n\n### ✨ New Functionality\n\n- Support Feature "
},
{
"path": ".changes/v0.1.5.md",
"chars": 332,
"preview": "## [v0.1.5](https://pypi.org/project/fabric-cicd/0.1.5) - February 18, 2025\n\n### 🔧 Bug Fix\n\n- Fix Environment Failure wi"
},
{
"path": ".changes/v0.1.6.md",
"chars": 748,
"preview": "## [v0.1.6](https://pypi.org/project/fabric-cicd/0.1.6) - February 24, 2025\n\n### 🆕 New Items Support\n\n- Onboard Lakehous"
},
{
"path": ".changes/v0.1.7.md",
"chars": 195,
"preview": "## [v0.1.7](https://pypi.org/project/fabric-cicd/0.1.7) - February 26, 2025\n\n### 🔧 Bug Fix\n\n- Fix special character supp"
},
{
"path": ".changes/v0.1.8.md",
"chars": 599,
"preview": "## [v0.1.8](https://pypi.org/project/fabric-cicd/0.1.8) - March 04, 2025\n\n### 🔧 Bug Fix\n\n- Handle null byPath object in "
},
{
"path": ".changes/v0.1.9.md",
"chars": 333,
"preview": "## [v0.1.9](https://pypi.org/project/fabric-cicd/0.1.9) - March 11, 2025\n\n### 🆕 New Items Support\n\n- Support for Mirrore"
},
{
"path": ".changes/v0.2.0.md",
"chars": 1792,
"preview": "## [v0.2.0](https://pypi.org/project/fabric-cicd/0.2.0) - February 16, 2026\n\n### ✨ New Functionality\n\n- Support parallel"
},
{
"path": ".changes/v0.3.0.md",
"chars": 2004,
"preview": "## [v0.3.0](https://pypi.org/project/fabric-cicd/0.3.0) - March 09, 2026\n\n### ✨ New Functionality\n\n- Support selective f"
},
{
"path": ".changes/v0.3.1.md",
"chars": 278,
"preview": "## [v0.3.1](https://pypi.org/project/fabric-cicd/0.3.1) - March 12, 2026\n\n### 🔧 Bug Fix\n\n- Fix override behavior of feat"
},
{
"path": ".changes/v1.0.0.md",
"chars": 2619,
"preview": "## [v1.0.0](https://pypi.org/project/fabric-cicd/1.0.0) - April 20, 2026\n\n### ⚠️ Breaking Change\n\n- Remove default crede"
},
{
"path": ".changie.yaml",
"chars": 1514,
"preview": "# docs: https://changie.dev/config/\n---\nchangesDir: .changes\nunreleasedDir: unreleased\nheaderPath: header.tpl.md\nversion"
},
{
"path": ".github/CODEOWNERS",
"chars": 238,
"preview": "##########################################\n\n# CODE OWNERS\n\n##########################################\n\n# default ownersh"
},
{
"path": ".github/ISSUE_TEMPLATE/1-bug.yml",
"chars": 2989,
"preview": "name: \"🐛 Bug Report\"\ndescription: Report a bug\ntitle: \"[BUG] \"\nlabels: [\"bug\"]\nbody:\n - type: markdown\n attribut"
},
{
"path": ".github/ISSUE_TEMPLATE/2-feature.yml",
"chars": 3179,
"preview": "name: \"🚀 Feature Request\"\ndescription: Suggest an idea or enhancement for fabric-cicd\ntitle: \"[FEATURE] \"\nlabels: [\"enha"
},
{
"path": ".github/ISSUE_TEMPLATE/3-documentation.yml",
"chars": 2656,
"preview": "name: \"📝 Documentation Feedback\"\ndescription: Provide documentation feedback\ntitle: \"[DOCUMENTATION] \"\nlabels: [\"documen"
},
{
"path": ".github/ISSUE_TEMPLATE/4-question.yml",
"chars": 2735,
"preview": "name: \"❓ Question\"\ndescription: Ask a question about fabric-cicd\ntitle: \"[QUESTION] \"\nlabels: [\"question\"]\nbody:\n - t"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 28,
"preview": "blank_issues_enabled: false\n"
},
{
"path": ".github/agents/new-item-type.agent.md",
"chars": 23461,
"preview": "---\nname: New Item Type\ndescription: Guide and assist with onboarding a new Microsoft Fabric item type into fabric-cicd\n"
},
{
"path": ".github/copilot-instructions.md",
"chars": 10005,
"preview": "# Fabric CICD\n\nfabric-cicd is a Python library for Microsoft Fabric CI/CD automation. It supports code-first Continuous "
},
{
"path": ".github/policies/resourceManagement.yml",
"chars": 6564,
"preview": "id: issue-triage\nname: GitOps.PullRequestIssueManagement\ndescription: Issue triage workflow\nowner:\nresource: repository\n"
},
{
"path": ".github/policies/sdl.yml",
"chars": 222,
"preview": "name: SDL\ndescription: Requires one reviewer for merges into main branch\nresource: repository\nwhere:\nconfiguration:\n "
},
{
"path": ".github/prompts/bug-triage.prompt.yml",
"chars": 18048,
"preview": "messages:\n - role: system\n content: >+\n You are a senior engineer triaging bug reports for **fabric-cic"
},
{
"path": ".github/prompts/feature-triage.prompt.yml",
"chars": 17140,
"preview": "messages:\n - role: system\n content: >+\n You are a product-minded engineer evaluating feature requests f"
},
{
"path": ".github/prompts/question-triage.prompt.yml",
"chars": 17215,
"preview": "messages:\n - role: system\n content: >+\n You are a knowledgeable support engineer for **fabric-cicd** (`"
},
{
"path": ".github/pull_request_template.md",
"chars": 446,
"preview": "## Description\n\nBriefly describe what this PR does and why.\n\n## Linked Issue (REQUIRED)\n\n<!-- \nREQUIRED: This PR must be"
},
{
"path": ".github/workflows/ai-issue-triage.yml",
"chars": 14211,
"preview": "name: \"AI Issue Triage\"\n\non:\n issues:\n types: [labeled]\n workflow_dispatch:\n inputs:\n iss"
},
{
"path": ".github/workflows/bump.yml",
"chars": 10314,
"preview": "name: Bump Version\n\non:\n pull_request:\n types: [closed]\n branches:\n - main\n workflow_disp"
},
{
"path": ".github/workflows/changelog.yml",
"chars": 3882,
"preview": "# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json\n---\nname: 🔄 Changelog\n\non:\n pull_re"
},
{
"path": ".github/workflows/publish_docs.yml",
"chars": 2478,
"preview": "name: Publish Docs\n\non:\n workflow_run:\n workflows: [\"Bump Version\"]\n types: [completed]\n workflow_di"
},
{
"path": ".github/workflows/test.yml",
"chars": 1008,
"preview": "name: Test\ndescription: \"Run unit tests for the Fabric CICD project\"\n\non:\n pull_request:\n branches: [\"main\"]\n "
},
{
"path": ".github/workflows/validate.yml",
"chars": 15093,
"preview": "name: Validate PR\ndescription: \"Validate pull requests for code conventions, naming conventions, linked issues, and vers"
},
{
"path": ".gitignore",
"chars": 3218,
"preview": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n\n# Distribution / packagi"
},
{
"path": ".prettierignore",
"chars": 50,
"preview": "sample/workspace/\ndocs/how_to/parameterization.md\n"
},
{
"path": ".prettierrc",
"chars": 113,
"preview": "{\n \"printWidth\": 100,\n \"tabWidth\": 4,\n \"useTabs\": false,\n \"semi\": true,\n \"trailingComma\": \"all\"\n}\n"
},
{
"path": ".python-version",
"chars": 5,
"preview": "3.11\n"
},
{
"path": ".vscode/extensions.json",
"chars": 170,
"preview": "{\n \"recommendations\": [\n \"ms-python.python\",\n \"esbenp.prettier-vscode\",\n \"ms-vscode.powershell\",\n \"charlier"
},
{
"path": ".vscode/launch.json",
"chars": 554,
"preview": "{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"name\": \"Debug: Trace Publish All Items\",\n "
},
{
"path": ".vscode/settings.json",
"chars": 1250,
"preview": "{\n \"editor\": {\n \"trimAutoWhitespace\": false,\n \"defaultFormatter\": \"esbenp.prettier-vscode\",\n \"fo"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 444,
"preview": "# Microsoft Open Source Code of Conduct\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://op"
},
{
"path": "CONTRIBUTING.md",
"chars": 12289,
"preview": "# Contributing\n\nThis project welcomes contributions and suggestions. Most contributions require you to\nagree to a Contri"
},
{
"path": "CodeQL.yml",
"chars": 49,
"preview": "path_classifiers:\n tests:\n - \"devtools/*.py\"\n"
},
{
"path": "LICENSE",
"chars": 1141,
"preview": " MIT License\n\n Copyright (c) Microsoft Corporation.\n\n Permission is hereby granted, free of charge, to any pers"
},
{
"path": "README.md",
"chars": 2298,
"preview": "# Fabric CICD\n\n[](https://www.python.org/)\n[ - April 20, 2026\n\n### ⚠️ Breaking Change\n\n- Remove "
},
{
"path": "docs/code_reference.md",
"chars": 33,
"preview": "# Code Reference\n::: fabric_cicd\n"
},
{
"path": "docs/config/overrides/main.html",
"chars": 189,
"preview": "{% extends \"base.html\" %}\n\n{% block announce %}\n <p style=\"text-align: center;\">ℹ️ This library is open source. Pleas"
},
{
"path": "docs/config/pre-build/section_toc.py",
"chars": 3875,
"preview": "from pathlib import Path\nimport re\nimport unicodedata\n\nimport yaml\n\n\ndef slugify(title):\n \"\"\"\n Generate an anchor "
},
{
"path": "docs/config/pre-build/update_item_types.py",
"chars": 779,
"preview": "import sys\nfrom pathlib import Path\n\nroot_directory = Path(__file__).resolve().parent.parent.parent.parent\nsys.path.inse"
},
{
"path": "docs/config/pre-build/update_python_version.py",
"chars": 2327,
"preview": "import re\ntry:\n import tomllib # Python 3.11+\nexcept ImportError:\n import toml as tomllib # Fallback for older P"
},
{
"path": "docs/config/stylesheets/extra.css",
"chars": 2690,
"preview": "[data-md-color-scheme=\"fabric\"] {\n --md-primary-fg-color: #117865;\n --md-primary-fg-color--light: #e3f7ef;\n --m"
},
{
"path": "docs/example/authentication.md",
"chars": 19779,
"preview": "# Authentication Examples\n\nThe following are the most common authentication flows for fabric-cicd. However, because fabr"
},
{
"path": "docs/example/deployment_variable.md",
"chars": 10838,
"preview": "# Deployment Variable Examples\n\nA key concept in CI/CD is defining environment-specific deployment variables. The follow"
},
{
"path": "docs/example/index.md",
"chars": 336,
"preview": "# How To\n\nWelcome to the Examples section! Here you will find all necessary code samples to leverage fabric-cicd. If the"
},
{
"path": "docs/example/release_pipeline.md",
"chars": 5256,
"preview": "# Release Pipeline Examples\n\nThe following are some common examples of how to deploy from tooling like Azure DevOps and "
},
{
"path": "docs/how_to/config_deployment.md",
"chars": 17978,
"preview": "# Configuration Deployment\n\n## Overview\n\nConfiguration-based deployment provides an alternative way to manage the deploy"
},
{
"path": "docs/how_to/getting_started.md",
"chars": 3292,
"preview": "# Getting Started\n\n## Installation\n\nTo install fabric-cicd, run:\n\n```bash\npip install fabric-cicd\n```\n\n## Authentication"
},
{
"path": "docs/how_to/index.md",
"chars": 333,
"preview": "# How To\n\nWelcome to the How To section! Here you will find all necessary information to leverage fabric-cicd. If there "
},
{
"path": "docs/how_to/item_types.md",
"chars": 15483,
"preview": "# Item Types\n\n## Activator\n\n- **Parameterization:**\n - The `find_replace` section in the `parameter.yml` file is not "
},
{
"path": "docs/how_to/optional_feature.md",
"chars": 11900,
"preview": "# Optional Features\n\nfabric-cicd has an expected default flow; however, there will always be cases where overriding defa"
},
{
"path": "docs/how_to/parameterization.md",
"chars": 61522,
"preview": "# Parameterization\n\n## Overview\n\nTo handle environment-specific values committed to git, use a `parameter.yml` file. Thi"
},
{
"path": "docs/how_to/troubleshooting.md",
"chars": 16994,
"preview": "# Troubleshooting\n\nThis guide provides comprehensive debugging and troubleshooting resources for both users deploying wi"
},
{
"path": "docs/index.md",
"chars": 2049,
"preview": "fabric-cicd is a Python library designed for use with [Microsoft Fabric](https://learn.microsoft.com/en-us/fabric/) work"
},
{
"path": "mkdocs.yml",
"chars": 4176,
"preview": "site_name: fabric-cicd\n\nrepo_name: microsoft/fabric-cicd\nrepo_url: https://github.com/microsoft/fabric-cicd\nsite_url: ht"
},
{
"path": "pyproject.toml",
"chars": 1598,
"preview": "[project]\nname = \"fabric-cicd\"\nauthors = [{ name = \"Microsoft Corporation\" }]\ndescription = \"Microsoft Fabric CI/CD\"\nrea"
},
{
"path": "ruff.toml",
"chars": 1560,
"preview": "line-length = 120\nexclude = [\"sample/*\", \"docs/*\"]\n\n[lint]\n# https://docs.astral.sh/ruff/rules/\nselect = [\n \"A\", # "
},
{
"path": "sample/workspace/ABC.Report/.platform",
"chars": 288,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/ABC.Report/StaticResources/SharedResources/BaseThemes/CY24SU10.json",
"chars": 13425,
"preview": "{\n \"name\": \"CY24SU10\",\n \"dataColors\": [\n \"#118DFF\",\n \"#12239E\",\n \"#E66C37\",\n \"#6B007B\",\n \"#E044A7\",\n "
},
{
"path": "sample/workspace/ABC.Report/definition.pbir",
"chars": 110,
"preview": "{\n \"version\": \"4.0\",\n \"datasetReference\": {\n \"byPath\": {\n \"path\": \"../ABC.SemanticModel\"\n }\n }\n}"
},
{
"path": "sample/workspace/ABC.Report/report.json",
"chars": 9682,
"preview": "{\n \"config\": \"{\\\"version\\\":\\\"5.59\\\",\\\"themeCollection\\\":{\\\"baseTheme\\\":{\\\"name\\\":\\\"CY24SU10\\\",\\\"version\\\":\\\"5.61\\\",\\\"ty"
},
{
"path": "sample/workspace/ABC.SemanticModel/.platform",
"chars": 294,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/cultures/en-US.tmdl",
"chars": 122,
"preview": "cultureInfo en-US\n\n\tlinguisticMetadata =\n\t\t\t{\n\t\t\t \"Version\": \"1.0.0\",\n\t\t\t \"Language\": \"en-US\"\n\t\t\t}\n\t\tcontentType: json"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/database.tmdl",
"chars": 36,
"preview": "database\n\tcompatibilityLevel: 1550\n\n"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/model.tmdl",
"chars": 451,
"preview": "model Model\n\tculture: en-US\n\tdefaultPowerBIDataSourceVersion: powerBI_V3\n\tsourceQueryCulture: en-US\n\tdataAccessOptions\n\t"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/relationships.tmdl",
"chars": 180,
"preview": "relationship AutoDetected_981379f6-d1c0-48e8-a4d4-cf3718d1fc57\n\tcrossFilteringBehavior: bothDirections\n\tfromCardinality:"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/tables/Table.tmdl",
"chars": 989,
"preview": "table Table\n\tlineageTag: e9a135a4-d745-4125-9c08-01f5a8ee959e\n\n\tcolumn Column1\n\t\tdataType: string\n\t\tlineageTag: 2b0b4597"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition/tables/Table_2.tmdl",
"chars": 775,
"preview": "table Table_2\n\tlineageTag: 2f801d69-7502-4625-aba2-356b8f4378b2\n\n\tcolumn Column1\n\t\tdataType: int64\n\t\tformatString: 0\n\t\tl"
},
{
"path": "sample/workspace/ABC.SemanticModel/definition.pbism",
"chars": 40,
"preview": "{\n \"version\": \"4.0\",\n \"settings\": {}\n}"
},
{
"path": "sample/workspace/ABC.SemanticModel/diagramLayout.json",
"chars": 1045,
"preview": "{\n \"version\": \"1.1.0\",\n \"diagrams\": [\n {\n \"ordinal\": 0,\n \"scrollPosition\": {\n \"x\": 0,\n \"y\":"
},
{
"path": "sample/workspace/ABCD.Report/.platform",
"chars": 315,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.jso"
},
{
"path": "sample/workspace/ABCD.Report/StaticResources/SharedResources/BaseThemes/CY24SU10.json",
"chars": 13425,
"preview": "{\n \"name\": \"CY24SU10\",\n \"dataColors\": [\n \"#118DFF\",\n \"#12239E\",\n \"#E66C37\",\n \"#6B007B\",\n \"#E044A7\",\n "
},
{
"path": "sample/workspace/ABCD.Report/definition.pbir",
"chars": 110,
"preview": "{\n \"version\": \"4.0\",\n \"datasetReference\": {\n \"byPath\": {\n \"path\": \"../ABC.SemanticModel\"\n }\n }\n}"
},
{
"path": "sample/workspace/ABCD.Report/report.json",
"chars": 4941,
"preview": "{\n \"config\": \"{\\\"version\\\":\\\"5.59\\\",\\\"themeCollection\\\":{\\\"baseTheme\\\":{\\\"name\\\":\\\"CY24SU10\\\",\\\"version\\\":\\\"5.61\\\",\\\"ty"
},
{
"path": "sample/workspace/ByConnection.Report/.platform",
"chars": 297,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/ByConnection.Report/definition.pbir",
"chars": 434,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/report/definitionProperties/2.0.0/schema.json\","
},
{
"path": "sample/workspace/ByConnection.Report/report.json",
"chars": 1054,
"preview": "{\n \"config\": \"{\\\"version\\\":\\\"5.59\\\",\\\"themeCollection\\\":{\\\"baseTheme\\\":{\\\"name\\\":\\\"CY24SU10\\\",\\\"version\\\":\\\"5.61\\\",\\\"ty"
},
{
"path": "sample/workspace/Default.Warehouse/.platform",
"chars": 295,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/DefaultCaseInsensitive.Warehouse/.platform",
"chars": 409,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Example Notebook.Notebook/.platform",
"chars": 338,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Example Notebook.Notebook/notebook-content.py",
"chars": 1146,
"preview": "# Fabric notebook source\n\n# METADATA ********************\n\n# META {\n# META \"kernel_info\": {\n# META \"name\": \"synaps"
},
{
"path": "sample/workspace/Hello Copy Job.CopyJob/.platform",
"chars": 299,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Hello Copy Job.CopyJob/copyjob-content.json",
"chars": 5201,
"preview": "{\n \"properties\": {\n \"jobMode\": \"Batch\",\n \"source\": {\n \"type\": \"LakehouseTable\",\n \"connectionSettings\": "
},
{
"path": "sample/workspace/Hello Dataflow.Dataflow/.platform",
"chars": 300,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Hello Dataflow.Dataflow/mashup.pq",
"chars": 864,
"preview": "[StagingDefinition = [Kind = \"FastCopy\"]]\nsection Section1;\nshared Table = let\n Source = Table.FromRows(Json.Document(B"
},
{
"path": "sample/workspace/Hello Dataflow.Dataflow/queryMetadata.json",
"chars": 294,
"preview": "{\n \"formatVersion\": \"202502\",\n \"computeEngineSettings\": {},\n \"name\": \"Hello Dataflow\",\n \"queryGroups\": [],\n \"docume"
},
{
"path": "sample/workspace/Hello World.Notebook/.platform",
"chars": 335,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Hello World.Notebook/notebook-content.py",
"chars": 547,
"preview": "# Fabric notebook source\n\n# METADATA ********************\n\n# META {\n# META \"kernel_info\": {\n# META \"name\": \"synaps"
},
{
"path": "sample/workspace/Hello db.SQLDatabase/.gitignore",
"chars": 7949,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## G"
},
{
"path": "sample/workspace/Hello db.SQLDatabase/.platform",
"chars": 298,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Hello db.SQLDatabase/Hello db.sqlproj",
"chars": 515,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\">\n <Sdk Name=\"Microsoft.Build.Sql\" Version=\"1.0.0"
},
{
"path": "sample/workspace/HelloEventhouse.Eventhouse/.children/HelloEventhouse.KQLDatabase/.platform",
"chars": 342,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/HelloEventhouse.Eventhouse/.children/HelloEventhouse.KQLDatabase/DatabaseProperties.json",
"chars": 183,
"preview": "{\n \"databaseType\": \"ReadWrite\",\n \"parentEventhouseItemId\": \"50adae54-3e43-9fda-464a-757b7f9fb86b\",\n \"oneLakeCachingPe"
},
{
"path": "sample/workspace/HelloEventhouse.Eventhouse/.children/HelloEventhouse.KQLDatabase/DatabaseSchema.kql",
"chars": 2800,
"preview": "// KQL script\n// Use management commands in this script to configure your database items, such as tables, functions, mat"
},
{
"path": "sample/workspace/HelloEventhouse.Eventhouse/.platform",
"chars": 341,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/HelloEventhouse.Eventhouse/EventhouseProperties.json",
"chars": 2,
"preview": "{}"
},
{
"path": "sample/workspace/HelloRealTimeDashboard.KQLDashboard/.platform",
"chars": 357,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/HelloRealTimeDashboard.KQLDashboard/RealTimeDashboard.json",
"chars": 4816,
"preview": "{\n \"schema_version\": \"60\",\n \"tiles\": [\n {\n \"id\": \"bad34d7e-6462-4811-b17a-5ed946fa0bf1\",\n \"title\": \"New t"
},
{
"path": "sample/workspace/MirroredDatabase_1.MirroredDatabase/.platform",
"chars": 312,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/MirroredDatabase_1.MirroredDatabase/mirroring.json",
"chars": 265,
"preview": "{\n \"properties\": {\n \"source\": {\n \"type\": \"GenericMirror\",\n \"typeProperties\": null\n },\n \"target\": {\n "
},
{
"path": "sample/workspace/OntologyDataLH.Lakehouse/.platform",
"chars": 301,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/OntologyDataLH.Lakehouse/alm.settings.json",
"chars": 970,
"preview": "{\n \"version\": \"1.0.1\",\n \"objectTypes\": [\n {\n \"name\": \"Shortcuts\",\n \"state\": \"Enabled\",\n \"subObjectTy"
},
{
"path": "sample/workspace/OntologyDataLH.Lakehouse/lakehouse.metadata.json",
"chars": 2,
"preview": "{}"
},
{
"path": "sample/workspace/OntologyDataLH.Lakehouse/shortcuts.metadata.json",
"chars": 2,
"preview": "[]"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/.platform",
"chars": 305,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/205398164146535/DataBindings/a790fdb3-e356-4f42-acf4-4420557c0fd7.json",
"chars": 1164,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/dataBinding/1.0.0/schema.json\",\n \"id\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/205398164146535/definition.json",
"chars": 1387,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/entityType/1.0.0/schema.json\",\n \"id\":"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/267812974919544/DataBindings/275d574a-4d0d-4935-9cfd-54e59ee36d7f.json",
"chars": 1069,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/dataBinding/1.0.0/schema.json\",\n \"id\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/267812974919544/definition.json",
"chars": 1235,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/entityType/1.0.0/schema.json\",\n \"id\":"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/28747097105824/DataBindings/5f66bbb3-9bb6-415a-9cd9-9d7421d0e553.json",
"chars": 955,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/dataBinding/1.0.0/schema.json\",\n \"id\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/28747097105824/DataBindings/f0767964-7f82-40a1-9ca2-f7e7fe931fcd.json",
"chars": 1315,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/dataBinding/1.0.0/schema.json\",\n \"id\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/28747097105824/definition.json",
"chars": 1734,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/entityType/1.0.0/schema.json\",\n \"id\":"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/52068896499199/DataBindings/3d6fc8a5-b442-46b2-9bee-c22d08038f2e.json",
"chars": 1167,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/dataBinding/1.0.0/schema.json\",\n \"id\""
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/EntityTypes/52068896499199/definition.json",
"chars": 1394,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/entityType/1.0.0/schema.json\",\n \"id\":"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4160405290834524422/Contextualizations/088a81ce-2a4c-4dbc-8887-ab6b831fa047.json",
"chars": 667,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/contextualization/1.0.0/schema.json\",\n"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4160405290834524422/definition.json",
"chars": 342,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/relationshipType/1.0.0/schema.json\",\n "
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4194354367812289411/Contextualizations/7be8afdf-2557-4950-930e-26c762fcb5a5.json",
"chars": 673,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/contextualization/1.0.0/schema.json\",\n"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4194354367812289411/definition.json",
"chars": 340,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/relationshipType/1.0.0/schema.json\",\n "
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4244194862547506054/Contextualizations/7f23e2a5-25f6-4c87-8b9a-43b3b9a142ec.json",
"chars": 666,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/contextualization/1.0.0/schema.json\",\n"
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/RelationshipTypes/4244194862547506054/definition.json",
"chars": 337,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/ontology/relationshipType/1.0.0/schema.json\",\n "
},
{
"path": "sample/workspace/RetailSalesOntology.Ontology/definition.json",
"chars": 2,
"preview": "{}"
},
{
"path": "sample/workspace/Run Hello World.DataPipeline/.platform",
"chars": 305,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Run Hello World.DataPipeline/.schedules",
"chars": 425,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/schedules/1.0.0/schema.json\",\n \"sche"
},
{
"path": "sample/workspace/Run Hello World.DataPipeline/pipeline-content.json",
"chars": 520,
"preview": "{\n \"properties\": {\n \"activities\": [\n {\n \"type\": \"TridentNotebook\",\n \"typeProperties\": {\n "
},
{
"path": "sample/workspace/Sample.GraphQLApi/.platform",
"chars": 294,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/Sample.GraphQLApi/graphql-definition.json",
"chars": 136,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/item/graphqlApi/definition/1.0.0/schema.json\",\n \"da"
},
{
"path": "sample/workspace/SampleDataActivator.Reflex/.platform",
"chars": 304,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleDataActivator.Reflex/ReflexEntities.json",
"chars": 2,
"preview": "[]"
},
{
"path": "sample/workspace/SampleDataBuildToolJob.DataBuildToolJob/.platform",
"chars": 354,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleDataBuildToolJob.DataBuildToolJob/dbt-content.json",
"chars": 667,
"preview": "{\n \"project\": {\n \"projectType\": \"OneLake\",\n \"folderPath\": \"dbt\"\n },\n \"profile\": {\n \"profileType\": \"DataWareh"
},
{
"path": "sample/workspace/SampleEventhouse.Eventhouse/.children/TaxiDB.KQLDatabase/.platform",
"chars": 296,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleEventhouse.Eventhouse/.children/TaxiDB.KQLDatabase/DatabaseProperties.json",
"chars": 178,
"preview": "{\n \"databaseType\": \"ReadWrite\",\n \"parentEventhouseItemId\": \"959f24d2-d283-ad08-4897-52f5ff52f4d3\",\n \"oneLakeCachingPe"
},
{
"path": "sample/workspace/SampleEventhouse.Eventhouse/.children/TaxiDB.KQLDatabase/DatabaseSchema.kql",
"chars": 5282,
"preview": "// KQL script\n// Use management commands in this script to configure your database items, such as tables, functions, mat"
},
{
"path": "sample/workspace/SampleEventhouse.Eventhouse/.platform",
"chars": 305,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleEventhouse.Eventhouse/EventhouseProperties.json",
"chars": 2,
"preview": "{}"
},
{
"path": "sample/workspace/SampleEventstream.Eventstream/.platform",
"chars": 307,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleEventstream.Eventstream/eventstream.json",
"chars": 23349,
"preview": "{\n \"sources\": [\n {\n \"id\": \"d4686b8c-e228-4328-871d-1f2d2bcd6248\",\n \"name\": \"Taxi\",\n \"type\": \"SampleDa"
},
{
"path": "sample/workspace/SampleEventstream.Eventstream/eventstreamProperties.json",
"chars": 63,
"preview": "{\n \"retentionTimeInDays\": 1,\n \"eventThroughputLevel\": \"Low\"\n}"
},
{
"path": "sample/workspace/SampleKQLQueryset.KQLQueryset/.platform",
"chars": 336,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleKQLQueryset.KQLQueryset/RealTimeQueryset.json",
"chars": 1219,
"preview": "{\n \"queryset\": {\n \"version\": \"1.0.0\",\n \"dataSources\": [\n {\n \"id\": \"50c1256c-4b67-4f03-a048-9aeadd2778"
},
{
"path": "sample/workspace/SampleSparkJobDefinition.SparkJobDefinition/.platform",
"chars": 364,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleSparkJobDefinition.SparkJobDefinition/Libs/pipeline_config.py",
"chars": 37,
"preview": "config = {\n 'range_limit': 1000\n}\n"
},
{
"path": "sample/workspace/SampleSparkJobDefinition.SparkJobDefinition/Main/main.py",
"chars": 834,
"preview": "from pyspark.sql import SparkSession\nimport logging\nimport sys\n\nfrom pipeline_config import config\n\n# Configure logging\n"
},
{
"path": "sample/workspace/SampleSparkJobDefinition.SparkJobDefinition/SparkJobDefinitionV1.json",
"chars": 379,
"preview": "{\n \"executableFile\": \"main.py\",\n \"defaultLakehouseArtifactId\": \"eb8e6aef-81f9-894c-4eda-7be021fdfc5d\",\n \"mainCl"
},
{
"path": "sample/workspace/SampleUserDataFunction.UserDataFunction/.platform",
"chars": 317,
"preview": "{\n \"$schema\": \"https://developer.microsoft.com/json-schemas/fabric/gitIntegration/platformProperties/2.0.0/schema.json\""
},
{
"path": "sample/workspace/SampleUserDataFunction.UserDataFunction/.resources/functions.json",
"chars": 651,
"preview": "{\n \"runtime\": \"PYTHON\",\n \"functionsMetadata\": [\n {\n \"name\": \"hello_fabric\",\n \"scriptFile\": \"function_app."
}
]
// ... and 121 more files (download for full content)
About this extraction
This page contains the full source code of the microsoft/fabric-cicd GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 321 files (1.7 MB), approximately 389.1k tokens, and a symbol index with 1205 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.