diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts index 3ac66a0023..d481e42c9f 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/OctokitProvider.ts @@ -32,6 +32,8 @@ export type OctokitIntegration = { /** * OctokitProvider provides Octokit client based on ScmIntegrationsRegistry configuration. * OctokitProvider supports GitHub credentials caching out of the box. + * + * @deprecated use the internal {@link getOctokitOptions} function instead */ export class OctokitProvider { private readonly integrations: ScmIntegrationRegistry; @@ -51,6 +53,8 @@ export class OctokitProvider { * gets standard Octokit client based on repository URL. * * @param repoUrl - Repository URL + * + * @deprecated use the internal {@link getOctokitOptions} function instead */ async getOctokit( repoUrl: string, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts index 0c8b4d4aab..f2329c9ca1 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubActionsDispatch.ts @@ -13,24 +13,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { InputError } from '@backstage/errors'; import { - DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrations, } from '@backstage/integration'; +import { Octokit } from 'octokit'; import { createTemplateAction } from '../../createTemplateAction'; -import { OctokitProvider } from './OctokitProvider'; +import { parseRepoUrl } from '../publish/util'; +import { getOctokitOptions } from './helpers'; export function createGithubActionsDispatchAction(options: { integrations: ScmIntegrations; githubCredentialsProvider?: GithubCredentialsProvider; }) { const { integrations, githubCredentialsProvider } = options; - const octokitProvider = new OctokitProvider( - integrations, - githubCredentialsProvider || - DefaultGithubCredentialsProvider.fromIntegrations(integrations), - ); return createTemplateAction<{ repoUrl: string; @@ -90,9 +87,19 @@ export function createGithubActionsDispatchAction(options: { `Dispatching workflow ${workflowId} for repo ${repoUrl} on ${branchOrTagName}`, ); - const { client, owner, repo } = await octokitProvider.getOctokit( - repoUrl, - { token: providedToken }, + const { owner, repo } = parseRepoUrl(repoUrl, integrations); + + if (!owner) { + throw new InputError('Invalid repository owner provided in repoUrl'); + } + + const client = new Octokit( + await getOctokitOptions({ + integrations, + repoUrl, + credentialsProvider: githubCredentialsProvider, + token: providedToken, + }), ); await client.rest.actions.createWorkflowDispatch({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts index 0c93ae1dd5..dc52bd5fb4 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/github/githubWebhook.ts @@ -14,27 +14,27 @@ * limitations under the License. */ import { - DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; import { createTemplateAction } from '../../createTemplateAction'; -import { OctokitProvider } from './OctokitProvider'; import { emitterEventNames } from '@octokit/webhooks'; import { assertError } from '@backstage/errors'; +import { Octokit } from 'octokit'; +import { getOctokitOptions } from './helpers'; +import { parseRepoUrl } from '../publish/util'; export function createGithubWebhookAction(options: { integrations: ScmIntegrationRegistry; defaultWebhookSecret?: string; githubCredentialsProvider?: GithubCredentialsProvider; }) { - const { integrations, defaultWebhookSecret, githubCredentialsProvider } = - options; - const octokitProvider = new OctokitProvider( + const { integrations, - githubCredentialsProvider ?? - DefaultGithubCredentialsProvider.fromIntegrations(integrations), - ); + defaultWebhookSecret, + githubCredentialsProvider, + } = options; + const eventNames = emitterEventNames.filter(event => !event.includes('.')); return createTemplateAction<{ @@ -127,12 +127,21 @@ export function createGithubWebhookAction(options: { } = ctx.input; ctx.logger.info(`Creating webhook ${webhookUrl} for repo ${repoUrl}`); + const { owner, repo } = parseRepoUrl(repoUrl, integrations); - const { client, owner, repo } = await octokitProvider.getOctokit( - repoUrl, - { token: providedToken }, + const client = new Octokit( + await getOctokitOptions({ + integrations, + credentialsProvider: githubCredentialsProvider, + repoUrl: repoUrl, + token: providedToken, + }), ); + if (!owner) { + throw new InputError('Invalid repository owner'); + } + try { const insecure_ssl = insecureSsl ? '1' : '0'; await client.rest.repos.createWebhook({ diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts index cabe40986f..418cce5043 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/github.ts @@ -14,7 +14,6 @@ * limitations under the License. */ import { - DefaultGithubCredentialsProvider, GithubCredentialsProvider, ScmIntegrationRegistry, } from '@backstage/integration'; @@ -22,11 +21,12 @@ import { enableBranchProtectionOnDefaultRepoBranch, initRepoAndPush, } from '../helpers'; -import { getRepoSourceDirectory } from './util'; +import { getRepoSourceDirectory, parseRepoUrl } from './util'; import { createTemplateAction } from '../../createTemplateAction'; import { Config } from '@backstage/config'; -import { OctokitProvider } from '../github/OctokitProvider'; -import { assertError } from '@backstage/errors'; +import { assertError, InputError } from '@backstage/errors'; +import { getOctokitOptions } from '../github/helpers'; +import { Octokit } from 'octokit'; export function createPublishGithubAction(options: { integrations: ScmIntegrationRegistry; @@ -34,11 +34,6 @@ export function createPublishGithubAction(options: { githubCredentialsProvider?: GithubCredentialsProvider; }) { const { integrations, config, githubCredentialsProvider } = options; - const octokitProvider = new OctokitProvider( - integrations, - githubCredentialsProvider || - DefaultGithubCredentialsProvider.fromIntegrations(integrations), - ); return createTemplateAction<{ repoUrl: string; @@ -160,10 +155,20 @@ export function createPublishGithubAction(options: { token: providedToken, } = ctx.input; - const { client, token, owner, repo } = await octokitProvider.getOctokit( + const { owner, repo } = parseRepoUrl(repoUrl, integrations); + + const octokitOptions = await getOctokitOptions({ + integrations, + credentialsProvider: githubCredentialsProvider, + token: providedToken, repoUrl, - { token: providedToken }, - ); + }); + + const client = new Octokit(octokitOptions); + + if (!owner) { + throw new InputError('Invalid repository owner provided in repoUrl'); + } const user = await client.rest.users.getByUsername({ username: owner, @@ -253,7 +258,7 @@ export function createPublishGithubAction(options: { defaultBranch, auth: { username: 'x-access-token', - password: token, + password: octokitOptions.token, }, logger: ctx.logger, commitMessage: config.getOptionalString( diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts index c329b6b6f3..ca70084ef5 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/publish/githubPullRequest.ts @@ -20,7 +20,6 @@ import { parseRepoUrl, isExecutable } from './util'; import { GithubCredentialsProvider, ScmIntegrationRegistry, - SingleInstanceGithubCredentialsProvider, } from '@backstage/integration'; import { zipObject } from 'lodash'; import { createTemplateAction } from '../../createTemplateAction'; @@ -29,6 +28,7 @@ import { InputError, CustomErrorBase } from '@backstage/errors'; import { createPullRequest } from 'octokit-plugin-create-pull-request'; import globby from 'globby'; import { resolveSafeChildPath } from '@backstage/backend-common'; +import { getOctokitOptions } from '../github/helpers'; export type Encoding = 'utf-8' | 'base64'; @@ -65,40 +65,15 @@ export const defaultClientFactory = async ({ host = 'github.com', token: providedToken, }: ClientFactoryInput): Promise => { - const integrationConfig = integrations.github.byHost(host)?.config; + const octokitOptions = await getOctokitOptions({ + integrations, + credentialsProvider: githubCredentialsProvider, + repoUrl: `https://${host}/${owner}/${repo}`, + token: providedToken, + }); + const OctokitPR = Octokit.plugin(createPullRequest); - - if (!integrationConfig) { - throw new InputError(`No integration for host ${host}`); - } - - if (providedToken) { - return new OctokitPR({ - auth: providedToken, - baseUrl: integrationConfig.apiBaseUrl, - }); - } - - const credentialsProvider = - githubCredentialsProvider || - SingleInstanceGithubCredentialsProvider.create(integrationConfig); - - const { token } = await credentialsProvider.getCredentials({ - url: `https://${host}/${encodeURIComponent(owner)}/${encodeURIComponent( - repo, - )}`, - }); - - if (!token) { - throw new InputError( - `No token available for host: ${host}, with owner ${owner}, and repo ${repo}`, - ); - } - - return new OctokitPR({ - auth: token, - baseUrl: integrationConfig.apiBaseUrl, - }); + return new OctokitPR(octokitOptions); }; interface CreateGithubPullRequestActionOptions {