Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(datasource/helm): optimize sourceurl massaging #11794

Merged
merged 4 commits into from Sep 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/datasource/helm/__fixtures__/index.yaml
Expand Up @@ -1851,7 +1851,6 @@ entries:
version: 1.1.0
- apiVersion: v1
appVersion: 0.50.1
created: 2019-02-13T00:56:01.476895808Z
description: A Helm chart for Datawire Ambassador
digest: aa09c62be843190cc85736ba59d6411579d83ba30e9305e6b2420ea013bb5979
engine: gotpl
Expand Down
95 changes: 95 additions & 0 deletions lib/datasource/helm/__fixtures__/sample.yaml
@@ -0,0 +1,95 @@
apiVersion: v1
entries:
airflow:
- annotations:
category: WorkFlow
apiVersion: v2
appVersion: 2.1.3
created: "2021-09-15T23:14:58.888273096Z"
dependencies:
- name: common
repository: https://charts.bitnami.com/bitnami
tags:
- bitnami-common
version: 1.x.x
- condition: postgresql.enabled
name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 10.x.x
- condition: redis.enabled
name: redis
repository: https://charts.bitnami.com/bitnami
version: 15.x.x
description: Apache Airflow is a platform to programmatically author, schedule
and monitor workflows.
digest: a651914c82b5aa5d005b24591c2474245942e6bede1a434ea74227d1a58a269c
home: https://github.com/bitnami/charts/tree/master/bitnami/airflow
icon: https://bitnami.com/assets/stacks/airflow/img/airflow-stack-220x234.png
keywords:
- apache
- airflow
- workflow
- dag
maintainers:
- email: containers@bitnami.com
name: Bitnami
name: airflow
sources:
- https://github.com/bitnami/bitnami-docker-airflow
- https://airflow.apache.org/
urls:
- https://charts.bitnami.com/bitnami/airflow-11.0.1.tgz
version: 11.0.1
coredns:
- annotations:
artifacthub.io/changes: |
- Initial helm chart changelog
apiVersion: v2
appVersion: 1.8.4
created: "2021-07-24T17:35:31.367313224Z"
description: CoreDNS is a DNS server that chains plugins and provides Kubernetes
DNS Services
digest: d7015cc7970f7304d8b023d12a854f1684f5b79b120e3eea22b78ac590d05b35
home: https://coredns.io
icon: https://coredns.io/images/CoreDNS_Colour_Horizontal.png
keywords:
- coredns
- dns
- kubedns
maintainers:
- name: mrueg
- name: haad
name: coredns
sources:
- https://github.com/coredns/coredns
type: application
urls:
- https://github.com/coredns/helm/releases/download/coredns-1.16.3/coredns-1.16.3.tgz
version: 1.16.3
pgadmin4:
- apiVersion: v1
appVersion: "5.5"
created: "2021-08-23T07:25:42.700577873Z"
description: pgAdmin4 is a web based administration tool for PostgreSQL database
digest: b15e5de91fcbe8c2cc896af8448e41ad94a9bfae9592fc13d3e5805d4cb707b0
home: https://www.pgadmin.org/
icon: https://wiki.postgresql.org/images/3/30/PostgreSQL_logo.3colors.120x120.png
keywords:
- pgadmin
- postgres
- database
- sql
maintainers:
- email: rowanruseler@gmail.com
name: rowanruseler
name: pgadmin4
sources:
- https://some.test
- https://github.com/rowanruseler/helm-charts
urls:
- pgadmin4-1.7.2.tgz
version: 1.7.2
dummy:
- home:
urls:
- some.tgz
1 change: 0 additions & 1 deletion lib/datasource/helm/__snapshots__/index.spec.ts.snap
Expand Up @@ -20,7 +20,6 @@ Object {
"registryUrl": "https://example-repository.com",
"releases": Array [
Object {
"releaseTimestamp": "2019-02-13T00:56:01.476Z",
"version": "1.0.0",
},
Object {
Expand Down
26 changes: 26 additions & 0 deletions lib/datasource/helm/common.spec.ts
@@ -0,0 +1,26 @@
import { load } from 'js-yaml';
import { loadFixture } from '../../../test/util';
import { findSourceUrl } from './common';
import type { HelmRepository } from './types';

// Truncated index.yaml file
const repo = load(loadFixture('sample.yaml'), {
json: true,
}) as HelmRepository;

describe('datasource/helm/common', () => {
describe('findSourceUrl', () => {
test.each`
input | output
${'airflow'} | ${'https://github.com/bitnami/charts'}
${'coredns'} | ${'https://github.com/coredns/helm'}
${'pgadmin4'} | ${'https://github.com/rowanruseler/helm-charts'}
${'dummy'} | ${undefined}
`(
'$input -> $output',
({ input, output }: { input: string; output: string }) => {
expect(findSourceUrl(repo.entries[input][0])).toEqual(output);
}
);
});
});
33 changes: 33 additions & 0 deletions lib/datasource/helm/common.ts
@@ -0,0 +1,33 @@
import type { HelmRelease } from './types';

const chartRepo = /charts?|helm|helm-charts/i;
const githubUrl =
/^(?<url>https:\/\/github\.com\/[^/]+\/(?<repo>[^/]+))(?:\/|$)/;
const githubRelease = /^(https:\/\/github\.com\/[^/]+\/[^/]+)\/releases\//;

export function findSourceUrl(release: HelmRelease): string {
// it's a github release :)
let match = githubRelease.exec(release.urls[0]);
if (match) {
return match[1];
}

match = githubUrl.exec(release.home);
if (chartRepo.test(match?.groups.repo)) {
return match.groups.url;
}

if (!release.sources?.length) {
return undefined;
}

for (const url of release.sources) {
match = githubUrl.exec(url);
if (chartRepo.test(match?.groups.repo)) {
return match.groups.url;
}
}

// fallback
return release.sources[0];
}
5 changes: 3 additions & 2 deletions lib/datasource/helm/index.ts
Expand Up @@ -5,6 +5,7 @@ import { cache } from '../../util/cache/package/decorator';
import { ensureTrailingSlash } from '../../util/url';
import { Datasource } from '../datasource';
import type { GetReleasesConfig, ReleaseResult } from '../types';
import { findSourceUrl } from './common';
import type { HelmRepository, RepositoryData } from './types';

export class HelmDatasource extends Datasource {
Expand Down Expand Up @@ -52,10 +53,10 @@ export class HelmDatasource extends Datasource {
for (const [name, releases] of Object.entries(doc.entries)) {
result[name] = {
homepage: releases[0].home,
sourceUrl: releases[0].sources ? releases[0].sources[0] : undefined,
sourceUrl: findSourceUrl(releases[0]),
releases: releases.map((release) => ({
version: release.version,
releaseTimestamp: release.created ? release.created : null,
releaseTimestamp: release.created ?? null,
})),
};
}
Expand Down
18 changes: 9 additions & 9 deletions lib/datasource/helm/types.ts
@@ -1,15 +1,15 @@
import type { ReleaseResult } from '../types';

export interface HelmRelease {
home?: string;
sources?: string[];
version: string;
created: string;
urls: string[];
}

export interface HelmRepository {
entries: Record<
string,
{
home?: string;
sources?: string[];
version: string;
created: string;
}[]
>;
entries: Record<string, HelmRelease[]>;
}

export type RepositoryData = Record<string, ReleaseResult>;