Skip to content

Commit 256b57e

Browse files
committed
fix(linear): exclude projects based on non-public label
1 parent 10bda5e commit 256b57e

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

src/linear/build-snapshot.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const CUSTOM_VIEW_QUERY = `
7171
sortOrder
7272
}
7373
}
74+
labelIds
7475
}
7576
pageInfo {
7677
hasNextPage
@@ -111,6 +112,7 @@ type ViewProjectNode = {
111112
sortOrder: number
112113
}>
113114
}
115+
labelIds: string[]
114116
}
115117

116118
type CustomViewQueryResult = {
@@ -122,6 +124,20 @@ type CustomViewQueryResult = {
122124
} | null
123125
}
124126

127+
const PROJECT_LABELS_QUERY = `
128+
query FetchProjectLabels {
129+
projectLabels {
130+
nodes { id name }
131+
}
132+
}
133+
`
134+
135+
type ProjectLabelsQueryResult = {
136+
projectLabels: {
137+
nodes: Array<{ id: string; name: string }>
138+
}
139+
}
140+
125141
// ---------------------------------------------------------------------------
126142
// Retry helper — retries transient 5xx errors with exponential backoff
127143
// ---------------------------------------------------------------------------
@@ -181,6 +197,17 @@ async function fetchTeams(): Promise<TeamsQueryResult['teams']['nodes']> {
181197
return all
182198
}
183199

200+
async function fetchPrivateLabelIds(): Promise<Set<string>> {
201+
const PRIVATE_LABELS = new Set(['non-public', 'not-public'])
202+
const result = await withRetry(() =>
203+
linear.client.request<ProjectLabelsQueryResult>(PROJECT_LABELS_QUERY)
204+
)
205+
const ids = result.projectLabels.nodes
206+
.filter((l) => PRIVATE_LABELS.has(l.name.toLowerCase()))
207+
.map((l) => l.id)
208+
return new Set(ids)
209+
}
210+
184211
async function fetchViewProjects(viewId: string): Promise<ViewProjectNode[]> {
185212
const all: ViewProjectNode[] = []
186213
let hasNextPage = true
@@ -218,14 +245,16 @@ async function fetchViewProjects(viewId: string): Promise<ViewProjectNode[]> {
218245
export async function buildSnapshot(): Promise<RoadmapSnapshot> {
219246
const viewId = process.env.LINEAR_CUSTOM_VIEW_ID ?? DEFAULT_VIEW_ID
220247

221-
const [teamNodes, viewProjects] = await Promise.all([
248+
const [teamNodes, viewProjects, privateLabelIds] = await Promise.all([
222249
fetchTeams(),
223-
fetchViewProjects(viewId)
250+
fetchViewProjects(viewId),
251+
fetchPrivateLabelIds()
224252
])
225253

226254
const projects: RoadmapProject[] = viewProjects
227255
.filter((p) => !p.name.includes('(Archived) '))
228256
.filter((p) => p.state !== 'completed' && p.state !== 'cancelled')
257+
.filter((p) => !p.labelIds.some((id) => privateLabelIds.has(id)))
229258
.map((p) => {
230259
const firstTeam = p.teams.nodes[0] ?? null
231260
return {

0 commit comments

Comments
 (0)