General #32
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright 2022-2024 the Kubeapps contributors. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| --- | |
| name: General | |
| on: | |
| workflow_call: | |
| inputs: | |
| run_gke_tests: | |
| type: boolean | |
| required: false | |
| default: false | |
| run_linters: | |
| type: boolean | |
| required: false | |
| default: true | |
| trigger_release: | |
| type: boolean | |
| required: false | |
| default: false | |
| workflow_dispatch: | |
| inputs: | |
| run_gke_tests: | |
| type: boolean | |
| required: false | |
| default: false | |
| description: "Run GKE tests (requires cloud setup)" | |
| run_linters: | |
| type: boolean | |
| required: false | |
| default: true | |
| description: "Run linters" | |
| trigger_release: | |
| type: boolean | |
| required: false | |
| default: false | |
| description: "Trigger release process" | |
| env: | |
| CHARTMUSEUM_VERSION: "3.10.3" | |
| CHARTS_REPO_ORIGINAL: "bitnami/charts" | |
| BRANCH_CHARTS_REPO_ORIGINAL: "main" | |
| CHARTS_REPO_FORKED: "kubeapps-bot/charts" | |
| BRANCH_CHARTS_REPO_FORKED: "main" | |
| CI_BOT_USERNAME: "kubeapps-bot" | |
| CI_BOT_EMAIL: "tanzu-kubeapps-team@vmware.com" | |
| CI_BOT_GPG: "3BC1973CE3AC2BD2B5A2E7D06A7635AE8F48F448" | |
| # DEBUG_MODE allows to activate some SSH debugging steps, and modify the verbosity level of some scripts (eg. e2e-tests.sh) | |
| DEBUG_MODE: "false" | |
| SSH_KEY_KUBEAPPS_DEPLOY_FILENAME: "id_rsa_kubeapps_deploy_key" | |
| SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME: "id_rsa_forked_charts_deploy_key" | |
| KUBEAPPS_REPO: "vmware-tanzu/kubeapps" | |
| BRANCH_KUBEAPPS_REPO: "main" | |
| README_GENERATOR_REPO: "bitnami-labs/readme-generator-for-helm" | |
| DOCKER_REGISTRY_VERSION: "2.8.3" | |
| GOLANG_VERSION: "1.23.2" | |
| GOLANGCI_LINT_VERSION: "1.61.0" | |
| HELM_VERSION_MIN: "v3.8.0" | |
| HELM_VERSION_STABLE: "v3.16.2" | |
| GITHUB_VERSION: "2.59.0" | |
| IMAGES_TO_PUSH: "apprepository-controller dashboard asset-syncer pinniped-proxy kubeapps-apis oci-catalog" | |
| # IMG_DEV_TAG is the tags used for the Kubeapps docker images. Ideally there should be an IMG_PROD_TAG | |
| # but its value is dynamic and GitHub actions doesn't support it in the `env` block, so it is generated | |
| # as an output of the `setup` job. | |
| IMG_DEV_TAG: "build-${{ github.sha }}" | |
| # Apart from using a dev tag we use a different image ID to avoid polluting the tag history of the production tag | |
| IMG_MODIFIER: "-ci" | |
| IMG_PREFIX: "kubeapps/" | |
| # We use IMG_PREFIX_FOR_FORKS for development purposes, it's used when the workflow is run from a fork of the kubeapps repo | |
| IMG_PREFIX_FOR_FORKS: "your-dockerhub-username/" | |
| # Currently, we only build the images for linux/amd64 because building cross-platform images is extremely slow... | |
| IMG_PLATFORMS: "linux/amd64" | |
| KAPP_CONTROLLER_VERSION: "v0.50.6" | |
| FLUX_VERSION: "v2.2.3" | |
| KIND_VERSION: "v0.23.0" | |
| K8S_KIND_VERSION: "v1.30.0@sha256:047357ac0cfea04663786a612ba1eaba9702bef25227a794b52890dd8bcd692e" | |
| MKCERT_VERSION: "v1.4.4" | |
| NODE_VERSION: "20.19.5" | |
| OLM_VERSION: "v0.28.0" | |
| POSTGRESQL_VERSION: "17.6.0-debian-12-r4" | |
| RUST_VERSION: "1.81.0" | |
| SEMVER_VERSION: "3.4.0" | |
| KUBECTL_VERSION: "v1.30.5" | |
| GKE_REGULAR_VERSION: "1.30" | |
| GKE_STABLE_VERSION: "1.30" | |
| GKE_ZONE: "us-east1-c" | |
| GKE_PROJECT: "vmware-kubeapps-ci" | |
| GKE_CLUSTER: "kubeapps-test" | |
| jobs: | |
| setup: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| golang_version: ${{ steps.set-outputs.outputs.golang_version }} | |
| img_modifier: ${{ steps.set-outputs.outputs.img_modifier }} | |
| img_prefix: ${{ steps.set-outputs.outputs.img_prefix }} | |
| img_dev_tag: ${{ steps.set-outputs.outputs.img_dev_tag }} | |
| img_prod_tag: ${{ steps.set-outputs.outputs.img_prod_tag }} | |
| postgresql_version: ${{ steps.set-outputs.outputs.postgresql_version }} | |
| rust_version: ${{ steps.set-outputs.outputs.rust_version }} | |
| running_on_main: ${{ steps.set-outputs.outputs.running_on_main }} | |
| ssh_key_kubeapps_deploy_filename: ${{ steps.set-outputs.outputs.ssh_key_kubeapps_deploy_filename }} | |
| ssh_key_forked_charts_deploy_filename: ${{ steps.set-outputs.outputs.ssh_key_forked_charts_deploy_filename }} | |
| triggered_from_fork: ${{ steps.set-outputs.outputs.triggered_from_fork }} | |
| steps: | |
| - name: Show GitHub event | |
| env: | |
| EVENT_CONTEXT: ${{ toJSON(github.event) }} | |
| run: echo $EVENT_CONTEXT | jq | |
| - name: Show PR context | |
| env: | |
| PR_CONTEXT: ${{ toJSON(github.event.pull_request) }} | |
| run: echo $PR_CONTEXT | jq | |
| - name: Set outputs | |
| id: set-outputs | |
| env: | |
| PR_CONTEXT: ${{ toJSON(github.event.pull_request) }} | |
| PR_SOURCE_REPO_NAME: ${{ github.event.pull_request.head.repo.full_name }} | |
| run: | | |
| if [[ "${GITHUB_REPOSITORY}" == "${KUBEAPPS_REPO}" ]]; then | |
| echo "img_prefix=${IMG_PREFIX}" >> $GITHUB_OUTPUT | |
| else | |
| # When running in forks (NOT triggered due to a PR from an external fork, but running the workflow in the | |
| # external repo), we push the images to a personal dockerhub namespace (or whatever other registry) if configured | |
| echo "img_prefix=${IMG_PREFIX_FOR_FORKS}" >> $GITHUB_OUTPUT | |
| fi; | |
| # Check if the workflow is triggered due to a PR from an external fork | |
| if [[ ("${PR_CONTEXT}" != "" && "${PR_CONTEXT}" != null) && "${PR_SOURCE_REPO_NAME}" != "${GITHUB_REPOSITORY}" ]]; then | |
| echo "triggered_from_fork=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "triggered_from_fork=false" >> $GITHUB_OUTPUT | |
| fi | |
| if [[ ${GITHUB_REF_TYPE} == "tag" ]]; then | |
| echo "img_prod_tag=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT | |
| echo "version=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT | |
| else | |
| echo "img_prod_tag=latest" >> $GITHUB_OUTPUT | |
| echo "version=${GITHUB_SHA}" >> $GITHUB_OUTPUT | |
| fi; | |
| if [[ ${GITHUB_REF_NAME} == ${BRANCH_KUBEAPPS_REPO} ]]; then | |
| echo "running_on_main=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "running_on_main=false" >> $GITHUB_OUTPUT | |
| fi | |
| echo "golang_version=${GOLANG_VERSION}" >> $GITHUB_OUTPUT | |
| echo "golangci_lint_version=${GOLANGCI_LINT_VERSION}" >> $GITHUB_OUTPUT | |
| echo "ssh_key_kubeapps_deploy_filename=${SSH_KEY_KUBEAPPS_DEPLOY_FILENAME}" >> $GITHUB_OUTPUT | |
| echo "ssh_key_forked_charts_deploy_filename=${SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME}" >> $GITHUB_OUTPUT | |
| echo "img_modifier=${IMG_MODIFIER}" >> $GITHUB_OUTPUT | |
| echo "img_dev_tag=${IMG_DEV_TAG}" >> $GITHUB_OUTPUT | |
| echo "postgresql_version=${POSTGRESQL_VERSION}" >> $GITHUB_OUTPUT | |
| echo "rust_version=${RUST_VERSION}" >> $GITHUB_OUTPUT | |
| - name: Show outputs | |
| run: | | |
| echo "GOLANG_VERSION: ${{steps.set-outputs.outputs.golang_version}}" | |
| echo "GOLANGCI_LINT_VERSION: ${{steps.set-outputs.outputs.golangci_lint_version}}" | |
| echo "IMG_MODIFIER: ${{steps.set-outputs.outputs.img_modifier}}" | |
| echo "IMG_PREFIX: ${{steps.set-outputs.outputs.img_prefix}}" | |
| echo "IMG_DEV_TAG: ${{steps.set-outputs.outputs.img_dev_tag}}" | |
| echo "IMG_PROD_TAG: ${{steps.set-outputs.outputs.img_prod_tag}}" | |
| echo "POSTGRESQL_VERSION: ${{steps.set-outputs.outputs.postgresql_version}}" | |
| echo "RUST_VERSION: ${{steps.set-outputs.outputs.rust_version}}" | |
| echo "RUNNING_ON_MAIN: ${{steps.set-outputs.outputs.running_on_main}}" | |
| echo "SSH_KEY_KUBEAPPS_DEPLOY_FILENAME: ${{steps.set-outputs.outputs.ssh_key_kubeapps_deploy_filename}}" | |
| echo "SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME: ${{steps.set-outputs.outputs.ssh_key_forked_charts_deploy_filename}}" | |
| echo "TRIGGERED_FROM_FORK: ${{steps.set-outputs.outputs.triggered_from_fork}}" | |
| echo "VERSION: ${{steps.set-outputs.outputs.version}}" | |
| linters: | |
| if: inputs.run_linters | |
| needs: | |
| - setup | |
| uses: ./.github/workflows/linters.yml | |
| with: | |
| golang_version: ${{ needs.setup.outputs.golang_version }} | |
| golangci_lint_version: ${{ needs.setup.outputs.golangci_lint_version }} | |
| linters_result: | |
| if: inputs.run_linters && always() | |
| needs: linters | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: "Check all linters result" | |
| if: needs.linters.result != 'success' | |
| run: exit 1 | |
| test_go: | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| services: | |
| postgresql: | |
| image: ghcr.io/sap/kubeapps/bitnami-deprecated-postgresql:${{needs.setup.outputs.postgresql_version}} | |
| options: >- | |
| --health-cmd "pg_isready -U postgres" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5432:5432 | |
| env: | |
| ALLOW_EMPTY_PASSWORD: "yes" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GOLANG_VERSION }} | |
| - name: Run go unit tests | |
| run: make test | |
| - run: make test-db | |
| test_dashboard: | |
| runs-on: ubuntu-latest | |
| needs: | |
| - setup | |
| env: | |
| # Note that the max old space setting is per worker, so running the tests | |
| # with 4 workers on a 7Gb (free plan) needs 1.75Gb of max old space. Forcing | |
| # garbage collection to start earlier with 1024M per worker. | |
| # See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources | |
| NODE_OPTIONS: "--max-old-space-size=1024" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: Install dashboard dependencies | |
| run: yarn install --cwd=dashboard --frozen-lockfile | |
| - name: Run dashboard linter | |
| run: yarn --cwd=dashboard run lint | |
| - name: Run dashboard unit tests | |
| run: yarn --cwd=dashboard run test --maxWorkers=4 --coverage --logHeapUsage | |
| test_pinniped_proxy: | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| container: | |
| image: rust:${{needs.setup.outputs.rust_version}} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run rust unit tests | |
| run: cargo test --manifest-path cmd/pinniped-proxy/Cargo.toml | |
| test_oci_catalog: | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| container: | |
| image: rust:${{needs.setup.outputs.rust_version}} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install protoc dependency | |
| run: | | |
| apt-get update -y | |
| apt-get install -y protobuf-compiler | |
| - name: Run rust unit tests | |
| run: cargo test --manifest-path cmd/oci-catalog/Cargo.toml | |
| test_chart_render: | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-go@v5 | |
| with: | |
| go-version: ${{ env.GOLANG_VERSION }} | |
| - name: "Install helm (minimum and stable)" | |
| run: | | |
| set -eu | |
| source ./script/lib/libcitools.sh | |
| installHelm ${HELM_VERSION_MIN} | |
| installHelm ${HELM_VERSION_STABLE} helm-stable | |
| - name: Run chart template test | |
| run: ./script/chart-template-test.sh | |
| build_docker_images: | |
| name: "Build ${{matrix.image}} image" | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - apprepository-controller | |
| - asset-syncer | |
| - kubeapps-apis | |
| - pinniped-proxy | |
| - oci-catalog | |
| steps: | |
| - id: setup | |
| run: | | |
| echo "img_name=${{matrix.image}}" >> $GITHUB_OUTPUT | |
| echo "img_file=/tmp/${{matrix.image}}-image.tar" >> $GITHUB_OUTPUT | |
| - uses: docker/metadata-action@v5 | |
| id: meta | |
| with: | |
| images: ${{needs.setup.outputs.img_prefix}}${{steps.setup.outputs.img_name}}${{needs.setup.outputs.img_modifier}} | |
| flavor: latest=true | |
| tags: ${{needs.setup.outputs.img_dev_tag}} | |
| - uses: docker/setup-qemu-action@v3 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Build image | |
| uses: docker/build-push-action@v6 | |
| env: | |
| DOCKER_BUILD_RECORD_UPLOAD: false | |
| with: | |
| file: cmd/${{matrix.image}}/Dockerfile | |
| platforms: ${{ env.IMG_PLATFORMS }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: ${{ needs.setup.outputs.version }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| outputs: type=docker,dest=${{ steps.setup.outputs.img_file }} | |
| - name: Upload image | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{matrix.image}}-image | |
| path: ${{ steps.setup.outputs.img_file }} | |
| build_dashboard_image: | |
| name: "Build dashboard image" | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| env: | |
| IMG_NAME: dashboard | |
| steps: | |
| - id: setup | |
| run: | | |
| echo "img_name=${IMG_NAME}" >> $GITHUB_OUTPUT | |
| echo "img_file=/tmp/${IMG_NAME}-image.tar" >> $GITHUB_OUTPUT | |
| - uses: actions/checkout@v4 | |
| - uses: docker/metadata-action@v5 | |
| id: meta | |
| with: | |
| images: ${{needs.setup.outputs.img_prefix}}${{steps.setup.outputs.img_name}}${{needs.setup.outputs.img_modifier}} | |
| flavor: latest=true | |
| tags: ${{needs.setup.outputs.img_dev_tag}} | |
| - uses: docker/setup-qemu-action@v3 | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Build image | |
| uses: docker/build-push-action@v6 | |
| env: | |
| DOCKER_BUILD_RECORD_UPLOAD: false | |
| with: | |
| context: dashboard | |
| platforms: ${{ env.IMG_PLATFORMS }} | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: ${{ needs.setup.outputs.version }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| outputs: type=docker,dest=${{ steps.setup.outputs.img_file }} | |
| - name: Upload image | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ steps.setup.outputs.img_name }}-image | |
| path: ${{ steps.setup.outputs.img_file }} | |
| build_e2e_runner_image: | |
| name: "Build E2E runner image" | |
| needs: | |
| - setup | |
| runs-on: ubuntu-latest | |
| env: | |
| IMG_NAME: integration-tests | |
| steps: | |
| - id: setup | |
| run: | | |
| echo "img_name=${IMG_NAME}" >> $GITHUB_OUTPUT | |
| echo "img_file=/tmp/${IMG_NAME}-image.tar" >> $GITHUB_OUTPUT | |
| - uses: actions/checkout@v4 | |
| - uses: docker/metadata-action@v5 | |
| id: meta | |
| with: | |
| images: ${{needs.setup.outputs.img_prefix}}${{steps.setup.outputs.img_name}}${{needs.setup.outputs.img_modifier}} | |
| flavor: latest=true | |
| tags: ${{needs.setup.outputs.img_dev_tag}} | |
| - uses: docker/setup-buildx-action@v3 | |
| - name: Build image | |
| uses: docker/build-push-action@v6 | |
| env: | |
| DOCKER_BUILD_RECORD_UPLOAD: false | |
| with: | |
| context: integration | |
| # It doesn't make sense investing CI time in making a multiplatform image here | |
| platforms: linux/amd64 | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: ${{ needs.setup.outputs.version }} | |
| outputs: type=docker,dest=${{ steps.setup.outputs.img_file }} | |
| - name: Upload image | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{steps.setup.outputs.img_name}}-image | |
| path: ${{ steps.setup.outputs.img_file }} | |
| # Push images to docker.io/kubeapps/[image]-ci:[dev-tag] | |
| push_dev_images: | |
| # If the workflow is triggered from a PR from an external fork, secrets won't be available, so we cannot log into dockerhub | |
| if: needs.setup.outputs.triggered_from_fork == 'false' | |
| runs-on: ubuntu-latest | |
| needs: | |
| - setup | |
| - build_docker_images | |
| - build_dashboard_image | |
| - build_e2e_runner_image | |
| env: | |
| ADDITIONAL_IMAGES_TO_PUSH: integration-tests | |
| IMG_PREFIX: ${{ needs.setup.outputs.img_prefix }} | |
| steps: | |
| - run: echo "IMAGES_TO_PUSH=\"${IMAGES_TO_PUSH} ${ADDITIONAL_IMAGES_TO_PUSH}\"" >> $GITHUB_ENV | |
| - name: Login to GitHub Container Registry (ghcr.io) | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download built images | |
| uses: actions/download-artifact@v5 | |
| - name: Load and push images | |
| run: | | |
| set -eu | |
| for artifact in *; do | |
| echo "::debug::Processing artifact '${artifact}'" | |
| if [[ "${artifact}" != *"-image" ]]; then | |
| echo "::notice ::Skipping artifact ${artifact}, it's not a container image" | |
| continue | |
| fi | |
| image=${artifact/-image/} | |
| if [[ "${IMAGES_TO_PUSH}" != *"${image}"* ]]; then | |
| echo "::notice ::Skipping image ${image}, it's not an image to push" | |
| continue | |
| fi | |
| echo "::notice ::Loading image ${image}" | |
| docker load --input "${artifact}/${artifact}.tar" | |
| docker images | head -n 100 | |
| dev_image=${IMG_PREFIX}${image}${IMG_MODIFIER}:${IMG_DEV_TAG} | |
| echo "::notice ::Pushing image ${dev_image}" | |
| docker push $dev_image | |
| done | |
| local_e2e_tests: | |
| needs: | |
| - setup | |
| - test_go | |
| - test_dashboard | |
| - test_pinniped_proxy | |
| - test_oci_catalog | |
| - test_chart_render | |
| - build_docker_images | |
| - build_dashboard_image | |
| - build_e2e_runner_image | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| tests_group: | |
| - carvel | |
| - flux | |
| - main-group-1 | |
| - main-group-2 | |
| - main-group-3 | |
| - multicluster | |
| - multicluster-nokubeapps | |
| - operators | |
| env: | |
| DEFAULT_DEX_IP: "172.18.0.2" | |
| IMG_PREFIX: ${{ needs.setup.outputs.img_prefix }} | |
| TESTS_GROUP: ${{ matrix.tests_group }} | |
| TEST_OPERATORS: "1" | |
| TEST_UPGRADE: "1" | |
| TEST_TIMEOUT_MINUTES: 6 # Timeout minutes for each test | |
| USE_MULTICLUSTER_OIDC_ENV: "true" | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: "Install required CLI tools" | |
| run: | | |
| set -eu | |
| source ./script/lib/libcitools.sh | |
| installKind ${KIND_VERSION} | |
| installKubectl ${KUBECTL_VERSION} | |
| installMkcert ${MKCERT_VERSION} | |
| installHelm ${HELM_VERSION_MIN} | |
| installHelm ${HELM_VERSION_STABLE} helm-stable | |
| - name: "Spin up Kind cluster" | |
| run: | | |
| set -eu | |
| DEFAULT_DEX_IP=${DEFAULT_DEX_IP} K8S_KIND_VERSION=${K8S_KIND_VERSION} ./script/create-kind-cluster.sh | |
| - name: "Copy apiserver certificates" | |
| run: | | |
| set -eu | |
| # dex will be running on the same node as the API server in the dev environment, so we can reuse the key and cert from the apiserver | |
| docker cp kubeapps-ci-control-plane:/etc/kubernetes/pki/apiserver.crt ./devel/dex.crt | |
| docker cp kubeapps-ci-control-plane:/etc/kubernetes/pki/apiserver.key ./devel/dex.key | |
| sudo chown $(whoami) ./devel/dex.key | |
| sudo chown $(whoami) ./devel/dex.crt | |
| - name: "Install additional cluster" | |
| run: | | |
| set -eu | |
| DEFAULT_DEX_IP=${DEFAULT_DEX_IP} K8S_KIND_VERSION=${K8S_KIND_VERSION} ./script/create-additional-kind-cluster.sh | |
| - name: "Export cluster variables" | |
| run: | | |
| set -eu | |
| DEX_IP=`docker network inspect kind | jq -r '.[0].IPAM.Config[] | select(.Gateway) | .Gateway' | awk -F. '{ print $1"."$2"."$3"."$4+1 }'` | |
| ADDITIONAL_CLUSTER_IP=`docker network inspect kind | jq -r '.[0].IPAM.Config[] | select(.Gateway) | .Gateway' | awk -F. '{ print $1"."$2"."$3"."$4+2 }'` | |
| echo DEFAULT_DEX_IP=$DEFAULT_DEX_IP | |
| echo DEX_IP=$DEX_IP | |
| echo ADDITIONAL_CLUSTER_IP=$ADDITIONAL_CLUSTER_IP | |
| # If running kubectl without args, use the default "kubeapps-ci" cluster | |
| cp ${HOME}/.kube/kind-config-kubeapps-ci ${HOME}/.kube/config | |
| kubectl config set-context kind-kubeapps-ci | |
| # If the default IP is not the proper one, the multicluster setup will fail | |
| if [ "$DEFAULT_DEX_IP" != "$DEX_IP" ]; then echo "Default IP does not match with current IP used in Kind"; exit 1; fi | |
| echo "DEFAULT_DEX_IP=${DEFAULT_DEX_IP}" >> $GITHUB_ENV | |
| echo "DEX_IP=${DEX_IP}" >> $GITHUB_ENV | |
| echo "ADDITIONAL_CLUSTER_IP=${ADDITIONAL_CLUSTER_IP}" >> $GITHUB_ENV | |
| - name: "Load needed images into Kind" | |
| run: | | |
| set -eu | |
| ./script/load-kind-image.sh docker.io/bitnami/apache:2.4.48 kubeapps-ci kubeapps-ci-additional && | |
| ./script/load-kind-image.sh docker.io/bitnami/apache:2.4.48 kubeapps-ci kubeapps-ci-additional && | |
| ./script/load-kind-image.sh registry:$DOCKER_REGISTRY_VERSION kubeapps-ci kubeapps-ci-additional | |
| - name: "Download docker images" | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: /tmp/images | |
| - name: "Load CI images in the cluster" | |
| run: | | |
| set -eu | |
| source ./script/lib/liblog.sh | |
| for path in /tmp/images/*; do | |
| image=$(basename "$path") | |
| if [[ "${image}" != *"-image" ]]; then | |
| echo "::notice ::Skipping artifact ${image}, it's not a docker image" | |
| continue | |
| fi | |
| info "Loading image ${image}" | |
| kind load image-archive "${path}/${image}.tar" --name kubeapps-ci; | |
| done | |
| - name: "Install multicluster deps" | |
| run: | | |
| ./script/install-multicluster-deps.sh | |
| - name: "Run e2e tests script" | |
| run: ./script/run_e2e_tests.sh | |
| - name: "Print k8s KubeappsAPIs logs if the tests fail" | |
| run: kubectl --context kind-kubeapps-ci --kubeconfig ${HOME}/.kube/kind-config-kubeapps-ci logs -n kubeapps deploy/kubeapps-ci-internal-kubeappsapis | |
| if: failure() && env.TEST_RESULT == 1 | |
| continue-on-error: true | |
| - name: 'Upload Artifacts' | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e_tests_${{ matrix.tests_group }}_reports | |
| path: integration/reports | |
| # We need this job to aggregate the result of the local_e2e_tests matrix and summarize it. We don't need it because of | |
| # GHA itself, but because in GH branch protection rules, we cannot check the status for a job matrix, and would have | |
| # require the status for each job in the matrix (eg. local_e2e_tests(carvel)). | |
| # See https://github.com/orgs/community/discussions/26822 | |
| local_e2e_tests_result: | |
| needs: | |
| - local_e2e_tests | |
| runs-on: ubuntu-latest | |
| if: always() | |
| steps: | |
| - name: "Check local_e2e_tests matrix status" | |
| if: needs.local_e2e_tests.result != 'success' | |
| run: exit 1 | |
| push_images: | |
| if: needs.setup.outputs.running_on_main == 'true' || inputs.trigger_release | |
| runs-on: ubuntu-latest | |
| needs: | |
| - setup | |
| - local_e2e_tests | |
| env: | |
| IMG_PROD_TAG: ${{ needs.setup.outputs.img_prod_tag }} | |
| IMG_PREFIX: ${{ needs.setup.outputs.img_prefix }} | |
| steps: | |
| - name: Login to Docker Hub | |
| uses: docker/login-action@v3 | |
| with: | |
| username: ${{ secrets.DOCKER_USERNAME }} | |
| password: ${{ secrets.DOCKER_PASSWORD }} | |
| - uses: actions/download-artifact@v4 | |
| - run: | | |
| set -eu | |
| for artifact in *; do | |
| echo "::debug::Processing artifact '${artifact}'" | |
| if [[ "${artifact}" != *"-image" ]]; then | |
| echo "::notice ::Skipping artifact ${artifact}, it's not a docker image" | |
| continue | |
| fi | |
| image=${artifact/-image/} | |
| if [[ "${IMAGES_TO_PUSH}" != *"${image}"* ]]; then | |
| echo "::notice ::Skipping image ${image}, it's not an image to push" | |
| continue | |
| fi | |
| echo "::notice ::Loading image ${image}" | |
| docker load --input "${artifact}/${artifact}.tar" | |
| dev_image=${IMG_PREFIX}${image}${IMG_MODIFIER}:${IMG_DEV_TAG} | |
| prod_image=${IMG_PREFIX}${image}:${IMG_PROD_TAG} | |
| docker tag ${dev_image} ${prod_image} | |
| echo "::notice ::Pushing image ${prod_image}" | |
| docker push $prod_image | |
| done | |
| sync_chart_from_bitnami: | |
| needs: | |
| - setup | |
| if: needs.setup.outputs.running_on_main == 'true' || inputs.trigger_release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: "Install CLI tools" | |
| env: | |
| GPG_KEY_PUBLIC: ${{ secrets.GPG_KEY_PUBLIC }} | |
| GPG_KEY_PRIVATE: ${{ secrets.GPG_KEY_PRIVATE }} | |
| run: | | |
| set -eu | |
| source ./script/lib/libcitools.sh | |
| installGithubCLI ${GITHUB_VERSION} | |
| installSemver ${SEMVER_VERSION} | |
| installGPGKey | |
| - name: "Install SSH key: Forked Charts Deploy Key" | |
| uses: shimataro/ssh-key-action@v2 | |
| with: | |
| key: ${{ secrets.SSH_KEY_FORKED_CHARTS_DEPLOY }} | |
| name: ${{ needs.setup.outputs.ssh_key_forked_charts_deploy_filename }} | |
| known_hosts: | | |
| |1|2YkQ4jjACcc/1rgSBszyeEuKxW4=|hO4GB0XMwQj1gYQDmaS304aU8Tc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== | |
| if_key_exists: ignore | |
| - # This is a key pair | |
| # public key uploaded to GitHub as a deployment key with write permissions, | |
| # private key stored as a secret. | |
| name: Start ssh-agent and configure the key | |
| run: | | |
| set -eu | |
| eval "$(ssh-agent -s)" | |
| # Deployment key uploaded to the kubeapps-bot/charts repository | |
| ssh-add ~/.ssh/${SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME} | |
| - # Assuming there is a personal access token created in GitHub granted with the scopes | |
| # "repo:status", "public_repo" and "read:org" | |
| name: Run the check_upstream_chart script | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -eu | |
| ./script/chart_upstream_checker.sh \ | |
| ${CI_BOT_USERNAME} \ | |
| ${CI_BOT_EMAIL} \ | |
| ${CI_BOT_GPG} \ | |
| ${SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME} \ | |
| ${CHARTS_REPO_ORIGINAL} \ | |
| ${BRANCH_CHARTS_REPO_ORIGINAL} \ | |
| ${CHARTS_REPO_FORKED} \ | |
| ${BRANCH_CHARTS_REPO_FORKED} \ | |
| ${KUBEAPPS_REPO} \ | |
| ${BRANCH_KUBEAPPS_REPO} \ | |
| ${README_GENERATOR_REPO} \ | |
| sync_chart_to_bitnami: | |
| needs: | |
| - setup | |
| - local_e2e_tests | |
| - GKE_REGULAR_VERSION | |
| - GKE_STABLE_VERSION | |
| if: inputs.trigger_release | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: "Install CLI tools" | |
| env: | |
| GPG_KEY_PUBLIC: ${{ secrets.GPG_KEY_PUBLIC }} | |
| GPG_KEY_PRIVATE: ${{ secrets.GPG_KEY_PRIVATE }} | |
| run: | | |
| set -eu | |
| source ./script/lib/libcitools.sh | |
| installGithubCLI ${GITHUB_VERSION} | |
| installSemver ${SEMVER_VERSION} | |
| installGPGKey | |
| - name: "Install SSH key: Forked Charts Deploy Key" | |
| uses: shimataro/ssh-key-action@v2 | |
| with: | |
| key: ${{ secrets.SSH_KEY_FORKED_CHARTS_DEPLOY }} | |
| name: ${{ needs.setup.outputs.ssh_key_forked_charts_deploy_filename }} | |
| known_hosts: | | |
| |1|2YkQ4jjACcc/1rgSBszyeEuKxW4=|hO4GB0XMwQj1gYQDmaS304aU8Tc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== | |
| if_key_exists: ignore | |
| - # This is a key pair | |
| # public key uploaded to GitHub as a deployment key with write permissions, | |
| # private key stored as a secret. | |
| name: Start ssh-agent and configure the key | |
| run: | | |
| set -eu | |
| eval "$(ssh-agent -s)" | |
| # Deployment key uploaded to the kubeapps-bot/charts repository | |
| ssh-add ~/.ssh/${SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME} | |
| - name: Run the chart_sync script | |
| env: | |
| # Assuming there is a personal access token created in GitHub granted with the scopes | |
| # "repo:status", "public_repo" and "read:org" | |
| GITHUB_TOKEN: ${{ secrets.KUBEAPPS_BOT_GITHUB_TOKEN }} | |
| run: | | |
| set -eu | |
| ./script/chart_sync.sh \ | |
| ${CI_BOT_USERNAME} \ | |
| ${CI_BOT_EMAIL} \ | |
| ${CI_BOT_GPG} \ | |
| ${SSH_KEY_FORKED_CHARTS_DEPLOY_FILENAME} \ | |
| ${CHARTS_REPO_ORIGINAL} \ | |
| ${BRANCH_CHARTS_REPO_ORIGINAL} \ | |
| ${CHARTS_REPO_FORKED} \ | |
| ${BRANCH_CHARTS_REPO_FORKED} \ | |
| release: | |
| if: inputs.trigger_release | |
| needs: | |
| - setup | |
| - sync_chart_to_bitnami | |
| - local_e2e_tests | |
| - GKE_REGULAR_VERSION | |
| - GKE_STABLE_VERSION | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - run: | | |
| set -eu | |
| source ./script/lib/libcitools.sh | |
| installGithubCLI ${GITHUB_VERSION} | |
| - # Assuming there is a personal access token created in GitHub granted with the scopes | |
| # "repo:status", "public_repo" and "read:org" | |
| name: Run the create_release script | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -eu | |
| ./script/create_release.sh "${GITHUB_REF_NAME}" "${KUBEAPPS_REPO}" | |
| gke_setup: | |
| if: inputs.run_gke_tests | |
| needs: | |
| - setup | |
| - test_go | |
| - test_dashboard | |
| - test_pinniped_proxy | |
| - test_oci_catalog | |
| - test_chart_render | |
| - build_docker_images | |
| - build_dashboard_image | |
| - build_e2e_runner_image | |
| - sync_chart_from_bitnami | |
| runs-on: ubuntu-latest | |
| outputs: | |
| CHARTMUSEUM_VERSION: ${{ steps.set-outputs.outputs.CHARTMUSEUM_VERSION }} | |
| DEBUG_MODE: ${{ steps.set-outputs.outputs.DEBUG_MODE }} | |
| GKE_STABLE_VERSION: ${{ steps.set-outputs.outputs.GKE_STABLE_VERSION }} | |
| GKE_REGULAR_VERSION: ${{ steps.set-outputs.outputs.GKE_REGULAR_VERSION }} | |
| GKE_CLUSTER: ${{ steps.set-outputs.outputs.GKE_CLUSTER }} | |
| GKE_PROJECT: ${{ steps.set-outputs.outputs.GKE_PROJECT }} | |
| GKE_ZONE: ${{ steps.set-outputs.outputs.GKE_ZONE }} | |
| HELM_VERSION_MIN: ${{ steps.set-outputs.outputs.HELM_VERSION_MIN }} | |
| HELM_VERSION_STABLE: ${{ steps.set-outputs.outputs.HELM_VERSION_STABLE }} | |
| IMG_DEV_TAG: ${{ steps.set-outputs.outputs.IMG_DEV_TAG }} | |
| IMG_MODIFIER: ${{ steps.set-outputs.outputs.IMG_MODIFIER }} | |
| IMG_PREFIX: ${{ steps.set-outputs.outputs.IMG_PREFIX }} | |
| KAPP_CONTROLLER_VERSION: ${{ steps.set-outputs.outputs.KAPP_CONTROLLER_VERSION }} | |
| FLUX_VERSION: ${{ steps.set-outputs.outputs.FLUX_VERSION }} | |
| KUBECTL_VERSION: ${{ steps.set-outputs.outputs.KUBECTL_VERSION }} | |
| OLM_VERSION: ${{ steps.set-outputs.outputs.OLM_VERSION }} | |
| steps: | |
| - id: set-outputs | |
| run: | | |
| echo "CHARTMUSEUM_VERSION=${CHARTMUSEUM_VERSION}" >> $GITHUB_OUTPUT | |
| echo "DEBUG_MODE=${DEBUG_MODE}" >> $GITHUB_OUTPUT | |
| echo "GKE_STABLE_VERSION=${GKE_STABLE_VERSION}" >> $GITHUB_OUTPUT | |
| echo "GKE_REGULAR_VERSION=${GKE_REGULAR_VERSION}" >> $GITHUB_OUTPUT | |
| echo "GKE_CLUSTER=${GKE_CLUSTER}" >> $GITHUB_OUTPUT | |
| echo "GKE_PROJECT=${GKE_PROJECT}" >> $GITHUB_OUTPUT | |
| echo "GKE_ZONE=${GKE_ZONE}" >> $GITHUB_OUTPUT | |
| echo "HELM_VERSION_MIN=${HELM_VERSION_MIN}" >> $GITHUB_OUTPUT | |
| echo "HELM_VERSION_STABLE=${HELM_VERSION_STABLE}" >> $GITHUB_OUTPUT | |
| echo "IMG_DEV_TAG=${{ needs.setup.outputs.img_dev_tag }}" >> $GITHUB_OUTPUT | |
| echo "IMG_MODIFIER=${{ needs.setup.outputs.img_modifier }}" >> $GITHUB_OUTPUT | |
| echo "IMG_PREFIX=${{ needs.setup.outputs.img_prefix }}" >> $GITHUB_OUTPUT | |
| echo "KAPP_CONTROLLER_VERSION=${KAPP_CONTROLLER_VERSION}" >> $GITHUB_OUTPUT | |
| echo "FLUX_VERSION=${FLUX_VERSION}" >> $GITHUB_OUTPUT | |
| echo "KUBECTL_VERSION=${KUBECTL_VERSION}" >> $GITHUB_OUTPUT | |
| echo "OLM_VERSION=${OLM_VERSION}" >> $GITHUB_OUTPUT | |
| GKE_REGULAR_VERSION: | |
| needs: | |
| - gke_setup | |
| uses: ./.github/workflows/gke_e2e_tests.yaml | |
| with: | |
| GKE_VERSION: ${{ needs.gke_setup.outputs.GKE_REGULAR_VERSION }} | |
| DEBUG_MODE: ${{ needs.gke_setup.outputs.DEBUG_MODE == 'true' }} | |
| CHARTMUSEUM_VERSION: ${{ needs.gke_setup.outputs.CHARTMUSEUM_VERSION }} | |
| GKE_CLUSTER: ${{ needs.gke_setup.outputs.GKE_CLUSTER }} | |
| GKE_PROJECT: ${{ needs.gke_setup.outputs.GKE_PROJECT }} | |
| GKE_RELEASE_CHANNEL: "regular" | |
| GKE_ZONE: ${{ needs.gke_setup.outputs.GKE_ZONE }} | |
| HELM_VERSION_MIN: ${{ needs.gke_setup.outputs.HELM_VERSION_MIN }} | |
| HELM_VERSION_STABLE: ${{ needs.gke_setup.outputs.HELM_VERSION_STABLE }} | |
| IMG_DEV_TAG: ${{ needs.gke_setup.outputs.IMG_DEV_TAG }} | |
| IMG_MODIFIER: ${{ needs.gke_setup.outputs.IMG_MODIFIER }} | |
| IMG_PREFIX: ${{ needs.gke_setup.outputs.IMG_PREFIX }} | |
| KAPP_CONTROLLER_VERSION: ${{ needs.gke_setup.outputs.KAPP_CONTROLLER_VERSION }} | |
| FLUX_VERSION: ${{ needs.gke_setup.outputs.FLUX_VERSION }} | |
| KUBECTL_VERSION: ${{ needs.gke_setup.outputs.KUBECTL_VERSION }} | |
| OLM_VERSION: ${{ needs.gke_setup.outputs.OLM_VERSION }} | |
| secrets: | |
| GKE_ADMIN: ${{ secrets.GKE_ADMIN }} | |
| GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }} | |
| GKE_STABLE_VERSION: | |
| needs: | |
| - gke_setup | |
| uses: ./.github/workflows/gke_e2e_tests.yaml | |
| with: | |
| GKE_VERSION: ${{ needs.gke_setup.outputs.GKE_STABLE_VERSION }} | |
| DEBUG_MODE: ${{ needs.gke_setup.outputs.DEBUG_MODE == 'true' }} | |
| CHARTMUSEUM_VERSION: ${{ needs.gke_setup.outputs.CHARTMUSEUM_VERSION }} | |
| GKE_CLUSTER: ${{ needs.gke_setup.outputs.GKE_CLUSTER }} | |
| GKE_PROJECT: ${{ needs.gke_setup.outputs.GKE_PROJECT }} | |
| GKE_RELEASE_CHANNEL: "stable" | |
| GKE_ZONE: ${{ needs.gke_setup.outputs.GKE_ZONE }} | |
| HELM_VERSION_MIN: ${{ needs.gke_setup.outputs.HELM_VERSION_MIN }} | |
| HELM_VERSION_STABLE: ${{ needs.gke_setup.outputs.HELM_VERSION_STABLE }} | |
| IMG_DEV_TAG: ${{ needs.gke_setup.outputs.IMG_DEV_TAG }} | |
| IMG_MODIFIER: ${{ needs.gke_setup.outputs.IMG_MODIFIER }} | |
| IMG_PREFIX: ${{ needs.gke_setup.outputs.IMG_PREFIX }} | |
| KAPP_CONTROLLER_VERSION: ${{ needs.gke_setup.outputs.KAPP_CONTROLLER_VERSION }} | |
| FLUX_VERSION: ${{ needs.gke_setup.outputs.FLUX_VERSION }} | |
| KUBECTL_VERSION: ${{ needs.gke_setup.outputs.KUBECTL_VERSION }} | |
| OLM_VERSION: ${{ needs.gke_setup.outputs.OLM_VERSION }} | |
| secrets: | |
| GKE_ADMIN: ${{ secrets.GKE_ADMIN }} | |
| GCLOUD_KEY: ${{ secrets.GCLOUD_KEY }} |