From 72fab2f8c2cb52f7fa2475b40e84ed8f81723fce Mon Sep 17 00:00:00 2001 From: Alex Lokshin Date: Fri, 7 Feb 2025 13:17:36 -0800 Subject: [PATCH 1/3] fix: Update runs-on labels in GitHub Actions workflows (#189) --- .github/workflows/chart-dependency-update.yaml | 2 +- .github/workflows/chart-release.yaml | 4 ++-- .github/workflows/conventional-commits.yml | 2 +- .github/workflows/generate-schemas.yaml | 2 +- .github/workflows/release-please.yaml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/chart-dependency-update.yaml b/.github/workflows/chart-dependency-update.yaml index 309de0a..aee0b98 100644 --- a/.github/workflows/chart-dependency-update.yaml +++ b/.github/workflows/chart-dependency-update.yaml @@ -8,7 +8,7 @@ on: jobs: update_chart_locks: - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: - name: Generate token id: generate_token diff --git a/.github/workflows/chart-release.yaml b/.github/workflows/chart-release.yaml index f3899fd..82d9498 100644 --- a/.github/workflows/chart-release.yaml +++ b/.github/workflows/chart-release.yaml @@ -10,7 +10,7 @@ concurrency: jobs: check-chart-released: - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: - name: Checkout uses: actions/checkout@v4 @@ -37,7 +37,7 @@ jobs: if: ${{ needs.check-chart-released.outputs.chart_released == 'true' }} needs: - check-chart-released - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: - name: Parse Tag id: parse_tag diff --git a/.github/workflows/conventional-commits.yml b/.github/workflows/conventional-commits.yml index b99bfe2..8eb791d 100644 --- a/.github/workflows/conventional-commits.yml +++ b/.github/workflows/conventional-commits.yml @@ -14,6 +14,6 @@ concurrency: cancel-in-progress: true jobs: conventional_commit_title: - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: - uses: chanzuckerberg/github-actions/.github/actions/conventional-commits@v1.4.0 diff --git a/.github/workflows/generate-schemas.yaml b/.github/workflows/generate-schemas.yaml index 476646f..9bb63e5 100644 --- a/.github/workflows/generate-schemas.yaml +++ b/.github/workflows/generate-schemas.yaml @@ -7,7 +7,7 @@ on: jobs: update_schema_and_readme: - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/release-please.yaml b/.github/workflows/release-please.yaml index e711b28..c77ba3e 100644 --- a/.github/workflows/release-please.yaml +++ b/.github/workflows/release-please.yaml @@ -8,7 +8,7 @@ concurrency: name: release-please jobs: release-please: - runs-on: [ARM64, self-hosted, Linux] + runs-on: ARM64 steps: # See https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow # For why we need to generate a token and not use the default From 2a396e0078d5e481d149dc266318c2160a2f686a Mon Sep 17 00:00:00 2001 From: Hayden Spitzley <105455169+hspitzley-czi@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:14:10 -0700 Subject: [PATCH 2/3] feat: add support for k8s jobs to stack helm chart (#190) --- Makefile | 2 + common.mk | 8 ++ stack/Makefile | 2 + stack/README.md | 1 + stack/templates/job.yaml | 179 ++++++++++++++++++++++++++++++++++ stack/tests/cronjob_test.yaml | 2 +- stack/tests/job_test.yaml | 122 +++++++++++++++++++++++ stack/values.schema.json | 5 + stack/values.yaml | 18 ++++ 9 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100755 common.mk create mode 100644 stack/Makefile create mode 100644 stack/templates/job.yaml create mode 100644 stack/tests/job_test.yaml diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..12c496b --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ + +include ./common.mk diff --git a/common.mk b/common.mk new file mode 100755 index 0000000..6e1942a --- /dev/null +++ b/common.mk @@ -0,0 +1,8 @@ + +.PHONY: test +test: + @for i in $$(find . -type d); do \ + if [ -e "$$i/Chart.yaml" ]; then \ + helm unittest $$i; \ + fi; \ + done diff --git a/stack/Makefile b/stack/Makefile new file mode 100644 index 0000000..5fe6707 --- /dev/null +++ b/stack/Makefile @@ -0,0 +1,2 @@ + +include ../common.mk diff --git a/stack/README.md b/stack/README.md index fe755b3..b25bcc3 100644 --- a/stack/README.md +++ b/stack/README.md @@ -149,3 +149,4 @@ A Helm chart for deploying an Argus stack. | `global.oidcProxy.resources.requests.memory` | Memory request | `4Gi` | | `services` | Services to deploy, all values in the above global section are inherited by the services and each service can override them | `{}` | | `cronJobs` | Cron jobs to deploy, all values in the above global section are inherited by the cron jobs and each cron job can override them | `{}` | +| `jobs` | Jobs to deploy, all values in the above global section are inherited by the jobs and each job can override them | `{}` | diff --git a/stack/templates/job.yaml b/stack/templates/job.yaml new file mode 100644 index 0000000..877d1d8 --- /dev/null +++ b/stack/templates/job.yaml @@ -0,0 +1,179 @@ +{{ $global := . }} +{{ range $jobName, $jobValues := .Values.jobs }} + {{- $globalValuesDict := $global.Values.global | toYaml -}} + {{- $values := fromYaml $globalValuesDict -}} + {{- $values = set $values "name" $jobName -}} + {{- $values := mergeOverwrite $values $jobValues -}} + {{- $job := dict "Chart" $global.Chart "Release" $global.Release "Capabilities" $global.Capabilities "Values" $values -}} +{{- with $job -}} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "service.fullname" . }} + labels: + {{- include "service.labels" . | nindent 4 }} + annotations: + {{- toYaml (mergeOverwrite + (dict) + (fromYaml (include "stack.annotations" $job )) + ) | nindent 4 }} +spec: + {{- if .Values.activeDeadlineSeconds }} + activeDeadlineSeconds: {{ .Values.activeDeadlineSeconds }} + {{- end }} + {{- if .Values.ttlSecondsAfterFinished }} + ttlSecondsAfterFinished: {{ .Values.ttlSecondsAfterFinished }} + {{- end }} + {{- if .Values.backoffLimit }} + backoffLimit: {{ .Values.backoffLimit }} + {{- end }} + {{- if .Values.completions }} + completions: {{ .Values.completions }} + {{- end }} + {{- if .Values.parallelism }} + parallelism: {{ .Values.parallelism }} + {{- end }} + template: + metadata: + {{- with mergeOverwrite .Values.podAnnotations (dict "linkerd.io/inject" "disabled") }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "service.labels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "service.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + shareProcessNamespace: {{ .Values.shareProcessNamespace }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if and .Values.args (ne (len .Values.args) 0) }} + args: + {{- toYaml .Values.args | nindent 12 }} + {{- end }} + {{- if and .Values.command (ne (len .Values.command) 0) }} + command: + {{- toYaml .Values.command | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.service.port }} + protocol: TCP + livenessProbe: + {{- include "container.probe" .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- include "container.probe" .Values.readinessProbe | nindent 12 }} + {{- if eq .Values.startupProbe.enabled true }} + startupProbe: + {{- include "container.probe" (omit .Values.startupProbe "enabled") | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or (and .Values.persistence.enabled .Values.persistence.mountPath) .Values.volumeMounts}} + volumeMounts: + {{- if and .Values.persistence.enabled .Values.persistence.mountPath }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + {{- end }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- include "service.configuration" . | nindent 10}} + {{- include "service.nonsensitiveEnvVars" (list $global.Values.global .Values) | nindent 10 }} + {{- range $i, $container := .Values.sidecars }} + {{- $imageDict := fromYaml (include "image" $container) }} + {{- $container = mergeOverwrite $container $imageDict }} + {{- with omit $container "envFrom" "env" }} + - {{- toYaml . | nindent 10 }} + {{- include "service.configuration" $job | nindent 10}} + {{- end }} + {{- include "service.nonsensitiveEnvVars" (list $global.Values.global $job.Values $container) | nindent 10 }} + {{- end }} + initContainers: + {{- range $i, $container := .Values.initContainers }} + {{- $imageDict := fromYaml (include "image" $container) }} + {{- $container = mergeOverwrite $container $imageDict }} + {{- with omit $container "envFrom" "env" }} + - {{- toYaml . | nindent 10 }} + {{- include "service.configuration" $job | nindent 10}} + {{- end }} + {{- include "service.nonsensitiveEnvVars" (list $global.Values.global $job.Values $container) | nindent 10 }} + {{- end }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- if eq .Values.restartPolicy "Always" }} + restartPolicy: OnFailure + {{- else }} + restartPolicy: {{ .Values.restartPolicy }} + {{- end }} + {{- if or .Values.persistence.enabled .Values.volumes}} + volumes: + {{- if .Values.persistence.enabled }} + - name: data + persistentVolumeClaim: + claimName: {{ include "service.claimName" . }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- else }} + topologySpreadConstraints: + - maxSkew: 2 + topologyKey: topology.kubernetes.io/zone + whenUnsatisfiable: ScheduleAnyway + labelSelector: + matchLabels: + {{- include "service.selectorLabels" . | nindent 14 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +{{ if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "service.serviceAccountName" . }} + labels: + {{- include "service.labels" . | nindent 4 }} + {{- with mergeOverwrite + (dict) + .Values.annotations + .Values.serviceAccount.annotations + }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +--- +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/stack/tests/cronjob_test.yaml b/stack/tests/cronjob_test.yaml index 3db6aca..7a17a28 100644 --- a/stack/tests/cronjob_test.yaml +++ b/stack/tests/cronjob_test.yaml @@ -110,6 +110,6 @@ tests: - containsDocument: apiVersion: v1 kind: ServiceAccount - name: "release-name-stack-job1" + name: "release-name-stack-job2" not: true diff --git a/stack/tests/job_test.yaml b/stack/tests/job_test.yaml new file mode 100644 index 0000000..245c210 --- /dev/null +++ b/stack/tests/job_test.yaml @@ -0,0 +1,122 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json +suite: test jobs +templates: + - job.yaml +tests: + - it: should work + set: + jobs: + job1: + activeDeadlineSeconds: 300 + backoffLimit: 2 + completions: 5 + parallelism: 3 + serviceAccount: + create: true + annotations: + "eks.amazonaws.com/role-arn": some-role + image: + repository: my-repo + tag: sha-mytag + command: ["hello-world"] + args: ["arg1", "arg2"] + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + containsDocument: + apiVersion: batch/v1 + kind: Job + name: "release-name-stack-job1" + template: job.yaml + - documentIndex: 0 + equal: + path: metadata.name + value: "release-name-stack-job1" + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].image + value: "my-repo:sha-mytag" + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].command + value: ["hello-world"] + - documentIndex: 0 + equal: + path: spec.template.spec.containers[0].args + value: ["arg1", "arg2"] + - documentIndex: 0 + equal: + path: spec.activeDeadlineSeconds + value: 300 + - documentIndex: 0 + equal: + path: spec.backoffLimit + value: 2 + - documentIndex: 0 + equal: + path: spec.completions + value: 5 + - documentIndex: 0 + equal: + path: spec.parallelism + value: 3 + - documentIndex: 1 + containsDocument: + apiVersion: v1 + kind: ServiceAccount + name: "release-name-stack-job1" + - documentIndex: 1 + equal: + path: metadata.name + value: "release-name-stack-job1" + - documentIndex: 1 + equal: + path: metadata.annotations["eks.amazonaws.com/role-arn"] + value: "some-role" + - documentIndex: 1 + equal: + path: metadata.labels["app.kubernetes.io/name"] + value: "stack" + - documentIndex: 1 + equal: + path: metadata.labels["app.kubernetes.io/instance"] + value: "RELEASE-NAME" + - documentIndex: 1 + equal: + path: metadata.labels["app.kubernetes.io/version"] + value: "1.16.0" + - documentIndex: 1 + equal: + path: metadata.labels["app.kubernetes.io/managed-by"] + value: "Helm" + - documentIndex: 1 + equal: + path: metadata.labels["app.kubernetes.io/service"] + value: "release-name-stack-job1" + - documentIndex: 1 + equal: + path: automountServiceAccountToken + value: true + - it: should not make service account for job + set: + jobs: + job2: + image: + repository: my-repo + tag: sha-mytag + command: ["hello-world"] + args: ["arg1", "arg2"] + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: batch/v1 + kind: Job + name: "release-name-stack-job2" + template: job.yaml + - containsDocument: + apiVersion: v1 + kind: ServiceAccount + name: "release-name-stack-job2" + not: true diff --git a/stack/values.schema.json b/stack/values.schema.json index ae797ed..d2ab317 100644 --- a/stack/values.schema.json +++ b/stack/values.schema.json @@ -648,6 +648,11 @@ "type": "object", "description": "Cron jobs to deploy, all values in the above global section are inherited by the cron jobs and each cron job can override them", "default": {} + }, + "jobs": { + "type": "object", + "description": "Jobs to deploy, all values in the above global section are inherited by the jobs and each job can override them", + "default": {} } } } \ No newline at end of file diff --git a/stack/values.yaml b/stack/values.yaml index 1780dcc..bf38ac1 100644 --- a/stack/values.yaml +++ b/stack/values.yaml @@ -390,3 +390,21 @@ cronJobs: # tag: "latest" # command: ["command1", "command2"] # args: ["arg1", "arg2"] + +## @param jobs Jobs to deploy, all values in the above global section are inherited by the jobs and each job can override them +jobs: + {} + # job1: + # activeDeadlineSeconds: 300 + # backoffLimit: 2 + # completions: 5 + # parallelism: 3 + # serviceAccount: + # create: true + # annotations: + # "eks.amazonaws.com/role-arn": some-role + # image: + # repository: my-repo + # tag: sha-mytag + # command: ["hello-world"] + # args: ["arg1", "arg2"] From 00fe403cb64f84ccaa4fa86ab283f8da26d8a192 Mon Sep 17 00:00:00 2001 From: "czi-github-helper[bot]" <95879977+czi-github-helper[bot]@users.noreply.github.com> Date: Mon, 3 Mar 2025 10:16:46 -0700 Subject: [PATCH 3/3] chore: release main (#191) --- .release-please-manifest.json | 2 +- stack/CHANGELOG.md | 7 +++++++ stack/Chart.yaml | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d3328a7..e785940 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,4 @@ { - "stack": "2.5.3", + "stack": "2.6.0", "argus-config": "1.2.3" } diff --git a/stack/CHANGELOG.md b/stack/CHANGELOG.md index 0322880..7c9252c 100644 --- a/stack/CHANGELOG.md +++ b/stack/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.6.0](https://github.com/chanzuckerberg/argo-helm-charts/compare/stack-v2.5.3...stack-v2.6.0) (2025-03-03) + + +### Features + +* add support for k8s jobs to stack helm chart ([#190](https://github.com/chanzuckerberg/argo-helm-charts/issues/190)) ([2a396e0](https://github.com/chanzuckerberg/argo-helm-charts/commit/2a396e0078d5e481d149dc266318c2160a2f686a)) + ## [2.5.3](https://github.com/chanzuckerberg/argo-helm-charts/compare/stack-v2.5.2...stack-v2.5.3) (2025-01-22) diff --git a/stack/Chart.yaml b/stack/Chart.yaml index 8b74520..0335f64 100644 --- a/stack/Chart.yaml +++ b/stack/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.5.3 +version: 2.6.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to