Prerequisites
This guide is for organization and project administrators preparing an Azure DevOps organization for AnyKanban. The extension is purely client-side: it renders a Kanban board (and a backlog-style list) over any saved work item query. Everything it needs already exists in Azure DevOps, and this document lists what must be in place before your first board works.
Applies to: Azure DevOps Services (cloud).
You may not have to do any of this by hand. The Fields tab of the organization settings page adds the fields this page describes, under its own names (section 5b), for every process in your organization at once, when an administrator presses Execute plan. It shows you the list first, and it changes no states, rules, forms or card data. Azure DevOps' own locked processes have no wizard: creating an inherited process from one is your decision, in your own portal.
1. Install the extension
AnyKanban is installed from the Visual Studio Marketplace, once for the whole organization. A user with Project Collection Administrator permission installs it and picks the organization to install it into. Afterwards it is listed under Organization Settings > Extensions.
The extension requests four scopes, shown and accepted at install time. vso.work_write reads and changes work items. Azure DevOps also covers process customization under this scope, and AnyKanban uses that in one place only: the Fields tab on the organization settings page, which adds fields to inherited processes (and gives a process its own copy of a work item type where Azure DevOps requires it) after an administrator presses Execute plan. vso.extension.data_write stores board settings in this extension's own documents. vso.analytics reads cycle-time history and cannot write. vso.memberentitlementmanagement grants read access to member entitlements, which is more than AnyKanban uses, because Azure DevOps offers no scope for the totals alone. All four read or write only inside your own Azure DevOps. See Security and data handling.
When a new version asks for a scope your organization has not granted yet, Azure DevOps holds that update, and every later one, until an organization administrator approves the new scope under Organization Settings > Extensions. Until then everybody keeps the version already installed.
When an administrator presses Count users on the AnyKanban page in Organization settings, vso.memberentitlementmanagement reads the aggregate number of users at each access level. It reads no names or user list and stores nothing. The extension sends the non-Stakeholder total to no one. The total reaches the buy page only if the administrator follows the buy link on that page, and remains editable there.
Reference: Publish, share, and install extensions
2. The order field for manual card ordering
Manual drag-and-drop ordering persists the order in the numeric order field your process already uses, on the work item itself. Order is real data, visible to queries, not hidden extension state, and it is one order per process: every board, query and backlog sorted by that field shows the same order.
Which field that is depends on the process family, and the board derives it for its work item type; nothing is chosen per board:
| Process family | Order field |
|---|---|
| Agile, CMMI, Basic | Stack Rank (Microsoft.VSTS.Common.StackRank) |
| Scrum, and processes inherited from it | Backlog Priority (Microsoft.VSTS.Common.BacklogPriority) |
| A hosted XML process | whatever its backlog configuration names as its Order field |
A type on a backlog level already carries it in every system template, and so does every regular type outside the backlog (Issue, Impediment, Change Request, Risk, Review); only Test Case, Test Plan, Test Suite, Code Review, Feedback and Shared Steps carry none. When a type carries only the other of the two platform fields, for example Stack Rank on a Scrum-derived process, the board orders by that one and its settings say so.
When the type carries neither, the board loads, moves between columns keep working, and a notice names the field your process orders by. The remedy is Organization settings > AnyKanban > Fields > Reordering: an administrator reads the exact plan and selects Execute plan, which attaches the process's own order field to the type in an inherited process. On a system process, create an inherited process first and change the project to use it. A board that already exists orders by the field from its next load or Refresh, as long as its query has no sort of its own or sorts by that field ascending (see Backing query). A board does not store which field it orders by, so its settings have nothing to save again. A custom numeric field of your own is never used as an order field, so that a field holding real data is never overwritten with a rank.
When the Fields page cannot tell which field your process orders by, that remedy is not available for the process. The page plans no Reordering for it and says so under it. The page works for the whole organization, so it reads the answer off the enabled types on your backlog levels: Stack Rank when every one of them carries Stack Rank, Backlog Priority when every one carries Backlog Priority. It cannot answer when:
- every type on your backlog levels carries both fields,
- neither field is on all of them,
- no enabled type of the process sits on a backlog level, or
- a backlog type could not be read, and the types that were read do not settle it because they all carry both or there are none.
In each case the page names the types left without an order field and gives the reason. A backlog type that could not be read is left out of the count, so when the types that were read agree on one field, Reordering is planned as usual. The page does not guess, because a board ordered by a field your backlog does not read is worse than a board you cannot reorder. When the reason is a type that could not be read, reloading the page may settle it. Otherwise add the field to those types by hand: the notice on a board of those types names the field, and Open process settings beside the reason opens your organization's processes.
A board of backlog items reads that order and does not change it. While its type carries an order field, its query has no sort of its own or sorts by that field ascending, and Reorder from this board is off, the Card order row in its settings names that field as the backlog's own order. Dragging a card within a column does nothing there unless the board's owner turns on Reorder from this board, and then the drag changes the backlog everyone shares. A second option on the same tab, Take priorities, reorders that backlog from a request board's order after a preview (see Put the backlog in the order of its requests). An item whose type does not carry its level's order field keeps its place there.
3. Backing query
Each board is bound to a saved work item query that defines its membership:
Any query type works. A flat list of work items boards exactly what it returns. A tree of work items or work items and direct links query is flattened to the distinct items it returns; on a configured board the work item type chooses which level becomes cards, and items of other levels are counted as the tree's structure, visibly rather than silently.
Leave the query without an
ORDER BY, or end it withORDER BYyour process's order field, ascending, for example:ORDER BY [Microsoft.VSTS.Common.StackRank] ASCEither way the board shows that field's order and reordering is on: with no
ORDER BYthe board adds that order to the query it runs, and never changes your saved query. A query sorted by anything else, a date, a state, the other platform field, or the order field descending, shows that order instead and reordering is off; a line above the board and the Card order row in its settings say so (on the Board tab of a query's results page, Order: query in the row above the board). On a board of backlog items reordering is off whatever the query sorts by unless the board's settings allow it, so the line appears there only where they do.Save the query somewhere the intended users can read it: Shared Queries for any board other people open. Only you can read a query in My Queries, so a board made from one is listed in your own board list.
Size limit: Azure DevOps caps query results at 20,000 work items; beyond that the REST API returns error VS402337 and the board cannot load. Keep board queries scoped well below this. The rest is on Microsoft's work tracking object limits page.
4. Optional: field for split columns (Doing / Done)
Split columns (a column subdivided into Doing and Done, as on native boards) are bound to a real boolean field on the work item type, so the placement is queryable and follows the same concurrency-safe write pipeline as every other change.
- Add a boolean field to the work item type (suggested reference name:
Custom.BoardColumnDone): Organization Settings > Process > (your inherited process) > (your work item type) > New field, a new custom field of type Boolean. - Pick that field in the board settings, under Board > Columns. The picker offers the boolean fields you added to the type, custom ones only, because native and hidden fields are never offered. Nothing is typed by hand.
The field does not need to appear on the work item form. Nobody edits it by hand, because the board writes it through the API, and Azure DevOps keeps its own ordering field (Microsoft.VSTS.Common.StackRank) off the Agile form for the same reason. The portal places a newly added field in the first group on the form; removing it from the layout afterwards leaves the field and its data intact. Leaving it on the form is not an error, only noise for everyone who opens a work item.
On the second and third project of a cross-project board, this is three clicks, not eight. Field names are unique across the whole organization, so once the field exists anywhere it is added to another type with New field > Use an existing field rather than created again. If the name you want is already taken, use another one. The board stores whatever reference name the service reports, and depends on no particular name.
Undoing is not one action but two, and only one of them is safe. Remove takes the field off a work item type: the data is kept, and adding the field back restores it. Delete removes the field from the whole organization, from every work item type that uses it. A deleted field can be restored through the Azure DevOps REST API, but its values may not come back with it, so do not delete a field you may want to keep.
Without a configured field, the split-column option is simply not available on that board.
4b. Optional: field for columns that are not 1:1 with states
A board can define its own columns and put several of them over one state, so that Analysis, Development and Testing all sit over Active, the way the native board does. Which of those columns a card sits in is something the state cannot express, so it binds to a real text field on the work item type, exactly like the split flag above.
- Add a text (single line) field to the work item type (suggested reference name:
Custom.BoardColumn), a new custom field the same way as the boolean one in section 3. - Pick that field in the board settings, under Board > Columns. The picker offers the text fields you added to the type, custom ones only, because native and hidden fields are never offered. Nothing is typed by hand.
The one label you cannot use is the obvious one. Every Azure DevOps organization already contains a read-only field called Board Column (System.BoardColumn), which is the platform's own projection of the native board, and field names are unique across an organization. Naming yours Board Column is therefore refused with "VS402803: Field name 'Board Column' you specified is already in use, choose a different name.", an error that cannot tell you which field holds the name because that field is not one you can see in your process. Give yours any free label. The fields the Fields tab of the organization settings page creates are labeled AnyKanban Board Column 01 and AnyKanban Board Column Done 01 (then 02, 03 and so on), so nobody mistakes them for the native pair. The label is not what the board binds. It binds the reference name the service reports and depends on no particular one, which is why Custom.BoardColumn above is a suggestion and not a requirement.
Everything said in section 4 applies here too: the field does not need to appear on the work item form, on later projects it is added with Use an existing field, and Remove is not Delete.
You only need this field to share a state between columns. Renaming the columns, or reordering them, needs nothing at all, because a layout with one column per state is fully derivable from the state, whatever the columns are called. Without the field, a layout that shares a state falls back to one column per state and the board says which field is missing.
5. Optional: fields used by swimlanes
Swimlanes are opt-in (off by default) and, like native boards, defined by rules: you name each lane and give it conditions, and the first lane whose conditions all match wins. Unmatched items land in an implicit "(no lane)" row. Dropping a card into a lane applies that lane's equality conditions to the item.
There is no single prerequisite field. A lane can test whatever the conditions reference: a picklist, a tag, a priority or a date. What matters is that the fields your conditions use exist on the work item type and hold the values you expect.
A simpler mode is retained for boards that want only one row per value of a single field: choose that single-select field in the board settings, and its values become the lanes. Free-form lanes with no backing data are not supported in either mode, because a lane must be derivable from the work item, so that dropping a card into it means something.
Process note: if you introduce an expedite lane, be aware it tends to degrade the throughput of the default lane, so use it deliberately.
5b. Doing it by hand, from the plan the page shows you
Some organizations route every process change through their own change management, and an administrator there cannot simply press a button. The settings page is built for that too: Copy plan puts the whole block on the clipboard as plain text: the field names, what happens to each work item type, and, after a run, what the service answered.
After a run, the block reports only what Azure DevOps actually did. A field it created moves under Created, and a line whose work went through is written in the past tense. Everything Azure DevOps refused, or that was not attempted because a step before it was refused, keeps the plan's own words, with the service's answer quoted under it. So a copy taken after a refused or partial run still lists exactly what is left to do. When Azure DevOps refused every step, for example because your account may not edit the process, the page says that nothing changed, and someone who has that permission can run the plan or follow the copy. When a step failed without an answer Azure DevOps is known to give, for example because the connection dropped, the page says only that no step was confirmed: a change whose answer never arrived may still have been made.
That copy is a usable instruction rather than only a record, because every name
in it is reproducible in the portal. AnyKanban's own fields are created under
Custom., the namespace Azure DevOps assigns to a field made through the
process UI, so creating a field named AnyKanban Board Column 01 by hand
produces exactly Custom.AnyKanbanBoardColumn01, the same reference name the
plan names.
To follow the plan by hand, for each line:
| The plan says | What to do in the portal |
|---|---|
under Creates (organization-wide, empty, off the form), a Custom.AnyKanbanBoardColumn… name followed by string |
New field > Create a field, type Text (single line), labeled with the name split into words: Custom.AnyKanbanBoardColumn01 becomes AnyKanban Board Column 01 |
under the same heading, a Custom.AnyKanbanBoardColumnDone… name followed by boolean |
the same, type Boolean: Custom.AnyKanbanBoardColumnDone01 becomes AnyKanban Board Column Done 01 |
create the fields |
nothing more; this is the step that creates the fields listed under Creates |
| under Attaches (already exist), a field | nothing on its own; it is attached per type below |
prepare inherited type |
the type is still the system one. Azure DevOps derives it for you the moment you add a field to it through the portal, so there is no separate step. It is listed because the REST path we use has to ask for it explicitly |
add the fields |
New field > Use an existing field, once for each Custom.AnyKanbanBoardColumn… field the plan names, on that work item type |
add Stack Rank / add Backlog Priority / add State Change Date |
the same, with that existing field |
Where to do it:
Organization Settings > Process > (your inherited process) > (the work item type) > New field
The page does not link to that dialog. Beside a system process, which Azure DevOps locks, it offers Open process settings, which opens the organization's process list. From there, open your inherited process and then the work item type.
A board configured afterwards can use fields added this way, because the column pickers in its settings offer the custom fields on the work item type. The settings page is stricter: it reuses only fields it has a record of creating. If it later finds a field you created by hand under one of its names, it lists that field under Left alone, and why and plans its own fields under the next free names.
Why there is no downloadable script. A script would be a snapshot of a plan that goes stale, it would need a credential of its own, and it would have to reproduce the product's knowledge of what each refusal means. The copied plan is a list a person follows, and the page recomputes itself every time it is opened.
6. Permissions and where settings live
Work items: users need standard Azure DevOps permissions to view and edit work items in the relevant area paths. The extension performs all reads and writes as the signed-in user; it grants no additional access.
Board settings (board definitions, column mapping, WIP limits, styling rules and so on) are stored in the Azure DevOps Extension Data Service. A board filed to a team's group or to the project board list is stored in the shared scope, so everyone it is listed for opens the same board: people who may read work items at the project's root for a project board, people who may read work items in one of the team's area paths for a board that reads a team, and always the person who created it. A board kept in My board list is stored in your own user scope, and nobody else's list shows it. Note: the Extension Data Service has no built-in permission model for shared documents, so any user of the extension can technically modify shared board settings. There is no way to restrict board configuration to administrators at the platform level. AnyKanban adds a guard of its own: it offers changes to a shared board only to the person who created it, to people with Edit project-level information in the project (members of Project Administrators have it, and members of Project Collection Administrators are meant to, though one outside Project Administrators has not been checked yet) and, for a board in a team's group, to that team's administrators. A project administrator changes any shared board they can open. A board that reads a team Azure DevOps no longer returns, for example because the team was deleted, opens for its creator alone, so nobody else can change it in AnyKanban. If it also records no creator, it opens for nobody, and Export leaves it out, so move a team's boards to another team or to No team, or export them, before you delete the team. Treat it as protection against accidental change, not as an enforced control. Per-user preferences (view choice, collapsed columns and lanes, list column widths, silenced notices, and the filter left on a saved query's page) are stored in the user scope and are private. A filter on a board in the hub is not stored at all; one left on a saved query's page is kept until you clear it or close the filter bar.
Reference: Extension data storage
Checklist
- Project Collection Administrator installed the extension
- The work item type carries your process's order field (every regular type does; see section 2 for the ones that do not and the Fields page that adds it)
- Saved query exists (flat, tree or direct-links); a flat query carries no
ORDER BY, or sorts by the order field ascending - (Optional) Boolean field added and bound for split columns
- (Optional) Text field added and bound for columns that share a state
- (Optional) Single-select field chosen for swimlanes
- Users have view/edit work item permissions in the relevant area paths
- Team agreed on who maintains board configuration (AnyKanban offers changes to a board's creator and to administrators, as a guard rather than an enforced control)