Skip to content

Use PATCH /repos/:owner/:repo/issues/:number for set-issue-type safe output #41238

Description

@alondahari

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:

  1. GET /repos/:owner/:repo/issues/:number — fetch issue node_id
  2. GraphQL repository.issueTypes query — discover available types and resolve name → node ID
  3. 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

  1. Remove getIssueNodeId() helper — no longer needed
  2. Remove fetchIssueTypes() GraphQL query — server resolves by name; invalid names get a 422
  3. Remove setIssueTypeById() GraphQL mutation
  4. Replace with single githubClient.rest.issues.update() call
  5. Client-side validation of type name against allowed list stays unchanged
  6. Pass intent metadata (rationale, confidence, suggest) in Hash form when hasIssueIntentsRuntimeFeature() is true
  7. 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

  • Replace 3-call GraphQL flow with single PATCH REST call
  • Verify type name string works (simple form)
  • Verify clearing works (empty/blank type value)
  • Verify intent metadata (rationale, confidence, suggest) passes through correctly in Hash form
  • Verify 422 error from server maps to the same handler error shape
  • Remove getIssueNodeId(), fetchIssueTypes(), setIssueTypeById() helpers
  • Maintain allowed-types client-side validation
  • Maintain required-labels / required-title-prefix filters
  • Maintain staged-mode preview behavior
  • Maintain temporary ID resolution
  • Update handler tests to cover the new REST call
  • Measure: 3 API calls → 1 API call per invocation

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions