mirror of
https://github.com/renovatebot/renovate.git
synced 2025-01-11 14:36:25 +00:00
feat(worker): convert 'branch' to typescript (#4449)
Co-Authored-By: Jamie Magee <JamieMagee@users.noreply.github.com>
This commit is contained in:
parent
4d6b98f9b0
commit
2a4de19c77
12 changed files with 165 additions and 91 deletions
|
@ -157,7 +157,7 @@ export interface Upgrade<T = Record<string, any>>
|
|||
version?: string;
|
||||
}
|
||||
|
||||
interface ArtifactError {
|
||||
export interface ArtifactError {
|
||||
lockFile?: string;
|
||||
stderr?: string;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@ import got from 'got';
|
|||
import Git from 'simple-git/promise';
|
||||
import { RenovateConfig } from '../config/common';
|
||||
|
||||
export interface FileData {
|
||||
name: string;
|
||||
contents: string;
|
||||
}
|
||||
|
||||
export interface GotApiOptions {
|
||||
useCache?: boolean;
|
||||
hostType?: string;
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
const { logger } = require('../../logger');
|
||||
const { platform } = require('../../platform');
|
||||
import { logger } from '../../logger';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { platform } from '../../platform';
|
||||
|
||||
module.exports = {
|
||||
tryBranchAutomerge,
|
||||
};
|
||||
export type AutomergeResult =
|
||||
| 'automerged'
|
||||
| 'automerge aborted - PR exists'
|
||||
| 'branch status error'
|
||||
| 'failed'
|
||||
| 'no automerge'
|
||||
| 'not ready';
|
||||
|
||||
async function tryBranchAutomerge(config) {
|
||||
export async function tryBranchAutomerge(
|
||||
config: RenovateConfig
|
||||
): Promise<AutomergeResult> {
|
||||
logger.debug('Checking if we can automerge branch');
|
||||
if (!(config.automerge && config.automergeType === 'branch')) {
|
||||
return 'no automerge';
|
|
@ -1,11 +1,11 @@
|
|||
const { logger } = require('../../logger');
|
||||
const { platform } = require('../../platform');
|
||||
import { logger } from '../../logger';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { platform } from '../../platform';
|
||||
|
||||
module.exports = {
|
||||
prAlreadyExisted,
|
||||
};
|
||||
|
||||
async function prAlreadyExisted(config) {
|
||||
/** TODO: Proper return type */
|
||||
export async function prAlreadyExisted(
|
||||
config: RenovateConfig
|
||||
): Promise<any | null> {
|
||||
logger.trace({ config }, 'prAlreadyExisted');
|
||||
if (config.recreateClosed) {
|
||||
logger.debug('recreateClosed is true');
|
|
@ -1,12 +1,21 @@
|
|||
import is from '@sindresorhus/is';
|
||||
import { platform } from '../../platform';
|
||||
import minimatch from 'minimatch';
|
||||
import { FileData, platform } from '../../platform';
|
||||
import { logger } from '../../logger';
|
||||
import { RenovateConfig } from '../../config';
|
||||
|
||||
const minimatch = require('minimatch');
|
||||
const { logger } = require('../../logger');
|
||||
export type CommitConfig = RenovateConfig & {
|
||||
baseBranch?: string;
|
||||
branchName: string;
|
||||
commitMessage: string;
|
||||
excludeCommitPaths?: string[];
|
||||
updatedPackageFiles: FileData[];
|
||||
updatedArtifacts: FileData[];
|
||||
};
|
||||
|
||||
export { commitFilesToBranch };
|
||||
|
||||
async function commitFilesToBranch(config) {
|
||||
export async function commitFilesToBranch(
|
||||
config: CommitConfig
|
||||
): Promise<boolean> {
|
||||
let updatedFiles = config.updatedPackageFiles.concat(config.updatedArtifacts);
|
||||
// istanbul ignore if
|
||||
if (is.nonEmptyArray(config.excludeCommitPaths)) {
|
|
@ -1,17 +1,25 @@
|
|||
import is from '@sindresorhus/is';
|
||||
import { platform } from '../../platform';
|
||||
import { FileData, platform } from '../../platform';
|
||||
import { logger } from '../../logger';
|
||||
import { get } from '../../manager';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { UpdateArtifactsConfig, ArtifactError } from '../../manager/common';
|
||||
|
||||
const { logger } = require('../../logger');
|
||||
const { get } = require('../../manager');
|
||||
export interface PackageFilesResult {
|
||||
artifactErrors: ArtifactError[];
|
||||
parentBranch: string;
|
||||
updatedPackageFiles: FileData[];
|
||||
updatedArtifacts: FileData[];
|
||||
}
|
||||
|
||||
export { getUpdatedPackageFiles };
|
||||
|
||||
async function getUpdatedPackageFiles(config) {
|
||||
export async function getUpdatedPackageFiles(
|
||||
config: RenovateConfig & UpdateArtifactsConfig
|
||||
): Promise<PackageFilesResult> {
|
||||
logger.debug('manager.getUpdatedPackageFiles()');
|
||||
logger.trace({ config });
|
||||
const updatedFileContents = {};
|
||||
const packageFileManagers = {};
|
||||
const packageFileUpdatedDeps = {};
|
||||
const updatedFileContents: Record<string, string> = {};
|
||||
const packageFileManagers: Record<string, string> = {};
|
||||
const packageFileUpdatedDeps: Record<string, string[]> = {};
|
||||
const lockFileMaintenanceFiles = [];
|
||||
for (const upgrade of config.upgrades) {
|
||||
const { manager, packageFile, depName } = upgrade;
|
||||
|
@ -68,8 +76,8 @@ async function getUpdatedPackageFiles(config) {
|
|||
name,
|
||||
contents: updatedFileContents[name],
|
||||
}));
|
||||
const updatedArtifacts = [];
|
||||
const artifactErrors = [];
|
||||
const updatedArtifacts: FileData[] = [];
|
||||
const artifactErrors: ArtifactError[] = [];
|
||||
for (const packageFile of updatedPackageFiles) {
|
||||
const manager = packageFileManagers[packageFile.name];
|
||||
const updatedDeps = packageFileUpdatedDeps[packageFile.name];
|
||||
|
@ -82,7 +90,7 @@ async function getUpdatedPackageFiles(config) {
|
|||
config
|
||||
);
|
||||
if (is.nonEmptyArray(results)) {
|
||||
for (/** @type any */ const res of results) {
|
||||
for (const res of results) {
|
||||
const { file, artifactError } = res;
|
||||
if (file) {
|
||||
updatedArtifacts.push(file);
|
||||
|
@ -109,7 +117,7 @@ async function getUpdatedPackageFiles(config) {
|
|||
config
|
||||
);
|
||||
if (is.nonEmptyArray(results)) {
|
||||
for (/** @type any */ const res of results) {
|
||||
for (const res of results) {
|
||||
const { file, artifactError } = res;
|
||||
if (file) {
|
||||
updatedArtifacts.push(file);
|
|
@ -1,26 +1,52 @@
|
|||
const { DateTime } = require('luxon');
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
const { logger, setMeta } = require('../../logger');
|
||||
const schedule = require('./schedule');
|
||||
const { getUpdatedPackageFiles } = require('./get-updated');
|
||||
const { getAdditionalFiles } = require('../../manager/npm/post-update');
|
||||
const { commitFilesToBranch } = require('./commit');
|
||||
const { getParentBranch } = require('./parent');
|
||||
const { tryBranchAutomerge } = require('./automerge');
|
||||
const { setStability, setUnpublishable } = require('./status-checks');
|
||||
const { prAlreadyExisted } = require('./check-existing');
|
||||
const prWorker = require('../pr');
|
||||
const { appName, appSlug } = require('../../config/app-strings');
|
||||
const { platform } = require('../../platform');
|
||||
const { emojify } = require('../../util/emoji');
|
||||
import { logger, setMeta } from '../../logger';
|
||||
import { isScheduledNow } from './schedule';
|
||||
import { getUpdatedPackageFiles } from './get-updated';
|
||||
import {
|
||||
getAdditionalFiles,
|
||||
AdditionalPackageFiles,
|
||||
} from '../../manager/npm/post-update';
|
||||
import { commitFilesToBranch, CommitConfig } from './commit';
|
||||
import { getParentBranch } from './parent';
|
||||
import { tryBranchAutomerge } from './automerge';
|
||||
import {
|
||||
setStability,
|
||||
setUnpublishable,
|
||||
StabilityConfig,
|
||||
UnpublishableConfig,
|
||||
} from './status-checks';
|
||||
import { prAlreadyExisted } from './check-existing';
|
||||
import { ensurePr, checkAutoMerge } from '../pr';
|
||||
import { appName, appSlug } from '../../config/app-strings';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { platform } from '../../platform';
|
||||
import { emojify } from '../../util/emoji';
|
||||
|
||||
const { isScheduledNow } = schedule;
|
||||
export type BranchConfig = RenovateConfig &
|
||||
StabilityConfig &
|
||||
UnpublishableConfig &
|
||||
CommitConfig;
|
||||
|
||||
module.exports = {
|
||||
processBranch,
|
||||
};
|
||||
export type ProcessBranchResult =
|
||||
| 'already-existed'
|
||||
| 'automerged'
|
||||
| 'done'
|
||||
| 'error'
|
||||
| 'needs-approval'
|
||||
| 'needs-pr-approval'
|
||||
| 'not-scheduled'
|
||||
| 'no-work'
|
||||
| 'pending'
|
||||
| 'pr-created'
|
||||
| 'pr-edited'
|
||||
| 'pr-hourly-limit-reached';
|
||||
|
||||
async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
|
||||
export async function processBranch(
|
||||
branchConfig: BranchConfig,
|
||||
prHourlyLimitReached?: boolean,
|
||||
packageFiles?: AdditionalPackageFiles
|
||||
): Promise<ProcessBranchResult> {
|
||||
const config = { ...branchConfig };
|
||||
const dependencies = config.upgrades
|
||||
.map(upgrade => upgrade.depName)
|
||||
|
@ -418,7 +444,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
|
|||
logger.debug(
|
||||
`There are ${config.errors.length} errors and ${config.warnings.length} warnings`
|
||||
);
|
||||
const pr = await prWorker.ensurePr(config);
|
||||
const pr = await ensurePr(config);
|
||||
// TODO: ensurePr should check for automerge itself
|
||||
if (pr === 'needs-pr-approval') {
|
||||
return 'needs-pr-approval';
|
||||
|
@ -504,7 +530,7 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
|
|||
await platform.ensureCommentRemoval(pr.number, topic);
|
||||
}
|
||||
}
|
||||
const prAutomerged = await prWorker.checkAutoMerge(pr, config);
|
||||
const prAutomerged = await checkAutoMerge(pr, config);
|
||||
if (prAutomerged) {
|
||||
return 'automerged';
|
||||
}
|
||||
|
@ -530,7 +556,8 @@ async function processBranch(branchConfig, prHourlyLimitReached, packageFiles) {
|
|||
return 'done';
|
||||
}
|
||||
|
||||
function rebaseCheck(config, branchPr) {
|
||||
// TODO: proper typings
|
||||
function rebaseCheck(config: RenovateConfig, branchPr: any): boolean {
|
||||
const titleRebase = branchPr.title && branchPr.title.startsWith('rebase!');
|
||||
const labelRebase =
|
||||
branchPr.labels && branchPr.labels.includes(config.rebaseLabel);
|
|
@ -1,12 +1,13 @@
|
|||
const { logger } = require('../../logger');
|
||||
const { appSlug } = require('../../config/app-strings');
|
||||
const { platform } = require('../../platform');
|
||||
import { logger } from '../../logger';
|
||||
import { appSlug } from '../../config/app-strings';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { platform } from '../../platform';
|
||||
|
||||
module.exports = {
|
||||
getParentBranch,
|
||||
};
|
||||
type ParentBranch = { parentBranch: string | undefined; isModified?: boolean };
|
||||
|
||||
async function getParentBranch(config) {
|
||||
export async function getParentBranch(
|
||||
config: RenovateConfig
|
||||
): Promise<ParentBranch> {
|
||||
const { branchName } = config;
|
||||
// Check if branch exists
|
||||
const branchExists = await platform.branchExists(branchName);
|
|
@ -1,35 +1,30 @@
|
|||
import is from '@sindresorhus/is';
|
||||
|
||||
const later = require('later');
|
||||
const moment = require('moment-timezone');
|
||||
const { logger } = require('../../logger');
|
||||
|
||||
export { hasValidTimezone, hasValidSchedule, isScheduledNow };
|
||||
import later from 'later';
|
||||
import moment from 'moment-timezone';
|
||||
import { logger } from '../../logger';
|
||||
|
||||
const scheduleMappings = {
|
||||
'every month': 'before 3am on the first day of the month',
|
||||
monthly: 'before 3am on the first day of the month',
|
||||
};
|
||||
|
||||
function fixShortHours(input) {
|
||||
function fixShortHours(input: string): string {
|
||||
return input.replace(/( \d?\d)((a|p)m)/g, '$1:00$2');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[boolean] | [boolean, string]}
|
||||
*/
|
||||
function hasValidTimezone(timezone) {
|
||||
export function hasValidTimezone(
|
||||
timezone: string
|
||||
): [boolean] | [boolean, string] {
|
||||
if (!moment.tz.zone(timezone)) {
|
||||
return [false, `Invalid timezone: ${timezone}`];
|
||||
}
|
||||
return [true];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[boolean] | [boolean, string]}
|
||||
*/
|
||||
function hasValidSchedule(schedule) {
|
||||
let message;
|
||||
export function hasValidSchedule(
|
||||
schedule: string[] | null | 'at any time'
|
||||
): [boolean] | [boolean, string] {
|
||||
let message: string;
|
||||
if (
|
||||
!schedule ||
|
||||
schedule === 'at any time' ||
|
||||
|
@ -70,7 +65,7 @@ function hasValidSchedule(schedule) {
|
|||
return [true, ''];
|
||||
}
|
||||
|
||||
function isScheduledNow(config) {
|
||||
export function isScheduledNow(config) {
|
||||
let configSchedule = config.schedule;
|
||||
logger.debug(`Checking schedule(${configSchedule}, ${config.timezone})`);
|
||||
if (
|
|
@ -1,13 +1,14 @@
|
|||
const { logger } = require('../../logger');
|
||||
const { appSlug, urls } = require('../../config/app-strings');
|
||||
const { platform } = require('../../platform');
|
||||
import { logger } from '../../logger';
|
||||
import { appSlug, urls } from '../../config/app-strings';
|
||||
import { RenovateConfig } from '../../config';
|
||||
import { platform } from '../../platform';
|
||||
|
||||
module.exports = {
|
||||
setStability,
|
||||
setUnpublishable,
|
||||
};
|
||||
|
||||
async function setStatusCheck(branchName, context, description, state) {
|
||||
async function setStatusCheck(
|
||||
branchName: string,
|
||||
context: string,
|
||||
description: string,
|
||||
state: string
|
||||
) {
|
||||
const existingState = await platform.getBranchStatusCheck(
|
||||
branchName,
|
||||
context
|
||||
|
@ -27,7 +28,12 @@ async function setStatusCheck(branchName, context, description, state) {
|
|||
}
|
||||
}
|
||||
|
||||
async function setStability(config) {
|
||||
export type StabilityConfig = RenovateConfig & {
|
||||
stabilityStatus: string;
|
||||
branchName: string;
|
||||
};
|
||||
|
||||
export async function setStability(config: StabilityConfig) {
|
||||
if (!config.stabilityStatus) {
|
||||
return;
|
||||
}
|
||||
|
@ -44,7 +50,15 @@ async function setStability(config) {
|
|||
);
|
||||
}
|
||||
|
||||
async function setUnpublishable(config) {
|
||||
export type UnpublishableConfig = RenovateConfig & {
|
||||
unpublishSafe?: boolean;
|
||||
canBeUnpublished?: boolean;
|
||||
branchName: string;
|
||||
};
|
||||
|
||||
export async function setUnpublishable(
|
||||
config: UnpublishableConfig
|
||||
): Promise<void> {
|
||||
if (!config.unpublishSafe) {
|
||||
return;
|
||||
}
|
|
@ -182,6 +182,7 @@
|
|||
"@types/later": "1.2.5",
|
||||
"@types/lodash": "4.14.144",
|
||||
"@types/luxon": "1.15.2",
|
||||
"@types/moment-timezone": "0.5.12",
|
||||
"@types/nock": "10.0.3",
|
||||
"@types/node": "11.13.22",
|
||||
"@types/node-emoji": "1.8.1",
|
||||
|
|
|
@ -1236,6 +1236,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/moment-timezone@0.5.12":
|
||||
version "0.5.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/moment-timezone/-/moment-timezone-0.5.12.tgz#0fb680c03db194fe8ff4551eaeb1eec8d3d80e9f"
|
||||
integrity sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==
|
||||
dependencies:
|
||||
moment ">=2.14.0"
|
||||
|
||||
"@types/nock@10.0.3":
|
||||
version "10.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/nock/-/nock-10.0.3.tgz#dab1d18ffbccfbf2db811dab9584304eeb6e1c4c"
|
||||
|
@ -6163,7 +6170,7 @@ moment-timezone@0.5.26:
|
|||
dependencies:
|
||||
moment ">= 2.9.0"
|
||||
|
||||
moment@2.24.0, "moment@>= 2.9.0", moment@^2.10.6:
|
||||
moment@2.24.0, "moment@>= 2.9.0", moment@>=2.14.0, moment@^2.10.6:
|
||||
version "2.24.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
|
||||
|
|
Loading…
Reference in a new issue