From 1127c447c4bc6e3bec7d4eb20108daea652d4d1b Mon Sep 17 00:00:00 2001 From: David Young Date: Sun, 24 Jan 2021 19:37:01 +1300 Subject: [PATCH] Add GitHub Actions to publish helm chart (#257) * Add chart workflows (#1) * Add chart workflows * Fix publishing step in CI Signed-off-by: David Young * Update CI on push-to-master (#3) * Put helm installation step in the correct CI job Signed-off-by: David Young * Put helm installation step in the correct CI job (#4) * Update on-push-master-publish-chart.yml * Remove references to certmanager dependency Signed-off-by: David Young * Add ability to customize kube-rbac-proxy image Signed-off-by: David Young * Only install cert-manager if we're going to spin up KinD Signed-off-by: David Young --- .github/workflows/on-push-lint-charts.yml | 75 +++++++++++++ .../on-push-master-publish-chart.yml | 101 ++++++++++++++++++ charts/.ci/ct-config.yaml | 4 + charts/.ci/lint-config.yaml | 6 ++ charts/.ci/scripts/local-ct-lint.sh | 3 + charts/.ci/scripts/local-kube-score.sh | 15 +++ charts/actions-runner-controller/Chart.yaml | 17 ++- .../ci/ci-values.yaml | 27 +++++ .../templates/_helpers.tpl | 2 +- .../templates/ci-secret.yaml | 10 ++ .../templates/deployment.yaml | 13 ++- charts/actions-runner-controller/values.yaml | 7 +- 12 files changed, 275 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/on-push-lint-charts.yml create mode 100644 .github/workflows/on-push-master-publish-chart.yml create mode 100644 charts/.ci/ct-config.yaml create mode 100644 charts/.ci/lint-config.yaml create mode 100755 charts/.ci/scripts/local-ct-lint.sh create mode 100755 charts/.ci/scripts/local-kube-score.sh create mode 100644 charts/actions-runner-controller/ci/ci-values.yaml create mode 100644 charts/actions-runner-controller/templates/ci-secret.yaml diff --git a/.github/workflows/on-push-lint-charts.yml b/.github/workflows/on-push-lint-charts.yml new file mode 100644 index 00000000..661f260c --- /dev/null +++ b/.github/workflows/on-push-lint-charts.yml @@ -0,0 +1,75 @@ +name: Lint and Test Charts + +on: + push: + paths: + - 'charts/**' + - '.github/**' + workflow_dispatch: + +env: + KUBE_SCORE_VERSION: 1.10.0 + HELM_VERSION: v3.4.1 + +jobs: + lint-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: ${{ env.HELM_VERSION }} + + - name: Set up kube-score + run: | + wget https://github.com/zegl/kube-score/releases/download/v${{ env.KUBE_SCORE_VERSION }}/kube-score_${{ env.KUBE_SCORE_VERSION }}_linux_amd64 -O kube-score + chmod 755 kube-score + + - name: Kube-score generated manifests + run: helm template --values charts/.ci/values-kube-score.yaml charts/* | ./kube-score score - + --ignore-test pod-networkpolicy + --ignore-test deployment-has-poddisruptionbudget + --ignore-test deployment-has-host-podantiaffinity + --ignore-test container-security-context + --ignore-test pod-probes + --ignore-test container-image-tag + --enable-optional-test container-security-context-privileged + --enable-optional-test container-security-context-readonlyrootfilesystem + + # python is a requirement for the chart-testing action below (supports yamllint among other tests) + - uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.0.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --config charts/.ci/ct-config.yaml) + if [[ -n "$changed" ]]; then + echo "::set-output name=changed::true" + fi + + - name: Run chart-testing (lint) + run: ct lint --config charts/.ci/ct-config.yaml + + - name: Create kind cluster + uses: helm/kind-action@v1.0.0 + if: steps.list-changed.outputs.changed == 'true' + + # We need cert-manager already installed in the cluster because we assume the CRDs exist + - name: Install cert-manager + run: | + helm repo add jetstack https://charts.jetstack.io --force-update + helm install cert-manager jetstack/cert-manager --set installCRDs=true --wait + if: steps.list-changed.outputs.changed == 'true' + + - name: Run chart-testing (install) + run: ct install --config charts/.ci/ct-config.yaml diff --git a/.github/workflows/on-push-master-publish-chart.yml b/.github/workflows/on-push-master-publish-chart.yml new file mode 100644 index 00000000..a6d4fa5c --- /dev/null +++ b/.github/workflows/on-push-master-publish-chart.yml @@ -0,0 +1,101 @@ +name: Publish helm chart + +on: + push: + branches: + - master + - main # assume that the branch name may change in future + paths: + - 'charts/**' + - '.github/**' + workflow_dispatch: + +env: + KUBE_SCORE_VERSION: 1.10.0 + HELM_VERSION: v3.4.1 + +jobs: + lint-chart: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: ${{ env.HELM_VERSION }} + + - name: Set up kube-score + run: | + wget https://github.com/zegl/kube-score/releases/download/v${{ env.KUBE_SCORE_VERSION }}/kube-score_${{ env.KUBE_SCORE_VERSION }}_linux_amd64 -O kube-score + chmod 755 kube-score + + - name: Kube-score generated manifests + run: helm template --values charts/.ci/values-kube-score.yaml charts/* | ./kube-score score - + --ignore-test pod-networkpolicy + --ignore-test deployment-has-poddisruptionbudget + --ignore-test deployment-has-host-podantiaffinity + --ignore-test container-security-context + --ignore-test pod-probes + --ignore-test container-image-tag + --enable-optional-test container-security-context-privileged + --enable-optional-test container-security-context-readonlyrootfilesystem + + # python is a requirement for the chart-testing action below (supports yamllint among other tests) + - uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.0.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --config charts/.ci/ct-config.yaml) + if [[ -n "$changed" ]]; then + echo "::set-output name=changed::true" + fi + + - name: Run chart-testing (lint) + run: ct lint --config charts/.ci/ct-config.yaml + + - name: Create kind cluster + uses: helm/kind-action@v1.0.0 + if: steps.list-changed.outputs.changed == 'true' + + # We need cert-manager already installed in the cluster because we assume the CRDs exist + - name: Install cert-manager + run: | + helm repo add jetstack https://charts.jetstack.io --force-update + helm install cert-manager jetstack/cert-manager --set installCRDs=true --wait + if: steps.list-changed.outputs.changed == 'true' + + - name: Run chart-testing (install) + run: ct install --config charts/.ci/ct-config.yaml + if: steps.list-changed.outputs.changed == 'true' + + publish-chart: + + runs-on: ubuntu-latest + needs: lint-chart + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.1.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + diff --git a/charts/.ci/ct-config.yaml b/charts/.ci/ct-config.yaml new file mode 100644 index 00000000..a4cee368 --- /dev/null +++ b/charts/.ci/ct-config.yaml @@ -0,0 +1,4 @@ +# This file defines the config for "ct" (chart tester) used by the helm linting GitHub workflow +lint-conf: charts/.ci/lint-config.yaml +chart-repos: + - jetstack=https://charts.jetstack.io diff --git a/charts/.ci/lint-config.yaml b/charts/.ci/lint-config.yaml new file mode 100644 index 00000000..164bbf96 --- /dev/null +++ b/charts/.ci/lint-config.yaml @@ -0,0 +1,6 @@ +rules: + # One blank line is OK + empty-lines: + max-start: 1 + max-end: 1 + max: 1 diff --git a/charts/.ci/scripts/local-ct-lint.sh b/charts/.ci/scripts/local-ct-lint.sh new file mode 100755 index 00000000..d88ca34e --- /dev/null +++ b/charts/.ci/scripts/local-ct-lint.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker run --rm -it -w /repo -v $(pwd):/repo quay.io/helmpack/chart-testing ct lint --all --config charts/.ci/ct-config.yaml diff --git a/charts/.ci/scripts/local-kube-score.sh b/charts/.ci/scripts/local-kube-score.sh new file mode 100755 index 00000000..3982b388 --- /dev/null +++ b/charts/.ci/scripts/local-kube-score.sh @@ -0,0 +1,15 @@ +#!/bin/bash + + +for chart in `ls charts`; +do +helm template --values charts/$chart/ci/ci-values.yaml charts/$chart | kube-score score - \ + --ignore-test pod-networkpolicy \ + --ignore-test deployment-has-poddisruptionbudget \ + --ignore-test deployment-has-host-podantiaffinity \ + --ignore-test pod-probes \ + --ignore-test container-image-tag \ + --enable-optional-test container-security-context-privileged \ + --enable-optional-test container-security-context-readonlyrootfilesystem \ + --ignore-test container-security-context +done \ No newline at end of file diff --git a/charts/actions-runner-controller/Chart.yaml b/charts/actions-runner-controller/Chart.yaml index 8979bc7e..cf0b8689 100644 --- a/charts/actions-runner-controller/Chart.yaml +++ b/charts/actions-runner-controller/Chart.yaml @@ -15,9 +15,22 @@ 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: 0.1.0 +version: 0.1.2 # 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 # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 0.11.2 +appVersion: 0.16.0 + +home: https://github.com/summerwind/actions-runner-controller + +sources: + - https://github.com/summerwind/actions-runner-controller + +maintainers: + - name: summerwind + email: contact@summerwind.jp + url: https://github.com/summerwind + - name: funkypenguin + email: davidy@funkypenguin.co.nz + url: https://www.funkypenguin.co.nz \ No newline at end of file diff --git a/charts/actions-runner-controller/ci/ci-values.yaml b/charts/actions-runner-controller/ci/ci-values.yaml new file mode 100644 index 00000000..ac42914d --- /dev/null +++ b/charts/actions-runner-controller/ci/ci-values.yaml @@ -0,0 +1,27 @@ +# This file sets some opinionated values for kube-score to use +# when parsing the chart +image: + pullPolicy: Always + +podSecurityContext: + fsGroup: 2000 + +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 2000 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# Set the following to true to create a dummy secret, allowing the manager pod to start +# This is only useful in CI +createDummySecret: true \ No newline at end of file diff --git a/charts/actions-runner-controller/templates/_helpers.tpl b/charts/actions-runner-controller/templates/_helpers.tpl index baa8c6e0..425c5544 100644 --- a/charts/actions-runner-controller/templates/_helpers.tpl +++ b/charts/actions-runner-controller/templates/_helpers.tpl @@ -89,7 +89,7 @@ Create the name of the service account to use {{- end }} {{- define "actions-runner-controller.authProxyServiceName" -}} -{{- include "actions-runner-controller.fullname" . }}-controller-manager-metrics-service +{{- include "actions-runner-controller.fullname" . }}-metrics-service {{- end }} {{- define "actions-runner-controller.selfsignedIssuerName" -}} diff --git a/charts/actions-runner-controller/templates/ci-secret.yaml b/charts/actions-runner-controller/templates/ci-secret.yaml new file mode 100644 index 00000000..7cdfaef4 --- /dev/null +++ b/charts/actions-runner-controller/templates/ci-secret.yaml @@ -0,0 +1,10 @@ +# This template only exists to facilitate CI testing of the chart, since +# a secret is expected to be found in the namespace by the controller manager +{{ if .Values.createDummySecret -}} +apiVersion: v1 +data: + github_token: dGVzdA== +kind: Secret +metadata: + name: controller-manager +{{- end }} \ No newline at end of file diff --git a/charts/actions-runner-controller/templates/deployment.yaml b/charts/actions-runner-controller/templates/deployment.yaml index 167428c0..9eeb0019 100644 --- a/charts/actions-runner-controller/templates/deployment.yaml +++ b/charts/actions-runner-controller/templates/deployment.yaml @@ -66,10 +66,14 @@ spec: protocol: TCP resources: {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} volumeMounts: - mountPath: "/etc/actions-runner-controller" name: controller-manager readOnly: true + - mountPath: /tmp + name: tmp - mountPath: /tmp/k8s-webhook-server/serving-certs name: cert readOnly: true @@ -78,11 +82,16 @@ spec: - "--upstream=http://127.0.0.1:8080/" - "--logtostderr=true" - "--v=10" - image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1 + image: "{{ .Values.kube_rbac_proxy.image.repository }}:{{ .Values.kube_rbac_proxy.image.tag }}" name: kube-rbac-proxy + imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: 8443 name: https + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} terminationGracePeriodSeconds: 10 volumes: - name: controller-manager @@ -92,6 +101,8 @@ spec: secret: defaultMode: 420 secretName: webhook-server-cert + - name: tmp + emptyDir: {} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/actions-runner-controller/values.yaml b/charts/actions-runner-controller/values.yaml index c507efbd..d4342d13 100644 --- a/charts/actions-runner-controller/values.yaml +++ b/charts/actions-runner-controller/values.yaml @@ -26,6 +26,11 @@ image: dindSidecarRepositoryAndTag: "docker:dind" pullPolicy: IfNotPresent +kube_rbac_proxy: + image: + repository: gcr.io/kubebuilder/kube-rbac-proxy + tag: v0.4.1 + imagePullSecrets: [] nameOverride: "" fullnameOverride: "" @@ -97,4 +102,4 @@ affinity: {} # Leverage a PriorityClass to ensure your pods survive resource shortages # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ # PriorityClass: system-cluster-critical -priorityClassName: "" +priorityClassName: "" \ No newline at end of file