Tool slots
Name a task's tools by a slot, such as a code host, and let each company fill it with the tool it connected, so one task works with any vendor.
Why a slot
A task normally names its tools by the tool they come from: github.create_issue. That task only works for a company that connected GitHub under that name. A team shared through the catalog then breaks for a company whose code lives somewhere else.
A tool slot names the kind of tool instead. The task declares a slot, codehost, and names its tools by it: codehost, or codehost.create_issue. Each company says which of its own connections fills the slot. The same task then runs against GitHub for one company and GitLab or Gitea for another, with no change to the task.
Declaring a slot on a task
A task version lists its slots in toolSlots. Each slot has a key, a label, and an optional description:
{
"toolSlots": [
{ "key": "codehost", "label": "Code host", "description": "Where the repository, its issues and its pull requests live" }
],
"tools": ["codehost", "os.set_execution_name"]
}
- The key reads like a tool type: a lowercase letter, then letters, digits,
_or-, up to 32 characters. It cannot beos,workspace,memoryorweb, which belong to the OS. - The label is what a person reads when they choose a connection for the slot, up to 80 characters.
- A task declares at most 16 slots.
The task's tools, its gates and its workspace credentials may all name a slot. codehost alone is the filling tool's whole catalogue, as a bare tool type is. A slot that no tool or gate names is flagged on save (tool_slot_unused), because it is almost always a renamed key.
On the task page, slots are under Tool slots in the task's settings. Over the API they are part of the version body (see Tasks).
Filling a slot
A connection fills a slot when its Fills slots list on Tools names the key. Anyone who may edit the connection may set it, Express connections included. Over the API it is the binding's slots list (PATCH /v1/tools/bindings/:id).
When a run starts, each slot its task declares is filled by the nearest connection that fills it, in the usual order: the task, its role, the member, the team, then the company. The run then names those tools by the filling connection's own tool type. A connection called github that fills codehost serves codehost.create_issue as github.create_issue, with its own credential.
Three rules decide the edge cases:
- A connection named for the key wins. If the company has a connection whose tool type is the key itself (
codehost), that connection is used directly, as it was before slots existed. - Several hosts at one level. When two connections of different tools fill the same slot at the same level, the one whose
git.reposcustom prop lists the run's repository is used.git.repostakesowner/nameentries, orowner/*for every repository of an owner, comma separated. A connection with nogit.reposfills the slot for any repository. If that still leaves two, the run stops withtool_slot_ambiguous:<key>until you addgit.reposor remove one. - Nothing fills it. A run whose slot nothing fills stops before it starts, with
tool_not_bound:<key>, the same as a tool nobody connected. Filling the slot resumes it by itself.
Approvals still apply
A slot never takes a tool out of an approval. A connection's must-gate list (the tools a task may only call with a gate, such as a merge) also holds for every slot the connection fills. codehost.merge_pull_request needs the same gate as github.merge_pull_request when the github connection fills codehost. A gate a task declares on a slot's tool (codehost.merge_pull_request) covers the call whichever connection fills the slot.
Sharing a team that uses slots
When you clone a team or a role from the catalog, the review lists each slot its tasks declare, under Slots to fill. You choose one of your connections for each. The connection is told it fills the slot, and the tasks are installed exactly as published, so they stay linked to the template and keep receiving its updates. A slot that one of your connections already fills is shown as filled.
This is the difference from swapping a tool. A swap rewrites the task to name another vendor and makes it your own copy. A slot needs no rewrite, because the task never named a vendor.