Repository navigation
Azure: Workday org data by CSV - #141
Merged
Keith McGrane (Keithland89) merged 1 commit intoOct 20, 2026
Merged
Conversation
This was referenced Oct 20, 2026
Merged
Keith McGrane (Keithland89)
force-pushed
the
keithmcgrane-microsoft-azure-product-feedback-csv
branch
from
October 20, 2026 06:53
968628e to
8a341e1
Compare
4 of 5 tasks
Keith McGrane (Keithland89)
changed the base branch from
keithmcgrane-microsoft-azure-product-feedback-csv
to
main
October 20, 2026 07:47
Keith McGrane (Keithland89)
force-pushed
the
keithmcgrane-microsoft-azure-workday-csv
branch
from
October 20, 2026 07:48
ef63b96 to
6484391
Compare
4 of 5 tasks
The workday data source now runs on Azure from a Workday CSV export, as the Fabric Copilot_Org_Data_Workday_Lander notebook does. valuelens_core.workday ports the notebook's rules unchanged: with Entra ID org data, the export adds the columns that data doesn't have, matched on the work email, and Entra ID's people and values always win; without it, AUTO lands the export on its own. Every check runs before anything is written. The jobs read the newest CSV in the drop folder's workday/ (the landing container, or the SharePoint folder with private networking) after the Entra ID org load. The installer deploys it as Fabric's does, enriching dbo.copilot_org_data in place; the jobs' default is the notebook's review table, dbo.copilot_org_data_workday_preview. Publish adds the new columns, so there's no migration. The installer offers Workday as csv or skip on Azure, behind Advanced settings or with --data workday=csv, with org data on. It says where the export goes, grants upload or SharePoint read access, and shows it in review, status and the summary. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keith McGrane (Keithland89)
force-pushed
the
keithmcgrane-microsoft-azure-workday-csv
branch
from
October 20, 2026 08:07
6484391 to
46a97ce
Compare
4 of 5 tasks
This was referenced Oct 20, 2026
Keith McGrane (Keithland89)
pushed a commit
that referenced
this pull request
Oct 20, 2026
Brings in #126 (least-privilege install into a resource group your Azure admin creates) and #141 (Workday org data by CSV on Azure). - azure/README.md: main's rewritten access bullet, then the "To do them by hand" line. - docs/MANUAL-INSTALL.md: "What you don't get by hand on Azure" adds Workday org data to the CSV bullet, and the least-privilege install. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 20, 2026
Merged
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.
For 0.6.8. Keith decides the merge.
Summary
Workday org data now installs on Azure, from its CSV export, at parity with Fabric. After each
Entra ID load, the jobs add the newest export's columns to
dbo.copilot_org_data, matched onPrimary Work Email, with the Fabric notebook's rules and checks. This is Keith's decision,
"Workday CSV on Azure: port it in 0.6.8 via W4", so it's part of workstream W4 of the 0.6.8 Azure
parity plan. No linked issue.
Stacked on #131 (Product feedback by CSV); merge after #131. This PR reuses the drop folder,
CSV landing and installer steps from #129 and #131, and edits the same lines, so its base is
#131's branch and its diff is one commit. Once #131 merges, this PR's base moves to main; if #131
is squash-merged, this branch also rebases onto main (
git rebase --onto main 968628e, #131'shead).
As on Fabric, Workday is a data source that comes with org data, not a module (
workdayininstaller/src/uploads.js,csvorskip). So the catalog's modules,AZURE_SUPPORTED_MODULESand the Azure module list in
installer/README.mddon't change.valuelens_core.workdayports the rules of the Fabric notebookCopilot_Org_Data_Workday_Lander(fabric/notebooks/workday-org-data/): its settings and theirdefaults, its column-name rules, its checks and its messages.
MODEauto(the default) enriches the org data when there is some, and otherwise lands theexport on its own.
enrichandstandaloneforce one or the other.to the org data's
PersonId. The export adds only the columns the org data doesn't have. Theorg data's people and values win, even blank ones, people only in Workday are left out, and
exact duplicate rows are kept once.
email; two different rows for one email; org data with a blank or repeated
PersonId; a matchrate under the minimum (0.5); or an empty result. Only the Workday step fails: the org data
stays as the Entra ID load left it, and the run carries on.
workdaycollector (collect/workday.py) runs right after the org data, whatever itsoutcome, as Fabric's pipeline runs the notebook. It runs when
VALUELENS_MODULEShas bothorgDataandworkday..csvor.txt(by modified time, then name) in the drop folder'sworkday/: thelandingcontainer, or the SharePoint drop folder with private networking. Itlogs how many older files it ignores. The drop folder's
SUBDIRSgainsworkday.VALUELENS_WORKDAY_OUTPUT_TABLEsays where the result goes. The default, as in the notebook,is a copy to review,
dbo.copilot_org_data_workday_preview, with a new snapshot publishtarget. The installer sets
dbo.copilot_org_datawithVALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE=true, as Fabric's installer does(
installer/src/catalog.js:215-216), so each run enrichesraw/copilot_org_datain placebefore publish.
keep their values. With no export, nothing is written.
VALUELENS_WORKDAY_MODE,VALUELENS_WORKDAY_MIN_MATCH_RATEandVALUELENS_WORKDAY_EMAIL_COLUMN, with the notebook's defaults. The step's messages name thesevariables rather than the notebook's settings.
dbo.copilot_org_dataasNVARCHAR(4000) NULL, and creates the review table when it's used.main.bicepgainsworkdayOutputTable(defaultdbo.copilot_org_data_workday_preview) andworkdayAllowBaseOverwrite(defaultfalse), whichcontainerapps.biceppasses to the jobs asVALUELENS_WORKDAY_OUTPUT_TABLEandVALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE.installer/src/azure/main.arm.jsonis rebuilt from it.offers Upload a CSV export or Leave it out, and
--data workday=csvsets it too. OnRepair or change, it's under Module connections. Demo mode leaves it out, with a note
if it was chosen.
SharePoint drop-folder question now also covers it.
Agent 365 export:
can upload it.
site.
workdayto the jobs' modules, and always passesworkdayOutputTable = dbo.copilot_org_dataandworkdayAllowBaseOverwrite = true.alone (from Azure: Agent 365 registry by CSV (V009) #129) covers it.
azure/README.mdhas a new Workday org data section.azure/jobs/README.md(a new section and four settings rows),azure/DESIGN.md(the Phase 2 row),
docs/DATA-DICTIONARY.md(the Workday section),installer/README.mdandCHANGELOG.md(## Unreleased).Scope
Parts affected (installer / app / Fabric notebooks and pipeline / Azure infra, jobs or web / core / Power BI models):
installer; Azure infra and jobs; core; docs. No app, Fabric, Power BI model or SQL migration
changes.
Source contracts, optional inputs, install record or deployed item names changed:
landing/workday/with public endpoints, orworkday/under theSharePoint drop folder with private networking. The jobs read the newest export there and never
move or delete files.
VALUELENS_MODULEScan now includeworkday(it needsorgData).VALUELENS_WORKDAY_MODE,VALUELENS_WORKDAY_OUTPUT_TABLE,VALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE,VALUELENS_WORKDAY_MIN_MATCH_RATEandVALUELENS_WORKDAY_EMAIL_COLUMN. Bicep sets the output table and the overwrite.copilot_org_data_workday_previewand the Parquet pathraw/copilot_org_data_workday_preview/part-0.parquet.workdayOutputTableandworkdayAllowBaseOverwrite, inmain.bicepand
installer/src/azure/main.arm.json. The installer's list of required template parametershas them.
dbo.copilot_org_datagains the export's columns, asNVARCHAR(4000) NULL.dataSources.workday(csvorskip) now applies on Azure.azure.drop(the SharePoint folder) is now also asked for when only the Workday export usesit.
FunctionandLocationcolumns whenit has them.
Validation
python -B -m pytest tests -qand recorded results below.npm test(andnpm run typecheckfor the installer) in each changed Node project..pbitfiles changed, documented the rebuild method and Desktop refresh / visual checks. (Not applicable: no.pbitfiles changed.)Results, skipped checks and limitations:
One commit, ef63b96, on Azure: Product feedback by CSV (V010) #131 (968628e, on Azure: Agent 365 registry by CSV (V009) #129's db08544, on main 61c9997). In
CHANGELOG.md's## Unreleased, Azure: Agent 365 registry by CSV (V009) #129's entry comes first, then Azure: Product feedback by CSV (V010) #131's, then this PR's, then main's entriesverbatim, so the stack's diff against main only adds lines there.
ARM drift check (the
arm-driftjob in.github/workflows/tests.yml, run locally):az bicep build --file azure/infra/main.bicep --outfile <temp>/main.arm.json(Bicep 0.47.16),then the job's comparison with
installer/src/azure/main.arm.json: passed, "ARM templatematches the Bicep source."
python -B -m pytest tests -q -p no:cacheprovider(repo root; the template's command, plus-p no:cacheproviderso the run leaves no cache in the worktree): 1061 passed, 5 skipped,12168 subtests passed, exit 0. The 1,599 warnings are all sqlite3's date and datetime adapter
deprecations from the existing Azure publish tests; none come from the new tests.
tests/test_azure_workday.py, 30 test functions (82 cases) on:against the Fabric regression's fixtures and expectations
(
tests/fabric_workday_enrichment.py, imported as it is);outputs, bad settings, long and awkward headers, and a failed Entra ID load;
parameters, and a publish that adds the export's columns in sqlite.
tests/test_workday_enrichment.py, the Fabric notebook's tests, is unchanged and passes.tests/test_docs.pychecks the changed links and anchors.CI's pytest job doesn't install PySpark, so the Workday tests also ran without it:
python -B -c "import sys; sys.modules['pyspark'] = None; sys.modules['py4j'] = None; import pytest; sys.exit(pytest.main(['tests/test_azure_workday.py', 'tests/test_workday_enrichment.py', '-q', '-p', 'no:cacheprovider']))"(repo root): 91 passed, 13 subtests passed, exit 0.
npm run typecheck(installer/): passed (exit 0).npm test(installer/): 901 tests, 900 passed, 1 failed (exit 1). It includes 6 newWorkday tests in
test/azure.test.jsand the new question intest/advanced.test.js. Thefailure,
test/script.test.js:115, isn't in code this PR touches. It's environmental: thismachine's PowerShell execution policy blocks
generate.ps1("running scripts is disabled on thissystem"), and the policy wasn't bypassed.
With Installer: recommend Azure and start new installs on it #128 (at a76fb80), which merges after this PR. An offline integration run, ef63b96 with
git merge --no-ff --no-commit a76fb80, merged clean. Then:npm test(installer/): 924 tests, 923 passed, 1 failed, the samescript.test.js:115;npm run typecheck(installer/): passed (exit 0);python -B -m pytest tests/test_consolidated_release.py tests/test_executive_query_measures.py tests/test_template_dax_fixes.py tests/test_docs.py tests/test_parked_ideas.py tests/test_azure_workday.py tests/test_workday_enrichment.py -q -p no:cacheprovider(repo root): 331 passed, 35 subtests passed, exit 0.
Installer: recommend Azure and start new installs on it #128's afeb4e9 already takes
workday: ['csv']out of the--datamodes it makes Fabric only,so
--data workday=csvreaches Azure with both merged.CI on ef63b96: passed.
testsworkflow's jobs all passed:python -B -m pytest tests -q -ra, without PySpark): 1061 passed, 5 skipped, 12168subtests passed;
npm test): 901 tests, 897 passed, 0 failed, 4 skipped; thennpm run typecheck;azure-imagesworkflow built both images and smoke-tested the jobs image. On pullrequests it doesn't push them.
Not done (offline only):
azure-images.ymlfrom this branch: it would push images taggedwith
installer/package.json's version (0.6.7).Suggested live check, once approved, on a test install with 0.6.8 images:
fabric/notebooks/workday-org-data/samples/org_workday/workday_org_sample.csvandreplace its fictional emails with the test tenant's user principal names. Otherwise fewer
than half match, and the step fails by design.
landing/workday/, and run the job.dbo.copilot_org_datagains the export's columns, that its other columns and rowsare unchanged, and that the model refreshes.
Departmentcolumn and run again, to check the first item under "Found while porting"below. Then drop a newer export: the next run uses it. The
Departmentcolumn stays indbo.copilot_org_data(see that item), so remove it before step 6.Compatibility
Existing Azure installs. Workday is off by default (
skip), so nothing changes on Repairor change until you choose Upload a CSV export. Choosing it:
workdayto the jobs' modules;dbo.copilot_org_data, from the first run after it lands.A record that already has
dataSources.workday = 'csv'turns it on at the next Repair orchange. The advanced settings show it, already chosen.
The deployment parameters. The installer always passes
dbo.copilot_org_dataandtrue.They do nothing unless
workdayis in the jobs' modules. A redeploy resets them, so a reviewtable set by hand on the job goes back to in-place enrichment at the next Repair or change.
A deployment from the Bicep alone keeps its defaults and writes the review table.
Where Azure differs from the notebook. These are deliberate, and the tests pin them:
Fabric installer keeps one, and two exports of the same people would conflict.
what it can't read.
warning.
Turning it off keeps its columns in
dbo.copilot_org_data, empty from the next run.Unchanged:
uploadcommand and--csv, which stay Fabric only.AZURE_SUPPORTED_MODULESand the Azure module list ininstaller/README.md: Workday is a data source.Migrations. None, so this PR uses no migration number.
ValueLens templates. No matching change is needed: the model reads the same
copilot_org_datacolumns as on Fabric.Installer: recommend Azure and start new installs on it #128 (recommend Azure). Its afeb4e9 takes
workday: ['csv']out of the--datamodes itmakes Fabric only. It merges after this PR. The two merge clean, and the integration run above
passed.
Lines shared with other 0.6.8 PRs. As a data source, this PR doesn't touch the catalog's
azureflags,AZURE_SUPPORTED_MODULES, theconfig.modulesline inplanAzureor the Azuremodule list in
installer/README.md. It adds an entry toCHANGELOG.md's## Unreleased.Known overlaps. Checked offline with
git merge-tree: this branch (ef63b96) against thecurrent head of each open PR, compared with Azure: Product feedback by CSV (V010) #131 (968628e) against the same head. Line numbers
are this branch's. In each, whichever PR lands second keeps both sides. The ones this PR adds to
Azure: Product feedback by CSV (V010) #131's are marked new.
CHANGELOG.md's## Unreleased: this stack's entries (lines 23-41) are at the top of thesection, above main's entries as main has them. So they conflict there with the PRs that also
add an entry at the top: Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133, Azure: Agent Evaluator model on Azure SQL, with org-scoped access (W2, 2 of 3) #140, Add an Azure by-hand setup path #115 and Managed app: one command sets it up by hand #114 (Add an Azure by-hand setup path #115 and Managed app: one command sets it up by hand #114 already conflict with main
there). Azure: Consumption Central parity with Fabric (fixes, docs and a parity runbook) #125, Fix the 0.6.7 Azure test findings, build release candidates, and credit the app's creator #127, Installer: recommend Azure and start new installs on it #128 and Size the Azure path for tenants above 10,000 seats #130 add theirs lower down and don't conflict there.
includes Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133):
azure/jobs/valuelens_jobs/__main__.py:20-21, the docstring's Parquet list: this stack'sraw/agents_365/part-0.parquetandraw/user_feedback/part-0.parquetlines replace the oldraw/agents_365/*.parquet (Phase 2, optional)line, and Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133'sagent_*lines go afterthem.
__main__.py:326-329, the publish targets: this stack'sagent365andproductFeedbacklines and Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133's
agentEvaluatorlines.azure/jobs/valuelens_jobs/publish.py:87-93, after the core targets: this stack'sagents_365,user_feedbackandcopilot_org_data_workday_previewtargets and Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133'sAgent Evaluator targets.
azure/jobs/README.md:262-266, the settings table: this stack'sVALUELENS_DROP_*row andthe four
VALUELENS_WORKDAY_*rows first, then Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133's five rows.azure/jobs/valuelens_jobs/config.py:36-41and:82-86. Both addSettingsfields and their
from_envlines: this PR'sworkday_*, and Azure: Agent Evaluator jobs collector, parser and V008 (W2, 1 of 3) #133'sdataverse_environmentsandtranscript_*.[:8]), soV009andV010don't affect it.
installer/src/config.js:286-287, theazurerecord's property docs: Azure: Agent Evaluator model on Azure SQL, with org-scoped access (W2, 2 of 3) #140'sagentEvaluatorDatasetIdline goes before this stack'sdropandstorageRolelines.installer/src/steps/azure/index.js:533-572: this stack'sazureAgent365On,azureProductFeedbackOn,azureWorkdayOn,azureReadsDropandazureDropContents, andAzure: Agent Evaluator model on Azure SQL, with org-scoped access (W2, 2 of 3) #140's
azureAgentEvaluatorOn.index.js:2023-2025, the end of the summary: this stack'sAgent 365:,Feedback:andWorkday:lines and Azure: Agent Evaluator model on Azure SQL, with org-scoped access (W2, 2 of 3) #140'sEvaluator:line.installer/test/azure.test.js:13, the import list.azure/DESIGN.md:467, the Phase 2 row: Azure: Consumption Central parity with Fabric (fixes, docs and a parity runbook) #125 rewrites the "follow." sentence; keep thisstack's three "done by CSV" sentences too.
installer/src/steps/azure/index.js:1005-1006, inazureDeployment's parameters:this PR's
modules:line, which addsworkday, and Azure: Consumption Central parity with Fabric (fixes, docs and a parity runbook) #125'ssemanticModels:line.index.js:2022-2025, the end of the summary: Azure: Consumption Central parity with Fabric (fixes, docs and a parity runbook) #125'sCredits:line (now shown whenazureConsumptionModelDeployed(config)), then this stack'sAgent 365:,Feedback:andWorkday:lines.installer/README.md:158, the list of modules supported on Azure: "core,orgData,m365Activity,agent365,productFeedback,consumptionanddefender".installer/src/steps/azure/index.js:2007, the end ofazureUninstall: Azure: Agent 365 registry by CSV (V009) #129'sif (az.drop?.folderUrl) ui.note(…)goes before Fix the 0.6.7 Azure test findings, build release candidates, and credit the app's creator #127's newif (!deleting) return true;.index.js:45, afterisPrivate. Keep Azure: least-privilege install into a resource group your Azure admin creates #126'sazureProvidersand this stack'sAZURE_SUPPORTED_MODULES. The Storage Blob DataContributor grant, which this PR also uses for the Workday upload, is already in Azure: least-privilege install into a resource group your Azure admin creates #126's
role-assignment condition.
installer/src/azure/main.arm.json:8, thetemplateHashonly. Both change the Bicep, so whichever lands second runsnpm run build:arm(installer/) and the ARM drift check.azure/README.md:287-288, the end of the "ARM can't dothese, so the installer:" list: keep both bullets. Also
CHANGELOG.md,README.mdanddocs/PREREQUISITES.md, the files Add an Azure by-hand setup path #115 already conflicts with main in. This stack adds nothingto those beyond
CHANGELOG.md's.CHANGELOG.md. Its other conflicts are withmain itself.
Bump the npm group across 2 directories with 7 updates #134, Bump the github-actions group with 3 updates #135 and Bump python from 3.12-slim-bookworm to 3.14-slim-bookworm in /azure/jobs #45.
Found while porting (not changed here; the same on Fabric). For Keith to decide:
Departmentcolumn probably breaks the model refresh, and on Azure it stays broken.Confirmed by reading the code. Not run: that needs Power Query.
Chat + Agent Org Dataquery (its lines 33-52) renames the firstcolumn whose name normalizes to
departmenttoOrganization, without checking whetherOrganizationexists. Three templates have it:ValueLens - Fabric.pbit,ValueLens - Fabric OneLake.pbitandAgent Evaluator.pbit. The Azure models are builtfrom them and keep the rename: the main model from
ValueLens - Fabric.pbit(
installer/src/steps/azure/index.js:1621-1628), and Azure: Agent Evaluator model on Azure SQL, with org-scoped access (W2, 2 of 3) #140's Agent Evaluator model fromAgent Evaluator.pbit.Organization(from Graph'sdepartment)and no
Department:BASE_COLUMNSincore/valuelens_core/org.py:15on Azure, andfabric/notebooks/Copilot_Org_Data_Direct_Ingester.ipynb:208on Fabric. So an export witha
Departmentcolumn adds one when it enriches, and the refresh probably fails with aduplicate column.
ensure_tableonly adds(
azure/jobs/valuelens_jobs/publish.py:121-135), anddbo.copilot_org_datais a snapshottarget, replaced by DELETE then INSERT (
:196-197). Nothing else in the jobs, themigrations or the installer drops one. So once
Departmenthas been published, it stays,as NULLs, and the refresh keeps failing even after Workday is turned off or the column
leaves the export.
overwriteSchema(Copilot_Org_Data_Direct_Ingester.ipynb:445-447), soDepartmentisgone until the Workday lander adds it back.
Organizationis missing alsostops a leftover column colliding. Leaving
Departmentout in both Workday paths doesn'theal a table that already has it: on Azure that also needs
ALTER TABLE dbo.copilot_org_data DROP COLUMN [Department].core/valuelens_core/org.py:179-180,docs/DATA-DICTIONARY.md:222andinstaller/src/steps/run.js:508suggest Workday for people without a department, butenrichment never fills
Organization: Entra ID's values win, even blank ones.installer/src/uploads.js:65andinstaller/src/transform/pipeline.js:618say Workday "adds or overrides" org fields. It onlyadds.
Images. The collector ships in the
valuelens-jobsimage, so it needs the 0.6.8 images.