Skip to content

Commit

Permalink
feat: handle semver dependencies (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
devthejo authored Nov 5, 2024
1 parent d37934b commit c344213
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 6 deletions.
38 changes: 32 additions & 6 deletions packages/helm-tree/dependencies/download-helm-chart.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
const fs = require("fs-extra")

const semver = require("semver")
const axios = require("~common/utils/axios-retry")
const yaml = require("~common/utils/yaml")
const downloadFile = require("~common/utils/download-file")
const slug = require("~common/utils/slug")
const handleAxiosError = require("~common/utils/handle-axios-error")

function satisfiesVersion(availableVersion, requiredVersion) {
// If requiredVersion is an exact version (no special characters), do a direct comparison
if (/^\d+\.\d+\.\d+$/.test(requiredVersion)) {
return availableVersion === requiredVersion
}

// For all other cases, use semver.satisfies
return semver.satisfies(availableVersion, requiredVersion)
}

module.exports = async ({ dependency, target, cachePath, logger }) => {
const { repository, version } = dependency
const localArchive = `${target}/charts/${dependency.name}-${version}.tgz`
Expand All @@ -31,13 +41,29 @@ module.exports = async ({ dependency, target, cachePath, logger }) => {
const repo = yaml.load(repositoryIndex.data)
const { entries } = repo
const entryVersions = entries[dependency.name]
const versionEntry = entryVersions.find(
(entry) => entry.version.toString() === dependency.version.toString()

// Find all versions that satisfy the constraint
const satisfyingVersions = entryVersions.filter((entry) =>
satisfiesVersion(entry.version, dependency.version)
)
if (!versionEntry) {
throw new Error(`version ${version} not found for ${dependency.name}`)

if (satisfyingVersions.length === 0) {
throw new Error(
`No matching version found for ${dependency.name}@${version}`
)
}

// Sort the satisfying versions in descending order
satisfyingVersions.sort((a, b) => semver.rcompare(a.version, b.version))

// Select the newest version that satisfies the constraint
const versionEntry = satisfyingVersions[0]

let url = versionEntry.urls[0]
// Check if the URL is relative and add the repository as prefix if needed
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = `${repository.replace(/\/$/, "")}/${url.replace(/^\//, "")}`
}
const url = versionEntry.urls[0]
logger.debug(`⬇️ downloading chart ${url}`)
await downloadFile(url, zfile, logger)
}
Expand Down
1 change: 1 addition & 0 deletions packages/helm-tree/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"decompress": "^4.2.1",
"fs-extra": "^11.1.1",
"semver": "^7.6.3",
"~common": "workspace:^"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`test build manifests with snapshots helm-dependencies-with-not-fixed-version.dev 1`] = `
"apiVersion: v1
kind: ServiceAccount
metadata:
name: release-name-postgresql
namespace: default
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
annotations:
kontinuous/chartPath: project.postgresql
kontinuous/source: project/charts/postgresql/templates/serviceaccount.yaml
automountServiceAccountToken: false
---
apiVersion: v1
kind: Secret
metadata:
name: release-name-postgresql
namespace: default
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
annotations:
kontinuous/chartPath: project.postgresql
kontinuous/source: project/charts/postgresql/templates/secrets.yaml
type: Opaque
data:
postgres-password: MTIzNA==
---
apiVersion: v1
kind: Service
metadata:
name: release-name-postgresql-hl
namespace: default
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
app.kubernetes.io/component: primary
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: \\"true\\"
kontinuous/chartPath: project.postgresql
kontinuous/source: project/charts/postgresql/templates/primary/svc-headless.yaml
spec:
type: ClusterIP
clusterIP: None
publishNotReadyAddresses: true
ports:
- name: tcp-postgresql
port: 5432
targetPort: tcp-postgresql
selector:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: postgresql
app.kubernetes.io/component: primary
---
apiVersion: v1
kind: Service
metadata:
name: release-name-postgresql
namespace: default
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
app.kubernetes.io/component: primary
annotations:
kontinuous/chartPath: project.postgresql
kontinuous/source: project/charts/postgresql/templates/primary/svc.yaml
spec:
type: ClusterIP
sessionAffinity: None
ports:
- name: tcp-postgresql
port: 5432
targetPort: tcp-postgresql
selector:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: postgresql
app.kubernetes.io/component: primary
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: release-name-postgresql
namespace: default
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
app.kubernetes.io/component: primary
annotations:
kontinuous/chartPath: project.postgresql
kontinuous/source: project/charts/postgresql/templates/primary/statefulset.yaml
spec:
replicas: 1
serviceName: release-name-postgresql-hl
updateStrategy:
rollingUpdate: {}
type: RollingUpdate
selector:
matchLabels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: postgresql
app.kubernetes.io/component: primary
template:
metadata:
name: release-name-postgresql
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: postgresql
app.kubernetes.io/version: 16.1.0
helm.sh/chart: postgresql-13.4.4
app.kubernetes.io/component: primary
spec:
serviceAccountName: release-name-postgresql
automountServiceAccountToken: false
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: postgresql
app.kubernetes.io/component: primary
topologyKey: kubernetes.io/hostname
weight: 1
securityContext:
fsGroup: 1001
fsGroupChangePolicy: Always
supplementalGroups: []
sysctls: []
hostNetwork: false
hostIPC: false
containers:
- name: postgresql
image: docker.io/bitnami/postgresql:16.1.0-debian-11-r25
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
privileged: false
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 1001
seccompProfile:
type: RuntimeDefault
env:
- name: BITNAMI_DEBUG
value: \\"false\\"
- name: POSTGRESQL_PORT_NUMBER
value: \\"5432\\"
- name: POSTGRESQL_VOLUME_DIR
value: /bitnami/postgresql
- name: PGDATA
value: /bitnami/postgresql/data
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: release-name-postgresql
key: postgres-password
- name: POSTGRESQL_ENABLE_LDAP
value: \\"no\\"
- name: POSTGRESQL_ENABLE_TLS
value: \\"no\\"
- name: POSTGRESQL_LOG_HOSTNAME
value: \\"false\\"
- name: POSTGRESQL_LOG_CONNECTIONS
value: \\"false\\"
- name: POSTGRESQL_LOG_DISCONNECTIONS
value: \\"false\\"
- name: POSTGRESQL_PGAUDIT_LOG_CATALOG
value: \\"off\\"
- name: POSTGRESQL_CLIENT_MIN_MESSAGES
value: error
- name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES
value: pgaudit
ports:
- name: tcp-postgresql
containerPort: 5432
livenessProbe:
failureThreshold: 6
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
exec:
command:
- /bin/sh
- -c
- exec pg_isready -U \\"postgres\\" -h 127.0.0.1 -p 5432
readinessProbe:
failureThreshold: 6
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
exec:
command:
- /bin/sh
- -c
- -e
- >
exec pg_isready -U \\"postgres\\" -h 127.0.0.1 -p 5432
[ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ]
resources:
limits: {}
requests:
cpu: 250m
memory: 256Mi
volumeMounts:
- name: dshm
mountPath: /dev/shm
- name: data
mountPath: /bitnami/postgresql
volumes:
- name: dshm
emptyDir:
medium: Memory
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v2
name: postgresql
version: 0.0.0
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: ^13.0.0
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
global:
postgresql:
auth:
password: "1234"
postgresPassword: "1234"
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9305,6 +9305,7 @@ __metadata:
dependencies:
decompress: "npm:^4.2.1"
fs-extra: "npm:^11.1.1"
semver: "npm:^7.6.3"
~common: "workspace:^"
languageName: unknown
linkType: soft
Expand Down Expand Up @@ -14092,6 +14093,15 @@ __metadata:
languageName: node
linkType: hard

"semver@npm:^7.6.3":
version: 7.6.3
resolution: "semver@npm:7.6.3"
bin:
semver: bin/semver.js
checksum: 783216b1ad06776dda65c8d24f7e447fd7d129c83f0d2e795b2791d234e2b41b631f5520f8baa5e6e0f1624ffa56f363a20c5f309958cdba8d648cb3dff5d808
languageName: node
linkType: hard

"semver@npm:~7.0.0":
version: 7.0.0
resolution: "semver@npm:7.0.0"
Expand Down

0 comments on commit c344213

Please sign in to comment.