renovate 44.11.2 → 44.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -234,32 +234,37 @@ var GithubHttp = class extends HttpBase {
234
234
  const baseUrl = httpOptions.baseUrl ?? this.baseUrl;
235
235
  const parsedUrl = new URL(next.url, baseUrl);
236
236
  const firstPageUrl = !!baseUrl && !!env.RENOVATE_X_REBASE_PAGINATION_LINKS && parsedUrl.origin !== "https://api.github.com" ? replaceUrlBase(parsedUrl, baseUrl) : parsedUrl;
237
- const pages = await all([...range(2, lastPage)].map((pageNumber) => () => {
238
- const nextUrl = parseUrl(firstPageUrl.toString());
239
- nextUrl.searchParams.set("page", String(pageNumber));
240
- return super.requestJsonUnsafe(method, {
241
- ...opts,
242
- url: nextUrl
243
- });
244
- }));
245
- // v8 ignore else -- TODO: add test #40625
246
- if (httpOptions.paginationField && isPlainObject(result.body)) {
247
- const paginatedResult = result.body[httpOptions.paginationField];
237
+ if (firstPageUrl.origin === resolvedUrl.origin) {
238
+ const pages = await all([...range(2, lastPage)].map((pageNumber) => () => {
239
+ const nextUrl = parseUrl(firstPageUrl.toString());
240
+ nextUrl.searchParams.set("page", String(pageNumber));
241
+ return super.requestJsonUnsafe(method, {
242
+ ...opts,
243
+ url: nextUrl
244
+ });
245
+ }));
248
246
  // v8 ignore else -- TODO: add test #40625
249
- if (isArray(paginatedResult)) {
250
- for (const nextPage of pages)
247
+ if (httpOptions.paginationField && isPlainObject(result.body)) {
248
+ const paginatedResult = result.body[httpOptions.paginationField];
249
+ // v8 ignore else -- TODO: add test #40625
250
+ if (isArray(paginatedResult)) {
251
+ for (const nextPage of pages)
251
252
  // v8 ignore else -- TODO: add test #40625
252
- if (isPlainObject(nextPage.body)) {
253
- const nextPageResults = nextPage.body[httpOptions.paginationField];
254
- // v8 ignore else -- TODO: add test #40625
255
- if (isArray(nextPageResults)) paginatedResult.push(...nextPageResults);
253
+ if (isPlainObject(nextPage.body)) {
254
+ const nextPageResults = nextPage.body[httpOptions.paginationField];
255
+ // v8 ignore else -- TODO: add test #40625
256
+ if (isArray(nextPageResults)) paginatedResult.push(...nextPageResults);
257
+ }
256
258
  }
257
- }
258
- } else if (isArray(result.body)) {
259
- for (const nextPage of pages)
259
+ } else if (isArray(result.body)) {
260
+ for (const nextPage of pages)
260
261
  // v8 ignore else -- TODO: add test #40625
261
- if (isArray(nextPage.body)) result.body.push(...nextPage.body);
262
- }
262
+ if (isArray(nextPage.body)) result.body.push(...nextPage.body);
263
+ }
264
+ } else logger.once.warn({
265
+ requestHost: resolvedUrl.host,
266
+ paginationHost: firstPageUrl.host
267
+ }, "Ignoring cross-origin GitHub pagination link. Set RENOVATE_X_REBASE_PAGINATION_LINKS if this is a self-hosted instance that returns a different host in pagination links.");
263
268
  }
264
269
  }
265
270
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"github.js","names":["hostRules.find","p.all"],"sources":["../../../lib/util/http/github.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyObject,\n isNullOrUndefined,\n isPlainObject,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { z } from 'zod/v4';\nimport { GlobalConfig } from '../../config/global.ts';\nimport {\n PLATFORM_BAD_CREDENTIALS,\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../constants/error-messages.ts';\nimport { logger } from '../../logger/index.ts';\nimport { ExternalHostError } from '../../types/errors/external-host-error.ts';\nimport { getCache } from '../cache/repository/index.ts';\nimport { getEnv } from '../env.ts';\nimport * as hostRules from '../host-rules.ts';\nimport { maskToken } from '../mask.ts';\nimport * as p from '../promises.ts';\nimport { range } from '../range.ts';\nimport { regEx } from '../regex.ts';\nimport { LooseArray } from '../schema-utils/index.ts';\nimport { joinUrlParts, parseLinkHeader, parseUrl } from '../url.ts';\nimport { findMatchingRule } from './host-rules.ts';\nimport {\n HttpBase,\n type InternalHttpOptions,\n type InternalJsonUnsafeOptions,\n} from './http.ts';\nimport type { GotLegacyError } from './legacy.ts';\nimport type {\n GraphqlOptions,\n HttpMethod,\n HttpOptions,\n HttpResponse,\n} from './types.ts';\n\nconst githubBaseUrl = 'https://api.github.com/';\nlet baseUrl = githubBaseUrl;\nexport function setBaseUrl(url: string): void {\n baseUrl = url;\n}\n\nexport interface GithubBaseHttpOptions extends HttpOptions {\n repository?: string;\n}\n\nexport interface GithubHttpOptions extends GithubBaseHttpOptions {\n paginate?: boolean | string;\n paginationField?: string;\n pageLimit?: number;\n}\n\ninterface GithubGraphqlRepoData<T = unknown> {\n repository?: T;\n}\n\nexport type GithubGraphqlResponse<T = unknown> =\n | {\n data: T;\n errors?: never;\n }\n | {\n data?: never;\n errors: {\n type?: string;\n message: string;\n }[];\n };\n\nconst GithubError = z.object({\n field: z.string().optional(),\n code: z.string().optional(),\n message: z.string().optional(),\n});\n\n/**\n * GitHub usually returns `errors` as an array, but not always - normalize it\n * into an array of error objects, dropping anything that doesn't fit.\n */\nconst GithubErrors = z\n .union([LooseArray(GithubError), GithubError.transform((error) => [error])])\n .catch([]);\n\nfunction handleGotError(\n err: GotLegacyError,\n url: string | URL,\n opts: GithubBaseHttpOptions,\n): Error {\n const path = url.toString();\n let message = err.message || '';\n const body = err.response?.body;\n if (isPlainObject(body) && 'message' in body) {\n message = String(body.message);\n }\n if (\n err.code === 'ERR_HTTP2_STREAM_ERROR' ||\n err.code === 'ENOTFOUND' ||\n err.code === 'ETIMEDOUT' ||\n err.code === 'EAI_AGAIN' ||\n err.code === 'ECONNRESET'\n ) {\n logger.debug({ err }, 'GitHub failure: RequestError');\n return new ExternalHostError(err, 'github');\n }\n if (err.name === 'ParseError') {\n logger.debug({ err }, '');\n return new ExternalHostError(err, 'github');\n }\n if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {\n logger.debug({ err }, 'GitHub failure: 5xx');\n return new ExternalHostError(err, 'github');\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('You have triggered an abuse detection mechanism')\n ) {\n logger.debug({ err }, 'GitHub failure: abuse detection');\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('You have exceeded a secondary rate limit')\n ) {\n logger.warn({ err }, 'GitHub failure: secondary rate limit');\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (err.statusCode === 403 && message.includes('Upgrade to GitHub Pro')) {\n logger.debug(`Endpoint: ${path}, needs paid GitHub plan`);\n return err;\n }\n if (err.statusCode === 403 && message.includes('rate limit exceeded')) {\n logger.debug({ err }, 'GitHub failure: rate limit');\n\n const parsed = parseUrl(baseUrl);\n\n const rule = hostRules.find({ url: baseUrl });\n if (rule.token || rule.password) {\n logger.once.warn(\n 'Rate limit exceeded for api.github.com, even though we are authenticated',\n );\n } else {\n if (parsed?.hostname === 'api.github.com') {\n logger.once.warn(\n {\n documentationUrl: `${GlobalConfig.get('productLinks').documentation}getting-started/running/#githubcom-token-for-changelogs-and-tools`,\n },\n 'Rate limit exceeded for api.github.com, as no hostRules set for this host. Please set a GITHUB_COM_TOKEN',\n );\n } else {\n logger.once.warn(\n { host: parsed!.host },\n 'Rate limit exceeded, as no hostRules set for this host',\n );\n }\n }\n\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('Resource not accessible by integration')\n ) {\n logger.debug(\n { err },\n 'GitHub failure: Resource not accessible by integration',\n );\n return new Error(PLATFORM_INTEGRATION_UNAUTHORIZED);\n }\n if (err.statusCode === 401) {\n // Warn once for github.com token if unauthorized\n const hostname = parseUrl(url)?.hostname;\n // v8 ignore else -- TODO: add test #40625\n if (hostname === 'github.com' || hostname === 'api.github.com') {\n logger.once.warn('github.com token 401 unauthorized');\n }\n if (message.includes('Bad credentials')) {\n const rateLimit = err.headers?.['x-ratelimit-limit'] ?? -1;\n logger.debug(\n {\n token: maskToken(opts.token),\n err,\n },\n 'GitHub failure: Bad credentials',\n );\n if (rateLimit === '60') {\n return new ExternalHostError(err, 'github');\n }\n return new Error(PLATFORM_BAD_CREDENTIALS);\n }\n }\n if (err.statusCode === 422) {\n if (\n message.includes('Review cannot be requested from pull request author')\n ) {\n return err;\n }\n\n const errors = GithubErrors.parse(err.body?.errors);\n if (errors.some((e) => e.field === 'milestone')) {\n return err;\n }\n if (errors.some((e) => e.code === 'invalid')) {\n logger.debug({ err }, 'Received invalid response - aborting');\n return new Error(REPOSITORY_CHANGED);\n }\n if (\n errors.some((e) => e.message?.startsWith('A pull request already exists'))\n ) {\n return err;\n }\n logger.debug({ err }, '422 Error thrown from GitHub');\n return new ExternalHostError(err, 'github');\n }\n if (\n err.statusCode === 410 &&\n err.body?.message === 'Issues are disabled for this repo'\n ) {\n return err;\n }\n return err;\n}\n\ninterface GraphqlPaginatedContent<T = unknown> {\n nodes?: T[];\n edges?: T[];\n pageInfo: { hasNextPage: boolean; endCursor: string };\n}\n\nfunction constructAcceptString(input?: unknown): string {\n const defaultAccept = 'application/vnd.github.v3+json';\n const acceptStrings =\n typeof input === 'string' ? input.split(regEx(/\\s*,\\s*/)) : [];\n\n // TODO: regression of #6736\n // v8 ignore else -- TODO: add test #40625\n if (\n !acceptStrings.some((x) => x === defaultAccept) &&\n (!acceptStrings.some((x) => x.startsWith('application/vnd.github.')) ||\n acceptStrings.length < 2)\n ) {\n acceptStrings.push(defaultAccept);\n }\n return acceptStrings.join(', ');\n}\n\nconst MAX_GRAPHQL_PAGE_SIZE = 100;\n\ninterface GraphqlPageCacheItem {\n pageLastResizedAt: string;\n pageSize: number;\n}\n\nexport type GraphqlPageCache = Record<string, GraphqlPageCacheItem>;\n\nfunction getGraphqlPageSize(\n fieldName: string,\n defaultPageSize = MAX_GRAPHQL_PAGE_SIZE,\n): number {\n const cache = getCache();\n const graphqlPageCache = cache?.platform?.github\n ?.graphqlPageCache as GraphqlPageCache;\n const cachedRecord = graphqlPageCache?.[fieldName];\n\n if (graphqlPageCache && cachedRecord) {\n logger.debug(\n { fieldName, ...cachedRecord },\n 'GraphQL page size: found cached value',\n );\n\n const oldPageSize = cachedRecord.pageSize;\n\n const now = DateTime.local();\n const then = DateTime.fromISO(cachedRecord.pageLastResizedAt);\n const expiry = then.plus({ hours: 24 });\n if (now > expiry) {\n const newPageSize = Math.min(oldPageSize * 2, MAX_GRAPHQL_PAGE_SIZE);\n if (newPageSize < MAX_GRAPHQL_PAGE_SIZE) {\n const timestamp = now.toISO();\n\n logger.debug(\n { fieldName, oldPageSize, newPageSize, timestamp },\n 'GraphQL page size: expanding',\n );\n\n cachedRecord.pageLastResizedAt = timestamp;\n cachedRecord.pageSize = newPageSize;\n } else {\n logger.debug(\n { fieldName, oldPageSize, newPageSize },\n 'GraphQL page size: expanded to default page size',\n );\n\n delete graphqlPageCache[fieldName];\n }\n\n return newPageSize;\n }\n\n return oldPageSize;\n }\n\n return defaultPageSize;\n}\n\nfunction setGraphqlPageSize(fieldName: string, newPageSize: number): void {\n const oldPageSize = getGraphqlPageSize(fieldName);\n if (newPageSize !== oldPageSize) {\n const now = DateTime.local();\n const pageLastResizedAt = now.toISO();\n logger.debug(\n { fieldName, oldPageSize, newPageSize, timestamp: pageLastResizedAt },\n 'GraphQL page size: shrinking',\n );\n const cache = getCache();\n cache.platform ??= {};\n cache.platform.github ??= {};\n cache.platform.github.graphqlPageCache ??= {};\n const graphqlPageCache = cache.platform.github\n .graphqlPageCache as GraphqlPageCache;\n graphqlPageCache[fieldName] = {\n pageLastResizedAt,\n pageSize: newPageSize,\n };\n }\n}\n\nfunction replaceUrlBase(url: URL, baseUrl: string): URL {\n const relativeUrl = `${url.pathname}${url.search}`;\n return new URL(relativeUrl, baseUrl);\n}\n\nexport class GithubHttp extends HttpBase<GithubHttpOptions> {\n protected override get baseUrl(): string | undefined {\n return baseUrl;\n }\n\n constructor(hostType = 'github', options?: HttpOptions) {\n super(hostType, options);\n }\n\n protected override extraOptions(): readonly string[] {\n return super\n .extraOptions()\n .concat([\n 'pageLimit',\n 'paginate',\n 'paginationField',\n 'repository',\n ] as (keyof GithubHttpOptions)[]);\n }\n\n protected override processOptions(\n url: URL,\n opts: InternalHttpOptions & GithubBaseHttpOptions,\n ): void {\n if (!opts.token) {\n // create a mutable copy of `url`\n const authUrl = parseUrl(url.toString())!;\n\n if (opts.repository) {\n // set authUrl to https://api.github.com/repos/org/repo or https://gihub.domain.com/api/v3/repos/org/repo\n authUrl.hash = '';\n authUrl.search = '';\n authUrl.pathname = joinUrlParts(\n authUrl.pathname.startsWith('/api/v3') ? '/api/v3' : '',\n 'repos',\n `${opts.repository}`,\n );\n }\n\n let readOnly = opts.readOnly;\n const { method = 'get' } = opts;\n if (\n readOnly === undefined &&\n ['get', 'head'].includes(method.toLowerCase())\n ) {\n readOnly = true;\n }\n const { token } = findMatchingRule(authUrl.toString(), {\n hostType: this.hostType,\n readOnly,\n });\n opts.token = token;\n }\n\n const accept = constructAcceptString(opts.headers?.accept);\n\n opts.headers = {\n ...opts.headers,\n accept,\n };\n }\n\n protected override handleError(\n url: string | URL,\n opts: HttpOptions,\n err: GotLegacyError,\n ): never {\n throw handleGotError(err, url, opts);\n }\n\n protected override async requestJsonUnsafe<T>(\n method: HttpMethod,\n options: InternalJsonUnsafeOptions<GithubHttpOptions>,\n ): Promise<HttpResponse<T>> {\n const httpOptions = options.httpOptions ?? {};\n const resolvedUrl = this.resolveUrl(options.url, httpOptions);\n const opts = {\n ...options,\n url: resolvedUrl,\n };\n\n const result = await super.requestJsonUnsafe<T>(method, opts);\n if (httpOptions.paginate) {\n delete httpOptions.cacheProvider;\n httpOptions.memCache = false;\n // Check if result is paginated\n const pageLimit = httpOptions.pageLimit ?? 10;\n const linkHeader = parseLinkHeader(result?.headers?.link);\n const next = linkHeader?.next;\n const env = getEnv();\n if (next?.url && linkHeader?.last?.page) {\n let lastPage = parseInt(linkHeader.last.page, 10);\n // v8 ignore else -- TODO: add test #40625\n if (!env.RENOVATE_PAGINATE_ALL && httpOptions.paginate !== 'all') {\n lastPage = Math.min(pageLimit, lastPage);\n }\n const baseUrl = httpOptions.baseUrl ?? this.baseUrl;\n const parsedUrl = new URL(next.url, baseUrl);\n const rebasePagination =\n !!baseUrl &&\n !!env.RENOVATE_X_REBASE_PAGINATION_LINKS &&\n // Preserve github.com URLs for use cases like release notes\n parsedUrl.origin !== 'https://api.github.com';\n const firstPageUrl = rebasePagination\n ? replaceUrlBase(parsedUrl, baseUrl)\n : parsedUrl;\n const queue = [...range(2, lastPage)].map(\n (pageNumber) => (): Promise<HttpResponse<T>> => {\n // copy before modifying searchParams\n const nextUrl = parseUrl(firstPageUrl.toString())!;\n nextUrl.searchParams.set('page', String(pageNumber));\n return super.requestJsonUnsafe<T>(method, {\n ...opts,\n url: nextUrl,\n });\n },\n );\n const pages = await p.all(queue);\n // v8 ignore else -- TODO: add test #40625\n if (httpOptions.paginationField && isPlainObject(result.body)) {\n const paginatedResult = result.body[httpOptions.paginationField];\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(paginatedResult)) {\n for (const nextPage of pages) {\n // v8 ignore else -- TODO: add test #40625\n if (isPlainObject(nextPage.body)) {\n const nextPageResults =\n nextPage.body[httpOptions.paginationField];\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(nextPageResults)) {\n paginatedResult.push(...nextPageResults);\n }\n }\n }\n }\n } else if (isArray<T>(result.body)) {\n for (const nextPage of pages) {\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(nextPage.body)) {\n result.body.push(...nextPage.body);\n }\n }\n }\n }\n }\n return result;\n }\n\n public async requestGraphql<T = unknown>(\n query: string,\n options: GraphqlOptions = {},\n ): Promise<GithubGraphqlResponse<T> | null> {\n const path = 'graphql';\n\n const { paginate, count = MAX_GRAPHQL_PAGE_SIZE, cursor = null } = options;\n let { variables } = options;\n if (paginate) {\n variables = {\n ...variables,\n count,\n cursor,\n };\n }\n const body = variables ? { query, variables } : { query };\n\n const opts: GithubBaseHttpOptions = {\n baseUrl: baseUrl.replace('/v3/', '/'), // GHE uses unversioned graphql path\n body,\n headers: { accept: options?.acceptHeader },\n readOnly: options.readOnly,\n };\n if (options.token) {\n opts.token = options.token;\n }\n logger.trace(`Performing Github GraphQL request`);\n\n try {\n const res = await this.postJson<GithubGraphqlResponse<T>>(path, opts);\n return res?.body;\n } catch (err) {\n logger.debug({ err, query, options }, 'Unexpected GraphQL Error');\n if (err instanceof ExternalHostError && count && count > 10) {\n logger.info('Reducing pagination count to workaround graphql errors');\n return null;\n }\n throw handleGotError(err, path, opts);\n }\n }\n\n async queryRepoField<T = Record<string, unknown>>(\n query: string,\n fieldName: string,\n options: GraphqlOptions = {},\n ): Promise<T[]> {\n const result: T[] = [];\n\n const { paginate = true } = options;\n\n let optimalCount: null | number = null;\n let count = getGraphqlPageSize(\n fieldName,\n options.count ?? MAX_GRAPHQL_PAGE_SIZE,\n );\n let limit = options.limit ?? 1000;\n let cursor: string | null = null;\n\n let isIterating = true;\n while (isIterating) {\n const res = await this.requestGraphql<GithubGraphqlRepoData<T>>(query, {\n ...options,\n count: Math.min(count, limit),\n cursor,\n paginate,\n });\n const repositoryData = res?.data?.repository;\n if (\n isNonEmptyObject(repositoryData) &&\n !isNullOrUndefined(repositoryData[fieldName])\n ) {\n optimalCount = count;\n\n const {\n nodes = [],\n edges = [],\n pageInfo,\n } = repositoryData[fieldName] as GraphqlPaginatedContent<T>;\n result.push(...nodes);\n result.push(...edges);\n\n limit = Math.max(0, limit - nodes.length - edges.length);\n\n if (limit === 0) {\n isIterating = false;\n } else if (paginate && pageInfo) {\n const { hasNextPage, endCursor } = pageInfo;\n if (hasNextPage && endCursor) {\n cursor = endCursor;\n } else {\n isIterating = false;\n }\n }\n } else {\n count = Math.floor(count / 2);\n if (count === 0) {\n logger.warn({ query, options, res }, 'Error fetching GraphQL nodes');\n isIterating = false;\n }\n }\n\n if (!paginate) {\n isIterating = false;\n }\n }\n\n if (optimalCount && optimalCount < MAX_GRAPHQL_PAGE_SIZE) {\n setGraphqlPageSize(fieldName, optimalCount);\n }\n\n return result;\n }\n\n /**\n * Get the raw text file from a URL.\n * Only use this method to fetch text files.\n *\n * @param url Full API URL, contents path or path inside the repository to the file\n * @param options\n *\n * @example url = 'https://api.github.com/repos/renovatebot/renovate/contents/package.json'\n * @example url = 'renovatebot/renovate/contents/package.json'\n * @example url = 'package.json' & options.repository = 'renovatebot/renovate'\n */\n public async getRawTextFile(\n url: string,\n options: InternalHttpOptions & GithubBaseHttpOptions = {},\n ): Promise<HttpResponse> {\n const newOptions: InternalHttpOptions & GithubBaseHttpOptions = {\n ...options,\n headers: {\n accept: 'application/vnd.github.raw+json',\n },\n };\n\n let newURL = url;\n const httpRegex = regEx(/^https?:\\/\\//);\n if (options.repository && !httpRegex.test(options.repository)) {\n newURL = joinUrlParts(options.repository, 'contents', url);\n }\n\n return await this.getText(newURL, newOptions);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"github.js","names":["hostRules.find","p.all"],"sources":["../../../lib/util/http/github.ts"],"sourcesContent":["import {\n isArray,\n isNonEmptyObject,\n isNullOrUndefined,\n isPlainObject,\n} from '@sindresorhus/is';\nimport { DateTime } from 'luxon';\nimport { z } from 'zod/v4';\nimport { GlobalConfig } from '../../config/global.ts';\nimport {\n PLATFORM_BAD_CREDENTIALS,\n PLATFORM_INTEGRATION_UNAUTHORIZED,\n PLATFORM_RATE_LIMIT_EXCEEDED,\n REPOSITORY_CHANGED,\n} from '../../constants/error-messages.ts';\nimport { logger } from '../../logger/index.ts';\nimport { ExternalHostError } from '../../types/errors/external-host-error.ts';\nimport { getCache } from '../cache/repository/index.ts';\nimport { getEnv } from '../env.ts';\nimport * as hostRules from '../host-rules.ts';\nimport { maskToken } from '../mask.ts';\nimport * as p from '../promises.ts';\nimport { range } from '../range.ts';\nimport { regEx } from '../regex.ts';\nimport { LooseArray } from '../schema-utils/index.ts';\nimport { joinUrlParts, parseLinkHeader, parseUrl } from '../url.ts';\nimport { findMatchingRule } from './host-rules.ts';\nimport {\n HttpBase,\n type InternalHttpOptions,\n type InternalJsonUnsafeOptions,\n} from './http.ts';\nimport type { GotLegacyError } from './legacy.ts';\nimport type {\n GraphqlOptions,\n HttpMethod,\n HttpOptions,\n HttpResponse,\n} from './types.ts';\n\nconst githubBaseUrl = 'https://api.github.com/';\nlet baseUrl = githubBaseUrl;\nexport function setBaseUrl(url: string): void {\n baseUrl = url;\n}\n\nexport interface GithubBaseHttpOptions extends HttpOptions {\n repository?: string;\n}\n\nexport interface GithubHttpOptions extends GithubBaseHttpOptions {\n paginate?: boolean | string;\n paginationField?: string;\n pageLimit?: number;\n}\n\ninterface GithubGraphqlRepoData<T = unknown> {\n repository?: T;\n}\n\nexport type GithubGraphqlResponse<T = unknown> =\n | {\n data: T;\n errors?: never;\n }\n | {\n data?: never;\n errors: {\n type?: string;\n message: string;\n }[];\n };\n\nconst GithubError = z.object({\n field: z.string().optional(),\n code: z.string().optional(),\n message: z.string().optional(),\n});\n\n/**\n * GitHub usually returns `errors` as an array, but not always - normalize it\n * into an array of error objects, dropping anything that doesn't fit.\n */\nconst GithubErrors = z\n .union([LooseArray(GithubError), GithubError.transform((error) => [error])])\n .catch([]);\n\nfunction handleGotError(\n err: GotLegacyError,\n url: string | URL,\n opts: GithubBaseHttpOptions,\n): Error {\n const path = url.toString();\n let message = err.message || '';\n const body = err.response?.body;\n if (isPlainObject(body) && 'message' in body) {\n message = String(body.message);\n }\n if (\n err.code === 'ERR_HTTP2_STREAM_ERROR' ||\n err.code === 'ENOTFOUND' ||\n err.code === 'ETIMEDOUT' ||\n err.code === 'EAI_AGAIN' ||\n err.code === 'ECONNRESET'\n ) {\n logger.debug({ err }, 'GitHub failure: RequestError');\n return new ExternalHostError(err, 'github');\n }\n if (err.name === 'ParseError') {\n logger.debug({ err }, '');\n return new ExternalHostError(err, 'github');\n }\n if (err.statusCode && err.statusCode >= 500 && err.statusCode < 600) {\n logger.debug({ err }, 'GitHub failure: 5xx');\n return new ExternalHostError(err, 'github');\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('You have triggered an abuse detection mechanism')\n ) {\n logger.debug({ err }, 'GitHub failure: abuse detection');\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('You have exceeded a secondary rate limit')\n ) {\n logger.warn({ err }, 'GitHub failure: secondary rate limit');\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (err.statusCode === 403 && message.includes('Upgrade to GitHub Pro')) {\n logger.debug(`Endpoint: ${path}, needs paid GitHub plan`);\n return err;\n }\n if (err.statusCode === 403 && message.includes('rate limit exceeded')) {\n logger.debug({ err }, 'GitHub failure: rate limit');\n\n const parsed = parseUrl(baseUrl);\n\n const rule = hostRules.find({ url: baseUrl });\n if (rule.token || rule.password) {\n logger.once.warn(\n 'Rate limit exceeded for api.github.com, even though we are authenticated',\n );\n } else {\n if (parsed?.hostname === 'api.github.com') {\n logger.once.warn(\n {\n documentationUrl: `${GlobalConfig.get('productLinks').documentation}getting-started/running/#githubcom-token-for-changelogs-and-tools`,\n },\n 'Rate limit exceeded for api.github.com, as no hostRules set for this host. Please set a GITHUB_COM_TOKEN',\n );\n } else {\n logger.once.warn(\n { host: parsed!.host },\n 'Rate limit exceeded, as no hostRules set for this host',\n );\n }\n }\n\n return new Error(PLATFORM_RATE_LIMIT_EXCEEDED);\n }\n if (\n err.statusCode === 403 &&\n message.startsWith('Resource not accessible by integration')\n ) {\n logger.debug(\n { err },\n 'GitHub failure: Resource not accessible by integration',\n );\n return new Error(PLATFORM_INTEGRATION_UNAUTHORIZED);\n }\n if (err.statusCode === 401) {\n // Warn once for github.com token if unauthorized\n const hostname = parseUrl(url)?.hostname;\n // v8 ignore else -- TODO: add test #40625\n if (hostname === 'github.com' || hostname === 'api.github.com') {\n logger.once.warn('github.com token 401 unauthorized');\n }\n if (message.includes('Bad credentials')) {\n const rateLimit = err.headers?.['x-ratelimit-limit'] ?? -1;\n logger.debug(\n {\n token: maskToken(opts.token),\n err,\n },\n 'GitHub failure: Bad credentials',\n );\n if (rateLimit === '60') {\n return new ExternalHostError(err, 'github');\n }\n return new Error(PLATFORM_BAD_CREDENTIALS);\n }\n }\n if (err.statusCode === 422) {\n if (\n message.includes('Review cannot be requested from pull request author')\n ) {\n return err;\n }\n\n const errors = GithubErrors.parse(err.body?.errors);\n if (errors.some((e) => e.field === 'milestone')) {\n return err;\n }\n if (errors.some((e) => e.code === 'invalid')) {\n logger.debug({ err }, 'Received invalid response - aborting');\n return new Error(REPOSITORY_CHANGED);\n }\n if (\n errors.some((e) => e.message?.startsWith('A pull request already exists'))\n ) {\n return err;\n }\n logger.debug({ err }, '422 Error thrown from GitHub');\n return new ExternalHostError(err, 'github');\n }\n if (\n err.statusCode === 410 &&\n err.body?.message === 'Issues are disabled for this repo'\n ) {\n return err;\n }\n return err;\n}\n\ninterface GraphqlPaginatedContent<T = unknown> {\n nodes?: T[];\n edges?: T[];\n pageInfo: { hasNextPage: boolean; endCursor: string };\n}\n\nfunction constructAcceptString(input?: unknown): string {\n const defaultAccept = 'application/vnd.github.v3+json';\n const acceptStrings =\n typeof input === 'string' ? input.split(regEx(/\\s*,\\s*/)) : [];\n\n // TODO: regression of #6736\n // v8 ignore else -- TODO: add test #40625\n if (\n !acceptStrings.some((x) => x === defaultAccept) &&\n (!acceptStrings.some((x) => x.startsWith('application/vnd.github.')) ||\n acceptStrings.length < 2)\n ) {\n acceptStrings.push(defaultAccept);\n }\n return acceptStrings.join(', ');\n}\n\nconst MAX_GRAPHQL_PAGE_SIZE = 100;\n\ninterface GraphqlPageCacheItem {\n pageLastResizedAt: string;\n pageSize: number;\n}\n\nexport type GraphqlPageCache = Record<string, GraphqlPageCacheItem>;\n\nfunction getGraphqlPageSize(\n fieldName: string,\n defaultPageSize = MAX_GRAPHQL_PAGE_SIZE,\n): number {\n const cache = getCache();\n const graphqlPageCache = cache?.platform?.github\n ?.graphqlPageCache as GraphqlPageCache;\n const cachedRecord = graphqlPageCache?.[fieldName];\n\n if (graphqlPageCache && cachedRecord) {\n logger.debug(\n { fieldName, ...cachedRecord },\n 'GraphQL page size: found cached value',\n );\n\n const oldPageSize = cachedRecord.pageSize;\n\n const now = DateTime.local();\n const then = DateTime.fromISO(cachedRecord.pageLastResizedAt);\n const expiry = then.plus({ hours: 24 });\n if (now > expiry) {\n const newPageSize = Math.min(oldPageSize * 2, MAX_GRAPHQL_PAGE_SIZE);\n if (newPageSize < MAX_GRAPHQL_PAGE_SIZE) {\n const timestamp = now.toISO();\n\n logger.debug(\n { fieldName, oldPageSize, newPageSize, timestamp },\n 'GraphQL page size: expanding',\n );\n\n cachedRecord.pageLastResizedAt = timestamp;\n cachedRecord.pageSize = newPageSize;\n } else {\n logger.debug(\n { fieldName, oldPageSize, newPageSize },\n 'GraphQL page size: expanded to default page size',\n );\n\n delete graphqlPageCache[fieldName];\n }\n\n return newPageSize;\n }\n\n return oldPageSize;\n }\n\n return defaultPageSize;\n}\n\nfunction setGraphqlPageSize(fieldName: string, newPageSize: number): void {\n const oldPageSize = getGraphqlPageSize(fieldName);\n if (newPageSize !== oldPageSize) {\n const now = DateTime.local();\n const pageLastResizedAt = now.toISO();\n logger.debug(\n { fieldName, oldPageSize, newPageSize, timestamp: pageLastResizedAt },\n 'GraphQL page size: shrinking',\n );\n const cache = getCache();\n cache.platform ??= {};\n cache.platform.github ??= {};\n cache.platform.github.graphqlPageCache ??= {};\n const graphqlPageCache = cache.platform.github\n .graphqlPageCache as GraphqlPageCache;\n graphqlPageCache[fieldName] = {\n pageLastResizedAt,\n pageSize: newPageSize,\n };\n }\n}\n\nfunction replaceUrlBase(url: URL, baseUrl: string): URL {\n const relativeUrl = `${url.pathname}${url.search}`;\n return new URL(relativeUrl, baseUrl);\n}\n\nexport class GithubHttp extends HttpBase<GithubHttpOptions> {\n protected override get baseUrl(): string | undefined {\n return baseUrl;\n }\n\n constructor(hostType = 'github', options?: HttpOptions) {\n super(hostType, options);\n }\n\n protected override extraOptions(): readonly string[] {\n return super\n .extraOptions()\n .concat([\n 'pageLimit',\n 'paginate',\n 'paginationField',\n 'repository',\n ] as (keyof GithubHttpOptions)[]);\n }\n\n protected override processOptions(\n url: URL,\n opts: InternalHttpOptions & GithubBaseHttpOptions,\n ): void {\n if (!opts.token) {\n // create a mutable copy of `url`\n const authUrl = parseUrl(url.toString())!;\n\n if (opts.repository) {\n // set authUrl to https://api.github.com/repos/org/repo or https://gihub.domain.com/api/v3/repos/org/repo\n authUrl.hash = '';\n authUrl.search = '';\n authUrl.pathname = joinUrlParts(\n authUrl.pathname.startsWith('/api/v3') ? '/api/v3' : '',\n 'repos',\n `${opts.repository}`,\n );\n }\n\n let readOnly = opts.readOnly;\n const { method = 'get' } = opts;\n if (\n readOnly === undefined &&\n ['get', 'head'].includes(method.toLowerCase())\n ) {\n readOnly = true;\n }\n const { token } = findMatchingRule(authUrl.toString(), {\n hostType: this.hostType,\n readOnly,\n });\n opts.token = token;\n }\n\n const accept = constructAcceptString(opts.headers?.accept);\n\n opts.headers = {\n ...opts.headers,\n accept,\n };\n }\n\n protected override handleError(\n url: string | URL,\n opts: HttpOptions,\n err: GotLegacyError,\n ): never {\n throw handleGotError(err, url, opts);\n }\n\n protected override async requestJsonUnsafe<T>(\n method: HttpMethod,\n options: InternalJsonUnsafeOptions<GithubHttpOptions>,\n ): Promise<HttpResponse<T>> {\n const httpOptions = options.httpOptions ?? {};\n const resolvedUrl = this.resolveUrl(options.url, httpOptions);\n const opts = {\n ...options,\n url: resolvedUrl,\n };\n\n const result = await super.requestJsonUnsafe<T>(method, opts);\n if (httpOptions.paginate) {\n delete httpOptions.cacheProvider;\n httpOptions.memCache = false;\n // Check if result is paginated\n const pageLimit = httpOptions.pageLimit ?? 10;\n const linkHeader = parseLinkHeader(result?.headers?.link);\n const next = linkHeader?.next;\n const env = getEnv();\n if (next?.url && linkHeader?.last?.page) {\n let lastPage = parseInt(linkHeader.last.page, 10);\n // v8 ignore else -- TODO: add test #40625\n if (!env.RENOVATE_PAGINATE_ALL && httpOptions.paginate !== 'all') {\n lastPage = Math.min(pageLimit, lastPage);\n }\n const baseUrl = httpOptions.baseUrl ?? this.baseUrl;\n const parsedUrl = new URL(next.url, baseUrl);\n const rebasePagination =\n !!baseUrl &&\n !!env.RENOVATE_X_REBASE_PAGINATION_LINKS &&\n // Preserve github.com URLs for use cases like release notes\n parsedUrl.origin !== 'https://api.github.com';\n const firstPageUrl = rebasePagination\n ? replaceUrlBase(parsedUrl, baseUrl)\n : parsedUrl;\n // Don't follow a cross-origin request, unless we've been explicitly requested to do so with `RENOVATE_X_REBASE_PAGINATION_LINKS`\n if (firstPageUrl.origin === resolvedUrl.origin) {\n const queue = [...range(2, lastPage)].map(\n (pageNumber) => (): Promise<HttpResponse<T>> => {\n // copy before modifying searchParams\n const nextUrl = parseUrl(firstPageUrl.toString())!;\n nextUrl.searchParams.set('page', String(pageNumber));\n return super.requestJsonUnsafe<T>(method, {\n ...opts,\n url: nextUrl,\n });\n },\n );\n const pages = await p.all(queue);\n // v8 ignore else -- TODO: add test #40625\n if (httpOptions.paginationField && isPlainObject(result.body)) {\n const paginatedResult = result.body[httpOptions.paginationField];\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(paginatedResult)) {\n for (const nextPage of pages) {\n // v8 ignore else -- TODO: add test #40625\n if (isPlainObject(nextPage.body)) {\n const nextPageResults =\n nextPage.body[httpOptions.paginationField];\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(nextPageResults)) {\n paginatedResult.push(...nextPageResults);\n }\n }\n }\n }\n } else if (isArray<T>(result.body)) {\n for (const nextPage of pages) {\n // v8 ignore else -- TODO: add test #40625\n if (isArray<T>(nextPage.body)) {\n result.body.push(...nextPage.body);\n }\n }\n }\n } else {\n // make sure that users are aware if there are any (potentially malicious, or misconfigured) pagination links being returned\n logger.once.warn(\n {\n requestHost: resolvedUrl.host,\n paginationHost: firstPageUrl.host,\n },\n 'Ignoring cross-origin GitHub pagination link. Set RENOVATE_X_REBASE_PAGINATION_LINKS if this is a self-hosted instance that returns a different host in pagination links.',\n );\n }\n }\n }\n return result;\n }\n\n public async requestGraphql<T = unknown>(\n query: string,\n options: GraphqlOptions = {},\n ): Promise<GithubGraphqlResponse<T> | null> {\n const path = 'graphql';\n\n const { paginate, count = MAX_GRAPHQL_PAGE_SIZE, cursor = null } = options;\n let { variables } = options;\n if (paginate) {\n variables = {\n ...variables,\n count,\n cursor,\n };\n }\n const body = variables ? { query, variables } : { query };\n\n const opts: GithubBaseHttpOptions = {\n baseUrl: baseUrl.replace('/v3/', '/'), // GHE uses unversioned graphql path\n body,\n headers: { accept: options?.acceptHeader },\n readOnly: options.readOnly,\n };\n if (options.token) {\n opts.token = options.token;\n }\n logger.trace(`Performing Github GraphQL request`);\n\n try {\n const res = await this.postJson<GithubGraphqlResponse<T>>(path, opts);\n return res?.body;\n } catch (err) {\n logger.debug({ err, query, options }, 'Unexpected GraphQL Error');\n if (err instanceof ExternalHostError && count && count > 10) {\n logger.info('Reducing pagination count to workaround graphql errors');\n return null;\n }\n throw handleGotError(err, path, opts);\n }\n }\n\n async queryRepoField<T = Record<string, unknown>>(\n query: string,\n fieldName: string,\n options: GraphqlOptions = {},\n ): Promise<T[]> {\n const result: T[] = [];\n\n const { paginate = true } = options;\n\n let optimalCount: null | number = null;\n let count = getGraphqlPageSize(\n fieldName,\n options.count ?? MAX_GRAPHQL_PAGE_SIZE,\n );\n let limit = options.limit ?? 1000;\n let cursor: string | null = null;\n\n let isIterating = true;\n while (isIterating) {\n const res = await this.requestGraphql<GithubGraphqlRepoData<T>>(query, {\n ...options,\n count: Math.min(count, limit),\n cursor,\n paginate,\n });\n const repositoryData = res?.data?.repository;\n if (\n isNonEmptyObject(repositoryData) &&\n !isNullOrUndefined(repositoryData[fieldName])\n ) {\n optimalCount = count;\n\n const {\n nodes = [],\n edges = [],\n pageInfo,\n } = repositoryData[fieldName] as GraphqlPaginatedContent<T>;\n result.push(...nodes);\n result.push(...edges);\n\n limit = Math.max(0, limit - nodes.length - edges.length);\n\n if (limit === 0) {\n isIterating = false;\n } else if (paginate && pageInfo) {\n const { hasNextPage, endCursor } = pageInfo;\n if (hasNextPage && endCursor) {\n cursor = endCursor;\n } else {\n isIterating = false;\n }\n }\n } else {\n count = Math.floor(count / 2);\n if (count === 0) {\n logger.warn({ query, options, res }, 'Error fetching GraphQL nodes');\n isIterating = false;\n }\n }\n\n if (!paginate) {\n isIterating = false;\n }\n }\n\n if (optimalCount && optimalCount < MAX_GRAPHQL_PAGE_SIZE) {\n setGraphqlPageSize(fieldName, optimalCount);\n }\n\n return result;\n }\n\n /**\n * Get the raw text file from a URL.\n * Only use this method to fetch text files.\n *\n * @param url Full API URL, contents path or path inside the repository to the file\n * @param options\n *\n * @example url = 'https://api.github.com/repos/renovatebot/renovate/contents/package.json'\n * @example url = 'renovatebot/renovate/contents/package.json'\n * @example url = 'package.json' & options.repository = 'renovatebot/renovate'\n */\n public async getRawTextFile(\n url: string,\n options: InternalHttpOptions & GithubBaseHttpOptions = {},\n ): Promise<HttpResponse> {\n const newOptions: InternalHttpOptions & GithubBaseHttpOptions = {\n ...options,\n headers: {\n accept: 'application/vnd.github.raw+json',\n },\n };\n\n let newURL = url;\n const httpRegex = regEx(/^https?:\\/\\//);\n if (options.repository && !httpRegex.test(options.repository)) {\n newURL = joinUrlParts(options.repository, 'contents', url);\n }\n\n return await this.getText(newURL, newOptions);\n }\n}\n"],"mappings":"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"}
@@ -40,10 +40,15 @@ var GitlabHttp = class extends HttpBase {
40
40
  nextUrl.protocol = defaultEndpoint.protocol;
41
41
  nextUrl.host = defaultEndpoint.host;
42
42
  }
43
- opts.url = nextUrl;
44
- const nextResult = await this.requestJsonUnsafe(method, opts);
45
- // v8 ignore else -- TODO: add test #40625
46
- if (isArray(nextResult.body)) result.body.push(...nextResult.body);
43
+ if (nextUrl.origin === resolvedUrl.origin) {
44
+ opts.url = nextUrl;
45
+ const nextResult = await this.requestJsonUnsafe(method, opts);
46
+ // v8 ignore else -- TODO: add test #40625
47
+ if (isArray(nextResult.body)) result.body.push(...nextResult.body);
48
+ } else logger.once.warn({
49
+ requestHost: resolvedUrl.host,
50
+ paginationHost: nextUrl.host
51
+ }, "Ignoring cross-origin GitLab pagination link. Set GITLAB_IGNORE_REPO_URL if this is a self-hosted instance that returns a different host in pagination links.");
47
52
  }
48
53
  } catch (err) {
49
54
  logger.warn({ err }, "Pagination error");
@@ -1 +1 @@
1
- {"version":3,"file":"gitlab.js","names":[],"sources":["../../../lib/util/http/gitlab.ts"],"sourcesContent":["import { isArray, isString } from '@sindresorhus/is';\nimport { RequestError, type RetryObject } from 'got';\nimport { logger } from '../../logger/index.ts';\nimport { ExternalHostError } from '../../types/errors/external-host-error.ts';\nimport { getEnv } from '../env.ts';\nimport { parseLinkHeader, parseUrl } from '../url.ts';\nimport { HttpBase, type InternalJsonUnsafeOptions } from './http.ts';\nimport type { HttpMethod, HttpOptions, HttpResponse } from './types.ts';\n\nlet baseUrl = 'https://gitlab.com/api/v4/';\nexport function setBaseUrl(url: string): void {\n baseUrl = url;\n}\n\nexport interface GitlabHttpOptions extends HttpOptions {\n paginate?: boolean;\n}\n\nexport class GitlabHttp extends HttpBase<GitlabHttpOptions> {\n protected override get baseUrl(): string | undefined {\n return baseUrl;\n }\n\n constructor(type = 'gitlab', options?: GitlabHttpOptions) {\n super(type, options);\n }\n\n protected override extraOptions(): readonly string[] {\n return super\n .extraOptions()\n .concat(['paginate'] as (keyof GitlabHttpOptions)[]);\n }\n\n protected override async requestJsonUnsafe<T = unknown>(\n method: HttpMethod,\n options: InternalJsonUnsafeOptions<GitlabHttpOptions>,\n ): Promise<HttpResponse<T>> {\n const resolvedUrl = this.resolveUrl(options.url, options.httpOptions);\n const opts = {\n ...options,\n url: resolvedUrl,\n };\n opts.httpOptions ??= {};\n opts.httpOptions.throwHttpErrors = true;\n\n const result = await super.requestJsonUnsafe<T>(method, opts);\n if (opts.httpOptions.paginate && isArray(result.body)) {\n opts.httpOptions.memCache = false;\n\n // Check if result is paginated\n try {\n const linkHeader = parseLinkHeader(result.headers.link);\n const nextUrl = linkHeader?.next?.url\n ? parseUrl(linkHeader.next.url)\n : null;\n if (nextUrl) {\n if (getEnv().GITLAB_IGNORE_REPO_URL) {\n const defaultEndpoint = parseUrl(baseUrl)!;\n nextUrl.protocol = defaultEndpoint.protocol;\n nextUrl.host = defaultEndpoint.host;\n }\n\n opts.url = nextUrl;\n\n const nextResult = await this.requestJsonUnsafe<T>(method, opts);\n // v8 ignore else -- TODO: add test #40625\n if (isArray(nextResult.body)) {\n result.body.push(...nextResult.body);\n }\n }\n } catch (err) {\n logger.warn({ err }, 'Pagination error');\n }\n }\n return result;\n }\n\n protected override handleError(\n url: string | URL,\n _httpOptions: HttpOptions,\n err: Error,\n ): never {\n if (err instanceof RequestError && err.response?.statusCode) {\n if (err.response.statusCode === 404) {\n logger.trace({ err }, 'GitLab 404');\n logger.debug({ url }, 'GitLab API 404');\n throw err;\n }\n logger.debug({ err }, 'Gitlab API error');\n if (\n err.response.statusCode === 429 ||\n (err.response.statusCode >= 500 && err.response.statusCode < 600)\n ) {\n throw new ExternalHostError(err, 'gitlab');\n }\n }\n const platformFailureCodes = [\n 'EAI_AGAIN',\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'UNABLE_TO_VERIFY_LEAF_SIGNATURE',\n ];\n // TODO: fix test, should be `RequestError`\n if (\n 'code' in err &&\n isString(err.code) &&\n platformFailureCodes.includes(err.code)\n ) {\n throw new ExternalHostError(err, 'gitlab');\n }\n if (err.name === 'ParseError') {\n throw new ExternalHostError(err, 'gitlab');\n }\n throw err;\n }\n\n protected override calculateRetryDelay(retryObject: RetryObject): number {\n const { error, attemptCount, retryOptions } = retryObject;\n if (\n attemptCount <= retryOptions.limit &&\n error.options.method === 'POST' &&\n isRetryablePostError(error)\n ) {\n const noise = Math.random() * 100;\n return 2 ** (attemptCount - 1) * 1000 + noise;\n }\n\n return super.calculateRetryDelay(retryObject);\n }\n}\n\n/**\n * Detects transient GitLab errors on POST requests that are safe to retry:\n *\n * - `409` with a `Resource lock` message, which happens when concurrent\n * requests conflict.\n * - `400` with a `source_branch does not exist` message, which happens when a\n * freshly pushed branch is not yet visible to the API due to Gitaly eventual\n * consistency.\n */\nfunction isRetryablePostError(error: RequestError): boolean {\n const { response } = error;\n if (response?.statusCode === 409) {\n return response.rawBody.toString().includes('Resource lock');\n }\n\n if (response?.statusCode === 400) {\n const rawBody = response.rawBody.toString();\n return (\n rawBody.includes('source_branch') && rawBody.includes('does not exist')\n );\n }\n\n return false;\n}\n"],"mappings":";;;;;;;;AASA,IAAI,UAAU;AACd,SAAgB,WAAW,KAAmB;CAC5C,UAAU;AACZ;AAMA,IAAa,aAAb,cAAgC,SAA4B;CAC1D,IAAuB,UAA8B;EACnD,OAAO;CACT;CAEA,YAAY,OAAO,UAAU,SAA6B;EACxD,MAAM,MAAM,OAAO;CACrB;CAEA,eAAqD;EACnD,OAAO,MACJ,aAAa,CAAC,CACd,OAAO,CAAC,UAAU,CAAgC;CACvD;CAEA,MAAyB,kBACvB,QACA,SAC0B;EAC1B,MAAM,cAAc,KAAK,WAAW,QAAQ,KAAK,QAAQ,WAAW;EACpE,MAAM,OAAO;GACX,GAAG;GACH,KAAK;EACP;EACA,KAAK,gBAAgB,CAAC;EACtB,KAAK,YAAY,kBAAkB;EAEnC,MAAM,SAAS,MAAM,MAAM,kBAAqB,QAAQ,IAAI;EAC5D,IAAI,KAAK,YAAY,YAAY,QAAQ,OAAO,IAAI,GAAG;GACrD,KAAK,YAAY,WAAW;GAG5B,IAAI;IACF,MAAM,aAAa,gBAAgB,OAAO,QAAQ,IAAI;IACtD,MAAM,UAAU,YAAY,MAAM,MAC9B,SAAS,WAAW,KAAK,GAAG,IAC5B;IACJ,IAAI,SAAS;KACX,IAAI,OAAO,CAAC,CAAC,wBAAwB;MACnC,MAAM,kBAAkB,SAAS,OAAO;MACxC,QAAQ,WAAW,gBAAgB;MACnC,QAAQ,OAAO,gBAAgB;KACjC;KAEA,KAAK,MAAM;KAEX,MAAM,aAAa,MAAM,KAAK,kBAAqB,QAAQ,IAAI;;KAE/D,IAAI,QAAQ,WAAW,IAAI,GACzB,OAAO,KAAK,KAAK,GAAG,WAAW,IAAI;IAEvC;GACF,SAAS,KAAK;IACZ,OAAO,KAAK,EAAE,IAAI,GAAG,kBAAkB;GACzC;EACF;EACA,OAAO;CACT;CAEA,YACE,KACA,cACA,KACO;EACP,IAAI,eAAe,gBAAgB,IAAI,UAAU,YAAY;GAC3D,IAAI,IAAI,SAAS,eAAe,KAAK;IACnC,OAAO,MAAM,EAAE,IAAI,GAAG,YAAY;IAClC,OAAO,MAAM,EAAE,IAAI,GAAG,gBAAgB;IACtC,MAAM;GACR;GACA,OAAO,MAAM,EAAE,IAAI,GAAG,kBAAkB;GACxC,IACE,IAAI,SAAS,eAAe,OAC3B,IAAI,SAAS,cAAc,OAAO,IAAI,SAAS,aAAa,KAE7D,MAAM,IAAI,kBAAkB,KAAK,QAAQ;EAE7C;EAQA,IACE,UAAU,OACV,SAAS,IAAI,IAAI,KACjB;GATA;GACA;GACA;GACA;EAMmB,CAAC,CAAC,SAAS,IAAI,IAAI,GAEtC,MAAM,IAAI,kBAAkB,KAAK,QAAQ;EAE3C,IAAI,IAAI,SAAS,cACf,MAAM,IAAI,kBAAkB,KAAK,QAAQ;EAE3C,MAAM;CACR;CAEA,oBAAuC,aAAkC;EACvE,MAAM,EAAE,OAAO,cAAc,iBAAiB;EAC9C,IACE,gBAAgB,aAAa,SAC7B,MAAM,QAAQ,WAAW,UACzB,qBAAqB,KAAK,GAC1B;GACA,MAAM,QAAQ,KAAK,OAAO,IAAI;GAC9B,OAAO,MAAM,eAAe,KAAK,MAAO;EAC1C;EAEA,OAAO,MAAM,oBAAoB,WAAW;CAC9C;AACF;;;;;;;;;;AAWA,SAAS,qBAAqB,OAA8B;CAC1D,MAAM,EAAE,aAAa;CACrB,IAAI,UAAU,eAAe,KAC3B,OAAO,SAAS,QAAQ,SAAS,CAAC,CAAC,SAAS,eAAe;CAG7D,IAAI,UAAU,eAAe,KAAK;EAChC,MAAM,UAAU,SAAS,QAAQ,SAAS;EAC1C,OACE,QAAQ,SAAS,eAAe,KAAK,QAAQ,SAAS,gBAAgB;CAE1E;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"gitlab.js","names":[],"sources":["../../../lib/util/http/gitlab.ts"],"sourcesContent":["import { isArray, isString } from '@sindresorhus/is';\nimport { RequestError, type RetryObject } from 'got';\nimport { logger } from '../../logger/index.ts';\nimport { ExternalHostError } from '../../types/errors/external-host-error.ts';\nimport { getEnv } from '../env.ts';\nimport { parseLinkHeader, parseUrl } from '../url.ts';\nimport { HttpBase, type InternalJsonUnsafeOptions } from './http.ts';\nimport type { HttpMethod, HttpOptions, HttpResponse } from './types.ts';\n\nlet baseUrl = 'https://gitlab.com/api/v4/';\nexport function setBaseUrl(url: string): void {\n baseUrl = url;\n}\n\nexport interface GitlabHttpOptions extends HttpOptions {\n paginate?: boolean;\n}\n\nexport class GitlabHttp extends HttpBase<GitlabHttpOptions> {\n protected override get baseUrl(): string | undefined {\n return baseUrl;\n }\n\n constructor(type = 'gitlab', options?: GitlabHttpOptions) {\n super(type, options);\n }\n\n protected override extraOptions(): readonly string[] {\n return super\n .extraOptions()\n .concat(['paginate'] as (keyof GitlabHttpOptions)[]);\n }\n\n protected override async requestJsonUnsafe<T = unknown>(\n method: HttpMethod,\n options: InternalJsonUnsafeOptions<GitlabHttpOptions>,\n ): Promise<HttpResponse<T>> {\n const resolvedUrl = this.resolveUrl(options.url, options.httpOptions);\n const opts = {\n ...options,\n url: resolvedUrl,\n };\n opts.httpOptions ??= {};\n opts.httpOptions.throwHttpErrors = true;\n\n const result = await super.requestJsonUnsafe<T>(method, opts);\n if (opts.httpOptions.paginate && isArray(result.body)) {\n opts.httpOptions.memCache = false;\n\n // Check if result is paginated\n try {\n const linkHeader = parseLinkHeader(result.headers.link);\n const nextUrl = linkHeader?.next?.url\n ? parseUrl(linkHeader.next.url)\n : null;\n if (nextUrl) {\n if (getEnv().GITLAB_IGNORE_REPO_URL) {\n const defaultEndpoint = parseUrl(baseUrl)!;\n nextUrl.protocol = defaultEndpoint.protocol;\n nextUrl.host = defaultEndpoint.host;\n }\n\n // Don't follow a cross-origin request, unless we've been explicitly requested to do so with `RENOVATE_X_REBASE_PAGINATION_LINKS`\n if (nextUrl.origin === resolvedUrl.origin) {\n opts.url = nextUrl;\n\n const nextResult = await this.requestJsonUnsafe<T>(method, opts);\n // v8 ignore else -- TODO: add test #40625\n if (isArray(nextResult.body)) {\n result.body.push(...nextResult.body);\n }\n } else {\n // make sure that users are aware if there are any (potentially malicious, or misconfigured) pagination links being returned\n logger.once.warn(\n { requestHost: resolvedUrl.host, paginationHost: nextUrl.host },\n 'Ignoring cross-origin GitLab pagination link. Set GITLAB_IGNORE_REPO_URL if this is a self-hosted instance that returns a different host in pagination links.',\n );\n }\n }\n } catch (err) {\n logger.warn({ err }, 'Pagination error');\n }\n }\n return result;\n }\n\n protected override handleError(\n url: string | URL,\n _httpOptions: HttpOptions,\n err: Error,\n ): never {\n if (err instanceof RequestError && err.response?.statusCode) {\n if (err.response.statusCode === 404) {\n logger.trace({ err }, 'GitLab 404');\n logger.debug({ url }, 'GitLab API 404');\n throw err;\n }\n logger.debug({ err }, 'Gitlab API error');\n if (\n err.response.statusCode === 429 ||\n (err.response.statusCode >= 500 && err.response.statusCode < 600)\n ) {\n throw new ExternalHostError(err, 'gitlab');\n }\n }\n const platformFailureCodes = [\n 'EAI_AGAIN',\n 'ECONNRESET',\n 'ETIMEDOUT',\n 'UNABLE_TO_VERIFY_LEAF_SIGNATURE',\n ];\n // TODO: fix test, should be `RequestError`\n if (\n 'code' in err &&\n isString(err.code) &&\n platformFailureCodes.includes(err.code)\n ) {\n throw new ExternalHostError(err, 'gitlab');\n }\n if (err.name === 'ParseError') {\n throw new ExternalHostError(err, 'gitlab');\n }\n throw err;\n }\n\n protected override calculateRetryDelay(retryObject: RetryObject): number {\n const { error, attemptCount, retryOptions } = retryObject;\n if (\n attemptCount <= retryOptions.limit &&\n error.options.method === 'POST' &&\n isRetryablePostError(error)\n ) {\n const noise = Math.random() * 100;\n return 2 ** (attemptCount - 1) * 1000 + noise;\n }\n\n return super.calculateRetryDelay(retryObject);\n }\n}\n\n/**\n * Detects transient GitLab errors on POST requests that are safe to retry:\n *\n * - `409` with a `Resource lock` message, which happens when concurrent\n * requests conflict.\n * - `400` with a `source_branch does not exist` message, which happens when a\n * freshly pushed branch is not yet visible to the API due to Gitaly eventual\n * consistency.\n */\nfunction isRetryablePostError(error: RequestError): boolean {\n const { response } = error;\n if (response?.statusCode === 409) {\n return response.rawBody.toString().includes('Resource lock');\n }\n\n if (response?.statusCode === 400) {\n const rawBody = response.rawBody.toString();\n return (\n rawBody.includes('source_branch') && rawBody.includes('does not exist')\n );\n }\n\n return false;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "renovate",
3
3
  "description": "Automated dependency updates. Flexible so you don't need to be.",
4
- "version": "44.11.2",
4
+ "version": "44.11.3",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "renovate": "dist/renovate.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$id": "https://docs.renovatebot.com/renovate-schema.json",
3
- "title": "JSON schema for Renovate 44.11.2 config files (https://renovatebot.com/)",
3
+ "title": "JSON schema for Renovate 44.11.3 config files (https://renovatebot.com/)",
4
4
  "$schema": "http://json-schema.org/draft-07/schema#",
5
- "x-renovate-version": "44.11.2",
5
+ "x-renovate-version": "44.11.3",
6
6
  "allowComments": true,
7
7
  "type": "object",
8
8
  "definitions": {