Skip to content

Azure: Workday org data by CSV - #141

Merged
Keith McGrane (Keithland89) merged 1 commit into
mainfrom
keithmcgrane-microsoft-azure-workday-csv
Oct 20, 2026
Merged

Keith McGrane (Keithland89) merged 1 commit into
mainfrom
keithmcgrane-microsoft-azure-workday-csv

Conversation

@Keithland89

@Keithland89 Keith McGrane (Keithland89) commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

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 on
Primary 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's
head).

As on Fabric, Workday is a data source that comes with org data, not a module (workday in
installer/src/uploads.js, csv or skip). So the catalog's modules, AZURE_SUPPORTED_MODULES
and the Azure module list in installer/README.md don't change.

  • Core. The new valuelens_core.workday ports the rules of the Fabric notebook
    Copilot_Org_Data_Workday_Lander (fabric/notebooks/workday-org-data/): its settings and their
    defaults, its column-name rules, its checks and its messages.
    • MODE auto (the default) enriches the org data when there is some, and otherwise lands the
      export on its own. enrich and standalone force one or the other.
    • The export's work email (Primary Work Email by default) is trimmed, lowercased and matched
      to the org data's PersonId. The export adds only the columns the org data doesn't have. The
      org data's people and values win, even blank ones, people only in Workday are left out, and
      exact duplicate rows are kept once.
    • Before anything is written, the step fails on: an export with no rows; a missing or blank
      email; two different rows for one email; org data with a blank or repeated PersonId; a match
      rate 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.
  • Jobs.
    • The new workday collector (collect/workday.py) runs right after the org data, whatever its
      outcome, as Fabric's pipeline runs the notebook. It runs when VALUELENS_MODULES has both
      orgData and workday.
    • It reads the newest .csv or .txt (by modified time, then name) in the drop folder's
      workday/: the landing container, or the SharePoint drop folder with private networking. It
      logs how many older files it ignores. The drop folder's SUBDIRS gains workday.
    • VALUELENS_WORKDAY_OUTPUT_TABLE says 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 publish
      target. The installer sets dbo.copilot_org_data with
      VALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE=true, as Fabric's installer does
      (installer/src/catalog.js:215-216), so each run enriches raw/copilot_org_data in place
      before publish.
    • If the Entra ID load fails, the last enriched org data is the baseline, so its Workday columns
      keep their values. With no export, nothing is written.
    • The other settings are VALUELENS_WORKDAY_MODE, VALUELENS_WORKDAY_MIN_MATCH_RATE and
      VALUELENS_WORKDAY_EMAIL_COLUMN, with the notebook's defaults. The step's messages name these
      variables rather than the notebook's settings.
  • SQL. No migration: publish adds the export's columns to dbo.copilot_org_data as
    NVARCHAR(4000) NULL, and creates the review table when it's used.
  • Infra. main.bicep gains workdayOutputTable (default
    dbo.copilot_org_data_workday_preview) and workdayAllowBaseOverwrite (default false), which
    containerapps.bicep passes to the jobs as VALUELENS_WORKDAY_OUTPUT_TABLE and
    VALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE. installer/src/azure/main.arm.json is rebuilt from it.
  • Installer.
    • Azure now offers Workday, with org data. Under the advanced settings, Workday org data?
      offers Upload a CSV export or Leave it out, and --data workday=csv sets it too. On
      Repair or change, it's under Module connections. Demo mode leaves it out, with a note
      if it was chosen.
    • The plan says how to export it and where to drop it. With private networking, the existing
      SharePoint drop-folder question now also covers it.
    • A new install step, "Workday export", grants access to where the export goes, as for the
      Agent 365 export:
      • Public endpoints: you get Storage Blob Data Contributor on the storage account, so you
        can upload it.
      • Private networking: the jobs' managed identity gets Sites.Selected read on the SharePoint
        site.
    • The deployment adds workday to the jobs' modules, and always passes
      workdayOutputTable = dbo.copilot_org_data and workdayAllowBaseOverwrite = true.
    • Confirm, status and the summary show it. Uninstall's note that the SharePoint folder is left
      alone (from Azure: Agent 365 registry by CSV (V009) #129) covers it.
  • Docs.
    • azure/README.md has a new Workday org data section.
    • Also updated: 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.md and
      CHANGELOG.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:

  • New drop subfolder: landing/workday/ with public endpoints, or workday/ under the
    SharePoint drop folder with private networking. The jobs read the newest export there and never
    move or delete files.
  • Jobs:
    • VALUELENS_MODULES can now include workday (it needs orgData).
    • New settings: VALUELENS_WORKDAY_MODE, VALUELENS_WORKDAY_OUTPUT_TABLE,
      VALUELENS_WORKDAY_ALLOW_BASE_OVERWRITE, VALUELENS_WORKDAY_MIN_MATCH_RATE and
      VALUELENS_WORKDAY_EMAIL_COLUMN. Bicep sets the output table and the overwrite.
    • For the review table, used only without the installer's settings: the publish target
      copilot_org_data_workday_preview and the Parquet path
      raw/copilot_org_data_workday_preview/part-0.parquet.
  • Deployment parameters: workdayOutputTable and workdayAllowBaseOverwrite, in main.bicep
    and installer/src/azure/main.arm.json. The installer's list of required template parameters
    has them.
  • Azure SQL: dbo.copilot_org_data gains the export's columns, as NVARCHAR(4000) NULL.
  • Install record:
    • dataSources.workday (csv or skip) now applies on Azure.
    • azure.drop (the SharePoint folder) is now also asked for when only the Workday export uses
      it.
  • Model: unchanged. As on Fabric, it reads the export's Function and Location columns when
    it has them.

Validation

  • Ran python -B -m pytest tests -q and recorded results below.
  • Ran npm test (and npm run typecheck for the installer) in each changed Node project.
  • Updated directly related documentation and checked changed links.
  • No credentials, tenant exports, prompts or customer names are included.
  • If .pbit files changed, documented the rebuild method and Desktop refresh / visual checks. (Not applicable: no .pbit files 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 entries
    verbatim, so the stack's diff against main only adds lines there.

  • ARM drift check (the arm-drift job 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 template
    matches the Bicep source."

  • python -B -m pytest tests -q -p no:cacheprovider (repo root; the template's command, plus
    -p no:cacheprovider so 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.

    • That includes the new tests/test_azure_workday.py, 30 test functions (82 cases) on:
      • the core, against the notebook's own source (its settings, name rules and messages) and
        against the Fabric regression's fixtures and expectations
        (tests/fabric_workday_enrichment.py, imported as it is);
      • the CSV reader;
      • the collector, from storage and SharePoint: the newest file, the review table and in-place
        outputs, bad settings, long and awkward headers, and a failed Entra ID load;
      • the wiring: collect order, publish targets, settings from the environment, the Bicep and ARM
        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.py checks 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 new
    Workday tests in test/azure.test.js and the new question in test/advanced.test.js. The
    failure, test/script.test.js:115, isn't in code this PR touches. It's environmental: this
    machine's PowerShell execution policy blocks generate.ps1 ("running scripts is disabled on this
    system"), 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 same script.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 --data modes it makes Fabric only,
    so --data workday=csv reaches Azure with both merged.

  • CI on ef63b96: passed.

    • The tests workflow's jobs all passed:
      • pytest (python -B -m pytest tests -q -ra, without PySpark): 1061 passed, 5 skipped, 12168
        subtests passed;
      • installer (npm test): 901 tests, 897 passed, 0 failed, 4 skipped; then npm run typecheck;
      • app, arm-drift and valuelens-web.
    • The azure-images workflow built both images and smoke-tested the jobs image. On pull
      requests it doesn't push them.
  • Not done (offline only):

    • no deployment, live tenant or Azure run;
    • no Sites.Selected grant on a real site;
    • no Power BI refresh;
    • no image build. Don't dispatch azure-images.yml from this branch: it would push images tagged
      with installer/package.json's version (0.6.7).

    Suggested live check, once approved, on a test install with 0.6.8 images:

    1. Under the advanced settings, answer Upload a CSV export to Workday org data?.
    2. Take fabric/notebooks/workday-org-data/samples/org_workday/workday_org_sample.csv and
      replace its fictional emails with the test tenant's user principal names. Otherwise fewer
      than half match, and the step fails by design.
    3. Drop it in landing/workday/, and run the job.
    4. Check that dbo.copilot_org_data gains the export's columns, that its other columns and rows
      are unchanged, and that the model refreshes.
    5. Add a Department column and run again, to check the first item under "Found while porting"
      below. Then drop a newer export: the next run uses it. The Department column stays in
      dbo.copilot_org_data (see that item), so remove it before step 6.
    6. Repeat with private networking and a SharePoint folder.

Compatibility

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>
@Keithland89
Keith McGrane (Keithland89) force-pushed the keithmcgrane-microsoft-azure-workday-csv branch from 6484391 to 46a97ce Compare October 20, 2026 08:07
@Keithland89
Keith McGrane (Keithland89) merged commit b902e58 into main Oct 20, 2026
12 checks passed
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant