fix(eslint): '@typescript-eslint/explicit-function-return-… (#4872)

This commit is contained in:
Michael Kriese 2019-11-26 16:13:07 +01:00 коммит произвёл Rhys Arkins
Родитель d210191fec
Коммит f0d4995fda
44 изменённых файлов: 771 добавлений и 587 удалений

Просмотреть файл

@ -25,6 +25,8 @@ module.exports = {
'prefer-template': 'off',
'no-underscore-dangle': 0,
'@typescript-eslint/explicit-function-return-type': 'error',
// TODO: fix lint
'@typescript-eslint/camelcase': 'off', // disabled until ??
'@typescript-eslint/no-explicit-any': 0,

Просмотреть файл

@ -9,16 +9,22 @@ import { logger } from '../../logger';
import got from '../../util/got';
import * as hostRules from '../../util/host-rules';
import { PkgReleaseConfig, ReleaseResult } from '../common';
import { GotResponse } from '../../platform';
// TODO: add got typings when available
// TODO: replace www-authenticate with https://www.npmjs.com/package/auth-header ?
const ecrRegex = /\d+\.dkr\.ecr\.([-a-z0-9]+)\.amazonaws\.com/;
export interface RegistryRepository {
registry: string;
repository: string;
}
export function getRegistryRepository(
lookupName: string,
registryUrls: string[]
) {
): RegistryRepository {
let registry: string;
const split = lookupName.split('/');
if (split.length > 1 && (split[0].includes('.') || split[0].includes(':'))) {
@ -48,7 +54,10 @@ export function getRegistryRepository(
};
}
function getECRAuthToken(region: string, opts: hostRules.HostRule) {
function getECRAuthToken(
region: string,
opts: hostRules.HostRule
): Promise<string | null> {
const config = { region, accessKeyId: undefined, secretAccessKey: undefined };
if (opts.username && opts.password) {
config.accessKeyId = opts.username;
@ -171,22 +180,22 @@ async function getAuthHeaders(
}
}
function digestFromManifestStr(str: hasha.HashaInput) {
function digestFromManifestStr(str: hasha.HashaInput): string {
return 'sha256:' + hasha(str, { algorithm: 'sha256' });
}
function extractDigestFromResponse(manifestResponse) {
function extractDigestFromResponse(manifestResponse: GotResponse): string {
if (manifestResponse.headers['docker-content-digest'] === undefined) {
return digestFromManifestStr(manifestResponse.body);
}
return manifestResponse.headers['docker-content-digest'];
return manifestResponse.headers['docker-content-digest'] as string;
}
async function getManifestResponse(
registry: string,
repository: string,
tag: string
) {
): Promise<GotResponse> {
logger.debug(`getManifestResponse(${registry}, ${repository}, ${tag})`);
try {
const headers = await getAuthHeaders(registry, repository);
@ -408,12 +417,15 @@ async function getTags(
}
}
export function getConfigResponse(url: string, headers: OutgoingHttpHeaders) {
export function getConfigResponse(
url: string,
headers: OutgoingHttpHeaders
): Promise<GotResponse> {
return got(url, {
headers,
hooks: {
beforeRedirect: [
(options: any) => {
(options: any): void => {
if (
options.search &&
options.search.indexOf('X-Amz-Algorithm') !== -1

Просмотреть файл

@ -66,7 +66,7 @@ export async function getPreset(
}
const cacheNamespace = 'datasource-github';
function getCacheKey(repo: string, type: string) {
function getCacheKey(repo: string, type: string): string {
return `${repo}:${type}`;
}

Просмотреть файл

@ -7,7 +7,9 @@ const glGot = api.get;
const GitLabApiUrl = 'https://gitlab.com/api/v4/projects';
async function getDefaultBranchName(urlEncodedPkgName: string) {
async function getDefaultBranchName(
urlEncodedPkgName: string
): Promise<string> {
const branchesUrl = `${GitLabApiUrl}/${urlEncodedPkgName}/repository/branches`;
type GlBranch = {
default: boolean;
@ -61,7 +63,11 @@ export async function getPreset(
}
const cacheNamespace = 'datasource-gitlab';
function getCacheKey(depHost: string, repo: string, lookupType: string) {
function getCacheKey(
depHost: string,
repo: string,
lookupType: string
): string {
const type = lookupType || 'tags';
return `${depHost}:${repo}:${type}`;
}

Просмотреть файл

@ -74,7 +74,9 @@ async function fetchReleases(
return dep;
}
function getRawReleases(config: PkgReleaseConfig): Promise<ReleaseResult> {
function getRawReleases(
config: PkgReleaseConfig
): Promise<ReleaseResult | null> {
const cacheKey =
cacheNamespace +
config.datasource +
@ -88,7 +90,9 @@ function getRawReleases(config: PkgReleaseConfig): Promise<ReleaseResult> {
return global.repoCache[cacheKey];
}
export async function getPkgReleases(config: PkgReleaseConfig) {
export async function getPkgReleases(
config: PkgReleaseConfig
): Promise<ReleaseResult | null> {
const res = await getRawReleases({
...config,
lookupName: config.lookupName || config.depName,
@ -101,7 +105,7 @@ export async function getPkgReleases(config: PkgReleaseConfig) {
// Filter by version scheme
const version = versioning.get(versionScheme);
// Return a sorted list of valid Versions
function sortReleases(release1: Release, release2: Release) {
function sortReleases(release1: Release, release2: Release): number {
return version.sortVersions(release1.version, release2.version);
}
if (res.releases) {
@ -112,7 +116,7 @@ export async function getPkgReleases(config: PkgReleaseConfig) {
return res;
}
export function supportsDigests(config: DigestConfig) {
export function supportsDigests(config: DigestConfig): boolean {
return !!datasources[config.datasource].getDigest;
}

Просмотреть файл

@ -2,13 +2,13 @@ import url from 'url';
import got from '../../util/got';
import { logger } from '../../logger';
function isMavenCentral(pkgUrl: url.URL | string) {
function isMavenCentral(pkgUrl: url.URL | string): boolean {
return (
(typeof pkgUrl === 'string' ? pkgUrl : pkgUrl.host) === 'central.maven.org'
);
}
function isTemporalError(err: { code: string; statusCode: number }) {
function isTemporalError(err: { code: string; statusCode: number }): boolean {
return (
err.code === 'ECONNRESET' ||
err.statusCode === 429 ||
@ -16,19 +16,19 @@ function isTemporalError(err: { code: string; statusCode: number }) {
);
}
function isHostError(err: { code: string }) {
function isHostError(err: { code: string }): boolean {
return err.code === 'ETIMEDOUT';
}
function isNotFoundError(err: { code: string; statusCode: number }) {
function isNotFoundError(err: { code: string; statusCode: number }): boolean {
return err.code === 'ENOTFOUND' || err.statusCode === 404;
}
function isPermissionsIssue(err: { statusCode: number }) {
function isPermissionsIssue(err: { statusCode: number }): boolean {
return err.statusCode === 401 || err.statusCode === 403;
}
function isConnectionError(err: { code: string }) {
function isConnectionError(err: { code: string }): boolean {
return err.code === 'ECONNREFUSED';
}
@ -42,7 +42,7 @@ export async function downloadHttpProtocol(
hostType,
hooks: {
beforeRedirect: [
(options: any) => {
(options: any): void => {
if (
options.search &&
options.search.indexOf('X-Amz-Algorithm') !== -1

Просмотреть файл

@ -67,7 +67,7 @@ export function addMetaData(
dep?: ReleaseResult,
datasource?: string,
lookupName?: string
) {
): void {
if (!dep) {
return;
}
@ -86,7 +86,7 @@ export function addMetaData(
/**
* @param {string} url
*/
const massageGithubUrl = url => {
const massageGithubUrl = (url: string): string => {
return url
.replace('http:', 'https:')
.replace('www.github.com', 'github.com')

Просмотреть файл

@ -15,12 +15,12 @@ import { Release, ReleaseResult } from '../common';
let memcache = {};
export function resetMemCache() {
export function resetMemCache(): void {
logger.debug('resetMemCache()');
memcache = {};
}
export function resetCache() {
export function resetCache(): void {
resetMemCache();
}

Просмотреть файл

@ -27,7 +27,7 @@ function envReplace(value: any, env = process.env): any {
});
}
export function setNpmrc(input?: string) {
export function setNpmrc(input?: string): void {
if (input) {
if (input === npmrcRaw) {
return;

Просмотреть файл

@ -4,7 +4,7 @@ import { logger } from '../../logger';
import got from '../../util/got';
import { ReleaseResult } from '../common';
function getPkgProp(pkgInfo: XmlElement, propName: string) {
function getPkgProp(pkgInfo: XmlElement, propName: string): string {
return pkgInfo.childNamed('m:properties').childNamed(`d:${propName}`).val;
}

Просмотреть файл

@ -9,7 +9,7 @@ import { ReleaseResult } from '../common';
const defaultNugetFeed = 'https://api.nuget.org/v3/index.json';
const cacheNamespace = 'datasource-nuget';
export function getDefaultFeed() {
export function getDefaultFeed(): string {
return defaultNugetFeed;
}

Просмотреть файл

@ -6,12 +6,12 @@ import parse from 'github-url-from-git';
import pAll from 'p-all';
import { logger } from '../../logger';
import got from '../../util/got';
import got, { GotJSONOptions } from '../../util/got';
import * as hostRules from '../../util/host-rules';
import { PkgReleaseConfig, ReleaseResult } from '../common';
function getHostOpts(url: string) {
const opts: any = {
function getHostOpts(url: string): GotJSONOptions {
const opts: GotJSONOptions = {
json: true,
};
const { username, password } = hostRules.find({ hostType: 'packagist', url });
@ -173,7 +173,9 @@ async function getAllPackages(regUrl: string): Promise<AllPackages | null> {
const { packages, providersUrl, files, includesFiles } = registryMeta;
const providerPackages: Record<string, string> = {};
if (files) {
const queue = files.map(file => () => getPackagistFile(regUrl, file));
const queue = files.map(file => (): Promise<PackagistFile> =>
getPackagistFile(regUrl, file)
);
const resolvedFiles = await pAll(queue, { concurrency: 5 });
for (const res of resolvedFiles) {
for (const [name, val] of Object.entries(res.providers)) {
@ -204,7 +206,7 @@ async function getAllPackages(regUrl: string): Promise<AllPackages | null> {
return allPackages;
}
async function packagistOrgLookup(name: string) {
async function packagistOrgLookup(name: string): Promise<ReleaseResult> {
const cacheNamespace = 'datasource-packagist-org';
const cachedResult = await renovateCache.get<ReleaseResult>(
cacheNamespace,

Просмотреть файл

@ -6,14 +6,14 @@ import { matches } from '../../versioning/pep440';
import got from '../../util/got';
import { PkgReleaseConfig, ReleaseResult } from '../common';
function normalizeName(input: string) {
function normalizeName(input: string): string {
return input.toLowerCase().replace(/(-|\.)/g, '_');
}
function compatibleVersions(
releases: Record<string, { requires_python?: boolean }[]>,
compatibility: Record<string, string>
) {
): string[] {
const versions = Object.keys(releases);
if (!(compatibility && compatibility.python)) {
return versions;

Просмотреть файл

@ -6,7 +6,7 @@ let lastSync = new Date('2000-01-01');
let packageReleases: Record<string, string[]> = Object.create(null); // Because we might need a "constructor" key
let contentLength = 0;
async function updateRubyGemsVersions() {
async function updateRubyGemsVersions(): Promise<void> {
const url = 'https://rubygems.org/versions';
const options = {
headers: {
@ -30,7 +30,7 @@ async function updateRubyGemsVersions() {
return;
}
function processLine(line: string) {
function processLine(line: string): void {
let split: string[];
let pkg: string;
let versions: string;
@ -68,14 +68,14 @@ async function updateRubyGemsVersions() {
lastSync = new Date();
}
function isDataStale() {
function isDataStale(): boolean {
const minutesElapsed = Math.floor(
(new Date().getTime() - lastSync.getTime()) / (60 * 1000)
);
return minutesElapsed >= 5;
}
async function syncVersions() {
async function syncVersions(): Promise<void> {
if (isDataStale()) {
global.updateRubyGemsVersions =
global.updateRubyGemsVersions || updateRubyGemsVersions();

Просмотреть файл

@ -1,3 +1,4 @@
import { OutgoingHttpHeaders } from 'http';
import { logger } from '../../logger';
import got from '../../util/got';
import { maskToken } from '../../util/mask';
@ -9,7 +10,7 @@ const INFO_PATH = '/api/v1/gems';
const VERSIONS_PATH = '/api/v1/versions';
// istanbul ignore next
const processError = ({ err, ...rest }) => {
const processError = ({ err, ...rest }): null => {
const { statusCode, headers = {} } = err;
const data = {
...rest,
@ -33,11 +34,11 @@ const processError = ({ err, ...rest }) => {
return null;
};
const getHeaders = () => {
const getHeaders = (): OutgoingHttpHeaders => {
return { hostType: 'rubygems' };
};
const fetch = async ({ dependency, registry, path }) => {
const fetch = async ({ dependency, registry, path }): Promise<any> => {
const json = true;
const retry = { retries: retriable() };

Просмотреть файл

@ -38,7 +38,7 @@ export type HTTPError = InstanceType<got.GotInstance['HTTPError']>;
export default (numberOfRetries = NUMBER_OF_RETRIES): got.RetryFunction => (
_?: number,
err?: Partial<HTTPError>
) => {
): number => {
if (numberOfRetries === 0) {
return 0;
}

Просмотреть файл

@ -12,7 +12,7 @@ async function resolvePackageReleases(
const indexContent = await downloadHttpProtocol(searchRoot, 'sbt');
if (indexContent) {
const releases: string[] = [];
const parseSubdirs = (content: string) =>
const parseSubdirs = (content: string): string[] =>
parseIndexDir(content, x => {
if (x === artifact) return true;
if (x.indexOf(`${artifact}_native`) === 0) return false;
@ -27,7 +27,7 @@ async function resolvePackageReleases(
) {
searchSubdirs = [`${artifact}_${scalaVersion}`];
}
const parseReleases = (content: string) =>
const parseReleases = (content: string): string[] =>
parseIndexDir(content, x => !/^\.+$/.test(x));
for (const searchSubdir of searchSubdirs) {
const content = await downloadHttpProtocol(
@ -49,9 +49,9 @@ async function resolvePluginReleases(
rootUrl: string,
artifact: string,
scalaVersion: string
) {
): Promise<string[]> {
const searchRoot = `${rootUrl}/${artifact}`;
const parse = (content: string) =>
const parse = (content: string): string[] =>
parseIndexDir(content, x => !/^\.+$/.test(x));
const indexContent = await downloadHttpProtocol(searchRoot, 'sbt');
if (indexContent) {

Просмотреть файл

@ -3,8 +3,8 @@ export const SBT_PLUGINS_REPO =
export function parseIndexDir(
content: string,
filterFn = (x: string) => !/^\.+/.test(x)
) {
filterFn = (x: string): boolean => !/^\.+/.test(x)
): string[] {
const unfiltered = content.match(/(?<=href=['"])[^'"]*(?=\/['"])/g) || [];
return unfiltered.filter(filterFn);
}

Просмотреть файл

@ -4,7 +4,15 @@ import { logger } from '../../logger';
import got from '../../util/got';
import { PkgReleaseConfig, ReleaseResult } from '../common';
function getRegistryRepository(lookupName: string, registryUrls: string[]) {
interface RegistryRepository {
registry: string;
repository: string;
}
function getRegistryRepository(
lookupName: string,
registryUrls: string[]
): RegistryRepository {
let registry: string;
const split = lookupName.split('/');
if (split.length > 3 && split[0].includes('.')) {

Просмотреть файл

@ -76,7 +76,7 @@ export function getDetails(rec: BunyanRecord): string {
.join(',\n')}\n`;
}
export function formatRecord(rec: BunyanRecord) {
export function formatRecord(rec: BunyanRecord): string {
const level = levels[rec.level];
const msg = `${indent(rec.msg)}`;
const meta = getMeta(rec);
@ -96,7 +96,7 @@ export class RenovateStream extends Stream {
}
// istanbul ignore next
write(data: BunyanRecord) {
write(data: BunyanRecord): boolean {
this.emit('data', formatRecord(data));
return true;
}

Просмотреть файл

@ -24,19 +24,19 @@ export class ErrorStream extends Stream {
this.writable = true;
}
write(data: BunyanRecord) {
write(data: BunyanRecord): boolean {
const err = { ...data };
for (const prop of excludeProps) delete err[prop];
this._errors.push(err);
return true;
}
getErrors() {
getErrors(): BunyanRecord[] {
return this._errors;
}
}
function sanitizeValue(value: any, seen = new WeakMap()) {
function sanitizeValue(value: any, seen = new WeakMap()): any {
if (Array.isArray(value)) {
const length = value.length;
const arrayResult = Array(length);
@ -76,7 +76,7 @@ export function withSanitizer(streamConfig): bunyan.Stream {
const stream = streamConfig.stream;
if (stream && stream.writable) {
const write = (chunk: BunyanRecord, enc, cb) => {
const write = (chunk: BunyanRecord, enc, cb): void => {
const raw = sanitizeValue(chunk);
const result =
streamConfig.type === 'raw'

Просмотреть файл

@ -1,10 +1,13 @@
import * as azure from 'azure-devops-node-api';
import { IGitApi } from 'azure-devops-node-api/GitApi';
import { ICoreApi } from 'azure-devops-node-api/CoreApi';
import { IPolicyApi } from 'azure-devops-node-api/PolicyApi';
import * as hostRules from '../../util/host-rules';
const hostType = 'azure';
let endpoint: string;
export function azureObj() {
export function azureObj(): azure.WebApi {
const config = hostRules.find({ hostType, url: endpoint });
if (!(config && config.token)) {
throw new Error(`No token found for azure`);
@ -13,18 +16,18 @@ export function azureObj() {
return new azure.WebApi(endpoint, authHandler);
}
export function gitApi() {
export function gitApi(): Promise<IGitApi> {
return azureObj().getGitApi();
}
export function coreApi() {
export function coreApi(): Promise<ICoreApi> {
return azureObj().getCoreApi();
}
export function policyApi() {
export function policyApi(): Promise<IPolicyApi> {
return azureObj().getPolicyApi();
}
export function setEndpoint(e: string) {
export function setEndpoint(e: string): void {
endpoint = e;
}

Просмотреть файл

@ -1,18 +1,26 @@
import { GitPullRequestMergeStrategy } from 'azure-devops-node-api/interfaces/GitInterfaces';
import {
GitPullRequestMergeStrategy,
GitRef,
GitCommit,
GitPullRequest,
} from 'azure-devops-node-api/interfaces/GitInterfaces';
import * as azureApi from './azure-got-wrapper';
import { logger } from '../../logger';
import { Pr } from '../common';
const mergePolicyGuid = 'fa4e907d-c16b-4a4c-9dfa-4916e5d171ab'; // Magic GUID for merge strategy policy configurations
export function getNewBranchName(branchName?: string) {
export function getNewBranchName(branchName?: string): string {
if (branchName && !branchName.startsWith('refs/heads/')) {
return `refs/heads/${branchName}`;
}
return branchName;
}
export function getBranchNameWithoutRefsheadsPrefix(branchPath: string) {
export function getBranchNameWithoutRefsheadsPrefix(
branchPath: string
): string | undefined {
if (!branchPath) {
logger.error(`getBranchNameWithoutRefsheadsPrefix(${branchPath})`);
return undefined;
@ -26,7 +34,9 @@ export function getBranchNameWithoutRefsheadsPrefix(branchPath: string) {
return branchPath.substring(11, branchPath.length);
}
function getBranchNameWithoutRefsPrefix(branchPath?: string) {
function getBranchNameWithoutRefsPrefix(
branchPath?: string
): string | undefined {
if (!branchPath) {
logger.error(`getBranchNameWithoutRefsPrefix(${branchPath})`);
return undefined;
@ -40,7 +50,10 @@ function getBranchNameWithoutRefsPrefix(branchPath?: string) {
return branchPath.substring(5, branchPath.length);
}
export async function getRefs(repoId: string, branchName?: string) {
export async function getRefs(
repoId: string,
branchName?: string
): Promise<GitRef[]> {
logger.debug(`getRefs(${repoId}, ${branchName})`);
const azureApiGit = await azureApi.gitApi();
const refs = await azureApiGit.getRefs(
@ -51,11 +64,16 @@ export async function getRefs(repoId: string, branchName?: string) {
return refs;
}
export interface AzureBranchObj {
name: string;
oldObjectId: string;
}
export async function getAzureBranchObj(
repoId: string,
branchName: string,
from?: string
) {
): Promise<AzureBranchObj> {
const fromBranchName = getNewBranchName(from);
const refs = await getRefs(repoId, fromBranchName);
if (refs.length === 0) {
@ -71,7 +89,7 @@ export async function getAzureBranchObj(
};
}
async function streamToString(stream: NodeJS.ReadableStream) {
async function streamToString(stream: NodeJS.ReadableStream): Promise<string> {
const chunks: string[] = [];
/* eslint-disable promise/avoid-new */
const p = await new Promise<string>(resolve => {
@ -90,7 +108,7 @@ export async function getFile(
repoId: string,
filePath: string,
branchName: string
) {
): Promise<string | null> {
logger.trace(`getFile(filePath=${filePath}, branchName=${branchName})`);
const azureApiGit = await azureApi.gitApi();
const item = await azureApiGit.getItemText(
@ -129,50 +147,15 @@ export async function getFile(
return null; // no file found
}
export async function getChanges(
files: { name: string; contents: any }[],
repoId: string,
branchName: string
) {
const changes = [];
for (const file of files) {
// Add or update
let changeType = 1;
const fileAlreadyThere = await getFile(repoId, file.name, branchName);
if (fileAlreadyThere) {
changeType = 2;
}
changes.push({
changeType,
item: {
path: file.name,
},
newContent: {
Content: file.contents,
ContentType: 0, // RawText
},
});
}
return changes;
}
export function max4000Chars(str: string) {
export function max4000Chars(str: string): string {
if (str && str.length >= 4000) {
return str.substring(0, 3999);
}
return str;
}
export function getRenovatePRFormat(azurePr: {
pullRequestId: any;
description: any;
status: number;
mergeStatus: number;
targetRefName: string;
}) {
const pr = azurePr as any;
export function getRenovatePRFormat(azurePr: GitPullRequest): Pr {
const pr: Pr = azurePr as any;
pr.displayNumber = `Pull Request #${azurePr.pullRequestId}`;
pr.number = azurePr.pullRequestId;
@ -213,14 +196,19 @@ export function getRenovatePRFormat(azurePr: {
return pr;
}
export async function getCommitDetails(commit: string, repoId: string) {
export async function getCommitDetails(
commit: string,
repoId: string
): Promise<GitCommit> {
logger.debug(`getCommitDetails(${commit}, ${repoId})`);
const azureApiGit = await azureApi.gitApi();
const results = await azureApiGit.getCommit(commit, repoId);
return results;
}
export function getProjectAndRepo(str: string) {
export function getProjectAndRepo(
str: string
): { project: string; repo: string } {
logger.trace(`getProjectAndRepo(${str})`);
const strSplited = str.split(`/`);
if (strSplited.length === 1) {

Просмотреть файл

@ -4,9 +4,16 @@ import * as azureHelper from './azure-helper';
import * as azureApi from './azure-got-wrapper';
import * as hostRules from '../../util/host-rules';
import { appSlug } from '../../config/app-strings';
import GitStorage from '../git/storage';
import GitStorage, { StatusResult, File } from '../git/storage';
import { logger } from '../../logger';
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
import {
PlatformConfig,
RepoParams,
RepoConfig,
Pr,
Issue,
VulnerabilityAlert,
} from '../common';
import { sanitize } from '../../util/sanitize';
import { smartTruncate } from '../utils/pr-body';
@ -37,7 +44,7 @@ export function initPlatform({
}: {
endpoint: string;
token: string;
}) {
}): PlatformConfig {
if (!endpoint) {
throw new Error('Init: You must configure an Azure DevOps endpoint');
}
@ -56,14 +63,14 @@ export function initPlatform({
return platformConfig;
}
export async function getRepos() {
export async function getRepos(): Promise<string[]> {
logger.info('Autodiscovering Azure DevOps repositories');
const azureApiGit = await azureApi.gitApi();
const repos = await azureApiGit.getRepositories();
return repos.map(repo => `${repo.project!.name}/${repo.name}`);
}
async function getBranchCommit(fullBranchName: string) {
async function getBranchCommit(fullBranchName: string): Promise<string> {
const azureApiGit = await azureApi.gitApi();
const commit = await azureApiGit.getBranch(
config.repoId,
@ -77,7 +84,7 @@ export async function initRepo({
localDir,
azureWorkItemId,
optimizeForDisabled,
}: RepoParams) {
}: RepoParams): Promise<RepoConfig> {
logger.debug(`initRepo("${repository}")`);
config = { repository, azureWorkItemId } as any;
const azureApiGit = await azureApi.gitApi();
@ -141,19 +148,21 @@ export async function initRepo({
return repoConfig;
}
export function getRepoForceRebase() {
export function getRepoForceRebase(): boolean {
return false;
}
// Search
export /* istanbul ignore next */ function getFileList(branchName: string) {
export /* istanbul ignore next */ function getFileList(
branchName: string
): Promise<string[]> {
return config.storage.getFileList(branchName);
}
export /* istanbul ignore next */ async function setBaseBranch(
branchName = config.baseBranch
) {
): Promise<void> {
logger.debug(`Setting baseBranch to ${branchName}`);
config.baseBranch = branchName;
delete config.baseCommitSHA;
@ -164,35 +173,39 @@ export /* istanbul ignore next */ async function setBaseBranch(
export /* istanbul ignore next */ function setBranchPrefix(
branchPrefix: string
) {
): Promise<void> {
return config.storage.setBranchPrefix(branchPrefix);
}
// Branch
export /* istanbul ignore next */ function branchExists(branchName: string) {
export /* istanbul ignore next */ function branchExists(
branchName: string
): Promise<boolean> {
return config.storage.branchExists(branchName);
}
export /* istanbul ignore next */ function getAllRenovateBranches(
branchPrefix: string
) {
): Promise<string[]> {
return config.storage.getAllRenovateBranches(branchPrefix);
}
export /* istanbul ignore next */ function isBranchStale(branchName: string) {
export /* istanbul ignore next */ function isBranchStale(
branchName: string
): Promise<boolean> {
return config.storage.isBranchStale(branchName);
}
export /* istanbul ignore next */ function getFile(
filePath: string,
branchName: string
) {
): Promise<string> {
return config.storage.getFile(filePath, branchName);
}
// istanbul ignore next
async function abandonPr(prNo: number) {
async function abandonPr(prNo: number): Promise<void> {
logger.debug(`abandonPr(prNo)(${prNo})`);
const azureApiGit = await azureApi.gitApi();
await azureApiGit.updatePullRequest(
@ -204,7 +217,7 @@ async function abandonPr(prNo: number) {
);
}
export async function getPr(pullRequestId: number) {
export async function getPr(pullRequestId: number): Promise<Pr | null> {
logger.debug(`getPr(${pullRequestId})`);
if (!pullRequestId) {
return null;
@ -231,8 +244,9 @@ export async function findPr(
branchName: string,
prTitle: string | null,
state = 'all'
) {
): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
// TODO: fix typing
let prsFiltered: any[] = [];
try {
const azureApiGit = await azureApi.gitApi();
@ -271,7 +285,7 @@ export async function findPr(
return prsFiltered[0];
}
export async function getBranchPr(branchName: string) {
export async function getBranchPr(branchName: string): Promise<Pr | null> {
logger.debug(`getBranchPr(${branchName})`);
const existingPr = await findPr(branchName, null, 'open');
return existingPr ? getPr(existingPr.pullRequestId) : null;
@ -280,7 +294,7 @@ export async function getBranchPr(branchName: string) {
export /* istanbul ignore next */ async function deleteBranch(
branchName: string,
abandonAssociatedPr = false
) {
): Promise<void> {
await config.storage.deleteBranch(branchName);
if (abandonAssociatedPr) {
const pr = await getBranchPr(branchName);
@ -290,24 +304,28 @@ export /* istanbul ignore next */ async function deleteBranch(
export /* istanbul ignore next */ function getBranchLastCommitTime(
branchName: string
) {
): Promise<Date> {
return config.storage.getBranchLastCommitTime(branchName);
}
export /* istanbul ignore next */ function getRepoStatus() {
export /* istanbul ignore next */ function getRepoStatus(): Promise<
StatusResult
> {
return config.storage.getRepoStatus();
}
export /* istanbul ignore next */ function mergeBranch(branchName: string) {
export /* istanbul ignore next */ function mergeBranch(
branchName: string
): Promise<void> {
return config.storage.mergeBranch(branchName);
}
export /* istanbul ignore next */ function commitFilesToBranch(
branchName: string,
files: any[],
files: File[],
message: string,
parentBranch = config.baseBranch
) {
): Promise<void> {
return config.storage.commitFilesToBranch(
branchName,
files,
@ -316,18 +334,20 @@ export /* istanbul ignore next */ function commitFilesToBranch(
);
}
export /* istanbul ignore next */ function getCommitMessages() {
export /* istanbul ignore next */ function getCommitMessages(): Promise<
string[]
> {
return config.storage.getCommitMessages();
}
export function getPrList() {
export function getPrList(): Pr[] {
return [];
}
export async function getBranchStatusCheck(
branchName: string,
context?: string
) {
): Promise<string> {
logger.trace(`getBranchStatusCheck(${branchName}, ${context})`);
const azureApiGit = await azureApi.gitApi();
const branch = await azureApiGit.getBranch(
@ -343,7 +363,7 @@ export async function getBranchStatusCheck(
export async function getBranchStatus(
branchName: string,
requiredStatusChecks: any
) {
): Promise<string> {
logger.debug(`getBranchStatus(${branchName})`);
if (!requiredStatusChecks) {
// null means disable status checks, so it always succeeds
@ -365,7 +385,7 @@ export async function createPr(
labels: string[],
useDefaultBranch?: boolean,
platformOptions: any = {}
) {
): Promise<Pr> {
const sourceRefName = azureHelper.getNewBranchName(branchName);
const targetRefName = azureHelper.getNewBranchName(
useDefaultBranch ? config.defaultBranch : config.baseBranch
@ -402,6 +422,7 @@ export async function createPr(
pr.pullRequestId!
);
}
// TODO: fixme
await labels.forEach(async label => {
await azureApiGit.createPullRequestLabel(
{
@ -415,7 +436,11 @@ export async function createPr(
return azureHelper.getRenovatePRFormat(pr);
}
export async function updatePr(prNo: number, title: string, body?: string) {
export async function updatePr(
prNo: number,
title: string,
body?: string
): Promise<void> {
logger.debug(`updatePr(${prNo}, ${title}, body)`);
const azureApiGit = await azureApi.gitApi();
const objToUpdate: any = {
@ -431,7 +456,7 @@ export async function ensureComment(
issueNo: number,
topic: string | null,
content: string
) {
): Promise<void> {
logger.debug(`ensureComment(${issueNo}, ${topic}, content)`);
const body = `### ${topic}\n\n${sanitize(content)}`;
const azureApiGit = await azureApi.gitApi();
@ -445,7 +470,10 @@ export async function ensureComment(
);
}
export async function ensureCommentRemoval(issueNo: number, topic: string) {
export async function ensureCommentRemoval(
issueNo: number,
topic: string
): Promise<void> {
logger.debug(`ensureCommentRemoval(issueNo, topic)(${issueNo}, ${topic})`);
if (issueNo) {
const azureApiGit = await azureApi.gitApi();
@ -477,18 +505,18 @@ export function setBranchStatus(
description: string,
state: string,
targetUrl: string
) {
): void {
logger.debug(
`setBranchStatus(${branchName}, ${context}, ${description}, ${state}, ${targetUrl}) - Not supported by Azure DevOps (yet!)`
);
}
export async function mergePr(pr: number) {
export async function mergePr(pr: number): Promise<void> {
logger.info(`mergePr(pr)(${pr}) - Not supported by Azure DevOps (yet!)`);
await null;
}
export function getPrBody(input: string) {
export function getPrBody(input: string): string {
// Remove any HTML we use
return smartTruncate(input, 4000)
.replace(new RegExp(`\n---\n\n.*?<!-- ${appSlug}-rebase -->.*?\n`), '')
@ -498,18 +526,19 @@ export function getPrBody(input: string) {
.replace('</details>', '');
}
export /* istanbul ignore next */ function findIssue() {
export /* istanbul ignore next */ function findIssue(): Issue | null {
logger.warn(`findIssue() is not implemented`);
return null;
}
export /* istanbul ignore next */ function ensureIssue() {
export /* istanbul ignore next */ function ensureIssue(): void {
logger.warn(`ensureIssue() is not implemented`);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
export /* istanbul ignore next */ function ensureIssueClosing() {}
export /* istanbul ignore next */ function ensureIssueClosing(): void {}
export /* istanbul ignore next */ function getIssueList() {
export /* istanbul ignore next */ function getIssueList(): Issue[] {
logger.debug(`getIssueList()`);
// TODO: Needs implementation
return [];
@ -520,7 +549,10 @@ export /* istanbul ignore next */ function getIssueList() {
* @param {number} issueNo
* @param {string[]} assignees
*/
export async function addAssignees(issueNo: number, assignees: string[]) {
export async function addAssignees(
issueNo: number,
assignees: string[]
): Promise<void> {
logger.trace(`addAssignees(${issueNo}, ${assignees})`);
await ensureComment(
issueNo,
@ -534,7 +566,10 @@ export async function addAssignees(issueNo: number, assignees: string[]) {
* @param {number} prNo
* @param {string[]} reviewers
*/
export async function addReviewers(prNo: number, reviewers: string[]) {
export async function addReviewers(
prNo: number,
reviewers: string[]
): Promise<void> {
logger.trace(`addReviewers(${prNo}, ${reviewers})`);
const azureApiGit = await azureApi.gitApi();
const azureApiCore = await azureApi.coreApi();
@ -594,25 +629,25 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
export /* istanbul ignore next */ async function deleteLabel(
prNumber: number,
label: string
) {
): Promise<void> {
logger.debug(`Deleting label ${label} from #${prNumber}`);
const azureApiGit = await azureApi.gitApi();
await azureApiGit.deletePullRequestLabels(config.repoId, prNumber, label);
}
// to become async?
export function getPrFiles(prNo: number) {
export function getPrFiles(prNo: number): string[] {
logger.info(
`getPrFiles(prNo)(${prNo}) - Not supported by Azure DevOps (yet!)`
);
return [];
}
export function getVulnerabilityAlerts() {
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
return [];
}
export function cleanRepo() {
export function cleanRepo(): void {
// istanbul ignore if
if (config.storage && config.storage.cleanRepo) {
config.storage.cleanRepo();

Просмотреть файл

@ -1,11 +1,14 @@
import URL from 'url';
import { GotJSONOptions } from 'got';
import got from '../../util/got';
import { GotApi, GotApiOptions } from '../common';
import { GotApi, GotApiOptions, GotResponse } from '../common';
let baseUrl: string;
function get(path: string, options: GotApiOptions & GotJSONOptions) {
function get(
path: string,
options: GotApiOptions & GotJSONOptions
): Promise<GotResponse> {
const url = URL.resolve(baseUrl, path);
const opts: GotApiOptions & GotJSONOptions = {
hostType: 'bitbucket-server',
@ -24,11 +27,11 @@ const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
export const api: GotApi = {} as any;
for (const x of helpers) {
(api as any)[x] = (url: string, opts: any) =>
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}
api.setBaseUrl = (e: string) => {
api.setBaseUrl = (e: string): void => {
baseUrl = e;
};

Просмотреть файл

@ -4,9 +4,17 @@ import delay from 'delay';
import { api } from './bb-got-wrapper';
import * as utils from './utils';
import * as hostRules from '../../util/host-rules';
import GitStorage from '../git/storage';
import GitStorage, { File, StatusResult } from '../git/storage';
import { logger } from '../../logger';
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
import {
PlatformConfig,
RepoParams,
RepoConfig,
Pr,
Issue,
VulnerabilityAlert,
GotResponse,
} from '../common';
import { sanitize } from '../../util/sanitize';
import { smartTruncate } from '../utils/pr-body';
@ -27,7 +35,7 @@ interface BbsConfig {
fileList: any[];
mergeMethod: string;
owner: string;
prList: any[];
prList: Pr[];
projectKey: string;
repository: string;
repositorySlug: string;
@ -45,7 +53,7 @@ const defaults: any = {
};
/* istanbul ignore next */
function updatePrVersion(pr: number, version: number) {
function updatePrVersion(pr: number, version: number): number {
const res = Math.max(config.prVersions.get(pr) || 0, version);
config.prVersions.set(pr, res);
return res;
@ -59,7 +67,7 @@ export function initPlatform({
endpoint: string;
username: string;
password: string;
}) {
}): PlatformConfig {
if (!endpoint) {
throw new Error('Init: You must configure a Bitbucket Server endpoint');
}
@ -78,7 +86,7 @@ export function initPlatform({
}
// Get all repositories that the user has access to
export async function getRepos() {
export async function getRepos(): Promise<string[]> {
logger.info('Autodiscovering Bitbucket Server repositories');
try {
const repos = await utils.accumulateValues(
@ -96,7 +104,7 @@ export async function getRepos() {
}
}
export function cleanRepo() {
export function cleanRepo(): void {
logger.debug(`cleanRepo()`);
if (config.storage) {
config.storage.cleanRepo();
@ -111,7 +119,7 @@ export async function initRepo({
localDir,
optimizeForDisabled,
bbUseDefaultReviewers,
}: RepoParams) {
}: RepoParams): Promise<RepoConfig> {
logger.debug(
`initRepo("${JSON.stringify({ repository, localDir }, null, 2)}")`
);
@ -208,7 +216,7 @@ export async function initRepo({
}
}
export function getRepoForceRebase() {
export function getRepoForceRebase(): boolean {
logger.debug(`getRepoForceRebase()`);
// TODO if applicable
// This function should return true only if the user has enabled a setting on the repo that enforces PRs to be kept up to date with master
@ -217,21 +225,25 @@ export function getRepoForceRebase() {
return false;
}
export async function setBaseBranch(branchName: string = config.defaultBranch) {
export async function setBaseBranch(
branchName: string = config.defaultBranch
): Promise<void> {
config.baseBranch = branchName;
await config.storage.setBaseBranch(branchName);
}
export /* istanbul ignore next */ function setBranchPrefix(
branchPrefix: string
) {
): Promise<void> {
return config.storage.setBranchPrefix(branchPrefix);
}
// Search
// Get full file list
export function getFileList(branchName: string = config.baseBranch) {
export function getFileList(
branchName: string = config.baseBranch
): Promise<string[]> {
logger.debug(`getFileList(${branchName})`);
return config.storage.getFileList(branchName);
}
@ -239,18 +251,21 @@ export function getFileList(branchName: string = config.baseBranch) {
// Branch
// Returns true if branch exists, otherwise false
export function branchExists(branchName: string) {
export function branchExists(branchName: string): Promise<boolean> {
logger.debug(`branchExists(${branchName})`);
return config.storage.branchExists(branchName);
}
export function isBranchStale(branchName: string) {
export function isBranchStale(branchName: string): Promise<boolean> {
logger.debug(`isBranchStale(${branchName})`);
return config.storage.isBranchStale(branchName);
}
// Gets details for a PR
export async function getPr(prNo: number, refreshCache?: boolean) {
export async function getPr(
prNo: number,
refreshCache?: boolean
): Promise<Pr | null> {
logger.debug(`getPr(${prNo})`);
if (!prNo) {
return null;
@ -314,7 +329,7 @@ export async function getPr(prNo: number, refreshCache?: boolean) {
// TODO: coverage
// istanbul ignore next
function matchesState(state: string, desiredState: string) {
function matchesState(state: string, desiredState: string): boolean {
if (desiredState === 'all') {
return true;
}
@ -330,14 +345,14 @@ const isRelevantPr = (
branchName: string,
prTitle: string | null | undefined,
state: string
) => (p: { branchName: string; title: string; state: string }) =>
) => (p: Pr): boolean =>
p.branchName === branchName &&
(!prTitle || p.title === prTitle) &&
matchesState(p.state, state);
// TODO: coverage
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export async function getPrList(_args?: any) {
export async function getPrList(_args?: any): Promise<Pr[]> {
logger.debug(`getPrList()`);
// istanbul ignore next
if (!config.prList) {
@ -365,7 +380,7 @@ export async function findPr(
prTitle?: string,
state = 'all',
refreshCache?: boolean
) {
): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, "${prTitle}", "${state}")`);
const prList = await getPrList({ refreshCache });
const pr = prList.find(isRelevantPr(branchName, prTitle, state));
@ -378,23 +393,28 @@ export async function findPr(
}
// Returns the Pull Request for a branch. Null if not exists.
export async function getBranchPr(branchName: string, refreshCache?: boolean) {
export async function getBranchPr(
branchName: string,
refreshCache?: boolean
): Promise<Pr | null> {
logger.debug(`getBranchPr(${branchName})`);
const existingPr = await findPr(branchName, undefined, 'open');
return existingPr ? getPr(existingPr.number, refreshCache) : null;
}
export function getAllRenovateBranches(branchPrefix: string) {
export function getAllRenovateBranches(
branchPrefix: string
): Promise<string[]> {
logger.debug('getAllRenovateBranches');
return config.storage.getAllRenovateBranches(branchPrefix);
}
export async function commitFilesToBranch(
branchName: string,
files: any[],
files: File[],
message: string,
parentBranch: string = config.baseBranch
) {
): Promise<void> {
logger.debug(
`commitFilesToBranch(${JSON.stringify(
{ branchName, filesLength: files.length, message, parentBranch },
@ -415,12 +435,15 @@ export async function commitFilesToBranch(
await getBranchPr(branchName, true);
}
export function getFile(filePath: string, branchName: string) {
export function getFile(filePath: string, branchName: string): Promise<string> {
logger.debug(`getFile(${filePath}, ${branchName})`);
return config.storage.getFile(filePath, branchName);
}
export async function deleteBranch(branchName: string, closePr = false) {
export async function deleteBranch(
branchName: string,
closePr = false
): Promise<void> {
logger.debug(`deleteBranch(${branchName}, closePr=${closePr})`);
// TODO: coverage
// istanbul ignore next
@ -428,27 +451,29 @@ export async function deleteBranch(branchName: string, closePr = false) {
// getBranchPr
const pr = await getBranchPr(branchName);
if (pr) {
const { body } = await api.post(
const { body } = await api.post<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${pr.number}/decline?version=${pr.version}`
);
updatePrVersion(pr, body);
updatePrVersion(pr.number, body.version);
}
}
return config.storage.deleteBranch(branchName);
}
export function mergeBranch(branchName: string) {
export function mergeBranch(branchName: string): Promise<void> {
logger.debug(`mergeBranch(${branchName})`);
return config.storage.mergeBranch(branchName);
}
export function getBranchLastCommitTime(branchName: string) {
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
logger.debug(`getBranchLastCommitTime(${branchName})`);
return config.storage.getBranchLastCommitTime(branchName);
}
export /* istanbul ignore next */ function getRepoStatus() {
export /* istanbul ignore next */ function getRepoStatus(): Promise<
StatusResult
> {
return config.storage.getRepoStatus();
}
@ -458,7 +483,7 @@ export /* istanbul ignore next */ function getRepoStatus() {
export async function getBranchStatus(
branchName: string,
requiredStatusChecks?: string[] | boolean | null
) {
): Promise<string> {
logger.debug(
`getBranchStatus(${branchName}, requiredStatusChecks=${!!requiredStatusChecks})`
);
@ -495,7 +520,7 @@ export async function getBranchStatus(
export async function getBranchStatusCheck(
branchName: string,
context: string
) {
): Promise<string | null> {
logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);
const branchCommit = await config.storage.getBranchCommit(branchName);
@ -530,7 +555,7 @@ export async function setBranchStatus(
description: string,
state: string | null,
targetUrl?: string
) {
): Promise<void> {
logger.debug(`setBranchStatus(${branchName})`);
const existingStatus = await getBranchStatusCheck(branchName, context);
@ -577,7 +602,9 @@ export async function setBranchStatus(
// return [];
// }
export /* istanbul ignore next */ function findIssue(title: string) {
export /* istanbul ignore next */ function findIssue(
title: string
): Issue | null {
logger.debug(`findIssue(${title})`);
// TODO: Needs implementation
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
@ -588,7 +615,7 @@ export /* istanbul ignore next */ function findIssue(title: string) {
export /* istanbul ignore next */ function ensureIssue(
title: string,
body: string
) {
): Promise<'updated' | 'created' | null> {
logger.warn({ title }, 'Cannot ensure issue');
// TODO: Needs implementation
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
@ -596,13 +623,15 @@ export /* istanbul ignore next */ function ensureIssue(
return null;
}
export /* istanbul ignore next */ function getIssueList() {
export /* istanbul ignore next */ function getIssueList(): Issue[] {
logger.debug(`getIssueList()`);
// TODO: Needs implementation
return [];
}
export /* istanbul ignore next */ function ensureIssueClosing(title: string) {
export /* istanbul ignore next */ function ensureIssueClosing(
title: string
): void {
logger.debug(`ensureIssueClosing(${title})`);
// TODO: Needs implementation
// This is used by Renovate when creating its own issues, e.g. for deprecated package warnings, config error notifications, or "masterIssue"
@ -610,14 +639,17 @@ export /* istanbul ignore next */ function ensureIssueClosing(title: string) {
}
// eslint-disable-next-line no-unused-vars
export function addAssignees(iid: number, assignees: string[]) {
export function addAssignees(iid: number, assignees: string[]): void {
logger.debug(`addAssignees(${iid}, ${assignees})`);
// TODO: Needs implementation
// Currently Renovate does "Create PR" and then "Add assignee" as a two-step process, with this being the second step.
// BB Server doesnt support assignees
}
export async function addReviewers(prNo: number, reviewers: string[]) {
export async function addReviewers(
prNo: number,
reviewers: string[]
): Promise<void> {
logger.debug(`Adding reviewers ${reviewers} to #${prNo}`);
try {
@ -653,13 +685,15 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
}
// eslint-disable-next-line no-unused-vars
export function deleteLabel(issueNo: number, label: string) {
export function deleteLabel(issueNo: number, label: string): void {
logger.debug(`deleteLabel(${issueNo}, ${label})`);
// TODO: Needs implementation
// Only used for the "request Renovate to rebase a PR using a label" feature
}
async function getComments(prNo: number) {
type Comment = { text: string; id: number };
async function getComments(prNo: number): Promise<Comment[]> {
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/activities
let comments = await utils.accumulateValues(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/activities`
@ -670,14 +704,14 @@ async function getComments(prNo: number) {
(a: { action: string; commentAction: string }) =>
a.action === 'COMMENTED' && a.commentAction === 'ADDED'
)
.map((a: { comment: string }) => a.comment);
.map((a: { comment: Comment }) => a.comment);
logger.debug(`Found ${comments.length} comments`);
return comments;
}
async function addComment(prNo: number, text: string) {
async function addComment(prNo: number, text: string): Promise<void> {
// POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments
await api.post(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments`,
@ -687,7 +721,10 @@ async function addComment(prNo: number, text: string) {
);
}
async function getCommentVersion(prNo: number, commentId: number) {
async function getCommentVersion(
prNo: number,
commentId: number
): Promise<number> {
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
const { version } = (await api.get(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`
@ -696,7 +733,11 @@ async function getCommentVersion(prNo: number, commentId: number) {
return version;
}
async function editComment(prNo: number, commentId: number, text: string) {
async function editComment(
prNo: number,
commentId: number,
text: string
): Promise<void> {
const version = await getCommentVersion(prNo, commentId);
// PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
@ -708,7 +749,7 @@ async function editComment(prNo: number, commentId: number, text: string) {
);
}
async function deleteComment(prNo: number, commentId: number) {
async function deleteComment(prNo: number, commentId: number): Promise<void> {
const version = await getCommentVersion(prNo, commentId);
// DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}
@ -721,7 +762,7 @@ export async function ensureComment(
prNo: number,
topic: string | null,
rawContent: string
) {
): Promise<boolean> {
const content = sanitize(rawContent);
try {
const comments = await getComments(prNo);
@ -731,7 +772,7 @@ export async function ensureComment(
if (topic) {
logger.debug(`Ensuring comment "${topic}" in #${prNo}`);
body = `### ${topic}\n\n${content}`;
comments.forEach((comment: { text: string; id: number }) => {
comments.forEach(comment => {
if (comment.text.startsWith(`### ${topic}\n\n`)) {
commentId = comment.id;
commentNeedsUpdating = comment.text !== body;
@ -740,7 +781,7 @@ export async function ensureComment(
} else {
logger.debug(`Ensuring content-only comment in #${prNo}`);
body = `${content}`;
comments.forEach((comment: { text: string; id: number }) => {
comments.forEach(comment => {
if (comment.text === body) {
commentId = comment.id;
commentNeedsUpdating = false;
@ -766,12 +807,15 @@ export async function ensureComment(
}
}
export async function ensureCommentRemoval(prNo: number, topic: string) {
export async function ensureCommentRemoval(
prNo: number,
topic: string
): Promise<void> {
try {
logger.debug(`Ensuring comment "${topic}" in #${prNo} is removed`);
const comments = await getComments(prNo);
let commentId;
comments.forEach((comment: { text: string; id: any }) => {
let commentId: number;
comments.forEach(comment => {
if (comment.text.startsWith(`### ${topic}\n\n`)) {
commentId = comment.id;
}
@ -786,7 +830,8 @@ export async function ensureCommentRemoval(prNo: number, topic: string) {
// Pull Request
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
const escapeHash = (input: string): string =>
input ? input.replace(/#/g, '%23') : input;
export async function createPr(
branchName: string,
@ -794,7 +839,7 @@ export async function createPr(
rawDescription: string,
_labels?: string[] | null,
useDefaultBranch?: boolean
) {
): Promise<Pr> {
const description = sanitize(rawDescription);
logger.debug(`createPr(${branchName}, title=${title})`);
const base = useDefaultBranch ? config.defaultBranch : config.baseBranch;
@ -831,7 +876,7 @@ export async function createPr(
},
reviewers,
};
let prInfoRes;
let prInfoRes: GotResponse;
try {
prInfoRes = await api.post(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,
@ -854,7 +899,7 @@ export async function createPr(
throw err;
}
const pr = {
const pr: Pr = {
id: prInfoRes.body.id,
displayNumber: `Pull Request #${prInfoRes.body.id}`,
isModified: false,
@ -873,24 +918,24 @@ export async function createPr(
// Return a list of all modified files in a PR
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html
export async function getPrFiles(prNo: number) {
export async function getPrFiles(prNo: number): Promise<string[]> {
logger.debug(`getPrFiles(${prNo})`);
if (!prNo) {
return [];
}
// GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/changes
const values = await utils.accumulateValues(
const values = await utils.accumulateValues<{ path: { toString: string } }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/changes?withComments=false`
);
return values.map((f: { path: string }) => f.path.toString);
return values.map(f => f.path.toString);
}
export async function updatePr(
prNo: number,
title: string,
rawDescription: string
) {
): Promise<void> {
const description = sanitize(rawDescription);
logger.debug(`updatePr(${prNo}, title=${title})`);
@ -900,7 +945,7 @@ export async function updatePr(
throw Object.assign(new Error('not-found'), { statusCode: 404 });
}
const { body } = await api.put(
const { body } = await api.put<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,
{
body: {
@ -926,7 +971,10 @@ export async function updatePr(
}
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp261
export async function mergePr(prNo: number, branchName: string) {
export async function mergePr(
prNo: number,
branchName: string
): Promise<boolean> {
logger.debug(`mergePr(${prNo}, ${branchName})`);
// Used for "automerge" feature
try {
@ -934,7 +982,7 @@ export async function mergePr(prNo: number, branchName: string) {
if (!pr) {
throw Object.assign(new Error('not-found'), { statusCode: 404 });
}
const { body } = await api.post(
const { body } = await api.post<{ version: number }>(
`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}`
);
updatePrVersion(prNo, body.version);
@ -956,7 +1004,7 @@ export async function mergePr(prNo: number, branchName: string) {
return true;
}
export function getPrBody(input: string) {
export function getPrBody(input: string): string {
logger.debug(`getPrBody(${input.split('\n')[0]})`);
// Remove any HTML we use
return smartTruncate(input, 30000)
@ -966,12 +1014,12 @@ export function getPrBody(input: string) {
.replace(new RegExp('<!--.*?-->', 'g'), '');
}
export function getCommitMessages() {
export function getCommitMessages(): Promise<string[]> {
logger.debug(`getCommitMessages()`);
return config.storage.getCommitMessages();
}
export function getVulnerabilityAlerts() {
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
logger.debug(`getVulnerabilityAlerts()`);
return [];
}

Просмотреть файл

@ -1,6 +1,7 @@
// SEE for the reference https://github.com/renovatebot/renovate/blob/c3e9e572b225085448d94aa121c7ec81c14d3955/lib/platform/bitbucket/utils.js
import url from 'url';
import { api } from './bb-got-wrapper';
import { Pr } from '../common';
// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp250
const prStateMapping: any = {
@ -9,7 +10,7 @@ const prStateMapping: any = {
OPEN: 'open',
};
export function prInfo(pr: any) {
export function prInfo(pr: any): Pr {
return {
version: pr.version,
number: pr.id,
@ -23,7 +24,7 @@ export function prInfo(pr: any) {
};
}
const addMaxLength = (inputUrl: string, limit = 100) => {
const addMaxLength = (inputUrl: string, limit = 100): string => {
const { search, ...parsedUrl } = url.parse(inputUrl, true); // eslint-disable-line @typescript-eslint/no-unused-vars
const maxedUrl = url.format({
...parsedUrl,
@ -32,13 +33,13 @@ const addMaxLength = (inputUrl: string, limit = 100) => {
return maxedUrl;
};
export async function accumulateValues(
export async function accumulateValues<T = any>(
reqUrl: string,
method = 'get',
options?: any,
limit?: number
) {
let accumulator: any = [];
): Promise<T[]> {
let accumulator: T[] = [];
let nextUrl = addMaxLength(reqUrl, limit);
const lowerCaseMethod = method.toLocaleLowerCase();

Просмотреть файл

@ -1,8 +1,11 @@
import { GotJSONOptions } from 'got';
import got from '../../util/got';
import { GotApi, GotApiOptions } from '../common';
import { GotApi, GotApiOptions, GotResponse } from '../common';
async function get(path: string, options: GotApiOptions & GotJSONOptions) {
async function get(
path: string,
options: GotApiOptions & GotJSONOptions
): Promise<GotResponse> {
const opts: GotApiOptions & GotJSONOptions = {
json: true,
hostType: 'bitbucket',
@ -18,7 +21,7 @@ const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
export const api: GotApi = {} as any;
for (const x of helpers) {
(api as any)[x] = (url: string, opts: any) =>
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}

Просмотреть файл

@ -9,7 +9,10 @@ interface Comment {
export type CommentsConfig = Pick<Config, 'repository'>;
async function getComments(config: CommentsConfig, prNo: number) {
async function getComments(
config: CommentsConfig,
prNo: number
): Promise<Comment[]> {
const comments = await accumulateValues<Comment>(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments`
);
@ -18,7 +21,11 @@ async function getComments(config: CommentsConfig, prNo: number) {
return comments;
}
async function addComment(config: CommentsConfig, prNo: number, raw: string) {
async function addComment(
config: CommentsConfig,
prNo: number,
raw: string
): Promise<void> {
await api.post(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments`,
{
@ -32,7 +39,7 @@ async function editComment(
prNo: number,
commentId: number,
raw: string
) {
): Promise<void> {
await api.put(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments/${commentId}`,
{
@ -45,7 +52,7 @@ async function deleteComment(
config: CommentsConfig,
prNo: number,
commentId: number
) {
): Promise<void> {
await api.delete(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/comments/${commentId}`
);
@ -56,7 +63,7 @@ export async function ensureComment(
prNo: number,
topic: string | null,
content: string
) {
): Promise<boolean> {
try {
const comments = await getComments(config, prNo);
let body: string;
@ -104,11 +111,11 @@ export async function ensureCommentRemoval(
config: CommentsConfig,
prNo: number,
topic: string
) {
): Promise<void> {
try {
logger.debug(`Ensuring comment "${topic}" in #${prNo} is removed`);
const comments = await getComments(config, prNo);
let commentId;
let commentId: number;
comments.forEach(comment => {
if (comment.content.raw.startsWith(`### ${topic}\n\n`)) {
commentId = comment.id;

Просмотреть файл

@ -4,11 +4,18 @@ import { api } from './bb-got-wrapper';
import * as utils from './utils';
import * as hostRules from '../../util/host-rules';
import { logger } from '../../logger';
import GitStorage from '../git/storage';
import GitStorage, { StatusResult, File } from '../git/storage';
import { readOnlyIssueBody } from '../utils/read-only-issue-body';
import { appSlug } from '../../config/app-strings';
import * as comments from './comments';
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
import {
PlatformConfig,
RepoParams,
RepoConfig,
Pr,
Issue,
VulnerabilityAlert,
} from '../common';
import { sanitize } from '../../util/sanitize';
import { smartTruncate } from '../utils/pr-body';
@ -22,7 +29,7 @@ export function initPlatform({
endpoint?: string;
username: string;
password: string;
}) {
}): PlatformConfig {
if (!(username && password)) {
throw new Error(
'Init: You must configure a Bitbucket username and password'
@ -41,13 +48,13 @@ export function initPlatform({
}
// Get all repositories that the user has access to
export async function getRepos() {
export async function getRepos(): Promise<string[]> {
logger.info('Autodiscovering Bitbucket Cloud repositories');
try {
const repos = await utils.accumulateValues(
const repos = await utils.accumulateValues<{ full_name: string }>(
`/2.0/repositories/?role=contributor`
);
return repos.map((repo: { full_name: string }) => repo.full_name);
return repos.map(repo => repo.full_name);
} catch (err) /* istanbul ignore next */ {
logger.error({ err }, `bitbucket getRepos error`);
throw err;
@ -60,7 +67,7 @@ export async function initRepo({
localDir,
optimizeForDisabled,
bbUseDefaultReviewers,
}: RepoParams) {
}: RepoParams): Promise<RepoConfig> {
logger.debug(`initRepo("${repository}")`);
const opts = hostRules.find({
hostType: 'bitbucket',
@ -71,7 +78,7 @@ export async function initRepo({
username: opts!.username,
bbUseDefaultReviewers: bbUseDefaultReviewers !== false,
} as any;
let info;
let info: utils.RepoInfo;
try {
info = utils.repoInfoTransformer(
(await api.get(`/2.0/repositories/${repository}`)).body
@ -133,7 +140,7 @@ export async function initRepo({
}
// Returns true if repository has rule enforcing PRs are up-to-date with base branch before merging
export function getRepoForceRebase() {
export function getRepoForceRebase(): boolean {
// BB doesnt have an option to flag staled branches
return false;
}
@ -141,11 +148,13 @@ export function getRepoForceRebase() {
// Search
// Get full file list
export function getFileList(branchName?: string) {
export function getFileList(branchName?: string): Promise<string[]> {
return config.storage.getFileList(branchName);
}
export async function setBaseBranch(branchName = config.baseBranch) {
export async function setBaseBranch(
branchName = config.baseBranch
): Promise<void> {
logger.debug(`Setting baseBranch to ${branchName}`);
config.baseBranch = branchName;
delete config.baseCommitSHA;
@ -156,31 +165,36 @@ export async function setBaseBranch(branchName = config.baseBranch) {
export /* istanbul ignore next */ function setBranchPrefix(
branchPrefix: string
) {
): Promise<void> {
return config.storage.setBranchPrefix(branchPrefix);
}
// Branch
// Returns true if branch exists, otherwise false
export function branchExists(branchName: string) {
export function branchExists(branchName: string): Promise<boolean> {
return config.storage.branchExists(branchName);
}
export function getAllRenovateBranches(branchPrefix: string) {
export function getAllRenovateBranches(
branchPrefix: string
): Promise<string[]> {
return config.storage.getAllRenovateBranches(branchPrefix);
}
export function isBranchStale(branchName: string) {
export function isBranchStale(branchName: string): Promise<boolean> {
return config.storage.isBranchStale(branchName);
}
export function getFile(filePath: string, branchName?: string) {
export function getFile(
filePath: string,
branchName?: string
): Promise<string> {
return config.storage.getFile(filePath, branchName);
}
// istanbul ignore next
function matchesState(state: string, desiredState: string) {
function matchesState(state: string, desiredState: string): boolean {
if (desiredState === 'all') {
return true;
}
@ -190,7 +204,7 @@ function matchesState(state: string, desiredState: string) {
return state === desiredState;
}
export async function getPrList() {
export async function getPrList(): Promise<Pr[]> {
logger.debug('getPrList()');
if (!config.prList) {
logger.debug('Retrieving PR list');
@ -207,11 +221,11 @@ export async function findPr(
branchName: string,
prTitle?: string | null,
state = 'all'
) {
): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
const prList = await getPrList();
const pr = prList.find(
(p: { branchName: string; title: string; state: string }) =>
p =>
p.branchName === branchName &&
(!prTitle || p.title === prTitle) &&
matchesState(p.state, state)
@ -222,7 +236,10 @@ export async function findPr(
return pr;
}
export async function deleteBranch(branchName: string, closePr?: boolean) {
export async function deleteBranch(
branchName: string,
closePr?: boolean
): Promise<void> {
if (closePr) {
const pr = await findPr(branchName, null, 'open');
if (pr) {
@ -234,25 +251,25 @@ export async function deleteBranch(branchName: string, closePr?: boolean) {
return config.storage.deleteBranch(branchName);
}
export function getBranchLastCommitTime(branchName: string) {
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
return config.storage.getBranchLastCommitTime(branchName);
}
// istanbul ignore next
export function getRepoStatus() {
export function getRepoStatus(): Promise<StatusResult> {
return config.storage.getRepoStatus();
}
export function mergeBranch(branchName: string) {
export function mergeBranch(branchName: string): Promise<void> {
return config.storage.mergeBranch(branchName);
}
export function commitFilesToBranch(
branchName: string,
files: any[],
files: File[],
message: string,
parentBranch = config.baseBranch
) {
): Promise<void> {
return config.storage.commitFilesToBranch(
branchName,
files,
@ -261,11 +278,11 @@ export function commitFilesToBranch(
);
}
export function getCommitMessages() {
export function getCommitMessages(): Promise<string[]> {
return config.storage.getCommitMessages();
}
async function isPrConflicted(prNo: number) {
async function isPrConflicted(prNo: number): Promise<boolean> {
const diff = (await api.get(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/diff`,
{ json: false } as any
@ -275,7 +292,7 @@ async function isPrConflicted(prNo: number) {
}
// Gets details for a PR
export async function getPr(prNo: number) {
export async function getPr(prNo: number): Promise<Pr | null> {
const pr = (await api.get(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}`
)).body;
@ -330,10 +347,11 @@ export async function getPr(prNo: number) {
return res;
}
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
const escapeHash = (input: string): string =>
input ? input.replace(/#/g, '%23') : input;
// Return the commit SHA for a branch
async function getBranchCommit(branchName: string) {
async function getBranchCommit(branchName: string): Promise<string | null> {
try {
const branch = (await api.get(
`/2.0/repositories/${config.repository}/refs/branches/${escapeHash(
@ -348,7 +366,7 @@ async function getBranchCommit(branchName: string) {
}
// Returns the Pull Request for a branch. Null if not exists.
export async function getBranchPr(branchName: string) {
export async function getBranchPr(branchName: string): Promise<Pr | null> {
logger.debug(`getBranchPr(${branchName})`);
const existingPr = await findPr(branchName, null, 'open');
return existingPr ? getPr(existingPr.number) : null;
@ -358,7 +376,7 @@ export async function getBranchPr(branchName: string) {
export async function getBranchStatus(
branchName: string,
requiredStatusChecks?: string[]
) {
): Promise<string> {
logger.debug(`getBranchStatus(${branchName})`);
if (!requiredStatusChecks) {
// null means disable status checks, so it always succeeds
@ -400,7 +418,7 @@ export async function getBranchStatus(
export async function getBranchStatusCheck(
branchName: string,
context: string
) {
): Promise<string | null> {
const sha = await getBranchCommit(branchName);
const statuses = await utils.accumulateValues(
`/2.0/repositories/${config.repository}/commit/${sha}/statuses`
@ -422,7 +440,7 @@ export async function setBranchStatus(
description: string,
state: string,
targetUrl?: string
) {
): Promise<void> {
const sha = await getBranchCommit(branchName);
// TargetUrl can not be empty so default to bitbucket
@ -442,7 +460,9 @@ export async function setBranchStatus(
);
}
async function findOpenIssues(title: string) {
type BbIssue = { id: number; content?: { raw: string } };
async function findOpenIssues(title: string): Promise<BbIssue[]> {
try {
const filter = encodeURIComponent(
[
@ -462,7 +482,7 @@ async function findOpenIssues(title: string) {
}
}
export async function findIssue(title: string) {
export async function findIssue(title: string): Promise<Issue> {
logger.debug(`findIssue(${title})`);
/* istanbul ignore if */
@ -481,7 +501,7 @@ export async function findIssue(title: string) {
};
}
async function closeIssue(issueNumber: number) {
async function closeIssue(issueNumber: number): Promise<void> {
await api.put(
`/2.0/repositories/${config.repository}/issues/${issueNumber}`,
{
@ -490,7 +510,7 @@ async function closeIssue(issueNumber: number) {
);
}
export function getPrBody(input: string) {
export function getPrBody(input: string): string {
// Remove any HTML we use
return smartTruncate(input, 50000)
.replace(/<\/?summary>/g, '**')
@ -499,7 +519,10 @@ export function getPrBody(input: string) {
.replace(/\]\(\.\.\/pull\//g, '](../../pull-requests/');
}
export async function ensureIssue(title: string, body: string) {
export async function ensureIssue(
title: string,
body: string
): Promise<string | null> {
logger.debug(`ensureIssue()`);
const description = getPrBody(sanitize(body));
@ -554,7 +577,9 @@ export async function ensureIssue(title: string, body: string) {
return null;
}
export /* istanbul ignore next */ async function getIssueList() {
export /* istanbul ignore next */ async function getIssueList(): Promise<
Issue[]
> {
logger.debug(`getIssueList()`);
/* istanbul ignore if */
@ -580,7 +605,7 @@ export /* istanbul ignore next */ async function getIssueList() {
}
}
export async function ensureIssueClosing(title: string) {
export async function ensureIssueClosing(title: string): Promise<void> {
/* istanbul ignore if */
if (!config.has_issues) {
logger.debug('Issues are disabled - cannot ensureIssueClosing');
@ -593,13 +618,19 @@ export async function ensureIssueClosing(title: string) {
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function addAssignees(_prNr: number, _assignees: string[]) {
export function addAssignees(
_prNr: number,
_assignees: string[]
): Promise<void> {
// Bitbucket supports "participants" and "reviewers" so does not seem to have the concept of "assignee"
logger.warn('Cannot add assignees');
return Promise.resolve();
}
export async function addReviewers(prId: number, reviewers: string[]) {
export async function addReviewers(
prId: number,
reviewers: string[]
): Promise<void> {
logger.debug(`Adding reviewers ${reviewers} to #${prId}`);
const { title } = await getPr(prId);
@ -614,7 +645,7 @@ export async function addReviewers(prId: number, reviewers: string[]) {
});
}
export /* istanbul ignore next */ function deleteLabel() {
export /* istanbul ignore next */ function deleteLabel(): never {
throw new Error('deleteLabel not implemented');
}
@ -622,12 +653,15 @@ export function ensureComment(
prNo: number,
topic: string | null,
content: string
) {
): Promise<boolean> {
// https://developer.atlassian.com/bitbucket/api/2/reference/search?q=pullrequest+comment
return comments.ensureComment(config, prNo, topic, sanitize(content));
}
export function ensureCommentRemoval(prNo: number, topic: string) {
export function ensureCommentRemoval(
prNo: number,
topic: string
): Promise<void> {
return comments.ensureCommentRemoval(config, prNo, topic);
}
@ -638,7 +672,7 @@ export async function createPr(
description: string,
_labels?: string[],
useDefaultBranch = true
) {
): Promise<Pr> {
// labels is not supported in Bitbucket: https://bitbucket.org/site/master/issues/11976/ability-to-add-labels-to-pull-requests-bb
const base = useDefaultBranch
@ -679,11 +713,12 @@ export async function createPr(
`/2.0/repositories/${config.repository}/pullrequests`,
{ body }
)).body;
const pr = {
// TODO: fix types
const pr: Pr = {
number: prInfo.id,
displayNumber: `Pull Request #${prInfo.id}`,
isModified: false,
};
} as any;
// istanbul ignore if
if (config.prList) {
config.prList.push(pr);
@ -700,7 +735,7 @@ interface Commit {
}
// Return a list of all modified files in a PR
export async function getPrFiles(prNo: number) {
export async function getPrFiles(prNo: number): Promise<string[]> {
logger.debug({ prNo }, 'getPrFiles');
const diff = (await api.get(
`/2.0/repositories/${config.repository}/pullrequests/${prNo}/diff`,
@ -714,14 +749,17 @@ export async function updatePr(
prNo: number,
title: string,
description: string
) {
): Promise<void> {
logger.debug(`updatePr(${prNo}, ${title}, body)`);
await api.put(`/2.0/repositories/${config.repository}/pullrequests/${prNo}`, {
body: { title, description: sanitize(description) },
});
}
export async function mergePr(prNo: number, branchName: string) {
export async function mergePr(
prNo: number,
branchName: string
): Promise<boolean> {
logger.debug(`mergePr(${prNo}, ${branchName})`);
try {
@ -745,7 +783,7 @@ export async function mergePr(prNo: number, branchName: string) {
// Pull Request
export function cleanRepo() {
export function cleanRepo(): void {
// istanbul ignore if
if (config.storage && config.storage.cleanRepo) {
config.storage.cleanRepo();
@ -753,6 +791,6 @@ export function cleanRepo() {
config = {} as any;
}
export function getVulnerabilityAlerts() {
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
return [];
}

Просмотреть файл

@ -1,7 +1,7 @@
import url from 'url';
import { api } from './bb-got-wrapper';
import { Storage } from '../git/storage';
import { GotResponse } from '../common';
import { GotResponse, Pr } from '../common';
export interface Config {
baseBranch: string;
@ -11,7 +11,7 @@ export interface Config {
has_issues: boolean;
mergeMethod: string;
owner: string;
prList: any[];
prList: Pr[];
repository: string;
storage: Storage;
bbUseDefaultReviewers: boolean;
@ -26,7 +26,15 @@ export interface PagedResult<T = any> {
values: T[];
}
export function repoInfoTransformer(repoInfoBody: any) {
export interface RepoInfo {
isFork: boolean;
owner: string;
mainbranch: string;
mergeMethod: string;
has_issues: boolean;
}
export function repoInfoTransformer(repoInfoBody: any): RepoInfo {
return {
isFork: !!repoInfoBody.parent,
owner: repoInfoBody.owner.username,
@ -55,7 +63,7 @@ export const buildStates: {
pending: 'INPROGRESS',
};
const addMaxLength = (inputUrl: string, pagelen = 100) => {
const addMaxLength = (inputUrl: string, pagelen = 100): string => {
const { search, ...parsedUrl } = url.parse(inputUrl, true); // eslint-disable-line @typescript-eslint/no-unused-vars
const maxedUrl = url.format({
...parsedUrl,
@ -69,7 +77,7 @@ export async function accumulateValues<T = any>(
method = 'get',
options?: any,
pagelen?: number
) {
): Promise<T[]> {
let accumulator: T[] = [];
let nextUrl = addMaxLength(reqUrl, pagelen);
const lowerCaseMethod = method.toLocaleLowerCase();
@ -86,7 +94,7 @@ export async function accumulateValues<T = any>(
return accumulator;
}
export /* istanbul ignore next */ function isConflicted(files: any) {
export /* istanbul ignore next */ function isConflicted(files: any): boolean {
for (const file of files) {
for (const chunk of file.chunks) {
for (const change of chunk.changes) {
@ -99,7 +107,7 @@ export /* istanbul ignore next */ function isConflicted(files: any) {
return false;
}
export function prInfo(pr: any) {
export function prInfo(pr: any): Pr {
return {
number: pr.id,
body: pr.summary ? pr.summary.raw : /* istanbul ignore next */ undefined,

Просмотреть файл

@ -1,6 +1,7 @@
import got from 'got';
import Git from 'simple-git/promise';
import { RenovateConfig } from '../config/common';
import { File } from './git/storage';
export interface FileData {
name: string;
@ -77,7 +78,10 @@ export interface RepoParams {
/**
* TODO: Proper typing
*/
export type Pr = any;
export type Pr = { branchName: string; title: string; state: string } & Record<
string,
any
>;
/**
* TODO: Proper typing
@ -158,7 +162,7 @@ export interface Platform {
setBaseBranch(baseBranch: string): Promise<void>;
commitFilesToBranch(
branchName: string,
updatedFiles: any[],
updatedFiles: File[],
commitMessage: string,
parentBranch?: string
): Promise<void>;
@ -173,7 +177,7 @@ export interface Platform {
branchName: string,
requiredStatusChecks?: string[] | null
): Promise<BranchStatus>;
getBranchPr(branchName: string): Promise<Pr>;
getBranchPr(branchName: string): Promise<Pr | null>;
getRepoStatus(): Promise<Git.StatusResult>;
getFile(lockFileName: string, branchName?: string): Promise<string>;
initPlatform(config: RenovateConfig): Promise<PlatformConfig>;

Просмотреть файл

@ -11,6 +11,23 @@ declare module 'fs-extra' {
export function exists(pathLike: string): Promise<boolean>;
}
export type StatusResult = Git.StatusResult;
/**
* File to commit to branch
*/
export interface File {
/**
* Relative file path
*/
name: string;
/**
* file contents
*/
contents: string;
}
interface StorageConfig {
localDir: string;
baseBranch?: string;
@ -21,12 +38,12 @@ interface StorageConfig {
interface LocalConfig extends StorageConfig {
baseBranch: string;
baseBranchSha: string;
branchExists: { [branch: string]: boolean };
branchExists: Record<string, boolean>;
branchPrefix: string;
}
// istanbul ignore next
function checkForPlatformFailure(err: Error) {
function checkForPlatformFailure(err: Error): void {
if (process.env.NODE_ENV === 'test') {
return;
}
@ -47,11 +64,11 @@ function checkForPlatformFailure(err: Error) {
}
}
function localName(branchName: string) {
function localName(branchName: string): string {
return branchName.replace(/^origin\//, '');
}
function throwBaseBranchValidationError(branchName) {
function throwBaseBranchValidationError(branchName: string): never {
const error = new Error('config-validation');
error.validationError = 'baseBranch not found';
error.validationMessage =
@ -66,7 +83,7 @@ export class Storage {
private _cwd: string | undefined;
private async _resetToBranch(branchName: string) {
private async _resetToBranch(branchName: string): Promise<void> {
logger.debug(`resetToBranch(${branchName})`);
await this._git!.raw(['reset', '--hard']);
await this._git!.checkout(branchName);
@ -74,7 +91,7 @@ export class Storage {
await this._git!.raw(['clean', '-fd']);
}
private async _cleanLocalBranches() {
private async _cleanLocalBranches(): Promise<void> {
const existingBranches = (await this._git!.raw(['branch']))
.split('\n')
.map(branch => branch.trim())
@ -86,7 +103,7 @@ export class Storage {
}
}
async initRepo(args: StorageConfig) {
async initRepo(args: StorageConfig): Promise<void> {
this.cleanRepo();
// eslint-disable-next-line no-multi-assign
const config: LocalConfig = (this._config = { ...args } as any);
@ -98,7 +115,7 @@ export class Storage {
let clone = true;
// TODO: move to private class scope
async function determineBaseBranch(git: Git.SimpleGit) {
async function determineBaseBranch(git: Git.SimpleGit): Promise<void> {
// see https://stackoverflow.com/a/44750379/1438522
try {
config.baseBranch =
@ -197,11 +214,11 @@ export class Storage {
}
// istanbul ignore next
getRepoStatus() {
getRepoStatus(): Promise<StatusResult> {
return this._git!.status();
}
async createBranch(branchName: string, sha: string) {
async createBranch(branchName: string, sha: string): Promise<void> {
logger.debug(`createBranch(${branchName})`);
await this._git!.reset('hard');
await this._git!.raw(['clean', '-fd']);
@ -211,7 +228,7 @@ export class Storage {
}
// Return the commit SHA for a branch
async getBranchCommit(branchName: string) {
async getBranchCommit(branchName: string): Promise<string> {
if (!(await this.branchExists(branchName))) {
throw Error(
'Cannot fetch commit for branch that does not exist: ' + branchName
@ -221,7 +238,7 @@ export class Storage {
return res.trim();
}
async getCommitMessages() {
async getCommitMessages(): Promise<string[]> {
logger.debug('getCommitMessages');
const res = await this._git!.log({
n: 10,
@ -230,7 +247,7 @@ export class Storage {
return res.all.map(commit => commit.message);
}
async setBaseBranch(branchName: string) {
async setBaseBranch(branchName: string): Promise<void> {
if (branchName) {
if (!(await this.branchExists(branchName))) {
throwBaseBranchValidationError(branchName);
@ -266,7 +283,7 @@ export class Storage {
* When we initially clone, we clone only the default branch so how no knowledge of other branches existing.
* By calling this function once the repo's branchPrefix is known, we can fetch all of Renovate's branches in one command.
*/
async setBranchPrefix(branchPrefix: string) {
async setBranchPrefix(branchPrefix: string): Promise<void> {
logger.debug('Setting branchPrefix: ' + branchPrefix);
this._config.branchPrefix = branchPrefix;
const ref = `refs/heads/${branchPrefix}*:refs/remotes/origin/${branchPrefix}*`;
@ -278,7 +295,7 @@ export class Storage {
}
}
async getFileList(branchName?: string) {
async getFileList(branchName?: string): Promise<string[]> {
const branch = branchName || this._config.baseBranch;
const exists = await this.branchExists(branch);
if (!exists) {
@ -303,7 +320,7 @@ export class Storage {
);
}
async getSubmodules() {
async getSubmodules(): Promise<string[]> {
return (
(await this._git!.raw([
'config',
@ -318,7 +335,7 @@ export class Storage {
.filter((_e: string, i: number) => i % 2);
}
async branchExists(branchName: string) {
async branchExists(branchName: string): Promise<boolean> {
// First check cache
if (this._config.branchExists[branchName] !== undefined) {
return this._config.branchExists[branchName];
@ -349,14 +366,14 @@ export class Storage {
}
}
async getAllRenovateBranches(branchPrefix: string) {
async getAllRenovateBranches(branchPrefix: string): Promise<string[]> {
const branches = await this._git!.branch(['--remotes', '--verbose']);
return branches.all
.map(localName)
.filter(branchName => branchName.startsWith(branchPrefix));
}
async isBranchStale(branchName: string) {
async isBranchStale(branchName: string): Promise<boolean> {
if (!(await this.branchExists(branchName))) {
throw Error(
'Cannot check staleness for branch that does not exist: ' + branchName
@ -371,11 +388,11 @@ export class Storage {
return !branches.all.map(localName).includes(branchName);
}
private async _deleteLocalBranch(branchName: string) {
private async _deleteLocalBranch(branchName: string): Promise<void> {
await this._git!.branch(['-D', branchName]);
}
async deleteBranch(branchName: string) {
async deleteBranch(branchName: string): Promise<void> {
try {
await this._git!.raw(['push', '--delete', 'origin', branchName]);
logger.debug({ branchName }, 'Deleted remote branch');
@ -394,7 +411,7 @@ export class Storage {
this._config.branchExists[branchName] = false;
}
async mergeBranch(branchName: string) {
async mergeBranch(branchName: string): Promise<void> {
await this._git!.reset('hard');
await this._git!.checkout(['-B', branchName, 'origin/' + branchName]);
await this._git!.checkout(this._config.baseBranch);
@ -403,7 +420,7 @@ export class Storage {
limits.incrementLimit('prCommitsPerRunLimit');
}
async getBranchLastCommitTime(branchName: string) {
async getBranchLastCommitTime(branchName: string): Promise<Date> {
try {
const time = await this._git!.show([
'-s',
@ -417,7 +434,7 @@ export class Storage {
}
}
async getFile(filePath: string, branchName?: string) {
async getFile(filePath: string, branchName?: string): Promise<string | null> {
if (branchName) {
const exists = await this.branchExists(branchName);
if (!exists) {
@ -438,10 +455,10 @@ export class Storage {
async commitFilesToBranch(
branchName: string,
files: any[],
files: File[],
message: string,
parentBranch = this._config.baseBranch
) {
): Promise<void> {
logger.debug(`Committing files to branch ${branchName}`);
try {
await this._git!.reset('hard');
@ -494,7 +511,7 @@ export class Storage {
}
// eslint-disable-next-line
cleanRepo() {}
cleanRepo(): void {}
static getUrl({
protocol,
@ -508,7 +525,7 @@ export class Storage {
hostname?: string;
host?: string;
repository: string;
}) {
}): string {
if (protocol === 'ssh') {
return `git@${hostname}:${repository}.git`;
}

Просмотреть файл

@ -4,7 +4,7 @@ import pAll from 'p-all';
import got from '../../util/got';
import { maskToken } from '../../util/mask';
import { GotApi } from '../common';
import { GotApi, GotResponse } from '../common';
import { logger } from '../../logger';
const hostType = 'github';
@ -14,7 +14,7 @@ async function get(
path: string,
options?: any,
okToRetry = true
): Promise<any> {
): Promise<GotResponse> {
const opts = {
hostType,
baseUrl,
@ -58,7 +58,7 @@ async function get(
new Array(lastPage),
(x, i) => i + 1
).slice(1);
const queue = pageNumbers.map(page => () => {
const queue = pageNumbers.map(page => (): Promise<GotResponse> => {
const nextUrl = URL.parse(linkHeader.next.url, true);
delete nextUrl.search;
nextUrl.query.page = page.toString();
@ -163,11 +163,11 @@ async function get(
const helpers = ['get', 'post', 'put', 'patch', 'head', 'delete'];
for (const x of helpers) {
(get as any)[x] = (url: string, opts: any) =>
(get as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}
get.setBaseUrl = (u: string) => {
get.setBaseUrl = (u: string): void => {
baseUrl = u;
};

Просмотреть файл

@ -6,8 +6,14 @@ import URL from 'url';
import { logger } from '../../logger';
import { api } from './gh-got-wrapper';
import * as hostRules from '../../util/host-rules';
import GitStorage from '../git/storage';
import { PlatformConfig, RepoParams, RepoConfig } from '../common';
import GitStorage, { StatusResult, File } from '../git/storage';
import {
PlatformConfig,
RepoParams,
RepoConfig,
Issue,
VulnerabilityAlert,
} from '../common';
import {
appName,
@ -50,8 +56,8 @@ interface LocalRepoConfig {
parentRepo: string;
baseCommitSHA: string | null;
forkToken?: string;
closedPrList: { [num: number]: Pr } | null;
openPrList: { [num: number]: Pr } | null;
closedPrList: PrList | null;
openPrList: PrList | null;
prList: Pr[] | null;
issueList: any[] | null;
mergeMethod: string;
@ -66,6 +72,9 @@ interface LocalRepoConfig {
renovateUsername: string;
}
type BranchProtection = any;
type PrList = Record<number, Pr>;
let config: LocalRepoConfig = {} as any;
const defaults = {
@ -73,7 +82,8 @@ const defaults = {
endpoint: 'https://api.github.com/',
};
const escapeHash = input => (input ? input.replace(/#/g, '%23') : input);
const escapeHash = (input: string): string =>
input ? input.replace(/#/g, '%23') : input;
export async function initPlatform({
endpoint,
@ -81,7 +91,7 @@ export async function initPlatform({
}: {
endpoint: string;
token: string;
}) {
}): Promise<PlatformConfig> {
if (!token) {
throw new Error('Init: You must configure a GitHub personal access token');
}
@ -130,7 +140,7 @@ export async function initPlatform({
}
// Get all repositories that the user has access to
export async function getRepos() {
export async function getRepos(): Promise<string[]> {
logger.info('Autodiscovering GitHub repositories');
try {
const res = await api.get('user/repos?per_page=100', { paginate: true });
@ -141,7 +151,7 @@ export async function getRepos() {
}
}
export function cleanRepo() {
export function cleanRepo(): void {
// istanbul ignore if
if (config.storage) {
config.storage.cleanRepo();
@ -150,7 +160,9 @@ export function cleanRepo() {
config = {} as any;
}
async function getBranchProtection(branchName: string) {
async function getBranchProtection(
branchName: string
): Promise<BranchProtection> {
// istanbul ignore if
if (config.parentRepo) {
return {};
@ -162,7 +174,7 @@ async function getBranchProtection(branchName: string) {
}
// Return the commit SHA for a branch
async function getBranchCommit(branchName: string) {
async function getBranchCommit(branchName: string): Promise<string> {
try {
const res = await api.get(
`repos/${config.repository}/git/refs/heads/${escapeHash(branchName)}`
@ -180,7 +192,7 @@ async function getBranchCommit(branchName: string) {
}
}
async function getBaseCommitSHA() {
async function getBaseCommitSHA(): Promise<string> {
if (!config.baseCommitSHA) {
config.baseCommitSHA = await getBranchCommit(config.baseBranch);
}
@ -198,7 +210,7 @@ export async function initRepo({
includeForks,
renovateUsername,
optimizeForDisabled,
}: RepoParams) {
}: RepoParams): Promise<RepoConfig> {
logger.debug(`initRepo("${repository}")`);
logger.info('Authenticated as user: ' + renovateUsername);
logger.info('Using renovate version: ' + global.renovateVersion);
@ -421,7 +433,7 @@ export async function initRepo({
return repoConfig;
}
export async function getRepoForceRebase() {
export async function getRepoForceRebase(): Promise<boolean> {
if (config.repoForceRebase === undefined) {
try {
config.repoForceRebase = false;
@ -467,63 +479,73 @@ export async function getRepoForceRebase() {
}
// istanbul ignore next
export async function setBaseBranch(branchName = config.baseBranch) {
export async function setBaseBranch(
branchName = config.baseBranch
): Promise<void> {
config.baseBranch = branchName;
config.baseCommitSHA = null;
await config.storage.setBaseBranch(branchName);
}
// istanbul ignore next
export function setBranchPrefix(branchPrefix: string) {
export function setBranchPrefix(branchPrefix: string): Promise<void> {
return config.storage.setBranchPrefix(branchPrefix);
}
// Search
// istanbul ignore next
export function getFileList(branchName = config.baseBranch) {
export function getFileList(branchName = config.baseBranch): Promise<string[]> {
return config.storage.getFileList(branchName);
}
// Branch
// istanbul ignore next
export function branchExists(branchName: string) {
export function branchExists(branchName: string): Promise<boolean> {
return config.storage.branchExists(branchName);
}
// istanbul ignore next
export function getAllRenovateBranches(branchPrefix: string) {
export function getAllRenovateBranches(
branchPrefix: string
): Promise<string[]> {
return config.storage.getAllRenovateBranches(branchPrefix);
}
// istanbul ignore next
export function isBranchStale(branchName: string) {
export function isBranchStale(branchName: string): Promise<boolean> {
return config.storage.isBranchStale(branchName);
}
// istanbul ignore next
export function getFile(filePath: string, branchName?: string) {
export function getFile(
filePath: string,
branchName?: string
): Promise<string> {
return config.storage.getFile(filePath, branchName);
}
// istanbul ignore next
export function deleteBranch(branchName: string, closePr?: boolean) {
export function deleteBranch(
branchName: string,
closePr?: boolean
): Promise<void> {
return config.storage.deleteBranch(branchName);
}
// istanbul ignore next
export function getBranchLastCommitTime(branchName: string) {
export function getBranchLastCommitTime(branchName: string): Promise<Date> {
return config.storage.getBranchLastCommitTime(branchName);
}
// istanbul ignore next
export function getRepoStatus() {
export function getRepoStatus(): Promise<StatusResult> {
return config.storage.getRepoStatus();
}
// istanbul ignore next
export function mergeBranch(branchName: string) {
export function mergeBranch(branchName: string): Promise<void> {
if (config.pushProtection) {
logger.info(
{ branch: branchName },
@ -536,10 +558,10 @@ export function mergeBranch(branchName: string) {
// istanbul ignore next
export function commitFilesToBranch(
branchName: string,
files: any[],
files: File[],
message: string,
parentBranch = config.baseBranch
) {
): Promise<void> {
return config.storage.commitFilesToBranch(
branchName,
files,
@ -549,11 +571,11 @@ export function commitFilesToBranch(
}
// istanbul ignore next
export function getCommitMessages() {
export function getCommitMessages(): Promise<string[]> {
return config.storage.getCommitMessages();
}
async function getClosedPrs() {
async function getClosedPrs(): Promise<PrList> {
if (!config.closedPrList) {
config.closedPrList = {};
let query;
@ -619,7 +641,7 @@ async function getClosedPrs() {
return config.closedPrList;
}
async function getOpenPrs() {
async function getOpenPrs(): Promise<PrList> {
// istanbul ignore if
if (config.isGhe) {
logger.debug(
@ -786,7 +808,7 @@ async function getOpenPrs() {
}
// Gets details for a PR
export async function getPr(prNo: number) {
export async function getPr(prNo: number): Promise<Pr | null> {
if (!prNo) {
return null;
}
@ -896,7 +918,7 @@ export async function getPr(prNo: number) {
return pr;
}
function matchesState(state: string, desiredState: string) {
function matchesState(state: string, desiredState: string): boolean {
if (desiredState === 'all') {
return true;
}
@ -906,7 +928,7 @@ function matchesState(state: string, desiredState: string) {
return state === desiredState;
}
export async function getPrList() {
export async function getPrList(): Promise<Pr[]> {
logger.trace('getPrList()');
if (!config.prList) {
logger.debug('Retrieving PR list');
@ -948,7 +970,7 @@ export async function findPr(
branchName: string,
prTitle?: string | null,
state = 'all'
) {
): Promise<Pr | null> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
const prList = await getPrList();
const pr = prList.find(
@ -964,7 +986,7 @@ export async function findPr(
}
// Returns the Pull Request for a branch. Null if not exists.
export async function getBranchPr(branchName: string) {
export async function getBranchPr(branchName: string): Promise<Pr | null> {
logger.debug(`getBranchPr(${branchName})`);
const existingPr = await findPr(branchName, null, 'open');
return existingPr ? getPr(existingPr.number) : null;
@ -974,7 +996,7 @@ export async function getBranchPr(branchName: string) {
export async function getBranchStatus(
branchName: string,
requiredStatusChecks: any
) {
): Promise<string> {
logger.debug(`getBranchStatus(${branchName})`);
if (!requiredStatusChecks) {
// null means disable status checks, so it always succeeds
@ -1066,7 +1088,7 @@ export async function getBranchStatus(
export async function getBranchStatusCheck(
branchName: string,
context: string
) {
): Promise<string> {
const branchCommit = await config.storage.getBranchCommit(branchName);
const url = `repos/${config.repository}/commits/${branchCommit}/statuses`;
try {
@ -1092,7 +1114,7 @@ export async function setBranchStatus(
description: string,
state: string,
targetUrl?: string
) {
): Promise<void> {
// istanbul ignore if
if (config.parentRepo) {
logger.info('Cannot set branch status when in forking mode');
@ -1119,7 +1141,9 @@ export async function setBranchStatus(
// Issue
/* istanbul ignore next */
async function getGraphqlIssues(afterCursor: string | null = null) {
async function getGraphqlIssues(
afterCursor: string | null = null
): Promise<[boolean, Issue[], string | null]> {
const url = 'graphql';
const headers = {
accept: 'application/vnd.github.merge-info-preview+json',
@ -1170,7 +1194,7 @@ async function getGraphqlIssues(afterCursor: string | null = null) {
}
// istanbul ignore next
async function getRestIssues() {
async function getRestIssues(): Promise<Issue[]> {
logger.debug('Retrieving issueList');
const res = await api.get<
{
@ -1197,7 +1221,7 @@ async function getRestIssues() {
}));
}
export async function getIssueList() {
export async function getIssueList(): Promise<Issue[]> {
if (!config.issueList) {
logger.debug('Retrieving issueList');
const filterBySupportMinimumGheVersion = '2.17.0';
@ -1228,7 +1252,7 @@ export async function getIssueList() {
return config.issueList;
}
export async function findIssue(title: string) {
export async function findIssue(title: string): Promise<Issue | null> {
logger.debug(`findIssue(${title})`);
const [issue] = (await getIssueList()).filter(
i => i.state === 'open' && i.title === title
@ -1246,7 +1270,7 @@ export async function findIssue(title: string) {
};
}
async function closeIssue(issueNumber: number) {
async function closeIssue(issueNumber: number): Promise<void> {
logger.debug(`closeIssue(${issueNumber})`);
await api.patch(
`repos/${config.parentRepo || config.repository}/issues/${issueNumber}`,
@ -1261,7 +1285,7 @@ export async function ensureIssue(
rawbody: string,
once = false,
reopen = true
) {
): Promise<string | null> {
logger.debug(`ensureIssue(${title})`);
const body = sanitize(rawbody);
try {
@ -1332,7 +1356,7 @@ export async function ensureIssue(
return null;
}
export async function ensureIssueClosing(title: string) {
export async function ensureIssueClosing(title: string): Promise<void> {
logger.debug(`ensureIssueClosing(${title})`);
const issueList = await getIssueList();
for (const issue of issueList) {
@ -1343,7 +1367,10 @@ export async function ensureIssueClosing(title: string) {
}
}
export async function addAssignees(issueNo: number, assignees: string[]) {
export async function addAssignees(
issueNo: number,
assignees: string[]
): Promise<void> {
logger.debug(`Adding assignees ${assignees} to #${issueNo}`);
const repository = config.parentRepo || config.repository;
await api.post(`repos/${repository}/issues/${issueNo}/assignees`, {
@ -1353,7 +1380,10 @@ export async function addAssignees(issueNo: number, assignees: string[]) {
});
}
export async function addReviewers(prNo: number, reviewers: string[]) {
export async function addReviewers(
prNo: number,
reviewers: string[]
): Promise<void> {
logger.debug(`Adding reviewers ${reviewers} to #${prNo}`);
const userReviewers = reviewers.filter(e => !e.startsWith('team:'));
@ -1373,7 +1403,10 @@ export async function addReviewers(prNo: number, reviewers: string[]) {
);
}
async function addLabels(issueNo: number, labels: string[] | null) {
async function addLabels(
issueNo: number,
labels: string[] | null
): Promise<void> {
logger.debug(`Adding labels ${labels} to #${issueNo}`);
const repository = config.parentRepo || config.repository;
if (is.array(labels) && labels.length) {
@ -1383,7 +1416,10 @@ async function addLabels(issueNo: number, labels: string[] | null) {
}
}
export async function deleteLabel(issueNo: number, label: string) {
export async function deleteLabel(
issueNo: number,
label: string
): Promise<void> {
logger.debug(`Deleting label ${label} from #${issueNo}`);
const repository = config.parentRepo || config.repository;
try {
@ -1393,7 +1429,7 @@ export async function deleteLabel(issueNo: number, label: string) {
}
}
async function addComment(issueNo: number, body: string) {
async function addComment(issueNo: number, body: string): Promise<void> {
// POST /repos/:owner/:repo/issues/:number/comments
await api.post(
`repos/${config.parentRepo ||
@ -1404,7 +1440,7 @@ async function addComment(issueNo: number, body: string) {
);
}
async function editComment(commentId: number, body: string) {
async function editComment(commentId: number, body: string): Promise<void> {
// PATCH /repos/:owner/:repo/issues/comments/:id
await api.patch(
`repos/${config.parentRepo ||
@ -1415,7 +1451,7 @@ async function editComment(commentId: number, body: string) {
);
}
async function deleteComment(commentId: number) {
async function deleteComment(commentId: number): Promise<void> {
// DELETE /repos/:owner/:repo/issues/comments/:id
await api.delete(
`repos/${config.parentRepo ||
@ -1423,7 +1459,7 @@ async function deleteComment(commentId: number) {
);
}
async function getComments(issueNo: number) {
async function getComments(issueNo: number): Promise<Comment[]> {
const pr = (await getClosedPrs())[issueNo];
if (pr) {
logger.debug('Returning closed PR list comments');
@ -1452,7 +1488,7 @@ export async function ensureComment(
issueNo: number,
topic: string | null,
rawContent: string
) {
): Promise<boolean> {
const content = sanitize(rawContent);
try {
const comments = await getComments(issueNo);
@ -1509,10 +1545,13 @@ export async function ensureComment(
}
}
export async function ensureCommentRemoval(issueNo: number, topic: string) {
export async function ensureCommentRemoval(
issueNo: number,
topic: string
): Promise<void> {
logger.debug(`Ensuring comment "${topic}" in #${issueNo} is removed`);
const comments = await getComments(issueNo);
let commentId;
let commentId: number;
comments.forEach(comment => {
if (comment.body.startsWith(`### ${topic}\n\n`)) {
commentId = comment.id;
@ -1537,7 +1576,7 @@ export async function createPr(
labels: string[] | null,
useDefaultBranch: boolean,
platformOptions: { statusCheckVerify?: boolean } = {}
) {
): Promise<Pr> {
const body = sanitize(rawBody);
const base = useDefaultBranch ? config.defaultBranch : config.baseBranch;
// Include the repository owner to handle forkMode and regular mode
@ -1583,7 +1622,7 @@ export async function createPr(
}
// Return a list of all modified files in a PR
export async function getPrFiles(prNo: number) {
export async function getPrFiles(prNo: number): Promise<string[]> {
logger.debug({ prNo }, 'getPrFiles');
if (!prNo) {
return [];
@ -1594,7 +1633,11 @@ export async function getPrFiles(prNo: number) {
return files.map((f: { filename: string }) => f.filename);
}
export async function updatePr(prNo: number, title: string, rawBody?: string) {
export async function updatePr(
prNo: number,
title: string,
rawBody?: string
): Promise<void> {
logger.debug(`updatePr(${prNo}, ${title}, body)`);
const body = sanitize(rawBody);
const patchBody: any = { title };
@ -1622,7 +1665,10 @@ export async function updatePr(prNo: number, title: string, rawBody?: string) {
}
}
export async function mergePr(prNo: number, branchName: string) {
export async function mergePr(
prNo: number,
branchName: string
): Promise<boolean> {
logger.debug(`mergePr(${prNo}, ${branchName})`);
// istanbul ignore if
if (config.isGhe && config.pushProtection) {
@ -1721,7 +1767,7 @@ export async function mergePr(prNo: number, branchName: string) {
return true;
}
export function getPrBody(input: string) {
export function getPrBody(input: string): string {
if (config.isGhe) {
return smartTruncate(input, 60000);
}
@ -1733,7 +1779,7 @@ export function getPrBody(input: string) {
return smartTruncate(massagedInput, 60000);
}
export async function getVulnerabilityAlerts() {
export async function getVulnerabilityAlerts(): Promise<VulnerabilityAlert[]> {
// istanbul ignore if
if (config.isGhe) {
logger.debug(

Просмотреть файл

@ -1,13 +1,13 @@
import parseLinkHeader from 'parse-link-header';
import { GotApi } from '../common';
import { GotApi, GotResponse } from '../common';
import got from '../../util/got';
import { logger } from '../../logger';
const hostType = 'gitlab';
let baseUrl = 'https://gitlab.com/api/v4/';
async function get(path: string, options: any) {
async function get(path: string, options: any): Promise<GotResponse> {
const opts = {
hostType,
baseUrl,
@ -60,11 +60,11 @@ interface GlGotApi
export const api: GlGotApi = {} as any;
for (const x of helpers) {
(api as any)[x] = (url: string, opts: any) =>
(api as any)[x] = (url: string, opts: any): Promise<GotResponse> =>
get(url, Object.assign({}, opts, { method: x.toUpperCase() }));
}
api.setBaseUrl = e => {
api.setBaseUrl = (e: string): void => {
baseUrl = e;
};

Просмотреть файл

@ -1,21 +1,24 @@
import URL, { URLSearchParams } from 'url';
import is from '@sindresorhus/is';
import { bool } from 'aws-sdk/clients/signer';
import simplegit from 'simple-git/promise';
import { api } from './gl-got-wrapper';
import * as hostRules from '../../util/host-rules';
import GitStorage from '../git/storage';
import GitStorage, { StatusResult } from '../git/storage';
import {
PlatformConfig,
RepoParams,
RepoConfig,
PlatformPrOptions,
GotResponse,
Pr,
Issue,
VulnerabilityAlert,
} from '../common';
import { configFileNames } from '../../config/app-strings';
import { logger } from '../../logger';
import { sanitize } from '../../util/sanitize';
import { smartTruncate } from '../utils/pr-body';
import { RenovateConfig } from '../../config';
const defaultConfigFile = configFileNames[0];
let config: {
@ -43,7 +46,7 @@ export async function initPlatform({
}: {
token: string;
endpoint: string;
}): Promise<any> {
}): Promise<PlatformConfig> {
if (!token) {
throw new Error('Init: You must configure a GitLab personal access token');
}
@ -73,7 +76,7 @@ export async function initPlatform({
}
// Get all repositories that the user has access to
export async function getRepos(): Promise<any> {
export async function getRepos(): Promise<string[]> {
logger.info('Autodiscovering GitLab repositories');
try {
const url = `projects?membership=true&per_page=100`;
@ -92,7 +95,7 @@ function urlEscape(str: string): string {
return str ? str.replace(/\//g, '%2F') : str;
}
export function cleanRepo(): any {
export function cleanRepo(): void {
// istanbul ignore if
if (config.storage) {
config.storage.cleanRepo();
@ -106,11 +109,17 @@ export async function initRepo({
repository,
localDir,
optimizeForDisabled,
}: RepoParams): Promise<any> {
}: RepoParams): Promise<RepoConfig> {
config = {} as any;
config.repository = urlEscape(repository);
config.localDir = localDir;
let res;
let res: GotResponse<{
archived: boolean;
mirror: boolean;
default_branch: string;
http_url_to_repo: string;
forked_from_project: boolean;
}>;
try {
res = await api.get(`projects/${config.repository}`);
if (res.body.archived) {
@ -129,7 +138,7 @@ export async function initRepo({
throw new Error('empty');
}
if (optimizeForDisabled) {
let renovateConfig;
let renovateConfig: RenovateConfig;
try {
renovateConfig = JSON.parse(
Buffer.from(
@ -158,7 +167,7 @@ export async function initRepo({
hostType: defaults.hostType,
url: defaults.endpoint,
});
let url;
let url: string;
if (res.body.http_url_to_repo === null) {
logger.debug('no http_url_to_repo found. Falling back to old behaviour.');
const { host, protocol } = URL.parse(defaults.endpoint);
@ -206,13 +215,13 @@ export async function initRepo({
return repoConfig;
}
export function getRepoForceRebase(): bool {
export function getRepoForceRebase(): boolean {
return false;
}
export async function setBaseBranch(
branchName = config.baseBranch
): Promise<any> {
): Promise<void> {
logger.debug(`Setting baseBranch to ${branchName}`);
config.baseBranch = branchName;
await config.storage.setBaseBranch(branchName);
@ -240,7 +249,7 @@ export function branchExists(branchName: string): Promise<boolean> {
export async function getBranchStatus(
branchName: string,
requiredStatusChecks?: string[] | null
) {
): Promise<string> {
logger.debug(`getBranchStatus(${branchName})`);
if (!requiredStatusChecks) {
// null means disable status checks, so it always succeeds
@ -292,7 +301,7 @@ export async function createPr(
labels?: string[] | null,
useDefaultBranch?: boolean,
platformOptions?: PlatformPrOptions
) {
): Promise<Pr> {
const description = sanitize(rawDescription);
const targetBranch = useDefaultBranch
? config.defaultBranch
@ -336,7 +345,7 @@ export async function createPr(
return pr;
}
export async function getPr(iid: number) {
export async function getPr(iid: number): Promise<Pr> {
logger.debug(`getPr(${iid})`);
const url = `projects/${config.repository}/merge_requests/${iid}?include_diverged_commits_count=1`;
const pr = (await api.get(url)).body;
@ -389,7 +398,7 @@ export async function getPr(iid: number) {
}
// Return a list of all modified files in a PR
export async function getPrFiles(mrNo: number) {
export async function getPrFiles(mrNo: number): Promise<string[]> {
logger.debug({ mrNo }, 'getPrFiles');
if (!mrNo) {
return [];
@ -401,7 +410,7 @@ export async function getPrFiles(mrNo: number) {
}
// istanbul ignore next
async function closePr(iid: number) {
async function closePr(iid: number): Promise<void> {
await api.put(`projects/${config.repository}/merge_requests/${iid}`, {
body: {
state_event: 'close',
@ -413,7 +422,7 @@ export async function updatePr(
iid: number,
title: string,
description: string
) {
): Promise<void> {
await api.put(`projects/${config.repository}/merge_requests/${iid}`, {
body: {
title,
@ -422,7 +431,7 @@ export async function updatePr(
});
}
export async function mergePr(iid: number) {
export async function mergePr(iid: number): Promise<boolean> {
try {
await api.put(`projects/${config.repository}/merge_requests/${iid}/merge`, {
body: {
@ -445,7 +454,7 @@ export async function mergePr(iid: number) {
}
}
export function getPrBody(input: string) {
export function getPrBody(input: string): string {
return smartTruncate(
input
.replace(/Pull Request/g, 'Merge Request')
@ -458,7 +467,7 @@ export function getPrBody(input: string) {
// Branch
// Returns the Pull Request for a branch. Null if not exists.
export async function getBranchPr(branchName: string): Promise<any> {
export async function getBranchPr(branchName: string): Promise<Pr> {
logger.debug(`getBranchPr(${branchName})`);
// istanbul ignore if
if (!(await branchExists(branchName))) {
@ -518,7 +527,7 @@ export function getFile(
export async function deleteBranch(
branchName: string,
shouldClosePr = false
): Promise<any> {
): Promise<void> {
if (shouldClosePr) {
logger.debug('Closing PR');
const pr = await getBranchPr(branchName);
@ -539,14 +548,14 @@ export function getBranchLastCommitTime(branchName: string): Promise<Date> {
}
// istanbul ignore next
export function getRepoStatus(): Promise<simplegit.StatusResult> {
export function getRepoStatus(): Promise<StatusResult> {
return config.storage.getRepoStatus();
}
export async function getBranchStatusCheck(
branchName: string,
context: string
): Promise<any> {
): Promise<string | null> {
// First, get the branch commit SHA
const branchSha = await config.storage.getBranchCommit(branchName);
// Now, check the statuses for that commit
@ -623,12 +632,7 @@ export async function getIssueList(): Promise<any[]> {
return config.issueList;
}
export async function findIssue(
title: string
): Promise<{
number: any;
body: any;
}> {
export async function findIssue(title: string): Promise<Issue | null> {
logger.debug(`findIssue(${title})`);
try {
const issueList = await getIssueList();
@ -652,7 +656,7 @@ export async function findIssue(
export async function ensureIssue(
title: string,
body: string
): Promise<'updated' | 'created'> {
): Promise<'updated' | 'created' | null> {
logger.debug(`ensureIssue()`);
const description = getPrBody(sanitize(body));
try {
@ -706,7 +710,7 @@ export async function ensureIssueClosing(title: string): Promise<void> {
export async function addAssignees(
iid: number,
assignees: string[]
): Promise<any> {
): Promise<void> {
logger.debug(`Adding assignees ${assignees} to #${iid}`);
try {
let assigneeId = (await api.get(`users?username=${assignees[0]}`)).body[0]
@ -731,7 +735,7 @@ export async function addAssignees(
}
}
export function addReviewers(iid: number, reviewers: string[]): any {
export function addReviewers(iid: number, reviewers: string[]): void {
logger.debug(`addReviewers('${iid}, '${reviewers})`);
logger.warn('Unimplemented in GitLab: approvals');
}
@ -739,7 +743,7 @@ export function addReviewers(iid: number, reviewers: string[]): any {
export async function deleteLabel(
issueNo: number,
label: string
): Promise<any> {
): Promise<void> {
logger.debug(`Deleting label ${label} from #${issueNo}`);
try {
const pr = await getPr(issueNo);
@ -752,7 +756,7 @@ export async function deleteLabel(
}
}
async function getComments(issueNo: number): Promise<any> {
async function getComments(issueNo: number): Promise<any[]> {
// GET projects/:owner/:repo/merge_requests/:number/notes
logger.debug(`Getting comments for #${issueNo}`);
const url = `projects/${config.repository}/merge_requests/${issueNo}/notes`;
@ -761,7 +765,7 @@ async function getComments(issueNo: number): Promise<any> {
return comments;
}
async function addComment(issueNo: number, body: string): Promise<any> {
async function addComment(issueNo: number, body: string): Promise<void> {
// POST projects/:owner/:repo/merge_requests/:number/notes
await api.post(
`projects/${config.repository}/merge_requests/${issueNo}/notes`,
@ -775,7 +779,7 @@ async function editComment(
issueNo: number,
commentId: number,
body: string
): Promise<any> {
): Promise<void> {
// PUT projects/:owner/:repo/merge_requests/:number/notes/:id
await api.put(
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`,
@ -785,7 +789,10 @@ async function editComment(
);
}
async function deleteComment(issueNo: number, commentId: number): Promise<any> {
async function deleteComment(
issueNo: number,
commentId: number
): Promise<void> {
// DELETE projects/:owner/:repo/merge_requests/:number/notes/:id
await api.delete(
`projects/${config.repository}/merge_requests/${issueNo}/notes/${commentId}`
@ -796,7 +803,7 @@ export async function ensureComment(
issueNo: number,
topic: string | null | undefined,
rawContent: string
): Promise<any> {
): Promise<void> {
const content = sanitize(rawContent);
const massagedTopic = topic
? topic.replace(/Pull Request/g, 'Merge Request').replace(/PR/g, 'MR')
@ -839,7 +846,7 @@ export async function ensureComment(
export async function ensureCommentRemoval(
issueNo: number,
topic: string
): Promise<any> {
): Promise<void> {
logger.debug(`Ensuring comment "${topic}" in #${issueNo} is removed`);
const comments = await getComments(issueNo);
let commentId;
@ -859,7 +866,7 @@ const mapPullRequests = (pr: {
title: string;
state: string;
created_at: string;
}) => ({
}): Pr => ({
number: pr.iid,
branchName: pr.source_branch,
title: pr.title,
@ -867,7 +874,7 @@ const mapPullRequests = (pr: {
createdAt: pr.created_at,
});
async function fetchPrList(): Promise<any> {
async function fetchPrList(): Promise<Pr[]> {
const query = new URLSearchParams({
per_page: '100',
author_id: `${authorId}`,
@ -885,14 +892,14 @@ async function fetchPrList(): Promise<any> {
}
}
export async function getPrList(): Promise<any> {
export async function getPrList(): Promise<Pr[]> {
if (!config.prList) {
config.prList = await fetchPrList();
}
return config.prList;
}
function matchesState(state: string, desiredState: string): bool {
function matchesState(state: string, desiredState: string): boolean {
if (desiredState === 'all') {
return true;
}
@ -906,7 +913,7 @@ export async function findPr(
branchName: string,
prTitle?: string | null,
state = 'all'
): Promise<any> {
): Promise<Pr> {
logger.debug(`findPr(${branchName}, ${prTitle}, ${state})`);
const prList = await getPrList();
return prList.find(
@ -921,6 +928,6 @@ export function getCommitMessages(): Promise<string[]> {
return config.storage.getCommitMessages();
}
export function getVulnerabilityAlerts(): any[] {
export function getVulnerabilityAlerts(): VulnerabilityAlert[] {
return [];
}

Просмотреть файл

@ -91,5 +91,5 @@ export const isOnboarded = async (config: RenovateConfig): Promise<boolean> => {
throw new Error('disabled');
};
export const onboardingPrExists = (): Promise<boolean> =>
platform.getBranchPr(onboardingBranch);
export const onboardingPrExists = async (): Promise<boolean> =>
(await platform.getBranchPr(onboardingBranch)) != null;

Просмотреть файл

@ -14,36 +14,6 @@ Object {
}
`;
exports[`platform/azure/helpers getChanges should be get the commit obj formated (file to create) 1`] = `
Array [
Object {
"changeType": 1,
"item": Object {
"path": "./myFilePath/test",
},
"newContent": Object {
"Content": "Hello world!",
"ContentType": 0,
},
},
]
`;
exports[`platform/azure/helpers getChanges should be get the commit obj formated (file to update) 1`] = `
Array [
Object {
"changeType": 2,
"item": Object {
"path": "./myFilePath/test",
},
"newContent": Object {
"Content": "Hello world!",
"ContentType": 0,
},
},
]
`;
exports[`platform/azure/helpers getCommitDetails should get commit details 1`] = `
Object {
"parents": Array [

Просмотреть файл

@ -105,63 +105,6 @@ describe('platform/azure/helpers', () => {
});
});
describe('getChanges', () => {
it('should be get the commit obj formated (file to update)', async () => {
let eventCount = 0;
const mockEventStream = new Readable({
objectMode: true,
/* eslint-disable func-names */
/* eslint-disable object-shorthand */
read: function() {
if (eventCount < 1) {
eventCount += 1;
return this.push('{"hello": "test"}');
}
return this.push(null);
},
});
azureApi.gitApi.mockImplementationOnce(
() =>
({
getItemText: jest.fn(() => mockEventStream),
} as any)
);
const res = await azureHelper.getChanges(
[
{
name: './myFilePath/test',
contents: 'Hello world!',
},
],
'123',
'repository'
);
expect(res).toMatchSnapshot();
});
it('should be get the commit obj formated (file to create)', async () => {
azureApi.gitApi.mockImplementationOnce(
() =>
({
getItemText: jest.fn(() => null),
} as any)
);
const res = await azureHelper.getChanges(
[
{
name: './myFilePath/test',
contents: 'Hello world!',
},
],
'123',
'repository'
);
expect(res).toMatchSnapshot();
});
});
describe('getFile', () => {
it('should return null error GitItemNotFoundException', async () => {
let eventCount = 0;

Просмотреть файл

@ -215,12 +215,15 @@ describe('platform/azure', () => {
azureHelper.getNewBranchName.mockImplementationOnce(
() => 'refs/heads/branch-a'
);
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'open',
}));
azureHelper.getRenovatePRFormat.mockImplementationOnce(
() =>
({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'open',
} as any)
);
const res = await azure.findPr('branch-a', 'branch a pr', 'open');
expect(res).toMatchSnapshot();
});
@ -241,12 +244,15 @@ describe('platform/azure', () => {
azureHelper.getNewBranchName.mockImplementationOnce(
() => 'refs/heads/branch-a'
);
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
}));
azureHelper.getRenovatePRFormat.mockImplementationOnce(
() =>
({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
} as any)
);
const res = await azure.findPr('branch-a', 'branch a pr', '!open');
expect(res).toMatchSnapshot();
});
@ -267,12 +273,15 @@ describe('platform/azure', () => {
azureHelper.getNewBranchName.mockImplementationOnce(
() => 'refs/heads/branch-a'
);
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
}));
azureHelper.getRenovatePRFormat.mockImplementationOnce(
() =>
({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
} as any)
);
const res = await azure.findPr('branch-a', 'branch a pr', 'closed');
expect(res).toMatchSnapshot();
});
@ -293,12 +302,15 @@ describe('platform/azure', () => {
azureHelper.getNewBranchName.mockImplementationOnce(
() => 'refs/heads/branch-a'
);
azureHelper.getRenovatePRFormat.mockImplementationOnce(() => ({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
}));
azureHelper.getRenovatePRFormat.mockImplementationOnce(
() =>
({
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
state: 'closed',
} as any)
);
const res = await azure.findPr('branch-a', 'branch a pr');
expect(res).toMatchSnapshot();
});
@ -342,13 +354,16 @@ describe('platform/azure', () => {
azureHelper.getNewBranchName.mockImplementation(
() => 'refs/heads/branch-a'
);
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
pullRequestId: 1,
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
isClosed: false,
}));
azureHelper.getRenovatePRFormat.mockImplementation(
() =>
({
pullRequestId: 1,
number: 1,
head: { ref: 'branch-a' },
title: 'branch a pr',
isClosed: false,
} as any)
);
const pr = await azure.getBranchPr('somebranch');
expect(pr).toMatchSnapshot();
});
@ -416,10 +431,13 @@ describe('platform/azure', () => {
]),
} as any)
);
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
pullRequestId: 1234,
labels: ['renovate'],
}));
azureHelper.getRenovatePRFormat.mockImplementation(
() =>
({
pullRequestId: 1234,
labels: ['renovate'],
} as any)
);
const pr = await azure.getPr(1234);
expect(pr).toMatchSnapshot();
});
@ -438,11 +456,14 @@ describe('platform/azure', () => {
createPullRequestLabel: jest.fn(() => ({})),
} as any)
);
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
displayNumber: 'Pull Request #456',
number: 456,
pullRequestId: 456,
}));
azureHelper.getRenovatePRFormat.mockImplementation(
() =>
({
displayNumber: 'Pull Request #456',
number: 456,
pullRequestId: 456,
} as any)
);
const pr = await azure.createPr(
'some-branch',
'The Title',
@ -463,11 +484,14 @@ describe('platform/azure', () => {
createPullRequestLabel: jest.fn(() => ({})),
} as any)
);
azureHelper.getRenovatePRFormat.mockImplementation(() => ({
displayNumber: 'Pull Request #456',
number: 456,
pullRequestId: 456,
}));
azureHelper.getRenovatePRFormat.mockImplementation(
() =>
({
displayNumber: 'Pull Request #456',
number: 456,
pullRequestId: 456,
} as any)
);
const pr = await azure.createPr(
'some-branch',
'The Title',
@ -507,7 +531,7 @@ describe('platform/azure', () => {
updatePullRequest: updateFn,
} as any)
);
azureHelper.getRenovatePRFormat.mockImplementation(x => x);
azureHelper.getRenovatePRFormat.mockImplementation(x => x as any);
const pr = await azure.createPr(
'some-branch',
'The Title',

Просмотреть файл

@ -211,7 +211,11 @@ describe('platform/bitbucket-server', () => {
it('sends to gitFs', async () => {
expect.assertions(1);
await initRepo();
await bitbucket.commitFilesToBranch('some-branch', [{}], 'message');
await bitbucket.commitFilesToBranch(
'some-branch',
[{ name: 'test', contents: 'dummy' }],
'message'
);
expect(api.get.mock.calls).toMatchSnapshot();
});
});

Просмотреть файл

@ -260,7 +260,7 @@ describe('platform/gitlab', () => {
describe('setBaseBranch(branchName)', () => {
it('sets the base branch', async () => {
await initRepo();
await gitlab.setBaseBranch('some-branch');
await gitlab.setBaseBranch();
expect(api.get.mock.calls).toMatchSnapshot();
});
it('uses default base branch', async () => {

Просмотреть файл

@ -40,7 +40,7 @@ describe('lib/workers/global/autodiscover', () => {
hostRules.find = jest.fn(() => ({
token: 'abc',
}));
ghApi.getRepos = jest.fn(() => Promise.resolve([{}, {}]));
ghApi.getRepos = jest.fn(() => Promise.resolve(['a', 'b']));
const res = await autodiscoverRepositories(config);
expect(res.repositories).toHaveLength(2);
});