diff --git a/.github/workflows/toolkit-base.yaml b/.github/workflows/toolkit-base.yaml new file mode 100644 index 00000000..30c98b7b --- /dev/null +++ b/.github/workflows/toolkit-base.yaml @@ -0,0 +1,74 @@ +name: Create and publish toolkit base image + +on: + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + BUILD_CONTEXT: ../../tests/images/toolkit-base/ + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + attestations: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v5 + + - name: Install jq + run: sudo apt-get update && sudo apt-get install -y jq + + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + + - name: Setup docker buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=sha,prefix=,suffix=,enable=true,event=push,length=7 + type=raw,value=latest,enable=true + + - name: Extract latest tool versions + id: versions + working-directory: ${{ env.BUILD_CONTEXT }} + run: | + chmod +x ./get_versions.sh + ./get_versions.sh + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: ${{ env.BUILD_CONTEXT }} + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + build-args: | + KUBECTL_VERSION=${{ steps.versions.outputs.k8s_tag }} + HELM_VERSION=${{ steps.versions.outputs.helm_version }} + KUSTOMIZE_VERSION=${{ steps.versions.outputs.kustomize_version }} + KUBESEAL_VERSION=${{ steps.versions.outputs.kubeseal_version }} + KREW_VERSION=${{ steps.versions.outputs.krew_version }} + VALS_VERSION=${{ steps.versions.outputs.vals_version }} + KUBECONFORM_VERSION=${{ steps.versions.outputs.kubeconform_version }} + diff --git a/tests/images/toolkit-base/Dockerfile b/tests/images/toolkit-base/Dockerfile new file mode 100644 index 00000000..b3db62c3 --- /dev/null +++ b/tests/images/toolkit-base/Dockerfile @@ -0,0 +1,112 @@ +FROM alpine + +ARG ARCH + +# Ignore to update versions here +# docker build --no-cache --build-arg KUBECTL_VERSION=${tag} --build-arg HELM_VERSION=${helm} --build-arg KUSTOMIZE_VERSION=${kustomize_version} -t ${image}:${tag} . +ARG HELM_VERSION=3.2.1 +ARG KUBECTL_VERSION=1.17.5 +ARG KUSTOMIZE_VERSION=v3.8.1 +ARG KUBESEAL_VERSION=0.18.1 +ARG KREW_VERSION=v0.4.4 +ARG VALS_VERSION=0.28.1 +ARG KUBECONFORM_VERSION=0.6.3 + +# Install helm (latest release) +# ENV BASE_URL="https://storage.googleapis.com/kubernetes-helm" +RUN case `uname -m` in \ + x86_64) ARCH=amd64; ;; \ + armv7l) ARCH=arm; ;; \ + aarch64) ARCH=arm64; ;; \ + ppc64le) ARCH=ppc64le; ;; \ + s390x) ARCH=s390x; ;; \ + *) echo "un-supported arch, exit ..."; exit 1; ;; \ + esac && \ + echo "export ARCH=$ARCH" > /envfile && \ + cat /envfile + +RUN . /envfile && echo $ARCH && \ + apk add --update --no-cache curl ca-certificates bash git && \ + curl -sL https://get.helm.sh/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz | tar -xvz && \ + mv linux-${ARCH}/helm /usr/bin/helm && \ + chmod +x /usr/bin/helm && \ + rm -rf linux-${ARCH} + +# add helm-diff +RUN helm plugin install https://github.com/databus23/helm-diff --verify=false && rm -rf /tmp/helm-* && \ + rm -rf ~/.cache/helm/plugins/https-github.com-databus23-helm-diff/.git + +# add helm-unittest +RUN helm plugin install https://github.com/helm-unittest/helm-unittest --verify=false && rm -rf /tmp/helm-* + +# add helm-push +RUN helm plugin install https://github.com/chartmuseum/helm-push --verify=false && \ + rm -rf /tmp/helm-* \ + /root/.local/share/helm/plugins/helm-push/testdata \ + /root/.cache/helm/plugins/https-github.com-chartmuseum-helm-push/testdata + +# Install kubectl +RUN . /envfile && echo $ARCH && \ + curl -sLO "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" && \ + mv kubectl /usr/bin/kubectl && \ + chmod +x /usr/bin/kubectl + +# Install kustomize (latest release) +RUN . /envfile && echo $ARCH && \ + curl -sLO https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz && \ + tar xvzf kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz && \ + mv kustomize /usr/bin/kustomize && \ + chmod +x /usr/bin/kustomize && \ + rm kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz + +# Install eksctl (latest version) +RUN . /envfile && echo $ARCH && \ + curl -sL "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_${ARCH}.tar.gz" | tar xz -C /tmp && \ + mv /tmp/eksctl /usr/bin && \ + chmod +x /usr/bin/eksctl + +# Install awscli +# Temp fix to allow system-wide package installation: +# https://stackoverflow.com/a/76540031/3671801 +RUN apk add --update --no-cache py3-pip && \ + pip3 install --break-system-packages --upgrade pip setuptools && \ + pip3 install --break-system-packages awscli && \ + pip3 cache purge + +# Install jq +RUN apk add --update --no-cache jq yq + +# https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html +# Install aws-iam-authenticator (latest version) +RUN . /envfile && echo $ARCH && \ + authenticator=$(curl -fs https://api.github.com/repos/kubernetes-sigs/aws-iam-authenticator/releases/latest | jq --raw-output '.name' | sed 's/^v//') && \ + curl -fL https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v${authenticator}/aws-iam-authenticator_${authenticator}_linux_${ARCH} -o /usr/bin/aws-iam-authenticator && \ + chmod +x /usr/bin/aws-iam-authenticator + +# Install for envsubst +RUN apk add --update --no-cache gettext + +# Install kubeseal +RUN . /envfile && echo $ARCH && \ + curl -L https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${ARCH}.tar.gz -o - | tar xz -C /usr/bin/ && \ + chmod +x /usr/bin/kubeseal + +# Install vals +RUN . /envfile && echo $ARCH && \ + curl -L https://github.com/helmfile/vals/releases/download/v${VALS_VERSION}/vals_${VALS_VERSION}_linux_${ARCH}.tar.gz -o -| tar xz -C /usr/bin/ && \ + chmod +x /usr/bin/vals + +# Install krew (latest release) +RUN . /envfile && echo $ARCH && \ + curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/download/v${KREW_VERSION}/krew-linux_${ARCH}.tar.gz" && \ + tar zxvf krew-linux_${ARCH}.tar.gz && \ + ./krew-linux_${ARCH} install krew && \ + echo 'export PATH=/root/.krew/bin:$PATH' >> ~/.bashrc && \ + rm krew-linux_${ARCH}.tar.gz + +# Install kubeconform +RUN . /envfile && echo $ARCH && \ + curl -L https://github.com/yannh/kubeconform/releases/download/v${KUBECONFORM_VERSION}/kubeconform-linux-${ARCH}.tar.gz -o - | tar xz -C /usr/bin/ && \ + chmod +x /usr/bin/kubeconform + +WORKDIR /apps diff --git a/tests/images/toolkit-base/get_versions.sh b/tests/images/toolkit-base/get_versions.sh new file mode 100755 index 00000000..3a1ed473 --- /dev/null +++ b/tests/images/toolkit-base/get_versions.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +# Make sure jq is installed for this script to work on the runner +# (The workflow will install it) + +# 1. helm latest +HELM_VERSION=$(curl -s https://api.github.com/repos/helm/helm/releases | jq -r '.[].tag_name | select([startswith("v"), (contains("-") | not)] | all)' | sort -rV | head -n 1 | sed 's/v//') +echo "HELM_VERSION=$HELM_VERSION" +echo "helm_version=$HELM_VERSION" >> $GITHUB_OUTPUT + +# 2. kustomize latest +KUSTOMIZE_RELEASE=$(curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases | jq -r '.[].tag_name | select(contains("kustomize"))' | sort -rV | head -n 1) +KUSTOMIZE_VERSION=$(basename ${KUSTOMIZE_RELEASE}) +echo "KUSTOMIZE_VERSION=$KUSTOMIZE_VERSION" +echo "kustomize_version=$KUSTOMIZE_VERSION" >> $GITHUB_OUTPUT + +# 3. kubeseal latest +KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//') +echo "KUBESEAL_VERSION=$KUBESEAL_VERSION" +echo "kubeseal_version=$KUBESEAL_VERSION" >> $GITHUB_OUTPUT + +# 4. krew latest +KREW_VERSION=$(curl -s https://api.github.com/repos/kubernetes-sigs/krew/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//') +echo "KREW_VERSION=$KREW_VERSION" +echo "krew_version=$KREW_VERSION" >> $GITHUB_OUTPUT + +# 5. vals latest +VALS_VERSION=$(curl -s https://api.github.com/repos/helmfile/vals/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//') +echo "VALS_VERSION=$VALS_VERSION" +echo "vals_version=$VALS_VERSION" >> $GITHUB_OUTPUT + +# 6. kubeconform latest +KUBECONFORM_VERSION=$(curl -s https://api.github.com/repos/yannh/kubeconform/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//') +echo "KUBECONFORM_VERSION=$KUBECONFORM_VERSION" +echo "kubeconform_version=$KUBECONFORM_VERSION" >> $GITHUB_OUTPUT + +# 7. Kubectl/K8s tag determination (your complex logic) +# This will be used as the image tag AND as the KUBECTL_VERSION build-arg +# For simplicity, let's just grab the latest stable K8s version +K8S_TAG=$(curl -s https://api.github.com/repos/kubernetes/kubernetes/releases | jq -r '.[].tag_name | select(test("alpha|beta|rc") | not)' | sort -rV | head -n 1 | sed 's/v//') +echo "K8S_TAG=$K8S_TAG" +echo "k8s_tag=$K8S_TAG" >> $GITHUB_OUTPUT