mirror of
https://github.com/renovatebot/renovate.git
synced 2026-10-25 15:01:49 +00:00
feat(manager): add bitrise manager (#30256)
This commit is contained in:
committed by
GitHub
parent
4da584a9a2
commit
d439f84bf9
@@ -10,6 +10,7 @@ import * as bazelModule from './bazel-module';
|
||||
import * as bazelisk from './bazelisk';
|
||||
import * as bicep from './bicep';
|
||||
import * as bitbucketPipelines from './bitbucket-pipelines';
|
||||
import * as bitrise from './bitrise';
|
||||
import * as buildkite from './buildkite';
|
||||
import * as bun from './bun';
|
||||
import * as bundler from './bundler';
|
||||
@@ -108,6 +109,7 @@ api.set('bazel-module', bazelModule);
|
||||
api.set('bazelisk', bazelisk);
|
||||
api.set('bicep', bicep);
|
||||
api.set('bitbucket-pipelines', bitbucketPipelines);
|
||||
api.set('bitrise', bitrise);
|
||||
api.set('buildkite', buildkite);
|
||||
api.set('bun', bun);
|
||||
api.set('bundler', bundler);
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
import { codeBlock } from 'common-tags';
|
||||
import { BitriseDatasource } from '../../datasource/bitrise';
|
||||
import { extractPackageFile } from '.';
|
||||
|
||||
describe('modules/manager/bitrise/extract', () => {
|
||||
describe('extractPackageFile()', () => {
|
||||
it('returns null on an empty file', () => {
|
||||
expect(extractPackageFile('', 'bitrise.yml')).toBeNull();
|
||||
});
|
||||
|
||||
it('returns a valid file', () => {
|
||||
expect(
|
||||
extractPackageFile(
|
||||
codeBlock`
|
||||
workflows:
|
||||
test:
|
||||
steps:
|
||||
- script@1.1.5:
|
||||
`,
|
||||
'bitrise.yml',
|
||||
),
|
||||
).toEqual({
|
||||
deps: [
|
||||
{
|
||||
datasource: BitriseDatasource.id,
|
||||
packageName: 'script',
|
||||
currentValue: '1.1.5',
|
||||
replaceString: 'script@1.1.5',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a valid file with custom default_step_lib_source', () => {
|
||||
expect(
|
||||
extractPackageFile(
|
||||
codeBlock`
|
||||
format_version: 11
|
||||
default_step_lib_source: https://github.com/custom/steplib.git
|
||||
project_type: android
|
||||
app:
|
||||
envs:
|
||||
- MY_NAME: My Name
|
||||
workflows:
|
||||
test:
|
||||
steps:
|
||||
- script@1.1.5:
|
||||
inputs:
|
||||
- content: echo "Hello!"
|
||||
- restore-cache@1.1.2:
|
||||
foo: bar
|
||||
`,
|
||||
'bitrise.yml',
|
||||
),
|
||||
).toEqual({
|
||||
deps: [
|
||||
{
|
||||
datasource: BitriseDatasource.id,
|
||||
packageName: 'script',
|
||||
currentValue: '1.1.5',
|
||||
replaceString: 'script@1.1.5',
|
||||
registryUrls: ['https://github.com/custom/steplib.git'],
|
||||
},
|
||||
{
|
||||
datasource: BitriseDatasource.id,
|
||||
packageName: 'restore-cache',
|
||||
currentValue: '1.1.2',
|
||||
replaceString: 'restore-cache@1.1.2',
|
||||
registryUrls: ['https://github.com/custom/steplib.git'],
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('extracts git and path prefixes', () => {
|
||||
expect(
|
||||
extractPackageFile(
|
||||
codeBlock`
|
||||
workflows:
|
||||
test:
|
||||
steps:
|
||||
- git::https://github.com/bitrise-io/steps-script.git@1.1.3:
|
||||
- path::./relative/path:
|
||||
- https://github.com/foo/bar.git::script@1:
|
||||
`,
|
||||
'bitrise.yml',
|
||||
),
|
||||
).toEqual({
|
||||
deps: [
|
||||
{
|
||||
currentValue: '1.1.3',
|
||||
datasource: 'git-tags',
|
||||
packageName: 'https://github.com/bitrise-io/steps-script.git',
|
||||
replaceString:
|
||||
'git::https://github.com/bitrise-io/steps-script.git@1.1.3',
|
||||
},
|
||||
{
|
||||
datasource: 'bitrise',
|
||||
packageName: 'path::./relative/path',
|
||||
replaceString: 'path::./relative/path',
|
||||
skipReason: 'unspecified-version',
|
||||
},
|
||||
{
|
||||
currentValue: '1',
|
||||
datasource: 'bitrise',
|
||||
packageName: 'script',
|
||||
registryUrls: ['https://github.com/foo/bar.git'],
|
||||
replaceString: 'https://github.com/foo/bar.git::script@1',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('extracts Bitrise library reference', () => {
|
||||
expect(
|
||||
extractPackageFile(
|
||||
codeBlock`
|
||||
workflows:
|
||||
test:
|
||||
steps:
|
||||
- https://github.com/foo/bar.git::script@1:
|
||||
`,
|
||||
'bitrise.yml',
|
||||
),
|
||||
).toEqual({
|
||||
deps: [
|
||||
{
|
||||
currentValue: '1',
|
||||
datasource: 'bitrise',
|
||||
packageName: 'script',
|
||||
registryUrls: ['https://github.com/foo/bar.git'],
|
||||
replaceString: 'https://github.com/foo/bar.git::script@1',
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import is from '@sindresorhus/is';
|
||||
import { logger } from '../../../logger';
|
||||
import { parseSingleYaml } from '../../../util/yaml';
|
||||
import type { PackageDependency, PackageFileContent } from '../types';
|
||||
import { BitriseFile } from './schema';
|
||||
import { parseStep } from './utils';
|
||||
|
||||
export function extractPackageFile(
|
||||
content: string,
|
||||
packageFile: string,
|
||||
): PackageFileContent | null {
|
||||
const deps: PackageDependency[] = [];
|
||||
|
||||
try {
|
||||
const parsed = parseSingleYaml(content, {
|
||||
customSchema: BitriseFile,
|
||||
});
|
||||
|
||||
const workflows = Object.values(parsed.workflows);
|
||||
for (const workflow of workflows) {
|
||||
const steps = workflow.steps.flatMap((step) => Object.keys(step));
|
||||
for (const step of steps) {
|
||||
const dep = parseStep(step, parsed.default_step_lib_source);
|
||||
|
||||
if (!is.nullOrUndefined(dep)) {
|
||||
deps.push(dep);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
logger.debug({ err, packageFile }, `Failed to parse Bitrise YAML config`);
|
||||
}
|
||||
|
||||
if (!deps.length) {
|
||||
return null;
|
||||
}
|
||||
return { deps };
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { Category } from '../../../constants';
|
||||
import { BitriseDatasource } from '../../datasource/bitrise';
|
||||
import { GitTagsDatasource } from '../../datasource/git-tags';
|
||||
import { extractPackageFile } from './extract';
|
||||
|
||||
export { extractPackageFile };
|
||||
|
||||
export const defaultConfig = {
|
||||
fileMatch: ['(^|/)bitrise\\.ya?ml$'],
|
||||
};
|
||||
|
||||
export const displayName = 'Bitrise';
|
||||
|
||||
export const categories: Category[] = ['ci'];
|
||||
|
||||
export const supportedDatasources = [
|
||||
BitriseDatasource.id,
|
||||
GitTagsDatasource.id,
|
||||
];
|
||||
|
||||
export const urls = [
|
||||
'https://devcenter.bitrise.io/en/steps-and-workflows/introduction-to-steps.html',
|
||||
];
|
||||
@@ -0,0 +1 @@
|
||||
Updates step references of `bitrise.yml` files.
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const BitriseStep = z.record(z.string(), z.unknown());
|
||||
|
||||
export const BitriseWorkflow = z.object({
|
||||
steps: z.array(BitriseStep),
|
||||
});
|
||||
|
||||
export const BitriseFile = z.object({
|
||||
default_step_lib_source: z.string().optional(),
|
||||
workflows: z.record(z.string(), BitriseWorkflow),
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { BitriseDatasource } from '../../datasource/bitrise';
|
||||
import { parseStep } from './utils';
|
||||
|
||||
describe('modules/manager/bitrise/utils', () => {
|
||||
describe('parseStep()', () => {
|
||||
it('returns null on an empty string', () => {
|
||||
expect(parseStep('')).toBeNull();
|
||||
});
|
||||
|
||||
it('returns dependency for step', () => {
|
||||
expect(parseStep('restore-gradle-cache@1.1.2')).toEqual({
|
||||
currentValue: '1.1.2',
|
||||
datasource: BitriseDatasource.id,
|
||||
packageName: 'restore-gradle-cache',
|
||||
replaceString: 'restore-gradle-cache@1.1.2',
|
||||
});
|
||||
});
|
||||
|
||||
it('parses missing version', () => {
|
||||
expect(parseStep('share-pipeline-variable')).toEqual({
|
||||
datasource: BitriseDatasource.id,
|
||||
packageName: 'share-pipeline-variable',
|
||||
replaceString: 'share-pipeline-variable',
|
||||
skipReason: 'unspecified-version',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,85 @@
|
||||
import is from '@sindresorhus/is';
|
||||
import { BitriseDatasource } from '../../datasource/bitrise';
|
||||
import { GitTagsDatasource } from '../../datasource/git-tags';
|
||||
import type { PackageDependency } from '../types';
|
||||
|
||||
export function parseStep(
|
||||
stepRef: string,
|
||||
defaultRegistry?: string,
|
||||
): PackageDependency | null {
|
||||
if (is.emptyString(stepRef)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const dep: PackageDependency = {
|
||||
datasource: BitriseDatasource.id,
|
||||
replaceString: stepRef,
|
||||
};
|
||||
|
||||
const [ref, currentValue] = stepRef.split('@', 2);
|
||||
|
||||
const refDep = parseStepRef(ref, defaultRegistry);
|
||||
|
||||
// no version
|
||||
if (is.nullOrUndefined(currentValue)) {
|
||||
return {
|
||||
...dep,
|
||||
packageName: stepRef,
|
||||
skipReason: 'unspecified-version',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
...dep,
|
||||
...refDep,
|
||||
currentValue,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseStepRef(
|
||||
ref: string,
|
||||
defaultRegistry?: string,
|
||||
): PackageDependency {
|
||||
// handle local path
|
||||
// https://devcenter.bitrise.io/en/references/steps-reference/step-reference-id-format.html
|
||||
if (ref.startsWith('path::')) {
|
||||
return {
|
||||
depName: ref.split('::', 2)[1],
|
||||
skipReason: 'local-dependency',
|
||||
};
|
||||
}
|
||||
|
||||
// handle Git references
|
||||
// https://devcenter.bitrise.io/en/references/steps-reference/step-reference-id-format.html
|
||||
if (ref.startsWith('git::')) {
|
||||
const [, packageName] = ref.split('::');
|
||||
return {
|
||||
packageName,
|
||||
datasource: GitTagsDatasource.id,
|
||||
};
|
||||
}
|
||||
|
||||
// step library references
|
||||
// https://devcenter.bitrise.io/en/references/steps-reference/step-reference-id-format.html
|
||||
const splitted = ref.split('::', 2);
|
||||
|
||||
// reference which uses default registry
|
||||
// - script:
|
||||
if (splitted.length === 1) {
|
||||
const [packageName] = splitted;
|
||||
return {
|
||||
packageName,
|
||||
datasource: BitriseDatasource.id,
|
||||
registryUrls: defaultRegistry ? [defaultRegistry] : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
// reference which overwrites Bitrise registry
|
||||
// https://github.com/bitrise-io/bitrise-steplib.git::script@1:
|
||||
const [registryUrl, packageName] = splitted;
|
||||
return {
|
||||
packageName,
|
||||
datasource: BitriseDatasource.id,
|
||||
registryUrls: [registryUrl],
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user