# # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # name: Pulsar Helm Chart CI on: push: branches: - master pull_request: branches: - master workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: preconditions: name: Preconditions runs-on: ubuntu-24.04 if: (github.event_name != 'schedule') || (github.repository == 'apache/pulsar-helm-chart') outputs: docs_only: ${{ steps.check_changes.outputs.docs_only }} steps: - name: checkout uses: actions/checkout@v4 - name: Detect changed files id: changes uses: apache/pulsar-test-infra/paths-filter@master with: filters: .github/changes-filter.yaml list-files: csv - name: Check changed files id: check_changes run: | if [[ "${GITHUB_EVENT_NAME}" != "schedule" && "${GITHUB_EVENT_NAME}" != "workflow_dispatch" ]]; then echo "docs_only=${{ fromJSON(steps.changes.outputs.all_count) == fromJSON(steps.changes.outputs.docs_count) && fromJSON(steps.changes.outputs.docs_count) > 0 }}" >> $GITHUB_OUTPUT else echo docs_only=false >> $GITHUB_OUTPUT fi license-check: needs: preconditions name: License Check runs-on: ubuntu-24.04 timeout-minutes: 10 if: ${{ needs.preconditions.outputs.docs_only != 'true' }} steps: - name: Set up Go 1.12 uses: actions/setup-go@v5 with: go-version: 1.12 id: go - name: Check out code into the Go module directory uses: actions/checkout@v4 - name: Check license run: | go test license_test.go # run "ct lint" https://github.com/helm/chart-testing/blob/main/doc/ct_lint.md ct-lint: needs: ['preconditions', 'license-check'] name: chart-testing lint runs-on: ubuntu-24.04 timeout-minutes: 45 if: ${{ needs.preconditions.outputs.docs_only != 'true' }} steps: - name: checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Tune Runner VM uses: ./.github/actions/tune-runner-vm - name: Setup ssh access to build runner VM # ssh access is enabled for builds in own forks if: ${{ github.repository != 'apache/pulsar-helm-chart' && github.event_name == 'pull_request' }} uses: ./.github/actions/ssh-access continue-on-error: true with: limit-access-to-actor: true - name: Set up Helm if: ${{ steps.check_changes.outputs.docs_only != 'true' }} uses: azure/setup-helm@v4 with: version: v3.16.4 - name: Set up Python if: ${{ steps.check_changes.outputs.docs_only != 'true' }} uses: actions/setup-python@v5 with: python-version: '3.12' - name: Install uv, a fast modern package manager for Python if: ${{ steps.check_changes.outputs.docs_only != 'true' }} run: curl -LsSf https://astral.sh/uv/install.sh | sh - name: Set up chart-testing if: ${{ steps.check_changes.outputs.docs_only != 'true' }} uses: ./.github/actions/chart-testing-action - name: Run chart-testing (lint) id: ct-lint if: ${{ steps.check_changes.outputs.docs_only != 'true' }} run: | ct lint --check-version-increment=false \ --validate-maintainers=false \ --target-branch ${{ github.event.repository.default_branch }} - name: Run kubeconform check for helm template with every major k8s version 1.23.0-1.32.0 if: ${{ steps.check_changes.outputs.docs_only != 'true' }} run: | PULSAR_CHART_HOME=$(pwd) source ${PULSAR_CHART_HOME}/hack/common.sh source ${PULSAR_CHART_HOME}/.ci/helm.sh hack::ensure_kubectl hack::ensure_helm hack::ensure_kubeconform ci::helm_repo_add helm dependency build charts/pulsar validate_helm_template_with_k8s_version() { local kube_version=$1 shift echo -n "Validating helm template with kubeconform for k8s version $kube_version" if [ $# -gt 0 ]; then echo " Extra args: $*" else echo "" fi helm template charts/pulsar --set kube-prometheus-stack.enabled=false --set components.pulsar_manager=true --kube-version $kube_version "$@" | \ kubeconform -schema-location default -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' -strict -kubernetes-version $kube_version -summary } set -o pipefail for k8s_version_part in {23..32}; do k8s_version="1.${k8s_version_part}.0" echo "Validating default values with k8s version $k8s_version" validate_helm_template_with_k8s_version $k8s_version for config in .ci/clusters/*.yaml; do echo "Validating $config with k8s version $k8s_version" validate_helm_template_with_k8s_version $k8s_version --values .ci/values-common.yaml --values $config done done - name: Validate kustomize yaml for extra new lines in pulsar-init commands if: ${{ steps.check_changes.outputs.docs_only != 'true' }} run: | ./.ci/helm.sh validate_kustomize_yaml - name: Wait for ssh connection when build fails # ssh access is enabled for builds in own forks uses: ./.github/actions/ssh-access if: ${{ failure() && github.repository != 'apache/pulsar-helm-chart' && github.event_name == 'pull_request' }} continue-on-error: true with: action: wait install-chart-tests: name: ${{ matrix.testScenario.name }} - k8s ${{ matrix.k8sVersion.version }} - ${{ matrix.testScenario.type || 'install' }} runs-on: ubuntu-24.04 timeout-minutes: ${{ matrix.testScenario.timeout || 45 }} needs: ['preconditions', 'ct-lint'] if: ${{ needs.preconditions.outputs.docs_only != 'true' }} strategy: fail-fast: false matrix: # see https://github.com/kubernetes-sigs/kind/releases/tag/v0.27.0 for the list of supported k8s versions for kind 0.27.0 # docker images are available at https://hub.docker.com/r/kindest/node/tags k8sVersion: - version: "1.23.17" kind_image_tag: v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3 - version: "1.32.2" kind_image_tag: v1.32.2@sha256:f226345927d7e348497136874b6d207e0b32cc52154ad8323129352923a3142f testScenario: - name: Upgrade latest released version values_file: .ci/clusters/values-upgrade.yaml shortname: upgrade type: upgrade - name: Use previous LTS Pulsar Image values_file: .ci/clusters/values-pulsar-previous-lts.yaml shortname: pulsar-previous-lts - name: JWT Asymmetric Keys values_file: .ci/clusters/values-jwt-asymmetric.yaml shortname: jwt-asymmetric - name: JWT Symmetric Key values_file: .ci/clusters/values-jwt-symmetric.yaml shortname: jwt-symmetric - name: TLS values_file: .ci/clusters/values-tls.yaml shortname: tls - name: Broker & Proxy TLS values_file: .ci/clusters/values-broker-tls.yaml shortname: broker-tls - name: BK TLS Only values_file: .ci/clusters/values-bk-tls.yaml shortname: bk-tls - name: ZK TLS Only values_file: .ci/clusters/values-zk-tls.yaml shortname: zk-tls - name: ZK & BK TLS Only values_file: .ci/clusters/values-zkbk-tls.yaml shortname: zkbk-tls - name: PSP values_file: .ci/clusters/values-psp.yaml shortname: psp - name: Pulsar Manager values_file: .ci/clusters/values-pulsar-manager.yaml shortname: pulsar-manager - name: Oxia values_file: .ci/clusters/values-oxia.yaml shortname: oxia include: - k8sVersion: version: "1.23.17" kind_image_tag: v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3 testScenario: name: "Upgrade TLS" values_file: .ci/clusters/values-tls.yaml shortname: tls type: upgrade - k8sVersion: version: "1.23.17" kind_image_tag: v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3 testScenario: name: "Upgrade PSP" values_file: .ci/clusters/values-psp.yaml shortname: psp type: upgrade - k8sVersion: version: "1.23.17" kind_image_tag: v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3 testScenario: name: "Upgrade kube-prometheus-stack for previous LTS" values_file: .ci/clusters/values-prometheus-grafana.yaml --values .ci/clusters/values-pulsar-previous-lts.yaml shortname: prometheus-grafana type: upgrade upgradeFromVersion: 3.2.0 - k8sVersion: version: "1.23.17" kind_image_tag: v1.23.17@sha256:14d0a9a892b943866d7e6be119a06871291c517d279aedb816a4b4bc0ec0a5b3 testScenario: name: "TLS with helm 3.12.0" values_file: .ci/clusters/values-tls.yaml shortname: tls type: install helmVersion: 3.12.0 env: k8sVersion: ${{ matrix.k8sVersion.kind_image_tag }} KUBECTL_VERSION: ${{ matrix.k8sVersion.version }} HELM_VERSION: ${{ matrix.helmVersion || '3.14.4' }} steps: - name: checkout uses: actions/checkout@v4 - name: Tune Runner VM uses: ./.github/actions/tune-runner-vm - name: Setup debugging tools for ssh access if: ${{ github.repository != 'apache/pulsar-helm-chart' && github.event_name == 'pull_request' }} run: .ci/configure_ci_runner_for_debugging.sh - name: Setup ssh access to build runner VM # ssh access is enabled for builds in own forks if: ${{ github.repository != 'apache/pulsar-helm-chart' && github.event_name == 'pull_request' }} uses: ./.github/actions/ssh-access continue-on-error: true with: limit-access-to-actor: true - name: Run chart-testing (${{ matrix.testScenario.type || 'install' }}) with helm ${{ env.HELM_VERSION }} run: | case "${{ matrix.testScenario.shortname }}" in "jwt-symmetric") export SYMMETRIC=true export EXTRA_SUPERUSERS=manager-admin ;; "jwt-asymmetric") export EXTRA_SUPERUSERS=manager-admin ;; esac if [[ "${{ matrix.testScenario.type || 'install' }}" == "upgrade" ]]; then export UPGRADE_FROM_VERSION="${{ matrix.testScenario.upgradeFromVersion || 'latest' }}" fi .ci/chart_test.sh ${{ matrix.testScenario.values_file }} - name: Collect k8s logs on failure if: ${{ cancelled() || failure() }} continue-on-error: true shell: bash run: | source .ci/helm.sh set +e ci::collect_k8s_logs - name: Upload k8s logs on failure uses: actions/upload-artifact@v4 if: ${{ cancelled() || failure() }} continue-on-error: true with: name: k8s-logs-${{ matrix.testScenario.shortname }} path: /tmp/k8s-logs retention-days: 7 if-no-files-found: ignore - name: Wait for ssh connection when build fails # ssh access is enabled for builds in own forks uses: ./.github/actions/ssh-access if: ${{ failure() && github.repository != 'apache/pulsar-helm-chart' && github.event_name == 'pull_request' }} continue-on-error: true with: action: wait # This job is required for pulls to be merged. # It depends on all other jobs in this workflow. pulsar-helm-chart-ci-checks-completed: name: "CI checks completed" if: ${{ always() && ((github.event_name != 'schedule') || (github.repository == 'apache/pulsar-helm-chart')) }} runs-on: ubuntu-24.04 timeout-minutes: 10 needs: [ 'preconditions', 'license-check', 'install-chart-tests' ] steps: - name: Check that all required jobs were completed successfully if: ${{ needs.preconditions.outputs.docs_only != 'true' }} run: | if [[ ! ( \ "${{ needs.license-check.result }}" == "success" \ && "${{ needs.install-chart-tests.result }}" == "success" \ ) ]]; then echo "Required jobs haven't been completed successfully." exit 1 fi