(SR-779) Add search-by-ID and release display to Linear app#85
(SR-779) Add search-by-ID and release display to Linear app#85dsayerdp wants to merge 5 commits into
Conversation
Search: replace the title containsIgnoreCase filter with Linear's
searchIssues(term:) query so issues can be found by identifier
(e.g. ENG-123) as well as title. gql() now omits `variables` from the
POST body when empty, which Linear otherwise rejects.
Releases: request releases { ... } in the issue queries, add
Release/ReleaseStage types, and render releases via a new ReleaseItem
component on issue list items and a Releases block on the issue view.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Reviewer's GuideImplements search-by-ID for Linear issues by switching list search to use the searchIssues GraphQL API, adds support for fetching and rendering associated releases on issue list and detail views, and hardens the GraphQL helper to omit empty variables objects while adding tests around the new behavior. Sequence diagram for getIssuesService search and GraphQL variables handlingsequenceDiagram
actor Agent
participant IssueListUI
participant getIssuesService
participant gql
participant LinearAPI
Agent->>IssueListUI: type search query
IssueListUI->>getIssuesService: getIssuesService(client, { q })
alt with_q
getIssuesService->>gql: gql({ term: q })`query SearchIssues($term: String!) { ... }`
gql-->>getIssuesService: JSON body with query and variables
getIssuesService->>LinearAPI: POST /graphql searchIssues(term)
LinearAPI-->>getIssuesService: searchIssues.nodes
else without_q
IssueListUI->>getIssuesService: getIssuesService(client, { ids? })
getIssuesService->>gql: gql(variables)`query Issues($filter: IssueFilter!) { ... }`
alt no_ids
gql-->>getIssuesService: JSON { query } (variables omitted)
else with_ids
gql-->>getIssuesService: JSON { query, variables: { filter: { id: { in: ids } } } }
end
getIssuesService->>LinearAPI: POST /graphql issues(filter)
LinearAPI-->>getIssuesService: issues.nodes
end
getIssuesService-->>IssueListUI: normalized Issue[]
IssueListUI-->>Agent: render issues
Entity relationship diagram for Issue releases and stageserDiagram
Issue {
string id
}
Release {
string id
string name
string version
string url
}
ReleaseStage {
string id
string name
string type
string color
}
Issue ||--o{ Release : releases
Release ||--|| ReleaseStage : stage
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Newer pnpm versions fail install with ERR_PNPM_IGNORED_BUILDS instead of warning when native build scripts aren't explicitly approved. Adds onlyBuiltDependencies so pnpm install succeeds in CI (devcontainer pins pnpm to "latest"). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CI's pnpm (pinned to "latest" in devcontainer.json) no longer reads the "pnpm" field in package.json at all, so the onlyBuiltDependencies fix from the previous commit was silently ignored. pnpm now expects overrides/onlyBuiltDependencies in pnpm-workspace.yaml instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CI still failed after moving config to pnpm-workspace.yaml: the devcontainer feature installs pnpm "latest" fresh on every run, and whatever version CI resolved to (with lockfile supply-chain scanning, newer than local 10.15.0) still hard-failed with ERR_PNPM_IGNORED_BUILDS despite the onlyBuiltDependencies config. Pinning to 10.15.0 (verified locally: install/typecheck/lint/tests all pass, no ignored-builds warning) removes the version-drift root cause instead of chasing each release's config format. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The devcontainer feature's pnpm-version input is baked into a cached Docker layer that CI keeps reusing, so pinning "10.15.0" in the feature config never actually took effect — every run still installed the same bleeding-edge pnpm (visible via its "supply-chain policies" lockfile check, present even in the very first failing run before any of these fixes). Activating the version via corepack in postCreateCommand runs at container start, not image build time, so it can't be short-circuited by the cached feature layer. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The
releases { nodes { id name version url stage { id name type color } } }selection string is duplicated acrossgetIssuesService,getIssueService, and the tests; consider extracting this into a shared constant or fragment-like helper so the shape stays in sync in one place. - In
Releases.tsxandReleaseItem.tsx, the props interfaces share names with the components (interface Releases,interface ReleaseItem), which can be confusing; renaming these toReleasesProps/ReleaseItemProps(or similar) will make the types easier to understand and avoid name clashes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `releases { nodes { id name version url stage { id name type color } } }` selection string is duplicated across `getIssuesService`, `getIssueService`, and the tests; consider extracting this into a shared constant or fragment-like helper so the shape stays in sync in one place.
- In `Releases.tsx` and `ReleaseItem.tsx`, the props interfaces share names with the components (`interface Releases`, `interface ReleaseItem`), which can be confusing; renaming these to `ReleasesProps`/`ReleaseItemProps` (or similar) will make the types easier to understand and avoid name clashes.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
AshleyDawson
left a comment
There was a problem hiding this comment.
Approved with an optional change request
| } | ||
| `; | ||
|
|
||
| const getIssuesService = (client: IDeskproClient, params?: Params) => { |
There was a problem hiding this comment.
Optional (see bottom of this comment).
Recommend we double-check the return shape of searchIssues here?
This query is selecting id, identifier, title, priority, etc. directly from searchIssues(term: $term).nodes, but the tests also note that this returns IssueSearchResult rather than Issue. If that result can contain mixed node types or needs narrowing via an inline fragment, this may break at runtime or return partial data.
If the schema supports multiple result types, I think we should guard this with something like:
searchIssues(term: $term) {
nodes {
... on Issue {
id
identifier
title
priority
priorityLabel
url
dueDate
...
}
}
}If the live schema guarantees Issue here, a short comment explaining that assumption would also help future readers.
Summary
Two features split out of the SR-91 working branch because they go beyond that bug's scope (the SR-91 relationship fix itself is in #84):
1. Search issues by ID
title containsIgnoreCasefilter with Linear'ssearchIssues(term:)GraphQL query, so agents can find issues by identifier (e.g.ABC-123) as well as title text.gql()now omits thevariableskey from the POST body when empty — Linear rejects an emptyvariablesobject.2. Display releases
ReleaseItemcomponent and aReleasesblock on the issue view.Releasesproperty on issue list items (home page).releases { id name version url stage { ... } }added to the issue GraphQL selections, with hand-rolledRelease/ReleaseStagetypes (the vendored schema predates Linear's Releases feature).Notes
getIssuesService.ts,getIssueService.ts,types.ts, andmanifest.json(both bump to 1.0.25) — whichever merges second resolves them.Testing
tsc --noEmitclean,pnpm lintclean,pnpm test: 41 suites / 151 tests pass.getIssuesService(searchIssues term + id-filter + releases selection),getIssueService(releases selection),gql(empty variables omitted),IssueItem(renders linked releases).Linear: https://linear.app/deskpro/issue/SR-779/linear-app-search-issues-by-id-and-display-releases
🤖 Generated with Claude Code
Summary by Sourcery
Add issue search by identifier and surface Linear releases on issue views and listings while improving GraphQL request handling.
New Features:
Enhancements:
Build:
Tests: