Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
adad148
docs: add workday-integration solution design spec
jeff-schnitter Aug 14, 2026
6790926
docs: update workday solution spec — no credential prompts, backup ex…
jeff-schnitter Aug 14, 2026
0159e3e
docs: add workday-integration solution implementation plan
jeff-schnitter Aug 14, 2026
6be798b
fix: apply test fixes and resolve rebase conflict in github-actions-d…
jeff-schnitter Aug 14, 2026
e260ead
chore: add Pied Piper hierarchy data and configuration for workday-in…
jeff-schnitter Aug 14, 2026
0671d34
feat: add workday-integration solution setup script
jeff-schnitter Aug 14, 2026
8af34b7
docs: add README for workday-integration solution
jeff-schnitter Aug 14, 2026
7458528
chore: rename solution slug from workday-integration to workday
jeff-schnitter Aug 14, 2026
9e881f9
fix: workday configuration, UI polish, and SETUP_DESCRIPTION wording
jeff-schnitter Aug 14, 2026
adfef29
fix: switch to supervisory org format, add validation step, update im…
jeff-schnitter Aug 14, 2026
6a12553
fix: mark_undone after deleting existing config, parse isValid from v…
jeff-schnitter Aug 14, 2026
5a82c04
fix: clear stale configure state when no integration exists on server
jeff-schnitter Aug 14, 2026
378a3e3
fix: use directory URL for ownershipReportUrl (Cortex appends /?forma…
jeff-schnitter Aug 14, 2026
2c526c5
fix: swap fieldOnParentNode/fieldOnChildNode in supervisory org mapping
jeff-schnitter Aug 14, 2026
8dee505
fix: restructure Pied Piper data to match cortex-cx supervisory org f…
jeff-schnitter Aug 14, 2026
a93bd93
fix: add employeeRole field to Pied Piper report entries
jeff-schnitter Aug 14, 2026
ef2bff7
fix: add After Installing, Report Format, and Field Mapping sections …
jeff-schnitter Aug 14, 2026
c2d55d0
chore: move Report Format and Field Mapping into Data Model section
jeff-schnitter Aug 14, 2026
59c5bfc
chore: consolidate Data Model, Report Format, and Field Mapping into …
jeff-schnitter Aug 14, 2026
3133849
fix: add prerequisite step to enable Auto Import Workday teams
jeff-schnitter Aug 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cortexapps_cli/commands/solutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ def _get_setup_description(solution_tag: str, solutions_dir: str | None = None)
"""Return the SETUP_DESCRIPTION from a solution's setup.py, or a generic fallback."""
module = _load_setup_module(solution_tag, solutions_dir)
if module:
return getattr(module, "SETUP_DESCRIPTION", "This solution includes a post-install setup script.")
return "This solution includes a post-install setup script."
return getattr(module, "SETUP_DESCRIPTION", "This solution includes a setup script.")
return "This solution includes a setup script."


def _run_post_install_script(solution_tag: str, solutions_dir: str | None = None, ctx=None, no_prompt: bool = False) -> None:
Expand Down Expand Up @@ -700,7 +700,7 @@ def _do_import() -> None:
if failed_m:
typer.echo(failed_m.group(0))
typer.echo(f"\n {total_imported} imported, {total_failed} failed")
else:
elif total_imported > 0:
typer.echo(f" {total_imported} entities imported")
else:
typer.echo(output)
Expand Down
5 changes: 5 additions & 0 deletions cortexapps_cli/solutions/_lib/setup_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ def mark_done(self, key: str) -> None:
self._state[key] = True
self._save_file()

def mark_undone(self, key: str) -> None:
"""Clear a step's completion state (e.g., after the underlying resource is deleted)."""
self._state.pop(key, None)
self._save_file()

@abstractmethod
def collect_prompts(self) -> None:
"""Collect all user inputs upfront before executing steps."""
Expand Down
4 changes: 1 addition & 3 deletions cortexapps_cli/solutions/github-actions-deploy/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

SETUP_DESCRIPTION = (
"This solution includes a post-install setup script that will create a GitHub "
"This solution includes a setup script that will create a GitHub "
"repository, seed it with a GitHub workflow that will add a deploy to a Cortex entity, and configure the required secrets."
)
import base64
Expand Down Expand Up @@ -172,8 +172,6 @@ def collect_prompts(self) -> None:

if self._session_base_url:
self._answers["cortex_base_url"] = self._session_base_url
else:
self.prompt("cortex_base_url", "Cortex base URL", default=self._session_base_url)
else:
self.prompt(
"cortex_base_url",
Expand Down
2 changes: 1 addition & 1 deletion cortexapps_cli/solutions/harness-deploy/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"""

SETUP_DESCRIPTION = (
"This solution includes a post-install setup script that will configure your Harness "
"This solution includes a setup script that will configure your Harness "
"integration in Cortex, create the deploy pipeline and cortex_api_key secret in Harness, "
"import the Cortex trigger workflow, and optionally fire a test deploy."
)
Expand Down
137 changes: 137 additions & 0 deletions cortexapps_cli/solutions/workday/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
name: Workday Integration
description: Configure the Cortex Workday integration with a sample org hierarchy from the fictional company Pied Piper (from the TV show Silicon Valley) to sync employees and teams into your service catalog.
---

# Workday Integration

Get the Cortex Workday integration running in minutes using a sample org hierarchy from the fictional company Pied Piper (from the TV show *Silicon Valley*). After install, trigger a sync to see employees and teams appear in your catalog — including the full team hierarchy.

## Data Model

```
┌──────────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ Workday Report │────▶│ Cortex Integration │────▶│ Team Catalog │
│ (JSON / RaaS) │ │ (field mapping) │ │ + Members │
└──────────────────────┘ └──────────────────────┘ └──────────────────────┘

Sample: Pied Piper supervisory org (Silicon Valley)

PP: Pied Piper (Erlich Bachman)
├── PP: Engineering (Richard Hendricks)
│ ├── PP: Platform (Bertram Gilfoyle)
│ │ └── PP: Infrastructure (Nelson Bighetti)
│ └── PP: Frontend (Dinesh Chugtai)
└── PP: Operations (Jared Dunn)
└── PP: People Ops (Monica Hall)

Report Format
─────────────
Each entry represents one employee. Workteam_Group lists the employee's teams.
Hierarchy is encoded as parentTeamId → teamName. Root teams use "NONE".
Managers have Team_Managed set to their team's teamName.

{
"Report_Entry": [
{
"Email": "erlich.bachman@piedpiper.com",
"Employee_ID": "PP-100000",
"First_Name": "Erlich",
"Last_Name": "Bachman",
"Managers_Email": "erlich.bachman@piedpiper.com",
"employeeRole": "CEO",
"Workteam_Group": [
{
"teamName": "PP: Pied Piper",
"teamDisplayName": "PP: Pied Piper",
"parentTeamId": "NONE",
"Team_Managed": "PP: Pied Piper"
}
]
},
...
]
}

Field Mapping (data/configuration.json)
────────────────────────────────────────
Maps report columns to employee fields, team identity, and hierarchy.
Workday reports can be customized — the configuration defines the field
attributes and the hierarchy, so it works with any supervisory org report.

{
"ownershipReportUrl": "<your-report-url>",
"reportMappingV2": {
"email": { "columnName": "Email" },
"employeeId": { "columnName": "Employee_ID" },
"firstName": { "columnName": "First_Name" },
"lastName": { "columnName": "Last_Name" },
"employeeRole": { "columnName": "employeeRole" },
"teamListFields": {
"teamListKey": { "columnName": "Workteam_Group" },
"teamId": { "columnName": "teamName" },
"teamName": { "columnName": "teamDisplayName" },
"hierarchy": {
"fieldOnParentNode": { "columnName": "teamName" },
"fieldOnChildNode": { "columnName": "parentTeamId" }
},
"teamEmployeeManages": { "columnName": "Team_Managed" }
},
"type": "ONE_EMPLOYEE_MULTIPLE_TEAMS"
}
}
```

## After Installing

Trigger the sync in Cortex to import the Pied Piper org hierarchy:

**Catalog → All Entities → Import Entities → Workday → Sync Entities → Next Step**

You should see 7 teams appear in your catalog with the full hierarchy:

```
PP: Pied Piper (Erlich Bachman)
├── PP: Engineering (Richard Hendricks)
│ ├── PP: Platform (Bertram Gilfoyle)
│ │ └── PP: Infrastructure (Nelson Bighetti)
│ └── PP: Frontend (Dinesh Chugtai)
└── PP: Operations (Jared Dunn)
└── PP: People Ops (Monica Hall)
```

Workday reports can be customized to match your org structure. The configuration defines which report columns map to employee fields, team identity, and the parent-child hierarchy — so the integration works with any supervisory org report that follows the same shape.

## What's Included

- **Pied Piper org data:** 7 employees across 4 levels of hierarchy (Erlich → Richard → Gilfoyle/Dinesh, Jared → Monica, Gilfoyle → Big Head)
- **Integration config:** field mapping and report URL pre-configured, pointing at the hosted data
- **Setup script:** one-command configuration of the Cortex Workday integration via API

## Quick Start

1. Install the solution:

```
cortex solutions install -s workday
```

2. Follow the post-install setup prompts, or run later:

```
cortex solutions post-install -s workday
```

3. Trigger the import in Cortex:

**Catalog → All Entities → Import Entities → Workday → Sync Entities → Next Step**

4. Check your team hierarchy to see the Pied Piper org chart.

## How It Works

The setup script calls the Cortex Workday integration API to configure a report URL pointing at the bundled Pied Piper supervisory org data. Cortex fetches the report and syncs employees and teams into your catalog on the next import run.

## Adapting to Real Workday Data

To connect your own Workday report, go to **Settings → Integrations → Workday** in the Cortex UI and update the Report URL, username, and password. The field mapping in `data/configuration.json` works unchanged for any Workday supervisory org report that uses the same column names.
31 changes: 31 additions & 0 deletions cortexapps_cli/solutions/workday/data/configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"username": "ISU_Cortex",
"ownershipReportUrl": "https://jeff-test-org.github.io/workday-mocks/pied-piper-supervisory-org",
"reportMappingV2": {
"email": { "columnName": "Email" },
"employeeId": { "columnName": "Employee_ID" },
"firstName": { "columnName": "First_Name" },
"lastName": { "columnName": "Last_Name" },
"managerEmail": null,
"employeeRole": { "columnName": "employeeRole" },
"rootTeams": [],
"teamListFields": {
"teamListKey": { "columnName": "Workteam_Group" },
"teamId": { "columnName": "teamName" },
"teamName": { "columnName": "teamDisplayName" },
"hierarchy": {
"fieldOnChildNode": { "columnName": "parentTeamId" },
"fieldOnParentNode": { "columnName": "teamName", "isList": false }
},
"teamEmployeeManages": { "columnName": "Team_Managed" }
},
"fallbackFields": {
"teamId": null,
"teamName": null,
"fieldOnParentNode": null,
"fieldOnChildNode": null
},
"type": "ONE_EMPLOYEE_MULTIPLE_TEAMS"
},
"password": "asdf"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"Report_Entry": [
{
"Email": "erlich.bachman@piedpiper.com",
"Employee_ID": "PP-100000",
"First_Name": "Erlich",
"Last_Name": "Bachman",
"Managers_Email": "erlich.bachman@piedpiper.com",
"employeeRole": "CEO",
"Workteam_Group": [
{
"teamName": "PP: Pied Piper",
"teamDisplayName": "PP: Pied Piper",
"parentTeamId": "NONE",
"Team_Managed": "PP: Pied Piper"
}
]
},
{
"Email": "richard.hendricks@piedpiper.com",
"Employee_ID": "PP-100001",
"First_Name": "Richard",
"Last_Name": "Hendricks",
"Managers_Email": "erlich.bachman@piedpiper.com",
"employeeRole": "CTO",
"Workteam_Group": [
{
"teamName": "PP: Engineering",
"teamDisplayName": "PP: Engineering",
"parentTeamId": "PP: Pied Piper",
"Team_Managed": "PP: Engineering"
}
]
},
{
"Email": "bertram.gilfoyle@piedpiper.com",
"Employee_ID": "PP-100002",
"First_Name": "Bertram",
"Last_Name": "Gilfoyle",
"Managers_Email": "richard.hendricks@piedpiper.com",
"employeeRole": "Staff Engineer",
"Workteam_Group": [
{
"teamName": "PP: Platform",
"teamDisplayName": "PP: Platform",
"parentTeamId": "PP: Engineering",
"Team_Managed": "PP: Platform"
}
]
},
{
"Email": "dinesh.chugtai@piedpiper.com",
"Employee_ID": "PP-100003",
"First_Name": "Dinesh",
"Last_Name": "Chugtai",
"Managers_Email": "richard.hendricks@piedpiper.com",
"employeeRole": "Senior Engineer",
"Workteam_Group": [
{
"teamName": "PP: Frontend",
"teamDisplayName": "PP: Frontend",
"parentTeamId": "PP: Engineering"
}
]
},
{
"Email": "jared.dunn@piedpiper.com",
"Employee_ID": "PP-100004",
"First_Name": "Jared",
"Last_Name": "Dunn",
"Managers_Email": "erlich.bachman@piedpiper.com",
"employeeRole": "COO",
"Workteam_Group": [
{
"teamName": "PP: Operations",
"teamDisplayName": "PP: Operations",
"parentTeamId": "PP: Pied Piper",
"Team_Managed": "PP: Operations"
}
]
},
{
"Email": "monica.hall@piedpiper.com",
"Employee_ID": "PP-100005",
"First_Name": "Monica",
"Last_Name": "Hall",
"Managers_Email": "jared.dunn@piedpiper.com",
"employeeRole": "VP People",
"Workteam_Group": [
{
"teamName": "PP: People Ops",
"teamDisplayName": "PP: People Ops",
"parentTeamId": "PP: Operations"
}
]
},
{
"Email": "nelson.bighetti@piedpiper.com",
"Employee_ID": "PP-100006",
"First_Name": "Nelson",
"Last_Name": "Bighetti",
"Managers_Email": "bertram.gilfoyle@piedpiper.com",
"employeeRole": "Engineer",
"Workteam_Group": [
{
"teamName": "PP: Infrastructure",
"teamDisplayName": "PP: Infrastructure",
"parentTeamId": "PP: Platform"
}
]
}
]
}
Loading
Loading