Summary
Migrate the set-issue-type safe output handler to use the REST PATCH /repos/:owner/:repo/issues/:number endpoint instead of the current GraphQL-based flow. This collapses 3 API calls into 1 and eliminates the GraphQL dependency.
Current Implementation
File: actions/setup/js/set_issue_type.cjs
The handler currently makes 3 API calls per invocation:
GET /repos/:owner/:repo/issues/:number — fetch issue node_id
- GraphQL
repository.issueTypes query — discover available types and resolve name → node ID
- GraphQL
updateIssue mutation — set the type by node ID
Investigation Results
The PATCH endpoint supports the type field natively.
Input format
- Simple:
{ "type": "Bug" } — accepts the type name as a plain string
- With intents:
{ "type": { "value": "Bug", "rationale": "...", "confidence": "high", "suggest": true } } — Hash form supports all intent metadata
- Clearing: passing an empty/blank
type value clears the issue type
Server-side type resolution
The endpoint resolves the type by name against the org. No separate type-discovery query needed. Returns 422 if the type name is invalid or not enabled.
Intent metadata fully supported
rationale — stored as an event annotation
confidence — accepts "low", "medium", "high"; used for confidence-based routing
suggest — routes to a pending suggestion instead of direct application
Proposed Change
Replace the 3-call GraphQL flow with a single REST PATCH:
// Before (3 calls):
const { data } = await githubClient.rest.issues.get({ owner, repo, issue_number }); // for node_id
const types = await githubClient.graphql(fetchTypesQuery, { owner, repo }); // discover types
await githubClient.graphql(updateIssueMutation, { issueId: nodeId, typeId }); // set type
// After (1 call):
await githubClient.rest.issues.update({
owner, repo, issue_number,
type: "Bug",
// OR with intents:
type: { value: "Bug", rationale: "...", confidence: "high", suggest: true }
});
Changes needed in set_issue_type.cjs
- Remove
getIssueNodeId() helper — no longer needed
- Remove
fetchIssueTypes() GraphQL query — server resolves by name; invalid names get a 422
- Remove
setIssueTypeById() GraphQL mutation
- Replace with single
githubClient.rest.issues.update() call
- Client-side validation of type name against
allowed list stays unchanged
- Pass intent metadata (
rationale, confidence, suggest) in Hash form when hasIssueIntentsRuntimeFeature() is true
- Map the 422 error from the server (invalid type name) to the same error shape the handler currently returns
What stays the same
allowed list validation (client-side, before the API call)
required-labels / required-title-prefix filters (still need to fetch issue for these — but only when configured)
- Staged-mode preview behavior
- Temporary ID resolution
- Max count enforcement
- Repo resolution and validation
Acceptance Criteria
Summary
Migrate the
set-issue-typesafe output handler to use the RESTPATCH /repos/:owner/:repo/issues/:numberendpoint instead of the current GraphQL-based flow. This collapses 3 API calls into 1 and eliminates the GraphQL dependency.Current Implementation
File:
actions/setup/js/set_issue_type.cjsThe handler currently makes 3 API calls per invocation:
GET /repos/:owner/:repo/issues/:number— fetch issuenode_idrepository.issueTypesquery — discover available types and resolve name → node IDupdateIssuemutation — set the type by node IDInvestigation Results
The PATCH endpoint supports the
typefield natively.Input format
{ "type": "Bug" }— accepts the type name as a plain string{ "type": { "value": "Bug", "rationale": "...", "confidence": "high", "suggest": true } }— Hash form supports all intent metadatatypevalue clears the issue typeServer-side type resolution
The endpoint resolves the type by name against the org. No separate type-discovery query needed. Returns 422 if the type name is invalid or not enabled.
Intent metadata fully supported
rationale— stored as an event annotationconfidence— accepts"low","medium","high"; used for confidence-based routingsuggest— routes to a pending suggestion instead of direct applicationProposed Change
Replace the 3-call GraphQL flow with a single REST PATCH:
Changes needed in
set_issue_type.cjsgetIssueNodeId()helper — no longer neededfetchIssueTypes()GraphQL query — server resolves by name; invalid names get a 422setIssueTypeById()GraphQL mutationgithubClient.rest.issues.update()callallowedlist stays unchangedrationale,confidence,suggest) in Hash form whenhasIssueIntentsRuntimeFeature()is trueWhat stays the same
allowedlist validation (client-side, before the API call)required-labels/required-title-prefixfilters (still need to fetch issue for these — but only when configured)Acceptance Criteria
PATCHREST callgetIssueNodeId(),fetchIssueTypes(),setIssueTypeById()helpers