-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(managers/ocb): add new manager for OpenTelemetryCollectorBuilder (…
…#26509) Co-authored-by: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com>
- Loading branch information
1 parent
5f24ab9
commit b14661f
Showing
9 changed files
with
354 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { codeBlock } from 'common-tags'; | ||
import { extractPackageFile } from '.'; | ||
|
||
describe('modules/manager/ocb/extract', () => { | ||
describe('extractPackageFile', () => { | ||
it('run successfully with full example', () => { | ||
const content = codeBlock` | ||
dist: | ||
name: otelcol-custom | ||
description: Local OpenTelemetry Collector binary | ||
module: github.com/open-telemetry/opentelemetry-collector | ||
otelcol_version: 0.40.0 | ||
version: 1.0.0 | ||
output_path: /tmp/dist | ||
exporters: | ||
- gomod: github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter v0.86.0 | ||
- gomod: go.opentelemetry.io/collector/exporter/debugexporter v0.86.0 | ||
receivers: | ||
- gomod: go.opentelemetry.io/collector/receiver/otlpreceiver v0.86.0 | ||
processors: | ||
- gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.86.0 | ||
`; | ||
const result = extractPackageFile(content, 'builder-config.yaml'); | ||
expect(result?.deps).toEqual([ | ||
{ | ||
currentValue: '0.40.0', | ||
datasource: 'go', | ||
depName: 'github.com/open-telemetry/opentelemetry-collector', | ||
depType: 'collector', | ||
extractVersion: '^v(?<version>\\S+)', | ||
}, | ||
{ | ||
currentValue: 'v0.86.0', | ||
datasource: 'go', | ||
depName: | ||
'github.com/open-telemetry/opentelemetry-collector-contrib/exporter/alibabacloudlogserviceexporter', | ||
depType: 'exports', | ||
}, | ||
{ | ||
currentValue: 'v0.86.0', | ||
datasource: 'go', | ||
depName: 'go.opentelemetry.io/collector/exporter/debugexporter', | ||
depType: 'exports', | ||
}, | ||
{ | ||
currentValue: 'v0.86.0', | ||
datasource: 'go', | ||
depName: 'go.opentelemetry.io/collector/processor/batchprocessor', | ||
depType: 'processors', | ||
}, | ||
]); | ||
}); | ||
|
||
it('return null for unknown content', () => { | ||
expect(extractPackageFile('foo', 'bar.yaml')).toBeNull(); | ||
}); | ||
|
||
it('return null for content which is not YAML', () => { | ||
expect( | ||
extractPackageFile( | ||
codeBlock` | ||
myObject: | ||
aString: value | ||
--- | ||
foo: bar | ||
`, | ||
'bar.yaml', | ||
), | ||
).toBeNull(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import is from '@sindresorhus/is'; | ||
import { logger } from '../../../logger'; | ||
import { regEx } from '../../../util/regex'; | ||
import { parseSingleYaml } from '../../../util/yaml'; | ||
import { GoDatasource } from '../../datasource/go'; | ||
import type { | ||
ExtractConfig, | ||
PackageDependency, | ||
PackageFileContent, | ||
} from '../types'; | ||
import { type Module, type OCBConfig, OCBConfigSchema } from './schema'; | ||
|
||
export function extractPackageFile( | ||
content: string, | ||
packageFile: string, | ||
_config?: ExtractConfig, | ||
): PackageFileContent | null { | ||
let definition: OCBConfig | null = null; | ||
try { | ||
const yaml = parseSingleYaml(content); | ||
const parsed = OCBConfigSchema.safeParse(yaml); | ||
if (!parsed.success) { | ||
logger.trace( | ||
{ packageFile, error: parsed.error }, | ||
'Failed to parse OCB schema', | ||
); | ||
return null; | ||
} | ||
|
||
definition = parsed.data; | ||
} catch (error) { | ||
logger.debug( | ||
{ packageFile, error }, | ||
'OCB manager failed to parse file as YAML', | ||
); | ||
return null; | ||
} | ||
|
||
const deps: PackageDependency[] = []; | ||
if (definition.dist.module && definition.dist.otelcol_version) { | ||
deps.push({ | ||
datasource: GoDatasource.id, | ||
depType: 'collector', | ||
depName: definition.dist.module, | ||
currentValue: definition.dist.otelcol_version, | ||
extractVersion: '^v(?<version>\\S+)', | ||
}); | ||
} | ||
|
||
deps.push(...processModule(definition.connectors, 'connectors')); | ||
deps.push(...processModule(definition.exporters, 'exports')); | ||
deps.push(...processModule(definition.extension, 'extensions')); | ||
deps.push(...processModule(definition.processors, 'processors')); | ||
|
||
return { | ||
packageFileVersion: definition.dist.version, | ||
deps, | ||
}; | ||
} | ||
|
||
export function processModule( | ||
module: Module, | ||
depType: string, | ||
): PackageDependency[] { | ||
const deps: PackageDependency[] = []; | ||
if (is.nullOrUndefined(module)) { | ||
return deps; | ||
} | ||
|
||
for (const element of module) { | ||
const [depName, currentValue] = element.gomod.trim().split(regEx(/\s+/)); | ||
deps.push({ | ||
datasource: GoDatasource.id, | ||
depType, | ||
depName, | ||
currentValue, | ||
}); | ||
} | ||
|
||
return deps; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import type { Category } from '../../../constants'; | ||
import { GoDatasource } from '../../datasource/go'; | ||
|
||
export { extractPackageFile } from './extract'; | ||
export { bumpPackageVersion } from './update'; | ||
|
||
export const supportedDatasources = [GoDatasource.id]; | ||
|
||
export const categories: Category[] = ['golang']; | ||
|
||
export const defaultConfig = { | ||
fileMatch: [], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
Renovate uses this manager to update dependencies defined in the build definitions for the [OpenTelemetry Collector Builder (ocb)](https://github.com/open-telemetry/opentelemetry-collector/tree/main/cmd/builder). | ||
|
||
By default, the `ocb` manager has no `fileMatch` patterns. | ||
This means you must set a `fileMatch` pattern for the `ocb` manager, in order for Renovate to update your `ocb` files. | ||
Here's a configuration example: | ||
|
||
```json title="If your builder files are named like foo-builder.yml or builder.yaml" | ||
{ | ||
"ocb": { | ||
"fileMatch": ["builder.ya?ml$"] | ||
} | ||
} | ||
``` | ||
|
||
Supported dependencies and their respective `depType`s are: | ||
|
||
| Name | depType | | ||
| -------------- | ------------ | | ||
| base collector | `collector` | | ||
| connectors | `connectors` | | ||
| exports | `exports` | | ||
| extensions | `extensions` | | ||
| processors | `processors` | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { z } from 'zod'; | ||
|
||
const Entry = z.object({ | ||
gomod: z.string(), | ||
}); | ||
|
||
const ModuleSchema = z.array(Entry).optional(); | ||
export type Module = z.infer<typeof ModuleSchema>; | ||
|
||
export const OCBConfigSchema = z.object({ | ||
dist: z.object({ | ||
otelcol_version: z.string().optional(), | ||
module: z.string().optional(), | ||
version: z.string().optional(), | ||
}), | ||
extension: ModuleSchema, | ||
exporters: ModuleSchema, | ||
receivers: ModuleSchema, | ||
processors: ModuleSchema, | ||
connectors: ModuleSchema, | ||
}); | ||
export type OCBConfig = z.infer<typeof OCBConfigSchema>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { codeBlock } from 'common-tags'; | ||
import { bumpPackageVersion } from '.'; | ||
|
||
describe('modules/manager/ocb/update', () => { | ||
describe('bumpPackageVersion()', () => { | ||
it('increments with all fields', () => { | ||
const content = codeBlock` | ||
dist: | ||
name: otelcol-custom | ||
description: Local OpenTelemetry Collector binary | ||
module: github.com/open-telemetry/opentelemetry-collector | ||
otelcol_version: 0.40.0 | ||
version: 1.0.0 | ||
output_path: /tmp/dist | ||
`; | ||
const expected = content.replace('1.0.0', '1.0.1'); | ||
|
||
const { bumpedContent } = bumpPackageVersion(content, '1.0.0', 'patch'); | ||
expect(bumpedContent).toEqual(expected); | ||
}); | ||
|
||
it('increments with double quotes', () => { | ||
const content = codeBlock` | ||
dist: | ||
version: "1.0.0" | ||
`; | ||
const expected = content.replace('1.0.0', '1.0.1'); | ||
|
||
const { bumpedContent } = bumpPackageVersion(content, '1.0.0', 'patch'); | ||
expect(bumpedContent).toEqual(expected); | ||
}); | ||
|
||
it('increments with single quotes', () => { | ||
const content = codeBlock` | ||
dist: | ||
version: '1.0.0' | ||
`; | ||
const expected = content.replace('1.0.0', '1.0.1'); | ||
|
||
const { bumpedContent } = bumpPackageVersion(content, '1.0.0', 'patch'); | ||
expect(bumpedContent).toEqual(expected); | ||
}); | ||
|
||
it('no ops', () => { | ||
const content = codeBlock` | ||
dist: | ||
version: '0.0.2' | ||
`; | ||
const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'patch'); | ||
expect(bumpedContent).toEqual(content); | ||
}); | ||
|
||
it('updates', () => { | ||
const content = codeBlock` | ||
dist: | ||
version: '0.0.2' | ||
`; | ||
const { bumpedContent } = bumpPackageVersion(content, '0.0.1', 'minor'); | ||
const expected = content.replace('0.0.2', '0.1.0'); | ||
expect(bumpedContent).toEqual(expected); | ||
}); | ||
|
||
it('returns content if bumping errors', () => { | ||
const content = codeBlock` | ||
dist: | ||
version: '1.0.0' | ||
`; | ||
const { bumpedContent } = bumpPackageVersion( | ||
content, | ||
'0.0.2', | ||
// @ts-expect-error supplying a wrong parameter to trigger an exception | ||
true, | ||
); | ||
expect(bumpedContent).toEqual(content); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { type ReleaseType, inc } from 'semver'; | ||
import { logger } from '../../../logger'; | ||
import { regEx } from '../../../util/regex'; | ||
import type { BumpPackageVersionResult } from '../types'; | ||
|
||
export function bumpPackageVersion( | ||
content: string, | ||
currentValue: string, | ||
bumpVersion: ReleaseType, | ||
): BumpPackageVersionResult { | ||
logger.debug( | ||
{ bumpVersion, currentValue }, | ||
'Checking if we should bump OCB version', | ||
); | ||
|
||
let bumpedContent = content; | ||
try { | ||
const newProjectVersion = inc(currentValue, bumpVersion); | ||
if (!newProjectVersion) { | ||
throw new Error('semver inc failed'); | ||
} | ||
|
||
logger.debug(`newProjectVersion: ${newProjectVersion}`); | ||
bumpedContent = content.replace( | ||
regEx(/\b(?<version>version:\s+["']?)(?<currentValue>[^'"\s]*)/), | ||
`$<version>${newProjectVersion}`, | ||
); | ||
|
||
if (bumpedContent === content) { | ||
logger.debug('Version was already bumped'); | ||
} else { | ||
logger.debug('Bumped OCB version'); | ||
} | ||
} catch (err) { | ||
logger.warn( | ||
{ | ||
content, | ||
currentValue, | ||
bumpVersion, | ||
manager: 'ocb', | ||
}, | ||
'Failed to bumpVersion', | ||
); | ||
} | ||
|
||
return { bumpedContent }; | ||
} |