Work Item Planner is a web application that allows users to generate Work Items that encompass all the action items while working on a feature.
The application is hosted using a Linux based Azure App Service (Web App).
Resource | Details |
---|---|
Azure App Service Web App | WorkItemPlanner |
Subscription Name | AzDev-Agents&Tasks-Test |
Subscription ID | fd8ab19b-944d-40f1-b13b-e2036680bf7e |
Tenant | Corp |
Application URL: https://workitemplanner.codeapp.ms
Vanity URL: https://aka.ms/workitemplanner, https://aka.ms/featureplanner, https://aka.ms/scenarioplanner
- Ensure to run the
npm install
locally before building using this approach. - Install the App Service extension for Visual Studio Code.
- In the App Service explorer, select the mentioned App Service, right click on it and click deploy.
Refer to this document for the detailed deployment steps. Ignore the steps which create the App Service itself.
A GitHub Action Tools.WorkItemPlanner-deploy has been created to build and deploy. Once a PR is merged to the 'main' branch the code is automatically deployed.
To run the application locally, you'll need to have Node.js and npm (Node Package Manager) installed on your machine. Here's how to set it up:
- Clone the repository:
git clone https://github.com/microsoft/Tools.WorkItemPlanner.git
- Install the dependencies by running:
npm install
- Start the local development server:
npm start
- Open your web browser and visit:
http://localhost:3000
- Note that you may have to enable CORS on your browser when running locally. There are a good number of Edge plugins to help you with this.
The application includes a rich text editor for work item and task descriptions. This feature can be controlled via a feature flag:
Location: public/scripts/richTextEditor.js
// Feature flag to enable/disable rich text editor
window.ENABLE_RICH_TEXT_EDITOR = false; // Set to true to enable rich text
When ENABLE_RICH_TEXT_EDITOR = false
(default):
- Description fields use plain text input
- Rich text toolbar is hidden via CSS
- All formatting features are disabled
- Content is stored and retrieved as plain text
When ENABLE_RICH_TEXT_EDITOR = true
:
- Description fields support rich text formatting
- Toolbar provides bold, italic, underline, and other formatting options
- Support for images via drag-and-drop or clipboard paste
- Content is stored as HTML
Implementation Details:
- All rich text code is preserved but conditionally executed
- The
getRichTextContent()
andsetRichTextContent()
functions automatically handle both modes - CSS class
plain-text-mode
is added to<body>
when rich text is disabled - No code deletion - feature can be easily re-enabled by changing the flag
- Fill out the required fields in the form, providing Organization, Project, Feature Id, Area Path, Iteration & Work Item(s).
- Click the "Prefill Work Item(s)" button to create the ADO items under the mentioned Feature.
- To add more Work Item(s), click the "+ Work Item" button.
- To add tasks to a Work Item(s), click the "+ Task" button under the specific Feature/Scenario.
- To reset the form, click the "Reset Form" link.
- To prefill the form with the Work Item(s) from a template, click on "Prefill Work Item(s)".
Dropdowns are populated based on the user's access to Organizations, Projects, Teams, Area Paths & Iterations in Azure DevOps.
Teams have the choice to onboard their own template i.e., customized choice of Work Item(s). To onboard a new template follow these steps.
- Create a JSON file adhering to this schema. Here is a reference template wpx_engineering_dcr_v1.0.0.json;
{
"version": "1.0.0",
"template": {
"workitems": [
{
"title": "string",
"tasks": [
{
"title": "string",
"estimate": "number",
"description": "string" // optional
}
]
}
]
}
}
- Ensure to name the template in adherence to the following pattern - teamname_category_process_version.
'teamname' | your team name |
'category' | Ex: 'engineering', 'design', 'product', etc. |
'process' | Ex: 'standard', 'rollout', 'hotfix', etc. |
'version' | numeric version with the letter 'v' as prefix |
File name cannot contain any special characters other than underscore(_) or whitespace( )
Example: wpx_engineering_dcr_v1.json, wpx_product_moments_v1.json, viva_engage_standard_v1.json, azure_devops_agent_release_v1.json
-
Clone the repository:
git clone https://github.com/microsoft/Tools.WorkItemPlanner.git
and create a local branch. -
Save the template at the this location
\Tools.WorkItemPlanner\public\work_item_templates
. -
Add the template file name and the display name to the 'work_item_templates_index.js' file located in
\tools.WorkItemPlanner\public\work_item_templates
. Ensure adherence to the existing naming convention in the file. -
Raise a pull request to the 'main' branch with the above additions.
-
Once your pull request is approved and completed, the new template is automatically deployed within 10 minutes.
Below are the niche steps which were executed to get the application up and running.
If you upload a .json file to the Windows Azure website and try to access it, it would give you a 404 File Not Found error, because the MIME Type of .json is not set by default. This also applies in general to any file that might need a specific MIME Type. To fix this issue, edit the web.config file located in the root directory of the application.
<!-- Mime type mapping -->
<staticContent>
<remove fileExtension=".json" />
<mimeMap fileExtension=".json" mimeType="application/json" />
<mimeMap fileExtension=".webp" mimeType="image/webp" />
</staticContent>
The effective web.config for any Azure App Service app can be accessed via the 'Kudu' service - https://workitemplanner.scm.azurewebsites.net/DebugConsole
-
Application Insights has been enabled to monitor both client-side and server-side telemetry. While separate Application Insights resources are recommended for the client and server, a single instance is being used since this is an internal tool. The configuration status of this instance can be accessed via this endpoint - https://workitemplanner.scm.azurewebsites.net/ApplicationInsights
-
Azure Application Insights Connection String is provided as an environment variable
APPLICATIONINSIGHTS_CONNECTION_STRING
.
This project uses GitHub Actions with OpenID Connect (OIDC) to deploy code directly to Azure App Service.
The flow looks like this:
- GitHub Actions Workflow authenticates to Azure using
azure/login@v2
. - Managed Identity (WorkItemPlanner-Identity) in Azure AD has a federated credential that trusts the GitHub repo (
microsoft/Tools.WorkItemPlanner
). - The Managed Identity is granted
Contributor
(or equivalent) permissions on the Web App. azure/webapps-deploy@v3
publishes the build artifact to the App Service.
πΉ This flow does not use a publish profile or Key Vault.
πΉ Authentication happens through Azure AD using OIDC, which is secure and does not require secret rotation.
The Web App also uses a custom domain secured with an SSL certificate stored in Azure Key Vault.
-
The Web App itself must fetch the certificate from Key Vault.
- This requires a Managed Identity assigned to the Web App.
-
That identity must be granted access to the Key Vault.
- Since the vault is configured for Azure RBAC, the required role is:
Key Vault Secrets User
(minimum required)
- Optionally,
Key Vault Certificates Officer
can be assigned for full certificate management.
- Since the vault is configured for Azure RBAC, the required role is:
-
When adding a binding in the Portal, the Portal currently defaults to system-assigned identity.
-
Once imported, the certificate can be bound to the custom domain in TLS/SSL settings.
Azure Managed Certificates (the free App Service managed option) are not used for this application and should not be used.
Instead, obtain the certificate via an Azure Key Vault backed by OneCert, then bind it to the Web App using the Web App's System Assigned Managed Identity. This ensures:
- Centralized certificate governance (issuance, rotation, expiry alerts) via OneCert.
- Consistent auditing & RBAC through Key Vault.
- Decoupled lifecycle management enabling proactive rotation without web app restarts tied to portal automation windows.
-
System-assigned managed identity (Web App): enabled on the App Service and granted the minimal Key Vault RBAC permissions required to read the TLS certificate (Key Vault Secrets User). This identity is used by the Web App to fetch and bind the certificate at runtime.
-
User-assigned managed identity (GitHub Actions): a separate user-assigned Managed Identity (WorkItemPlanner-Identity) was created and configured with a federated credential that trusts the repository/workflow. This identity has Contributor access on the Resource Group to allow OIDC-based deployments from GitHub Actions.
Security notes:
- Prefer least-privilege RBAC (scope to the Web App or specific resources instead of the whole resource group where possible).
- Restrict the federated credential to the specific repository and workflow.
- Use OIDC federation to avoid long-lived secrets and periodically review assigned permissions.
Contributions are welcome! If you find any bugs or have suggestions for improvements, please submit a pull request or reach out to adityamankal@microsoft.com.
- Implement Single Sign on - Done
- Support for custom templates - Done
- Track Telemetry - Done
- Support Work Item Description (Plain Text) - Done
- Support Work Item Description (Rich Text) - Started (alpha)