Skip to content

Commit

Permalink
feat: Cloud Native Buildpacks project descriptor manager
Browse files Browse the repository at this point in the history
  • Loading branch information
pbusko committed Aug 15, 2024
1 parent c1d44d5 commit 2ee3e78
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/config/options/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,7 @@ const options: RenovateOptions[] = [
supportedManagers: [
'ansible',
'bitbucket-pipelines',
'cnb-project-descriptor',
'crossplane',
'devcontainer',
'docker-compose',
Expand Down
1 change: 1 addition & 0 deletions lib/constants/category.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const Categories = [
'ansible',
'batect',
'bazel',
'buildpacks',
'c',
'cd',
'ci',
Expand Down
2 changes: 2 additions & 0 deletions lib/modules/manager/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import * as cargo from './cargo';
import * as cdnurl from './cdnurl';
import * as circleci from './circleci';
import * as cloudbuild from './cloudbuild';
import * as cnbProjectDesc from './cnb-project-descriptor';
import * as cocoapods from './cocoapods';
import * as composer from './composer';
import * as conan from './conan';
Expand Down Expand Up @@ -120,6 +121,7 @@ api.set('cargo', cargo);
api.set('cdnurl', cdnurl);
api.set('circleci', circleci);
api.set('cloudbuild', cloudbuild);
api.set('cnb-project-descriptor', cnbProjectDesc);
api.set('cocoapods', cocoapods);
api.set('composer', composer);
api.set('conan', conan);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[_]
schema-version = "0.2"

[io.buildpacks]
builder = "registry.corp/builder/noble:1.1.1"

[[io.buildpacks.group]]
uri = "docker://buildpacks/java:2.2.2"

[[io.buildpacks.group]]
uri = "buildpacks/nodejs:3.3.3"

[[io.buildpacks.group]]
uri = "file://local.oci"
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`modules/manager/cnb-project-descriptor/extract extractPackageFile() extracts builder and buildpack images 1`] = `
[
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
"currentDigest": undefined,
"currentValue": "1.1.1",
"datasource": "docker",
"depName": "registry.corp/builder/noble",
"replaceString": "registry.corp/builder/noble:1.1.1",
},
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
"currentDigest": undefined,
"currentValue": "2.2.2",
"datasource": "docker",
"depName": "buildpacks/java",
"replaceString": "buildpacks/java:2.2.2",
},
{
"autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}",
"currentDigest": undefined,
"currentValue": "3.3.3",
"datasource": "docker",
"depName": "buildpacks/nodejs",
"replaceString": "buildpacks/nodejs:3.3.3",
},
]
`;
21 changes: 21 additions & 0 deletions lib/modules/manager/cnb-project-descriptor/extract.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Fixtures } from '../../../../test/fixtures';

import { extractPackageFile } from '.';

describe('modules/manager/cnb-project-descriptor/extract', () => {
describe('extractPackageFile()', () => {
it('returns null for empty', () => {
expect(extractPackageFile('not a project toml', '', {})).toBeNull();
});

it('extracts builder and buildpack images', () => {
const res = extractPackageFile(
Fixtures.get('project.toml'),
'project.toml',
{},
);
expect(res?.deps).toMatchSnapshot();
expect(res?.deps).toHaveLength(3);
});
});
});
79 changes: 79 additions & 0 deletions lib/modules/manager/cnb-project-descriptor/extract.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import is from '@sindresorhus/is';
import { logger } from '../../../logger';
import { parse as parseToml } from '../../../util/toml';
import { getDep } from '../dockerfile/extract';
import type {
ExtractConfig,
PackageDependency,
PackageFileContent,
} from '../types';
import type { ProjectDescriptor } from './types';

const dockerPrefix = /^docker:\/\//;

export function extractPackageFile(
content: string,
packageFile: string,
config: ExtractConfig,
): PackageFileContent | null {
const deps: PackageDependency[] = [];
try {
const descriptor = parseToml(content) as ProjectDescriptor;
if (
descriptor.io.buildpacks?.builder &&
!descriptor.io.buildpacks.builder.startsWith('file://')
) {
const dep = getDep(
descriptor.io.buildpacks.builder.replace(dockerPrefix, ''),
true,
config.registryAliases,
);
logger.trace(
{
depName: dep.depName,
currentValue: dep.currentValue,
currentDigest: dep.currentDigest,
},
'Cloud Native Buildpacks builder',
);

deps.push(dep);
}

if (
descriptor.io.buildpacks?.group &&
is.array(descriptor.io.buildpacks.group)
) {
for (const group of descriptor.io.buildpacks.group) {
if (group.uri && !group.uri.startsWith('file://')) {
const dep = getDep(
group.uri.replace(dockerPrefix, ''),
true,
config.registryAliases,
);
logger.trace(
{
depName: dep.depName,
currentValue: dep.currentValue,
currentDigest: dep.currentDigest,
},
'Cloud Native Buildpack',
);

deps.push(dep);
}
}
}
} catch (err) {
logger.debug(
{ err, packageFile },
'Failed to parse buildpacks project descriptor TOML',
);
return null;
}

if (!deps.length) {
return null;
}
return { deps };
}
12 changes: 12 additions & 0 deletions lib/modules/manager/cnb-project-descriptor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Category } from '../../../constants';
import { DockerDatasource } from '../../datasource/docker';
export { extractPackageFile } from './extract';

export const defaultConfig = {
commitMessageTopic: 'buildpacks project descriptor {{depName}}',
fileMatch: ['(^|/)project\\.toml$'],
pinDigests: false,
};

export const categories: Category[] = ['docker', 'buildpacks'];
export const supportedDatasources = [DockerDatasource.id];
21 changes: 21 additions & 0 deletions lib/modules/manager/cnb-project-descriptor/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The `cnb-project-descriptor` manager updates Cloud Native Buildpacks project descriptor file (`project.toml`), which references builder and/or buildpack images by URIs.
Updates are performed if the `project.toml` file is found and it conforms to the [project descriptor](https://github.com/buildpacks/spec/blob/main/extensions/project-descriptor.md) specification.

__Note__: buildpacks in the `io.buildpacks.group` array must be configured with the docker reference (`uri`) for this manager to work.

```toml
[_]
schema-version = "0.2"

[io.buildpacks]
builder = "registry.corp/builder/noble:1.1.1"

[[io.buildpacks.group]]
uri = "docker://buildpacks/java:2.2.2"

[[io.buildpacks.group]]
uri = "buildpacks/nodejs:3.3.3"

[[io.buildpacks.group]]
uri = "file://local.oci" # will be ignored
```
15 changes: 15 additions & 0 deletions lib/modules/manager/cnb-project-descriptor/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface BuildpackGroup {
uri?: string;
}

export interface IoBuildpacks {
builder?: string;
group?: BuildpackGroup[];
}

export interface ProjectDescriptor {
'schema-version'?: string;
io: {
buildpacks?: IoBuildpacks;
};
}

0 comments on commit 2ee3e78

Please sign in to comment.