Docs + workflow rename + post-Phase-2 hardening + TypedDict pass#33
Merged
Conversation
Symmetric naming with reusable-deploy-bulk.yml. Both reusable workflows
are now named after their underlying deploy mechanism rather than what
they deploy ('supported items' was vague — both paths deploy supported
items).
Renames:
- File: reusable-deploy-supported.yml -> reusable-deploy-fabric-cicd.yml
- Reusable workflow name: 'Reusable: Deploy Supported Items' ->
'Reusable: Deploy via fabric-cicd'
- Reusable job name: 'Deploy supported items (...)' ->
'Deploy via fabric-cicd (...)'
- Orchestrator job ID: deploy-supported -> deploy-fabric-cicd
(in deploy-test.yml and deploy-prod.yml)
- Orchestrator job name: 'Deploy supported items' -> 'Deploy via fabric-cicd'
Other touches:
- reusable-deploy-bulk.yml header comments updated to reference the new
filename (two stale references)
- scripts/deploy_fabric_cicd.py module docstring updated
Not changed in this commit (covered by the docs pass on this same branch):
- 6 references in fabric-hybrid-cicd-guide.md
- 2 narrative 'deploy supported items' phrasings that describe the
sandwich-pattern concept, not workflow names — those stay
Caller wiring verified: deploy-test.yml and deploy-prod.yml point at the
new filename. ETL workflow_run triggers reference orchestrator names
(unchanged), so ETL chains stay intact.
Tests: 166 pass.
…arity Four small post-Phase-2 cleanups applied together because they all touch deploy_bulk.py and overlap. 1. Drop the ::add-mask:: line in acquire_token. The line itself emitted the bearer token to stdout before GitHub's mask filter could redact it, defeating the purpose. The token is never logged elsewhere, so no mask was needed in the first place. Test inverted to assert the token does NOT appear in stdout (regression guard). 2. Add POLL_CEILING_SECONDS = 600 and a _parse_retry_after helper that handles None, unparseable strings, and clamps to [POLL_FLOOR_SECONDS, POLL_CEILING_SECONDS]. Both poll_lro and interpret_post_response now use it. Prevents a pathological Retry-After value (or unparseable garbage) from either crashing the script or sleeping past the global polling timeout. 3. New VariableLibraryConfig nested dataclass replaces the flat BulkConfig.variable_library_active_value_set field. The dataclass shape now mirrors the YAML structure, and future VariableLibrary settings can be added without changing the parent shape. 4. main()'s log output now distinguishes three cases: - bulk-parameter.yml missing - present but no rules - present with N rules Cleaner mental model when debugging 'why isn't substitution happening?'. Tests: 173 pass (was 166; +7 for _parse_retry_after happy/clamp/fallback paths and the new interpret_post_response defensive behavior).
Pure annotation pass. No runtime behavior change; tests pass unchanged.
Adds TypedDict classes to document the shapes the scripts send and
receive from the Fabric REST API. They give Pylance/mypy the
information needed to catch field-name typos and to autocomplete on
response objects. Not enforced at runtime.
scripts/deploy_bulk.py — 4 new TypedDicts:
- DefinitionPart (total): one definitionParts[] element
- ImportItemDetail (partial): one importItemDefinitionsDetails[] entry
- BulkResponseBody (partial): sync 200 / LRO /result body
- LROStatusBody (partial): /v1/operations/{id} poll body
Function signatures updated: partition_dependencies, extract_item_ids,
apply_substitutions, build_definition_parts, check_per_item_status,
interpret_post_response, post_bulk, plus the body local in poll_lro.
scripts/run_fabric_etl.py — 2 new TypedDicts:
- FabricItem (partial): one List Items value[] element
- JobStatusBody (partial): Jobs API status response
Function signatures updated: find_item_id_by_name,
interpret_poll_response, plus the items local in main().
scripts/workspace_swap.py — 1 new TypedDict:
- ItemTypeRegistryEntry (total): one ITEM_TYPES element
Replaces the union-soup annotation
`list[dict[str, str | list[str] | bool | Callable[[str], bool] | None]]`
with a single named type. Highest readability win in this pass.
scripts/deploy_fabric_cicd.py — no changes (delegates to fabric-cicd
library types; no dict shapes worth typing locally).
`headers: dict` annotations left alone in all files — they're loose
CaseInsensitive mappings from requests that don't benefit from
TypedDict.
Verified:
- 173 tests pass (no regressions)
- Zero Pylance errors across all six edited files
Adds the Bulk CI/CD Implementation Guide and updates surrounding docs to honestly describe what the bulk path does, what it bridges, and what it doesn't. Closes the documentation gap from Phase 2 (the bulk gap-bridging work) and the workflow rename earlier on this branch. New file: - fabric-bulk-cicd-guide.md (~370 lines) — implementation guide for the bulk deploy path. Mirrors the structure of fabric-hybrid-cicd-guide.md (architecture, repo structure, deployment flow, workflows, configuration strategy, prerequisites, initial deploy, gotchas), with bulk-specific sections for the two-deploy decision, extension patterns, and limitations not bridged. Self-contained — duplicates workspace setup / SPN / GitHub environments rather than linking, so it reads end-to-end without bouncing between docs. Updated docs: - README.md — new row in the Documentation table for the bulk guide. - fabric-cicd-release-options.md — bulk row in the comparison table now says 'None at the API level' with a note pointer; new note block explains substitution and value-set activation are caller-implemented workarounds, not API capabilities, and links to the new bulk guide; recommendation paragraph reworded to reflect that bulk is still in Preview and that bridging is caller responsibility. - fabric-hybrid-cicd-guide.md — workflow rename (6 occurrences of the old reusable-deploy-supported.yml filename), repo structure tree updated with all currently-existing workflows / scripts / data items, new note pointing to the bulk path with link to the bulk guide. - .github/workflows/reusable-deploy-bulk.yml — Known Gaps comment block expanded honestly: distinguishes API gaps from caller-bridged gaps, notes orphan cleanup is not implemented because the API doesn't support delete. - scripts/deploy_bulk.py — module docstring expanded with the same framing (API gaps vs caller bridging) and the Known Gaps list now distinguishes 'no full parameter.yml feature coverage' (specific) from 'no orphan cleanup' (broader). Verified: - 173 tests still pass - Zero stale references to reusable-deploy-supported.yml or the old deploy-supported job ID anywhere in the repo - All cross-links between docs resolve to real anchors
This was referenced May 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cleanup branch covering everything that should land alongside Phase 2 but didn't fit the Phase 2 PR. Documentation, naming consistency, and code-quality hardening.
Commits in order
d3107e4reusable-deploy-supported.yml→reusable-deploy-fabric-cicd.ymlfor symmetry withreusable-deploy-bulk.yml. Updates display names + caller wiring.4e23ec3::add-mask::line; addPOLL_CEILING_SECONDS = 600and_parse_retry_afterclamp/try-except; nestactive_value_setunder aVariableLibraryConfigdataclass; distinguish missing vs emptybulk-parameter.ymlinmain()log output.1b67b5ascripts/(DefinitionPart,ImportItemDetail,BulkResponseBody,LROStatusBody,FabricItem,JobStatusBody,ItemTypeRegistryEntry). Replaces the union-soup annotation onITEM_TYPESinworkspace_swap.py.229a92ffabric-bulk-cicd-guide.md(~370 lines) implementation guide for the bulk path. UpdatesREADME.md,fabric-cicd-release-options.md,fabric-hybrid-cicd-guide.md,reusable-deploy-bulk.yml, andscripts/deploy_bulk.pydocstring with honest framing: API gaps remain, this repo just bridges them in caller code.Verification
Why one PR not four
Each commit is independently runnable and reviewable; combining them in a single PR keeps related cleanup together and avoids the four-promotion-cycle cost. Reviewers can read commit-by-commit if preferred.
Not in scope (deferred to followup)
interpret_post_response/interpret_poll_response— works, tested, refactor would be aesthetic. Noted in session memory..vscode/mcp.json— separate concern, can land independently when convenient.