diff --git a/lib/config/validation-helpers/managers.ts b/lib/config/validation-helpers/managers.ts index 0ea28c4d9ae8739a08f1d5e69a0daed6fa3378bc..682489f19a0c0446042eadc72f770b6a6dad5108 100644 --- a/lib/config/validation-helpers/managers.ts +++ b/lib/config/validation-helpers/managers.ts @@ -9,7 +9,7 @@ export function check({ resolvedRule, currentPath, }: CheckManagerArgs): ValidationMessage[] { - let managersErrMessage: string; + let managersErrMessage: string | undefined; if (Array.isArray(resolvedRule.matchManagers)) { if ( resolvedRule.matchManagers.find( diff --git a/lib/modules/platform/azure/azure-got-wrapper.ts b/lib/modules/platform/azure/azure-got-wrapper.ts index 0e415611b64b85d23195a7effd2a78fe39ca4c78..aaa337a718b832c5c9865f0e4b98dfd25f9e6c8f 100644 --- a/lib/modules/platform/azure/azure-got-wrapper.ts +++ b/lib/modules/platform/azure/azure-got-wrapper.ts @@ -15,7 +15,9 @@ function getAuthenticationHandler(config: HostRule): IRequestHandler { if (!config.token && config.username && config.password) { return getBasicHandler(config.username, config.password, true); } - return getHandlerFromToken(config.token, true); + // TODO: token can be undefined here + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + return getHandlerFromToken(config.token!, true); } export function azureObj(): azure.WebApi { diff --git a/lib/modules/platform/azure/azure-helper.ts b/lib/modules/platform/azure/azure-helper.ts index 06b32d25792a6794d076217e4b1f498f37f3ad80..04ab5cee5d22289743e45295d9bb57e71add592c 100644 --- a/lib/modules/platform/azure/azure-helper.ts +++ b/lib/modules/platform/azure/azure-helper.ts @@ -42,14 +42,17 @@ export async function getAzureBranchObj( const refs = await getRefs(repoId, fromBranchName); if (refs.length === 0) { logger.debug(`getAzureBranchObj without a valid from, so initial commit.`); + // TODO: fix undefined return { - name: getNewBranchName(branchName), + name: getNewBranchName(branchName)!, oldObjectId: '0000000000000000000000000000000000000000', }; } return { - name: getNewBranchName(branchName), - oldObjectId: refs[0].objectId, + // TODO: fix undefined + name: getNewBranchName(branchName)!, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + oldObjectId: refs[0].objectId!, }; } @@ -110,7 +113,7 @@ export async function getCommitDetails( export async function getMergeMethod( repoId: string, project: string, - branchRef?: string, + branchRef?: string | null, defaultBranch?: string ): Promise<GitPullRequestMergeStrategy> { type Scope = { @@ -133,7 +136,8 @@ export async function getMergeMethod( } return scope.matchKind === 'Exact' ? scope.refName === branchRef - : branchRef.startsWith(scope.refName); + : // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + branchRef.startsWith(scope.refName!); }; const policyConfigurations = ( @@ -141,7 +145,7 @@ export async function getMergeMethod( ) .filter( (p) => - p.settings.scope.some(isRelevantScope) && p.type.id === mergePolicyGuid + p.settings.scope.some(isRelevantScope) && p.type?.id === mergePolicyGuid ) .map((p) => p.settings)[0]; @@ -154,9 +158,15 @@ export async function getMergeMethod( ); try { + // TODO: fix me, wrong types return Object.keys(policyConfigurations) - .map((p) => GitPullRequestMergeStrategy[p.slice(5)]) - .find((p) => p); + .map( + (p) => + GitPullRequestMergeStrategy[ + p.slice(5) as never + ] as never as GitPullRequestMergeStrategy + ) + .find((p) => p)!; } catch (err) { return GitPullRequestMergeStrategy.NoFastForward; } diff --git a/lib/modules/platform/azure/index.ts b/lib/modules/platform/azure/index.ts index 6dd892fbd97a045155456afdba80722eb1c5dfbd..ee62bbfeafb90ea519ac135324f97a6cc11f79a1 100644 --- a/lib/modules/platform/azure/index.ts +++ b/lib/modules/platform/azure/index.ts @@ -113,7 +113,7 @@ export async function getRepos(): Promise<string[]> { logger.debug('Autodiscovering Azure DevOps repositories'); const azureApiGit = await azureApi.gitApi(); const repos = await azureApiGit.getRepositories(); - return repos.map((repo) => `${repo.project.name}/${repo.name}`); + return repos.map((repo) => `${repo.project?.name}/${repo.name}`); } export async function getRawFile( @@ -123,11 +123,11 @@ export async function getRawFile( ): Promise<string | null> { const azureApiGit = await azureApi.gitApi(); - let repoId: string; + let repoId: string | undefined; if (repoName) { const repos = await azureApiGit.getRepositories(); const repo = getRepoByName(repoName, repos); - repoId = repo.id; + repoId = repo?.id; } else { repoId = config.repoId; } @@ -137,7 +137,8 @@ export async function getRawFile( } as GitVersionDescriptor; const buf = await azureApiGit.getItemContent( - repoId, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + repoId!, fileName, undefined, undefined, @@ -159,9 +160,11 @@ export async function getJsonFile( ): Promise<any | null> { const raw = await getRawFile(fileName, repoName, branchOrTag); if (fileName.endsWith('.json5')) { - return JSON5.parse(raw); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + return JSON5.parse(raw!); } - return JSON.parse(raw); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + return JSON.parse(raw!); } export async function initRepo({ @@ -187,8 +190,9 @@ export async function initRepo({ logger.debug('Repo is empty'); throw new Error(REPOSITORY_EMPTY); } - config.repoId = repo.id; - config.project = repo.project.name; + config.repoId = repo.id!; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + config.project = repo.project!.name!; config.owner = '?owner?'; logger.debug(`${repository} owner = ${config.owner}`); const defaultBranch = repo.defaultBranch.replace('refs/heads/', ''); @@ -196,7 +200,8 @@ export async function initRepo({ logger.debug(`${repository} default branch = ${defaultBranch}`); const names = getProjectAndRepo(repository); config.defaultMergeMethod = await azureHelper.getMergeMethod( - repo.id, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + repo.id!, names.project, null, defaultBranch @@ -277,7 +282,8 @@ export async function getPr(pullRequestId: number): Promise<Pr | null> { azurePr.labels = labels .filter((label) => label.active) - .map((label) => label.name); + .map((label) => label.name) + .filter(is.string); azurePr.hasReviewers = is.nonEmptyArray(azurePr.reviewers); return azurePr; } @@ -332,11 +338,14 @@ async function getStatusCheck(branchName: string): Promise<GitStatus[]> { const azureApiGit = await azureApi.gitApi(); const branch = await azureApiGit.getBranch( config.repoId, - getBranchNameWithoutRefsheadsPrefix(branchName) + + // TODO: fix undefined + getBranchNameWithoutRefsheadsPrefix(branchName)! ); // only grab the latest statuses, it will group any by context return azureApiGit.getStatuses( - branch.commit.commitId, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + branch.commit!.commitId!, config.repoId, undefined, undefined, @@ -361,7 +370,8 @@ export async function getBranchStatusCheck( const res = await getStatusCheck(branchName); for (const check of res) { if (getGitStatusContextCombinedName(check.context) === context) { - return azureToRenovateStatusMapping[check.state] || BranchStatus.yellow; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + return azureToRenovateStatusMapping[check.state!] ?? BranchStatus.yellow; } } return null; @@ -429,7 +439,8 @@ export async function createPr({ pr = await azureApiGit.updatePullRequest( { autoCompleteSetBy: { - id: pr.createdBy.id, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + id: pr.createdBy!.id, }, completionOptions: { mergeStrategy: config.defaultMergeMethod, @@ -438,30 +449,36 @@ export async function createPr({ }, }, config.repoId, - pr.pullRequestId + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + pr.pullRequestId! ); } if (platformOptions?.azureAutoApprove) { await azureApiGit.createPullRequestReviewer( { - reviewerUrl: pr.createdBy.url, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + reviewerUrl: pr.createdBy!.url, vote: AzurePrVote.Approved, isFlagged: false, isRequired: false, }, config.repoId, - pr.pullRequestId, - pr.createdBy.id + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + pr.pullRequestId!, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + pr.createdBy!.id! ); } await Promise.all( - labels.map((label) => + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + labels!.map((label) => azureApiGit.createPullRequestLabel( { name: label, }, config.repoId, - pr.pullRequestId + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + pr.pullRequestId! ) ) ); @@ -509,17 +526,17 @@ export async function ensureComment({ const azureApiGit = await azureApi.gitApi(); const threads = await azureApiGit.getThreads(config.repoId, number); - let threadIdFound = null; - let commentIdFound = null; + let threadIdFound: number | undefined; + let commentIdFound: number | undefined; let commentNeedsUpdating = false; threads.forEach((thread) => { - const firstCommentContent = thread.comments[0].content; + const firstCommentContent = thread.comments?.[0].content; if ( (topic && firstCommentContent?.startsWith(header)) || (!topic && firstCommentContent === body) ) { threadIdFound = thread.id; - commentIdFound = thread.comments[0].id; + commentIdFound = thread.comments?.[0].id; commentNeedsUpdating = firstCommentContent !== body; } }); @@ -545,7 +562,8 @@ export async function ensureComment({ config.repoId, number, threadIdFound, - commentIdFound + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + commentIdFound! ); logger.debug( { repository: config.repository, issueNo: number, topic }, @@ -578,13 +596,15 @@ export async function ensureCommentRemoval( if (removeConfig.type === 'by-topic') { const thread = threads.find( (thread: GitPullRequestCommentThread): boolean => - thread.comments[0].content.startsWith(`### ${removeConfig.topic}\n\n`) + !!thread.comments?.[0].content?.startsWith( + `### ${removeConfig.topic}\n\n` + ) ); threadIdFound = thread?.id; } else { const thread = threads.find( (thread: GitPullRequestCommentThread): boolean => - thread.comments[0].content.trim() === removeConfig.content + thread.comments?.[0].content?.trim() === removeConfig.content ); threadIdFound = thread?.id; } @@ -621,7 +641,7 @@ export async function setBranchStatus({ const azureApiGit = await azureApi.gitApi(); const branch = await azureApiGit.getBranch( config.repoId, - getBranchNameWithoutRefsheadsPrefix(branchName) + getBranchNameWithoutRefsheadsPrefix(branchName)! ); const statusToCreate: GitStatus = { description, @@ -631,7 +651,8 @@ export async function setBranchStatus({ }; await azureApiGit.createCommitStatus( statusToCreate, - branch.commit.commitId, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + branch.commit!.commitId!, config.repoId ); logger.trace(`Created commit status of ${state} on branch ${branchName}`); @@ -647,8 +668,10 @@ export async function mergePr({ let pr = await azureApiGit.getPullRequestById(pullRequestId, config.project); const mergeMethod = - config.mergeMethods[pr.targetRefName] ?? - (config.mergeMethods[pr.targetRefName] = await azureHelper.getMergeMethod( + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + config.mergeMethods[pr.targetRefName!] ?? + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + (config.mergeMethods[pr.targetRefName!] = await azureHelper.getMergeMethod( config.repoId, config.project, pr.targetRefName, @@ -669,7 +692,7 @@ export async function mergePr({ `Updating PR ${pullRequestId} to status ${PullRequestStatus.Completed} (${ PullRequestStatus[PullRequestStatus.Completed] }) with lastMergeSourceCommit ${ - pr.lastMergeSourceCommit.commitId + pr.lastMergeSourceCommit?.commitId } using mergeStrategy ${mergeMethod} (${ GitPullRequestMergeStrategy[mergeMethod] })` @@ -702,7 +725,8 @@ export async function mergePr({ { pullRequestId, status: pr.status }, `Expected PR to have status ${ PullRequestStatus[PullRequestStatus.Completed] - }, however it is ${PullRequestStatus[pr.status]}.` + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + }, however it is ${PullRequestStatus[pr.status!]}.` ); } return true; @@ -725,7 +749,7 @@ export function massageMarkdown(input: string): string { /* istanbul ignore next */ export function findIssue(): Promise<Issue | null> { logger.warn(`findIssue() is not implemented`); - return null; + return Promise.resolve(null); } /* istanbul ignore next */ @@ -751,13 +775,16 @@ async function getUserIds(users: string[]): Promise<User[]> { const azureApiCore = await azureApi.coreApi(); const repos = await azureApiGit.getRepositories(); const repo = repos.filter((c) => c.id === config.repoId)[0]; - const teams = await azureApiCore.getTeams(repo.project.id); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const teams = await azureApiCore.getTeams(repo.project!.id!); const members = await Promise.all( teams.map( async (t) => await azureApiCore.getTeamMembersWithExtendedProperties( - repo.project.id, - t.id + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + repo.project!.id!, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + t.id! ) ) ); @@ -767,11 +794,12 @@ async function getUserIds(users: string[]): Promise<User[]> { listMembers.forEach((m) => { users.forEach((r) => { if ( - r.toLowerCase() === m.identity.displayName.toLowerCase() || - r.toLowerCase() === m.identity.uniqueName.toLowerCase() + r.toLowerCase() === m.identity?.displayName?.toLowerCase() || + r.toLowerCase() === m.identity?.uniqueName?.toLowerCase() ) { - if (ids.filter((c) => c.id === m.identity.id).length === 0) { - ids.push({ id: m.identity.id, name: r }); + if (ids.filter((c) => c.id === m.identity?.id).length === 0) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + ids.push({ id: m.identity.id!, name: r }); } } }); @@ -780,9 +808,10 @@ async function getUserIds(users: string[]): Promise<User[]> { teams.forEach((t) => { users.forEach((r) => { - if (r.toLowerCase() === t.name.toLowerCase()) { + if (r.toLowerCase() === t.name?.toLowerCase()) { if (ids.filter((c) => c.id === t.id).length === 0) { - ids.push({ id: t.id, name: r }); + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + ids.push({ id: t.id!, name: r }); } } }); diff --git a/lib/modules/platform/azure/util.ts b/lib/modules/platform/azure/util.ts index d71238b423bcea843a02dc56c4be9605c8cda41b..0730431b7c940a68f84cd50c27f7fb9a2a44063a 100644 --- a/lib/modules/platform/azure/util.ts +++ b/lib/modules/platform/azure/util.ts @@ -11,7 +11,7 @@ import { addSecretForSanitizing } from '../../../util/sanitize'; import { toBase64 } from '../../../util/string'; import type { AzurePr } from './types'; -export function getNewBranchName(branchName?: string): string { +export function getNewBranchName(branchName?: string): string | undefined { if (branchName && !branchName.startsWith('refs/heads/')) { return `refs/heads/${branchName}`; } @@ -19,7 +19,7 @@ export function getNewBranchName(branchName?: string): string { } export function getGitStatusContextCombinedName( - context: GitStatusContext + context: GitStatusContext | null | undefined ): string | undefined { if (!context) { return undefined; @@ -38,11 +38,11 @@ export function getGitStatusContextFromCombinedName( return undefined; } let name = context; - let genre; + let genre: string | undefined; const lastSlash = context.lastIndexOf('/'); if (lastSlash > 0) { - name = context.substr(lastSlash + 1); - genre = context.substr(0, lastSlash); + name = context.substring(lastSlash + 1); + genre = context.substring(0, lastSlash); } return { genre, @@ -51,7 +51,7 @@ export function getGitStatusContextFromCombinedName( } export function getBranchNameWithoutRefsheadsPrefix( - branchPath: string + branchPath: string | undefined ): string | undefined { if (!branchPath) { logger.error(`getBranchNameWithoutRefsheadsPrefix(${branchPath})`); @@ -82,6 +82,11 @@ export function getBranchNameWithoutRefsPrefix( return branchPath.substring(5, branchPath.length); } +const stateMap = { + [PullRequestStatus.Abandoned]: PrState.Closed, + [PullRequestStatus.Completed]: PrState.Merged, +} as Record<PullRequestStatus, PrState | undefined>; + export function getRenovatePRFormat(azurePr: GitPullRequest): AzurePr { const number = azurePr.pullRequestId; const displayNumber = `Pull Request #${number}`; @@ -95,11 +100,8 @@ export function getRenovatePRFormat(azurePr: GitPullRequest): AzurePr { const body = azurePr.description; const createdAt = azurePr.creationDate?.toISOString(); - const state = - { - [PullRequestStatus.Abandoned]: PrState.Closed, - [PullRequestStatus.Completed]: PrState.Merged, - }[azurePr.status] || PrState.Open; + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + const state = stateMap[azurePr.status!] ?? PrState.Open; const sourceRefName = azurePr.sourceRefName; @@ -135,12 +137,12 @@ export function getStorageExtraCloneOpts(config: HostRule): GitOptions { if (!config.token && config.username && config.password) { authType = 'basic'; authValue = toBase64(`${config.username}:${config.password}`); - } else if (config.token.length === 52) { + } else if (config.token?.length === 52) { authType = 'basic'; authValue = toBase64(`:${config.token}`); } else { authType = 'bearer'; - authValue = config.token; + authValue = config.token!; } addSecretForSanitizing(authValue, 'global'); return { diff --git a/tsconfig.strict.json b/tsconfig.strict.json index 863f94cd1bfae575ba5011611979dcc427d723a3..347d12f7c2066739dc500bdacb69662aeae5a63a 100644 --- a/tsconfig.strict.json +++ b/tsconfig.strict.json @@ -36,14 +36,9 @@ "lib/config/presets/npm/index.ts", "lib/config/presets/util.ts", "lib/config/utils.ts", - "lib/config/validation-helpers/managers.ts", "lib/config/validation.ts", "lib/modules/datasource/github-releases/test/index.ts", "lib/modules/platform/api.ts", - "lib/modules/platform/azure/azure-got-wrapper.ts", - "lib/modules/platform/azure/azure-helper.ts", - "lib/modules/platform/azure/index.ts", - "lib/modules/platform/azure/util.ts", "lib/modules/platform/bitbucket/index.ts", "lib/modules/platform/bitbucket-server/index.ts", "lib/modules/platform/bitbucket-server/utils.ts", @@ -141,12 +136,8 @@ "lib/workers/repository/updates/generate.ts", "test/util.ts", "tools/docs/config.ts", - "tools/docs/manager.ts", - "tools/docs/modules.ts", "tools/docs/platforms.ts", - "tools/docs/presets.ts", "tools/docs/schema.ts", - "tools/docs/versioning.ts", "tools/generate-docs.ts", "tools/generate-schema.ts" ]