[{"data":1,"prerenderedAt":28},["ShallowReactive",2],{"$f1lkx7b2fut0ks":3},{"href":4,"title":5,"description":6,"kind":7,"mark":7,"planned":8,"contributors":9,"provenance":7,"express":8,"html":10,"headings":11},"\u002Fdocs\u002Fwork\u002Ftool-slots","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.",null,false,[],"\u003Ch2 id=\"why-a-slot\">Why a slot\u003C\u002Fh2>\n\u003Cp>A task normally names its tools by the tool they come from: \u003Ccode>github.create_issue\u003C\u002Fcode>. 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.\u003C\u002Fp>\n\u003Cp>A \u003Cstrong>tool slot\u003C\u002Fstrong> names the kind of tool instead. The task declares a slot, \u003Ccode>codehost\u003C\u002Fcode>, and names its tools by it: \u003Ccode>codehost\u003C\u002Fcode>, or \u003Ccode>codehost.create_issue\u003C\u002Fcode>. 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.\u003C\u002Fp>\n\u003Ch2 id=\"declaring-a-slot-on-a-task\">Declaring a slot on a task\u003C\u002Fh2>\n\u003Cp>A task version lists its slots in \u003Ccode>toolSlots\u003C\u002Fcode>. Each slot has a key, a label, and an optional description:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  &quot;toolSlots&quot;: [\n    { &quot;key&quot;: &quot;codehost&quot;, &quot;label&quot;: &quot;Code host&quot;, &quot;description&quot;: &quot;Where the repository, its issues and its pull requests live&quot; }\n  ],\n  &quot;tools&quot;: [&quot;codehost&quot;, &quot;os.set_execution_name&quot;]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cul>\n\u003Cli>The \u003Cstrong>key\u003C\u002Fstrong> reads like a tool type: a lowercase letter, then letters, digits, \u003Ccode>_\u003C\u002Fcode> or \u003Ccode>-\u003C\u002Fcode>, up to 32 characters. It cannot be \u003Ccode>os\u003C\u002Fcode>, \u003Ccode>workspace\u003C\u002Fcode>, \u003Ccode>memory\u003C\u002Fcode> or \u003Ccode>web\u003C\u002Fcode>, which belong to the OS.\u003C\u002Fli>\n\u003Cli>The \u003Cstrong>label\u003C\u002Fstrong> is what a person reads when they choose a connection for the slot, up to 80 characters.\u003C\u002Fli>\n\u003Cli>A task declares at most 16 slots.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The task's tools, its gates and its workspace credentials may all name a slot. \u003Ccode>codehost\u003C\u002Fcode> 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 (\u003Ccode>tool_slot_unused\u003C\u002Fcode>), because it is almost always a renamed key.\u003C\u002Fp>\n\u003Cp>On the task page, slots are under \u003Cstrong>Tool slots\u003C\u002Fstrong> in the task's settings. Over the API they are part of the version body (see \u003Ca href=\"\u002Fdocs\u002Fapi\u002Ftasks\">Tasks\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"filling-a-slot\">Filling a slot\u003C\u002Fh2>\n\u003Cp>A connection fills a slot when its \u003Cstrong>Fills slots\u003C\u002Fstrong> list on \u003Cstrong>Tools\u003C\u002Fstrong> names the key. Anyone who may edit the connection may set it, Express connections included. Over the API it is the binding's \u003Ccode>slots\u003C\u002Fcode> list (\u003Ccode>PATCH \u002Fv1\u002Ftools\u002Fbindings\u002F:id\u003C\u002Fcode>).\u003C\u002Fp>\n\u003Cp>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 \u003Ccode>github\u003C\u002Fcode> that fills \u003Ccode>codehost\u003C\u002Fcode> serves \u003Ccode>codehost.create_issue\u003C\u002Fcode> as \u003Ccode>github.create_issue\u003C\u002Fcode>, with its own credential.\u003C\u002Fp>\n\u003Cp>Three rules decide the edge cases:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>A connection named for the key wins.\u003C\u002Fstrong> If the company has a connection whose tool type is the key itself (\u003Ccode>codehost\u003C\u002Fcode>), that connection is used directly, as it was before slots existed.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Several hosts at one level.\u003C\u002Fstrong> When two connections of different tools fill the same slot at the same level, the one whose \u003Ccode>git.repos\u003C\u002Fcode> custom prop lists the run's repository is used. \u003Ccode>git.repos\u003C\u002Fcode> takes \u003Ccode>owner\u002Fname\u003C\u002Fcode> entries, or \u003Ccode>owner\u002F*\u003C\u002Fcode> for every repository of an owner, comma separated. A connection with no \u003Ccode>git.repos\u003C\u002Fcode> fills the slot for any repository. If that still leaves two, the run stops with \u003Ccode>tool_slot_ambiguous:&lt;key&gt;\u003C\u002Fcode> until you add \u003Ccode>git.repos\u003C\u002Fcode> or remove one.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Nothing fills it.\u003C\u002Fstrong> A run whose slot nothing fills stops before it starts, with \u003Ccode>tool_not_bound:&lt;key&gt;\u003C\u002Fcode>, the same as a tool nobody connected. Filling the slot resumes it by itself.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"approvals-still-apply\">Approvals still apply\u003C\u002Fh2>\n\u003Cp>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. \u003Ccode>codehost.merge_pull_request\u003C\u002Fcode> needs the same gate as \u003Ccode>github.merge_pull_request\u003C\u002Fcode> when the \u003Ccode>github\u003C\u002Fcode> connection fills \u003Ccode>codehost\u003C\u002Fcode>. A gate a task declares on a slot's tool (\u003Ccode>codehost.merge_pull_request\u003C\u002Fcode>) covers the call whichever connection fills the slot.\u003C\u002Fp>\n\u003Ch2 id=\"sharing-a-team-that-uses-slots\">Sharing a team that uses slots\u003C\u002Fh2>\n\u003Cp>When you clone a team or a role from the catalog, the review lists each slot its tasks declare, under \u003Cstrong>Slots to fill\u003C\u002Fstrong>. 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.\u003C\u002Fp>\n\u003Cp>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.\u003C\u002Fp>\n",[12,16,19,22,25],{"id":13,"text":14,"level":15,"planned":8},"why-a-slot","Why a slot",2,{"id":17,"text":18,"level":15,"planned":8},"declaring-a-slot-on-a-task","Declaring a slot on a task",{"id":20,"text":21,"level":15,"planned":8},"filling-a-slot","Filling a slot",{"id":23,"text":24,"level":15,"planned":8},"approvals-still-apply","Approvals still apply",{"id":26,"text":27,"level":15,"planned":8},"sharing-a-team-that-uses-slots","Sharing a team that uses slots",1792244641316]