diff --git a/.changeset/stupid-feet-reply.md b/.changeset/stupid-feet-reply.md new file mode 100644 index 0000000000..d7213b1bdc --- /dev/null +++ b/.changeset/stupid-feet-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +Add support for non-organization accounts in GitHub Discovery diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts index 15280b96b8..88bddc93fb 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.test.ts @@ -156,7 +156,7 @@ describe('github', () => { describe('getOrganizationRepositories', () => { it('read repositories', async () => { const input: QueryResponse = { - organization: { + repositoryOwner: { repositories: { nodes: [ { diff --git a/plugins/catalog-backend/src/ingestion/processors/github/github.ts b/plugins/catalog-backend/src/ingestion/processors/github/github.ts index f5230ce044..f6cfcb8901 100644 --- a/plugins/catalog-backend/src/ingestion/processors/github/github.ts +++ b/plugins/catalog-backend/src/ingestion/processors/github/github.ts @@ -20,8 +20,8 @@ import { graphql } from '@octokit/graphql'; // Graphql types export type QueryResponse = { - organization: Organization; - user: User; + organization?: Organization; + repositoryOwner?: Organization | User; }; export type Organization = { @@ -66,14 +66,6 @@ export type Connection = { nodes: T[]; }; -export type RepositoryOwnerType = { - __typename: 'Organization' | 'User'; -}; - -export type RepositoryOwnerResponse = { - repositoryOwner: RepositoryOwnerType | null; -}; - /** * Gets all the users out of a GitHub organization. * @@ -237,54 +229,28 @@ export async function getOrganizationRepositories( client: typeof graphql, org: string, ): Promise<{ repositories: Repository[] }> { - let query = ``; - - switch (await getLoginType(client, org)) { - case 'Organization': - query = ` - query repositories($org: String!, $cursor: String) { - organization(login: $org) { + const query = ` + query repositories($org: String!, $cursor: String) { + repositoryOwner(login: $org) { + login + repositories(first: 100, after: $cursor) { + nodes { name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } + url + isArchived } - }`; - break; - - default: - query = ` - query repositories($org: String!, $cursor: String) { - user(login: $org) { - name - repositories(first: 100, after: $cursor) { - nodes { - name - url - isArchived - } - pageInfo { - hasNextPage - endCursor - } - } + pageInfo { + hasNextPage + endCursor } - }`; - break; - } + } + } + }`; const repositories = await queryWithPaging( client, query, - r => r.organization?.repositories || r.user?.repositories, + r => r.repositoryOwner?.repositories, x => x, { org }, ); @@ -362,16 +328,10 @@ export async function queryWithPaging< let cursor: string | undefined = undefined; for (let j = 0; j < 1000 /* just for sanity */; ++j) { - let response: Response; - - try { - response = await client(query, { - ...variables, - cursor, - }); - } catch (e) { - response = e.data; - } + const response: Response = await client(query, { + ...variables, + cursor, + }); const conn = connection(response); if (!conn) { @@ -391,19 +351,3 @@ export async function queryWithPaging< return result; } - -export async function getLoginType(client: typeof graphql, login: string) { - const query = ` - query repositoryOwner($login: String!) { - repositoryOwner(login: $login) { - __typename - } - }`; - - const response: RepositoryOwnerResponse = await client(query, { login }); - if (response.repositoryOwner === null) { - throw new Error(`Unknown repository owner for "${login}"`); - } - - return response.repositoryOwner.__typename; -}