From aafd97a0c148eaa8546053c52d42f71c0b2d4a71 Mon Sep 17 00:00:00 2001 From: Sinduri Guntupalli Date: Tue, 7 Apr 2026 13:03:30 +0200 Subject: [PATCH 1/3] feat: support --version flag in lib/**/init.sh scripts Add a --version flag to all 13 lib/**/init.sh scripts so adventures can pin specific tool versions without modifying shared scripts. - Refactor for-loop arg parsing to while/shift to support value-bearing flags - Each script defaults to its previously hardcoded version (backward-compatible) - kubernetes/init.sh uses per-tool flags (--kind-version, --kubectl-version, etc.) - prometheus/init.sh applies mode-specific defaults (operator: 82.1.1, standalone: latest) - otel-collector/init.sh accepts --version for API consistency with a stderr warning - Fix pre-existing unquoted variable in argocd/init.sh (shellcheck SC2086) - Update new-adventure.sh template and contributing docs with --version examples Closes #28 Signed-off-by: Sinduri Guntupalli --- docs/contributing/adventures.md | 10 +++- lib/argo-rollouts/init.sh | 35 +++++++++++++- lib/argocd/init.sh | 25 +++++++--- lib/gcp-api-mock/init.sh | 33 ++++++++++++- lib/github-cli/init.sh | 23 ++++++--- lib/jaeger/init.sh | 33 ++++++++++++- lib/kube-state-metrics/init.sh | 33 ++++++++++++- lib/kubernetes/init.sh | 85 ++++++++++++++++++++++++++++++--- lib/ollama/init.sh | 33 ++++++++++++- lib/open-tofu/init.sh | 37 ++++++++++++-- lib/otel-collector/init.sh | 29 +++++++++++ lib/prometheus/init.sh | 41 +++++++++++----- lib/qdrant/init.sh | 33 ++++++++++++- lib/shared/init.sh | 37 ++++++++++++-- scripts/new-adventure.sh | 12 ++++- 15 files changed, 453 insertions(+), 46 deletions(-) diff --git a/docs/contributing/adventures.md b/docs/contributing/adventures.md index 7eac8751..f5e0a5d8 100755 --- a/docs/contributing/adventures.md +++ b/docs/contributing/adventures.md @@ -77,10 +77,18 @@ Open the generated `.devcontainer/00-adventure-name_NN-level/` files and fill in For Kubernetes-based adventures, [Adventure 01](../../adventures/01-echoes-lost-in-orbit/) is a good reference for what features and setup scripts to use. **post-create.sh** runs once when the container is created: -- Install CLI tools using setup scripts from `lib/` +- Install CLI tools using setup scripts from `lib/` — every script accepts a `--version` flag to pin a specific version. Run any script with `--help` to see available flags and defaults. - Pull container images - Set up one-time configurations +Example calls in `post-create.sh`: +```bash +"$REPO_ROOT/lib/kubernetes/init.sh" # use default versions +"$REPO_ROOT/lib/argocd/init.sh" --version v3.5.0 # pin a version +"$REPO_ROOT/lib/argocd/init.sh" --read-only --version v3.5.0 # combine flags +"$REPO_ROOT/lib/kubernetes/init.sh" --kubectl-version v1.35.0 --helm-version v4.1.0 # per-tool versions +``` + **post-start.sh** runs every time the container starts: - Start services (databases, clusters, etc.) - Apply initial state diff --git a/lib/argo-rollouts/init.sh b/lib/argo-rollouts/init.sh index 147c3426..30b3094c 100755 --- a/lib/argo-rollouts/init.sh +++ b/lib/argo-rollouts/init.sh @@ -1,15 +1,46 @@ #!/usr/bin/env bash set -e +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version Argo Rollouts version to install (default: v1.8.3)" +} + +# Parse flags +version="v1.8.3" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Installing Argo Rollouts" kubectl create namespace argo-rollouts -kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/download/v1.8.3/install.yaml +kubectl apply -n argo-rollouts -f "https://github.com/argoproj/argo-rollouts/releases/download/${version}/install.yaml" echo "✨ Waiting for Argo Rollouts controller to be ready" kubectl rollout status deployment/argo-rollouts -n argo-rollouts --timeout=300s echo "✨ Installing Argo Rollouts Kubectl plugin" -curl -LO https://github.com/argoproj/argo-rollouts/releases/download/v1.8.3/kubectl-argo-rollouts-linux-amd64 +curl -LO "https://github.com/argoproj/argo-rollouts/releases/download/${version}/kubectl-argo-rollouts-linux-amd64" chmod +x ./kubectl-argo-rollouts-linux-amd64 sudo mv ./kubectl-argo-rollouts-linux-amd64 /usr/local/bin/kubectl-argo-rollouts diff --git a/lib/argocd/init.sh b/lib/argocd/init.sh index 8df89f76..2ad6b903 100755 --- a/lib/argocd/init.sh +++ b/lib/argocd/init.sh @@ -6,24 +6,35 @@ SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" help() { echo "Usage: $0 [OPTIONS]" echo "Options:" - echo " --help Display this help message" - echo " --read-only Disables the ArgoCD admin user and only provides read-only access" + echo " --help Display this help message" + echo " --read-only Disables the ArgoCD admin user and only provides read-only access" + echo " --version Argo CD version to install (default: v3.2.0)" } # Parse flags read_only=false +version="v3.2.0" -for arg in "$@"; do - case "$arg" in +while [[ $# -gt 0 ]]; do + case "$1" in --help) help exit 0 ;; --read-only) read_only=true + shift + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 ;; *) - echo "Unknown option: $arg" >&2 + echo "Unknown option: $1" >&2 exit 1 ;; esac @@ -34,7 +45,7 @@ kubectl create namespace argocd kubectl apply -k "$SCRIPT_DIR/manifests" echo "✨ Installing Argo CD CLI" -curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/download/v3.2.0/argocd-linux-amd64 +curl -sSL -o argocd-linux-amd64 "https://github.com/argoproj/argo-cd/releases/download/${version}/argocd-linux-amd64" sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd rm argocd-linux-amd64 @@ -49,7 +60,7 @@ if [ "$read_only" = true ]; then argocd login localhost:30100 --username admin --password "$admin_password" --plaintext argocd account update-password \ --account readonly \ - --current-password $admin_password \ + --current-password "$admin_password" \ --new-password a-super-secure-password echo "✨ Disabling admin user for read-only mode" diff --git a/lib/gcp-api-mock/init.sh b/lib/gcp-api-mock/init.sh index 9c7b073a..ca7d5203 100755 --- a/lib/gcp-api-mock/init.sh +++ b/lib/gcp-api-mock/init.sh @@ -1,8 +1,39 @@ #!/usr/bin/env bash set -e +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version GCP API Mock version to install (default: v1.1.4)" +} + +# Parse flags +version="v1.1.4" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Starting the GCP API Mock" -docker run -d -p 30104:8080 ghcr.io/katharinasick/gcp-api-mock:v1.1.4 +docker run -d -p 30104:8080 "ghcr.io/katharinasick/gcp-api-mock:${version}" # Set environment variable to redirect GCS backend requests to the mock echo 'export STORAGE_EMULATOR_HOST="http://localhost:30104"' >> ~/.bashrc diff --git a/lib/github-cli/init.sh b/lib/github-cli/init.sh index 0f37e9cd..98e0525f 100755 --- a/lib/github-cli/init.sh +++ b/lib/github-cli/init.sh @@ -4,31 +4,42 @@ set -e help() { echo "Usage: $0 [OPTIONS]" echo "Options:" - echo " --help Display this help message" - echo " --act Installs the nektos/act extension" + echo " --help Display this help message" + echo " --act Installs the nektos/act extension" + echo " --version GitHub CLI version to install (default: v2.86.0)" } # Parse flags act=false +version="v2.86.0" -for arg in "$@"; do - case "$arg" in +while [[ $# -gt 0 ]]; do + case "$1" in --help) help exit 0 ;; --act) act=true + shift + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 ;; *) - echo "Unknown option: $arg" >&2 + echo "Unknown option: $1" >&2 exit 1 ;; esac done echo "✨ Installing the GitHub CLI" -curl -sS https://webi.sh/gh@v2.86.0 | sh +curl -sS "https://webi.sh/gh@${version}" | sh if [ "$act" = true ]; then echo "✨ Installin nektos/act extension" diff --git a/lib/jaeger/init.sh b/lib/jaeger/init.sh index d0e7490e..8a3907fc 100755 --- a/lib/jaeger/init.sh +++ b/lib/jaeger/init.sh @@ -3,6 +3,37 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version Jaeger Helm chart version to install (default: 4.1.5)" +} + +# Parse flags +version="4.1.5" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + # Use a minimal Jaeger setup instead of deploying it via the operator to keep the Codespace lightweight and focused. echo "✨ Adding Jaeger Helm repo" @@ -14,7 +45,7 @@ kubectl create namespace jaeger echo "✨ Installing Jaeger via Helm" helm install jaeger jaegertracing/jaeger \ - --version 4.1.5 \ + --version "$version" \ --namespace jaeger \ --values "$SCRIPT_DIR/values.yaml" \ --wait \ diff --git a/lib/kube-state-metrics/init.sh b/lib/kube-state-metrics/init.sh index ae63beb6..0b0b6dae 100755 --- a/lib/kube-state-metrics/init.sh +++ b/lib/kube-state-metrics/init.sh @@ -3,6 +3,37 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version kube-state-metrics Helm chart version to install (default: 7.0.0)" +} + +# Parse flags +version="7.0.0" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Adding prometheus-community Helm repo" helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update @@ -12,7 +43,7 @@ kubectl create namespace kube-state-metrics echo "✨ Installing kube-state-metrics via Helm" helm install kube-state-metrics prometheus-community/kube-state-metrics \ - --version 7.0.0 \ + --version "$version" \ --namespace kube-state-metrics \ --values "$SCRIPT_DIR/values.yaml" \ --wait \ diff --git a/lib/kubernetes/init.sh b/lib/kubernetes/init.sh index 69bd004b..4e86369a 100755 --- a/lib/kubernetes/init.sh +++ b/lib/kubernetes/init.sh @@ -3,26 +3,97 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --kind-version kind version to install (default: v0.30.0)" + echo " --kubectl-version kubectl version to install (default: v1.34.1)" + echo " --kubens-version kubens version to install (default: v0.9.5)" + echo " --k9s-version k9s version to install (default: 0.50.16)" + echo " --helm-version Helm version to install (default: v4.0.1)" +} + +# Parse flags +kind_version="v0.30.0" +kubectl_version="v1.34.1" +kubens_version="v0.9.5" +k9s_version="0.50.16" +helm_version="v4.0.1" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --kind-version) + if [[ -z "${2-}" ]]; then + echo "Error: --kind-version requires a value" >&2 + exit 1 + fi + kind_version="$2" + shift 2 + ;; + --kubectl-version) + if [[ -z "${2-}" ]]; then + echo "Error: --kubectl-version requires a value" >&2 + exit 1 + fi + kubectl_version="$2" + shift 2 + ;; + --kubens-version) + if [[ -z "${2-}" ]]; then + echo "Error: --kubens-version requires a value" >&2 + exit 1 + fi + kubens_version="$2" + shift 2 + ;; + --k9s-version) + if [[ -z "${2-}" ]]; then + echo "Error: --k9s-version requires a value" >&2 + exit 1 + fi + k9s_version="$2" + shift 2 + ;; + --helm-version) + if [[ -z "${2-}" ]]; then + echo "Error: --helm-version requires a value" >&2 + exit 1 + fi + helm_version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Installing Kind" -curl -sS https://webi.sh/kind@v0.30.0 | sh +curl -sS "https://webi.sh/kind@${kind_version}" | sh echo "✨ Installing kubectl" -curl -LO "https://dl.k8s.io/release/v1.34.1/bin/linux/amd64/kubectl" +curl -LO "https://dl.k8s.io/release/${kubectl_version}/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/ echo "✨ Installing kubens" -curl -sS https://webi.sh/kubens@v0.9.5 | bash +curl -sS "https://webi.sh/kubens@${kubens_version}" | bash echo "✨ Installing k9s" -curl -sS https://webinstall.dev/k9s@0.50.16 | bash +curl -sS "https://webinstall.dev/k9s@${k9s_version}" | bash echo "✨ Installing Helm" -curl -LO "https://get.helm.sh/helm-v4.0.1-linux-amd64.tar.gz" -tar -zxvf helm-v4.0.1-linux-amd64.tar.gz +curl -LO "https://get.helm.sh/helm-${helm_version}-linux-amd64.tar.gz" +tar -zxvf "helm-${helm_version}-linux-amd64.tar.gz" chmod +x linux-amd64/helm sudo mv linux-amd64/helm /usr/local/bin/helm -rm -rf linux-amd64 helm-v4.0.1-linux-amd64.tar.gz +rm -rf linux-amd64 "helm-${helm_version}-linux-amd64.tar.gz" echo "✨ Starting Kind cluster" kind create cluster --config "$SCRIPT_DIR/config.yaml" --wait 300s diff --git a/lib/ollama/init.sh b/lib/ollama/init.sh index c0439521..b0830a44 100755 --- a/lib/ollama/init.sh +++ b/lib/ollama/init.sh @@ -3,6 +3,37 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version Ollama Helm chart version to install (default: 1.40.0)" +} + +# Parse flags +version="1.40.0" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + # Deploy Ollama to Kubernetes with TinyLlama model pre-loaded echo "✨ Adding Ollama Helm repo" @@ -11,7 +42,7 @@ helm repo update echo "✨ Installing Ollama via Helm" helm install ollama otwld/ollama \ - --version 1.40.0 \ + --version "$version" \ --namespace ollama --create-namespace \ --values "$SCRIPT_DIR/values.yaml" \ --wait \ diff --git a/lib/open-tofu/init.sh b/lib/open-tofu/init.sh index cb6da9dc..f8b83585 100755 --- a/lib/open-tofu/init.sh +++ b/lib/open-tofu/init.sh @@ -1,13 +1,44 @@ #!/usr/bin/env bash set -e +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version OpenTofu version to install (default: v1.11.2)" +} + +# Parse flags +version="v1.11.2" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Installing Open Tofu" -curl -LO "https://github.com/opentofu/opentofu/releases/download/v1.11.2/tofu_1.11.2_linux_amd64.zip" -unzip "tofu_1.11.2_linux_amd64.zip" tofu +curl -LO "https://github.com/opentofu/opentofu/releases/download/${version}/tofu_${version#v}_linux_amd64.zip" +unzip "tofu_${version#v}_linux_amd64.zip" tofu chmod +x tofu sudo mv tofu /usr/local/bin/tofu -rm -f "tofu_1.11.2_linux_amd64.zip" +rm -f "tofu_${version#v}_linux_amd64.zip" tofu version echo "✅ Open Tofu is ready" \ No newline at end of file diff --git a/lib/otel-collector/init.sh b/lib/otel-collector/init.sh index e456a35f..8ba6abd1 100755 --- a/lib/otel-collector/init.sh +++ b/lib/otel-collector/init.sh @@ -3,6 +3,35 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version Accepted for API consistency; the OTEL Collector version is defined in the manifests" +} + +# Parse flags +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + echo "Warning: --version is ignored for otel-collector; the version is defined in the manifests" >&2 + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Creating otel namespace" kubectl create namespace otel || true diff --git a/lib/prometheus/init.sh b/lib/prometheus/init.sh index 2fbfcf9b..ead644c4 100755 --- a/lib/prometheus/init.sh +++ b/lib/prometheus/init.sh @@ -6,24 +6,35 @@ SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" help() { echo "Usage: $0 [OPTIONS]" echo "Options:" - echo " --help Display this help message" - echo " --operator Install Prometheus Operator instead of standalone Prometheus" + echo " --help Display this help message" + echo " --operator Install Prometheus Operator instead of standalone Prometheus" + echo " --version Helm chart version to install (operator default: 82.1.1; standalone: latest)" } # Parse flags use_operator=false +version="" -for arg in "$@"; do - case "$arg" in +while [[ $# -gt 0 ]]; do + case "$1" in --help) help exit 0 ;; --operator) use_operator=true + shift + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 ;; *) - echo "Unknown option: $arg" >&2 + echo "Unknown option: $1" >&2 exit 1 ;; esac @@ -31,6 +42,11 @@ done # Use a minimal Prometheus setup instead of kube-prometheus-stack to keep the Codespace lightweight and focused. +# Apply mode-specific version defaults +if [[ "$use_operator" = true && -z "$version" ]]; then + version="82.1.1" +fi + echo "✨ Adding prometheus-community Helm repo" helm repo add prometheus-community https://prometheus-community.github.io/helm-charts 2>/dev/null || true helm repo update @@ -41,7 +57,7 @@ kubectl create namespace prometheus if [ "$use_operator" = true ]; then echo "✨ Installing Prometheus Operator (kube-prometheus-stack)" helm install prometheus prometheus-community/kube-prometheus-stack \ - --version 82.1.1 \ + --version "$version" \ --namespace prometheus \ --values "$SCRIPT_DIR/operator-values.yaml" \ --wait \ @@ -50,12 +66,15 @@ if [ "$use_operator" = true ]; then echo "✅ Prometheus Operator is ready" echo "💡 Use PrometheusRule CRDs to define recording and alerting rules" else + helm_args=(prometheus prometheus-community/prometheus + --namespace prometheus + --values "$SCRIPT_DIR/standalone-values.yaml" + --wait + --timeout 5m) + [[ -n "$version" ]] && helm_args+=(--version "$version") + echo "✨ Installing standalone Prometheus" - helm install prometheus prometheus-community/prometheus \ - --namespace prometheus \ - --values "$SCRIPT_DIR/standalone-values.yaml" \ - --wait \ - --timeout 5m + helm install "${helm_args[@]}" echo "✅ Prometheus is ready" fi diff --git a/lib/qdrant/init.sh b/lib/qdrant/init.sh index 3574fe32..38ec8683 100755 --- a/lib/qdrant/init.sh +++ b/lib/qdrant/init.sh @@ -3,6 +3,37 @@ set -e SCRIPT_DIR="$(dirname "$(realpath "${BASH_SOURCE[0]}")")" +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version Qdrant Helm chart version to install (default: 1.16.3)" +} + +# Parse flags +version="1.16.3" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Adding Qdrant Helm repo" helm repo add qdrant https://qdrant.github.io/qdrant-helm helm repo update @@ -12,7 +43,7 @@ kubectl create namespace qdrant || true echo "✨ Installing Qdrant via Helm" helm install qdrant qdrant/qdrant \ - --version 1.16.3 \ + --version "$version" \ --namespace qdrant \ --values "$SCRIPT_DIR/values.yaml" \ --wait \ diff --git a/lib/shared/init.sh b/lib/shared/init.sh index 06b4b658..a4adfae3 100755 --- a/lib/shared/init.sh +++ b/lib/shared/init.sh @@ -1,12 +1,43 @@ #!/usr/bin/env bash set -e +help() { + echo "Usage: $0 [OPTIONS]" + echo "Options:" + echo " --help Display this help message" + echo " --version gum version to install (default: v0.17.0)" +} + +# Parse flags +version="v0.17.0" + +while [[ $# -gt 0 ]]; do + case "$1" in + --help) + help + exit 0 + ;; + --version) + if [[ -z "${2-}" ]]; then + echo "Error: --version requires a value" >&2 + exit 1 + fi + version="$2" + shift 2 + ;; + *) + echo "Unknown option: $1" >&2 + exit 1 + ;; + esac +done + echo "✨ Installing gum" case "$(uname -m)" in aarch64|arm64) ARCH="arm64" ;; *) ARCH="amd64" ;; esac -curl -LO "https://github.com/charmbracelet/gum/releases/download/v0.17.0/gum_0.17.0_${ARCH}.deb" -sudo apt install ./gum_0.17.0_${ARCH}.deb -rm gum_0.17.0_${ARCH}.deb +curl -LO "https://github.com/charmbracelet/gum/releases/download/${version}/gum_${version#v}_${ARCH}.deb" +sudo apt install "./gum_${version#v}_${ARCH}.deb" +rm "gum_${version#v}_${ARCH}.deb" diff --git a/scripts/new-adventure.sh b/scripts/new-adventure.sh index 3336d150..3a08e3c9 100755 --- a/scripts/new-adventure.sh +++ b/scripts/new-adventure.sh @@ -349,7 +349,17 @@ track_codespace_created "\$REPO_ROOT/lib/shared/init.sh" -# TODO: install & configure the tools you need by using the setup scripts located in `/lib` (e.g. "\$REPO_ROOT/lib/kubernetes/init.sh") +# TODO: Install and configure the tools your adventure needs using the shared setup scripts in /lib. +# Every script accepts a --version flag to pin a specific tool version — use this instead of +# editing the shared script or duplicating install logic in this file. +# +# Examples: +# "\$REPO_ROOT/lib/kubernetes/init.sh" +# "\$REPO_ROOT/lib/argocd/init.sh" --version v3.5.0 +# "\$REPO_ROOT/lib/argocd/init.sh" --read-only --version v3.5.0 +# "\$REPO_ROOT/lib/kubernetes/init.sh" --kubectl-version v1.35.0 --helm-version v4.1.0 +# +# Run any script with --help to see all available flags and their defaults. EOF cat > "$DEVCONTAINER_DIR/post-start.sh" << EOF From 43ac8b3b76e2f067e14ecdc3adb8a5a826fd2b57 Mon Sep 17 00:00:00 2001 From: Sinduri Guntupalli Date: Tue, 14 Apr 2026 11:15:20 +0200 Subject: [PATCH 2/3] feat(28): add pinned version flags to all init.sh calls and CI lint check Signed-off-by: Sinduri Guntupalli --- .../post-create.sh | 12 +++-- .../post-create.sh | 18 ++++--- .../post-create.sh | 18 ++++--- .../post-create.sh | 6 +-- .../post-create.sh | 6 +-- .../post-create.sh | 8 ++-- .../post-create.sh | 16 +++++-- .../post-create.sh | 20 +++++--- .../post-create.sh | 18 ++++--- .devcontainer/post-create.sh | 2 +- .github/workflows/lint-init-versions.yaml | 48 +++++++++++++++++++ lib/argo-rollouts/init.sh | 9 +++- lib/argocd/init.sh | 17 +++++-- lib/argocd/manifests/kustomization.yaml | 3 ++ lib/gcp-api-mock/init.sh | 9 +++- lib/github-cli/init.sh | 9 +++- lib/jaeger/init.sh | 9 +++- lib/kube-state-metrics/init.sh | 9 +++- lib/kubernetes/init.sh | 41 ++++++++++++---- lib/ollama/init.sh | 9 +++- lib/open-tofu/init.sh | 9 +++- lib/otel-collector/init.sh | 18 +++++-- lib/otel-collector/manifests/deployment.yaml | 2 +- lib/prometheus/init.sh | 22 ++++----- lib/qdrant/init.sh | 9 +++- lib/shared/init.sh | 9 +++- scripts/new-adventure.sh | 6 +-- 27 files changed, 267 insertions(+), 95 deletions(-) create mode 100644 .github/workflows/lint-init-versions.yaml diff --git a/.devcontainer/01-echoes-lost-in-orbit_beginner/post-create.sh b/.devcontainer/01-echoes-lost-in-orbit_beginner/post-create.sh index ecaceb66..be345edd 100644 --- a/.devcontainer/01-echoes-lost-in-orbit_beginner/post-create.sh +++ b/.devcontainer/01-echoes-lost-in-orbit_beginner/post-create.sh @@ -1,6 +1,12 @@ #!/usr/bin/env bash set -e -lib/shared/init.sh -lib/kubernetes/init.sh -lib/argocd/init.sh --read-only +lib/shared/init.sh --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +lib/kubernetes/init.sh \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +lib/argocd/init.sh --read-only --version v3.2.0 # https://github.com/argoproj/argo-cd/releases diff --git a/.devcontainer/01-echoes-lost-in-orbit_expert/post-create.sh b/.devcontainer/01-echoes-lost-in-orbit_expert/post-create.sh index 2fd3dc01..f8c8bcc3 100644 --- a/.devcontainer/01-echoes-lost-in-orbit_expert/post-create.sh +++ b/.devcontainer/01-echoes-lost-in-orbit_expert/post-create.sh @@ -1,9 +1,15 @@ #!/usr/bin/env bash set -e -lib/shared/init.sh -lib/kubernetes/init.sh -lib/argocd/init.sh --read-only -lib/argo-rollouts/init.sh -lib/prometheus/init.sh -lib/jaeger/init.sh \ No newline at end of file +lib/shared/init.sh --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +lib/kubernetes/init.sh \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +lib/argocd/init.sh --read-only --version v3.2.0 # https://github.com/argoproj/argo-cd/releases +lib/argo-rollouts/init.sh --version v1.8.3 # https://github.com/argoproj/argo-rollouts/releases +lib/prometheus/init.sh --version 29.1.0 # https://artifacthub.io/packages/helm/prometheus-community/prometheus +lib/jaeger/init.sh --version 4.1.5 # https://artifacthub.io/packages/helm/jaegertracing/jaeger \ No newline at end of file diff --git a/.devcontainer/01-echoes-lost-in-orbit_intermediate/post-create.sh b/.devcontainer/01-echoes-lost-in-orbit_intermediate/post-create.sh index dd7c38b5..8103d440 100644 --- a/.devcontainer/01-echoes-lost-in-orbit_intermediate/post-create.sh +++ b/.devcontainer/01-echoes-lost-in-orbit_intermediate/post-create.sh @@ -1,9 +1,15 @@ #!/usr/bin/env bash set -e -lib/shared/init.sh -lib/kubernetes/init.sh -lib/argocd/init.sh --read-only -lib/argo-rollouts/init.sh -lib/kube-state-metrics/init.sh -lib/prometheus/init.sh \ No newline at end of file +lib/shared/init.sh --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +lib/kubernetes/init.sh \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +lib/argocd/init.sh --read-only --version v3.2.0 # https://github.com/argoproj/argo-cd/releases +lib/argo-rollouts/init.sh --version v1.8.3 # https://github.com/argoproj/argo-rollouts/releases +lib/kube-state-metrics/init.sh --version 7.0.0 # https://artifacthub.io/packages/helm/prometheus-community/kube-state-metrics +lib/prometheus/init.sh --version 29.1.0 # https://artifacthub.io/packages/helm/prometheus-community/prometheus \ No newline at end of file diff --git a/.devcontainer/02-building-cloudhaven_01-beginner/post-create.sh b/.devcontainer/02-building-cloudhaven_01-beginner/post-create.sh index 8f53f938..1ea5675e 100644 --- a/.devcontainer/02-building-cloudhaven_01-beginner/post-create.sh +++ b/.devcontainer/02-building-cloudhaven_01-beginner/post-create.sh @@ -8,7 +8,7 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "02-building-cloudhaven" "beginner" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases -"$REPO_ROOT/lib/open-tofu/init.sh" -"$REPO_ROOT/lib/gcp-api-mock/init.sh" +"$REPO_ROOT/lib/open-tofu/init.sh" --version v1.11.2 # https://github.com/opentofu/opentofu/releases +"$REPO_ROOT/lib/gcp-api-mock/init.sh" --version v1.1.4 # https://github.com/KatharinaSick/gcp-api-mock/releases diff --git a/.devcontainer/02-building-cloudhaven_02-intermediate/post-create.sh b/.devcontainer/02-building-cloudhaven_02-intermediate/post-create.sh index aeed3744..ac19bdc9 100644 --- a/.devcontainer/02-building-cloudhaven_02-intermediate/post-create.sh +++ b/.devcontainer/02-building-cloudhaven_02-intermediate/post-create.sh @@ -8,7 +8,7 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "02-building-cloudhaven" "intermediate" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases -"$REPO_ROOT/lib/open-tofu/init.sh" -"$REPO_ROOT/lib/gcp-api-mock/init.sh" \ No newline at end of file +"$REPO_ROOT/lib/open-tofu/init.sh" --version v1.11.2 # https://github.com/opentofu/opentofu/releases +"$REPO_ROOT/lib/gcp-api-mock/init.sh" --version v1.1.4 # https://github.com/KatharinaSick/gcp-api-mock/releases \ No newline at end of file diff --git a/.devcontainer/02-building-cloudhaven_03-expert/post-create.sh b/.devcontainer/02-building-cloudhaven_03-expert/post-create.sh index f9248874..c7961541 100644 --- a/.devcontainer/02-building-cloudhaven_03-expert/post-create.sh +++ b/.devcontainer/02-building-cloudhaven_03-expert/post-create.sh @@ -8,8 +8,8 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "02-building-cloudhaven" "expert" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases -"$REPO_ROOT/lib/github-cli/init.sh" -"$REPO_ROOT/lib/open-tofu/init.sh" -"$REPO_ROOT/lib/gcp-api-mock/init.sh" +"$REPO_ROOT/lib/github-cli/init.sh" --version v2.86.0 # https://github.com/cli/cli/releases +"$REPO_ROOT/lib/open-tofu/init.sh" --version v1.11.2 # https://github.com/opentofu/opentofu/releases +"$REPO_ROOT/lib/gcp-api-mock/init.sh" --version v1.1.4 # https://github.com/KatharinaSick/gcp-api-mock/releases diff --git a/.devcontainer/03-the-ai-observatory_01-beginner/post-create.sh b/.devcontainer/03-the-ai-observatory_01-beginner/post-create.sh index 98279ec3..fb49f9dd 100644 --- a/.devcontainer/03-the-ai-observatory_01-beginner/post-create.sh +++ b/.devcontainer/03-the-ai-observatory_01-beginner/post-create.sh @@ -8,8 +8,14 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "03-the-ai-observatory" "beginner" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" -"$REPO_ROOT/lib/kubernetes/init.sh" -"$REPO_ROOT/lib/jaeger/init.sh" -"$REPO_ROOT/lib/otel-collector/init.sh" -"$REPO_ROOT/lib/ollama/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +"$REPO_ROOT/lib/kubernetes/init.sh" \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +"$REPO_ROOT/lib/jaeger/init.sh" --version 4.1.5 # https://artifacthub.io/packages/helm/jaegertracing/jaeger +"$REPO_ROOT/lib/otel-collector/init.sh" --version 0.148.0 # https://github.com/open-telemetry/opentelemetry-collector-releases/releases +"$REPO_ROOT/lib/ollama/init.sh" --version 1.40.0 # https://artifacthub.io/packages/helm/otwld/ollama diff --git a/.devcontainer/03-the-ai-observatory_02-intermediate/post-create.sh b/.devcontainer/03-the-ai-observatory_02-intermediate/post-create.sh index 1737b735..817d8655 100644 --- a/.devcontainer/03-the-ai-observatory_02-intermediate/post-create.sh +++ b/.devcontainer/03-the-ai-observatory_02-intermediate/post-create.sh @@ -8,11 +8,17 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "03-the-ai-observatory" "intermediate" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" -"$REPO_ROOT/lib/kubernetes/init.sh" -"$REPO_ROOT/lib/jaeger/init.sh" -"$REPO_ROOT/lib/otel-collector/init.sh" -"$REPO_ROOT/lib/prometheus/init.sh" --operator -"$REPO_ROOT/lib/ollama/init.sh" -"$REPO_ROOT/lib/qdrant/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +"$REPO_ROOT/lib/kubernetes/init.sh" \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +"$REPO_ROOT/lib/jaeger/init.sh" --version 4.1.5 # https://artifacthub.io/packages/helm/jaegertracing/jaeger +"$REPO_ROOT/lib/otel-collector/init.sh" --version 0.148.0 # https://github.com/open-telemetry/opentelemetry-collector-releases/releases +"$REPO_ROOT/lib/prometheus/init.sh" --operator --version 82.1.1 # https://artifacthub.io/packages/helm/prometheus-community/kube-prometheus-stack +"$REPO_ROOT/lib/ollama/init.sh" --version 1.40.0 # https://artifacthub.io/packages/helm/otwld/ollama +"$REPO_ROOT/lib/qdrant/init.sh" --version 1.16.3 # https://artifacthub.io/packages/helm/qdrant/qdrant diff --git a/.devcontainer/03-the-ai-observatory_03-expert/post-create.sh b/.devcontainer/03-the-ai-observatory_03-expert/post-create.sh index 3032f4fb..6011f8c3 100644 --- a/.devcontainer/03-the-ai-observatory_03-expert/post-create.sh +++ b/.devcontainer/03-the-ai-observatory_03-expert/post-create.sh @@ -8,9 +8,15 @@ source "$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "03-the-ai-observatory" "expert" track_codespace_created -"$REPO_ROOT/lib/shared/init.sh" -"$REPO_ROOT/lib/kubernetes/init.sh" -"$REPO_ROOT/lib/jaeger/init.sh" -"$REPO_ROOT/lib/otel-collector/init.sh" -"$REPO_ROOT/lib/ollama/init.sh" -"$REPO_ROOT/lib/qdrant/init.sh" +"$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # https://github.com/charmbracelet/gum/releases +# kind: https://github.com/kubernetes-sigs/kind/releases | kubectl: https://dl.k8s.io | kubens: https://github.com/ahmetb/kubectx/releases | k9s: https://github.com/derailed/k9s/releases | helm: https://github.com/helm/helm/releases +"$REPO_ROOT/lib/kubernetes/init.sh" \ + --kind-version v0.30.0 \ + --kubectl-version v1.34.1 \ + --kubens-version v0.9.5 \ + --k9s-version v0.50.16 \ + --helm-version v4.0.1 +"$REPO_ROOT/lib/jaeger/init.sh" --version 4.1.5 # https://artifacthub.io/packages/helm/jaegertracing/jaeger +"$REPO_ROOT/lib/otel-collector/init.sh" --version 0.148.0 # https://github.com/open-telemetry/opentelemetry-collector-releases/releases +"$REPO_ROOT/lib/ollama/init.sh" --version 1.40.0 # https://artifacthub.io/packages/helm/otwld/ollama +"$REPO_ROOT/lib/qdrant/init.sh" --version 1.16.3 # https://artifacthub.io/packages/helm/qdrant/qdrant diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index aa256854..990b2d23 100644 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -lib/shared/init.sh +lib/shared/init.sh --version v0.17.0 # https://github.com/charmbracelet/gum/releases echo "→ Installing mkdocs-material..." pip install --quiet mkdocs-material mkdocs-monorepo-plugin diff --git a/.github/workflows/lint-init-versions.yaml b/.github/workflows/lint-init-versions.yaml new file mode 100644 index 00000000..1c8b612e --- /dev/null +++ b/.github/workflows/lint-init-versions.yaml @@ -0,0 +1,48 @@ +name: Lint init script versions + +on: + pull_request: + paths: + - '.devcontainer/**/post-create.sh' + - 'lib/**/init.sh' + +jobs: + check-versions-pinned: + name: All init.sh calls have pinned versions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check that every init.sh call has a version flag + run: | + set -euo pipefail + + failed=0 + + while IFS= read -r file; do + while IFS= read -r line; do + # Skip blank lines, comments, and lines that don't reference an init script + [[ "$line" =~ ^[[:space:]]*# ]] && continue + [[ "$line" =~ init\.sh ]] || continue + + + # Skip continuation lines (they carry the version flags for kubernetes/init.sh) + [[ "$line" =~ \\[[:space:]]*$ ]] && continue + [[ "$line" =~ ^[[:space:]]+-- ]] && continue + + # The line calls an init script — check it carries a version flag + if ! grep -qE '(--version|--kind-version|--kubectl-version|--kubens-version|--k9s-version|--helm-version)' <<< "$line"; then + echo "ERROR: $file: missing version flag on: $line" + failed=1 + fi + done < "$file" + done < <(find .devcontainer -name 'post-create.sh') + + if [[ $failed -eq 1 ]]; then + echo "" + echo "Every lib/**/init.sh call must pass a pinned --version flag." + echo "Run the script with --help to see available flags." + exit 1 + fi + + echo "✅ All init.sh calls have pinned version flags." diff --git a/lib/argo-rollouts/init.sh b/lib/argo-rollouts/init.sh index 30b3094c..1d391844 100755 --- a/lib/argo-rollouts/init.sh +++ b/lib/argo-rollouts/init.sh @@ -5,11 +5,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version Argo Rollouts version to install (default: v1.8.3)" + echo " --version Argo Rollouts version to install (required)" } # Parse flags -version="v1.8.3" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -32,6 +32,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Installing Argo Rollouts" kubectl create namespace argo-rollouts kubectl apply -n argo-rollouts -f "https://github.com/argoproj/argo-rollouts/releases/download/${version}/install.yaml" diff --git a/lib/argocd/init.sh b/lib/argocd/init.sh index 2ad6b903..61a7ba28 100755 --- a/lib/argocd/init.sh +++ b/lib/argocd/init.sh @@ -8,12 +8,12 @@ help() { echo "Options:" echo " --help Display this help message" echo " --read-only Disables the ArgoCD admin user and only provides read-only access" - echo " --version Argo CD version to install (default: v3.2.0)" + echo " --version Argo CD version to install (required)" } # Parse flags read_only=false -version="v3.2.0" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -40,9 +40,20 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Installing Argo CD" kubectl create namespace argocd -kubectl apply -k "$SCRIPT_DIR/manifests" + +manifests_tmp="$(mktemp -d)" +trap 'rm -rf "${manifests_tmp}"' EXIT +cp -r "$SCRIPT_DIR/manifests/." "${manifests_tmp}/" +sed -i "s|argoproj/argo-cd/v[^/]*/manifests/install.yaml|argoproj/argo-cd/${version}/manifests/install.yaml|" \ + "${manifests_tmp}/kustomization.yaml" +kubectl apply -k "${manifests_tmp}" echo "✨ Installing Argo CD CLI" curl -sSL -o argocd-linux-amd64 "https://github.com/argoproj/argo-cd/releases/download/${version}/argocd-linux-amd64" diff --git a/lib/argocd/manifests/kustomization.yaml b/lib/argocd/manifests/kustomization.yaml index bcf11242..f0b7ded1 100644 --- a/lib/argocd/manifests/kustomization.yaml +++ b/lib/argocd/manifests/kustomization.yaml @@ -3,6 +3,9 @@ kind: Kustomization namespace: argocd +# The version in the URL below is substituted at deploy time by init.sh using the +# --version flag. Do not bump the version here directly — update the callers in +# .devcontainer/**/post-create.sh instead. resources: - https://raw.githubusercontent.com/argoproj/argo-cd/v3.2.0/manifests/install.yaml diff --git a/lib/gcp-api-mock/init.sh b/lib/gcp-api-mock/init.sh index ca7d5203..f70f100b 100755 --- a/lib/gcp-api-mock/init.sh +++ b/lib/gcp-api-mock/init.sh @@ -5,11 +5,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version GCP API Mock version to install (default: v1.1.4)" + echo " --version GCP API Mock version to install (required)" } # Parse flags -version="v1.1.4" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -32,6 +32,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Starting the GCP API Mock" docker run -d -p 30104:8080 "ghcr.io/katharinasick/gcp-api-mock:${version}" diff --git a/lib/github-cli/init.sh b/lib/github-cli/init.sh index 98e0525f..cbfda1bb 100755 --- a/lib/github-cli/init.sh +++ b/lib/github-cli/init.sh @@ -6,12 +6,12 @@ help() { echo "Options:" echo " --help Display this help message" echo " --act Installs the nektos/act extension" - echo " --version GitHub CLI version to install (default: v2.86.0)" + echo " --version GitHub CLI version to install (required)" } # Parse flags act=false -version="v2.86.0" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -38,6 +38,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Installing the GitHub CLI" curl -sS "https://webi.sh/gh@${version}" | sh diff --git a/lib/jaeger/init.sh b/lib/jaeger/init.sh index 8a3907fc..c6bb816d 100755 --- a/lib/jaeger/init.sh +++ b/lib/jaeger/init.sh @@ -7,11 +7,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version Jaeger Helm chart version to install (default: 4.1.5)" + echo " --version Jaeger Helm chart version to install (required)" } # Parse flags -version="4.1.5" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -34,6 +34,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + # Use a minimal Jaeger setup instead of deploying it via the operator to keep the Codespace lightweight and focused. echo "✨ Adding Jaeger Helm repo" diff --git a/lib/kube-state-metrics/init.sh b/lib/kube-state-metrics/init.sh index 0b0b6dae..c5875482 100755 --- a/lib/kube-state-metrics/init.sh +++ b/lib/kube-state-metrics/init.sh @@ -7,11 +7,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version kube-state-metrics Helm chart version to install (default: 7.0.0)" + echo " --version kube-state-metrics Helm chart version to install (required)" } # Parse flags -version="7.0.0" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -34,6 +34,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Adding prometheus-community Helm repo" helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update diff --git a/lib/kubernetes/init.sh b/lib/kubernetes/init.sh index 4e86369a..102558cc 100755 --- a/lib/kubernetes/init.sh +++ b/lib/kubernetes/init.sh @@ -7,19 +7,19 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --kind-version kind version to install (default: v0.30.0)" - echo " --kubectl-version kubectl version to install (default: v1.34.1)" - echo " --kubens-version kubens version to install (default: v0.9.5)" - echo " --k9s-version k9s version to install (default: 0.50.16)" - echo " --helm-version Helm version to install (default: v4.0.1)" + echo " --kind-version kind version to install (required)" + echo " --kubectl-version kubectl version to install (required)" + echo " --kubens-version kubens version to install (required)" + echo " --k9s-version k9s version to install (required)" + echo " --helm-version Helm version to install (required)" } # Parse flags -kind_version="v0.30.0" -kubectl_version="v1.34.1" -kubens_version="v0.9.5" -k9s_version="0.50.16" -helm_version="v4.0.1" +kind_version="" +kubectl_version="" +kubens_version="" +k9s_version="" +helm_version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -74,6 +74,27 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$kind_version" ]]; then + echo "Error: --kind-version is required" >&2 + exit 1 +fi +if [[ -z "$kubectl_version" ]]; then + echo "Error: --kubectl-version is required" >&2 + exit 1 +fi +if [[ -z "$kubens_version" ]]; then + echo "Error: --kubens-version is required" >&2 + exit 1 +fi +if [[ -z "$k9s_version" ]]; then + echo "Error: --k9s-version is required" >&2 + exit 1 +fi +if [[ -z "$helm_version" ]]; then + echo "Error: --helm-version is required" >&2 + exit 1 +fi + echo "✨ Installing Kind" curl -sS "https://webi.sh/kind@${kind_version}" | sh diff --git a/lib/ollama/init.sh b/lib/ollama/init.sh index b0830a44..2c6e6110 100755 --- a/lib/ollama/init.sh +++ b/lib/ollama/init.sh @@ -7,11 +7,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version Ollama Helm chart version to install (default: 1.40.0)" + echo " --version Ollama Helm chart version to install (required)" } # Parse flags -version="1.40.0" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -34,6 +34,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + # Deploy Ollama to Kubernetes with TinyLlama model pre-loaded echo "✨ Adding Ollama Helm repo" diff --git a/lib/open-tofu/init.sh b/lib/open-tofu/init.sh index f8b83585..87aa0e03 100755 --- a/lib/open-tofu/init.sh +++ b/lib/open-tofu/init.sh @@ -5,11 +5,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version OpenTofu version to install (default: v1.11.2)" + echo " --version OpenTofu version to install (required)" } # Parse flags -version="v1.11.2" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -32,6 +32,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Installing Open Tofu" curl -LO "https://github.com/opentofu/opentofu/releases/download/${version}/tofu_${version#v}_linux_amd64.zip" diff --git a/lib/otel-collector/init.sh b/lib/otel-collector/init.sh index 8ba6abd1..b1d87ee5 100755 --- a/lib/otel-collector/init.sh +++ b/lib/otel-collector/init.sh @@ -7,9 +7,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version Accepted for API consistency; the OTEL Collector version is defined in the manifests" + echo " --version otel/opentelemetry-collector-contrib image tag (required)" } +version="" + # Parse flags while [[ $# -gt 0 ]]; do case "$1" in @@ -22,7 +24,7 @@ while [[ $# -gt 0 ]]; do echo "Error: --version requires a value" >&2 exit 1 fi - echo "Warning: --version is ignored for otel-collector; the version is defined in the manifests" >&2 + version="$2" shift 2 ;; *) @@ -32,11 +34,19 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Creating otel namespace" kubectl create namespace otel || true -echo "✨ Deploying OTEL Collector manifests" -kubectl apply -n otel -f "$SCRIPT_DIR/manifests/" +echo "✨ Deploying OTEL Collector manifests (version ${version})" +kubectl apply -n otel -f "$SCRIPT_DIR/manifests/config.yaml" +kubectl apply -n otel -f "$SCRIPT_DIR/manifests/service.yaml" +sed "s|otel/opentelemetry-collector-contrib:.*|otel/opentelemetry-collector-contrib:${version}|" \ + "$SCRIPT_DIR/manifests/deployment.yaml" | kubectl apply -n otel -f - echo "✨ Waiting for OTEL Collector to be ready" kubectl rollout status deployment/collector -n otel --timeout=120s diff --git a/lib/otel-collector/manifests/deployment.yaml b/lib/otel-collector/manifests/deployment.yaml index d340d278..eafcb59e 100644 --- a/lib/otel-collector/manifests/deployment.yaml +++ b/lib/otel-collector/manifests/deployment.yaml @@ -20,7 +20,7 @@ spec: spec: containers: - name: collector - image: otel/opentelemetry-collector-contrib:0.142.0 + image: otel/opentelemetry-collector-contrib:0.148.0 args: - --config=/conf/collector-config.yaml ports: diff --git a/lib/prometheus/init.sh b/lib/prometheus/init.sh index ead644c4..aad739b9 100755 --- a/lib/prometheus/init.sh +++ b/lib/prometheus/init.sh @@ -8,7 +8,7 @@ help() { echo "Options:" echo " --help Display this help message" echo " --operator Install Prometheus Operator instead of standalone Prometheus" - echo " --version Helm chart version to install (operator default: 82.1.1; standalone: latest)" + echo " --version Helm chart version to install (required)" } # Parse flags @@ -42,9 +42,9 @@ done # Use a minimal Prometheus setup instead of kube-prometheus-stack to keep the Codespace lightweight and focused. -# Apply mode-specific version defaults -if [[ "$use_operator" = true && -z "$version" ]]; then - version="82.1.1" +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 fi echo "✨ Adding prometheus-community Helm repo" @@ -66,15 +66,13 @@ if [ "$use_operator" = true ]; then echo "✅ Prometheus Operator is ready" echo "💡 Use PrometheusRule CRDs to define recording and alerting rules" else - helm_args=(prometheus prometheus-community/prometheus - --namespace prometheus - --values "$SCRIPT_DIR/standalone-values.yaml" - --wait - --timeout 5m) - [[ -n "$version" ]] && helm_args+=(--version "$version") - echo "✨ Installing standalone Prometheus" - helm install "${helm_args[@]}" + helm install prometheus prometheus-community/prometheus \ + --version "$version" \ + --namespace prometheus \ + --values "$SCRIPT_DIR/standalone-values.yaml" \ + --wait \ + --timeout 5m echo "✅ Prometheus is ready" fi diff --git a/lib/qdrant/init.sh b/lib/qdrant/init.sh index 38ec8683..b8dc0a55 100755 --- a/lib/qdrant/init.sh +++ b/lib/qdrant/init.sh @@ -7,11 +7,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version Qdrant Helm chart version to install (default: 1.16.3)" + echo " --version Qdrant Helm chart version to install (required)" } # Parse flags -version="1.16.3" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -34,6 +34,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Adding Qdrant Helm repo" helm repo add qdrant https://qdrant.github.io/qdrant-helm helm repo update diff --git a/lib/shared/init.sh b/lib/shared/init.sh index a4adfae3..03726a32 100755 --- a/lib/shared/init.sh +++ b/lib/shared/init.sh @@ -5,11 +5,11 @@ help() { echo "Usage: $0 [OPTIONS]" echo "Options:" echo " --help Display this help message" - echo " --version gum version to install (default: v0.17.0)" + echo " --version gum version to install (required)" } # Parse flags -version="v0.17.0" +version="" while [[ $# -gt 0 ]]; do case "$1" in @@ -32,6 +32,11 @@ while [[ $# -gt 0 ]]; do esac done +if [[ -z "$version" ]]; then + echo "Error: --version is required" >&2 + exit 1 +fi + echo "✨ Installing gum" case "$(uname -m)" in aarch64|arm64) ARCH="arm64" ;; diff --git a/scripts/new-adventure.sh b/scripts/new-adventure.sh index 3a08e3c9..a1f78b56 100755 --- a/scripts/new-adventure.sh +++ b/scripts/new-adventure.sh @@ -347,14 +347,14 @@ source "\$REPO_ROOT/lib/scripts/tracker.sh" set_tracking_context "$selected_slug" "$level_slug" track_codespace_created -"\$REPO_ROOT/lib/shared/init.sh" +"\$REPO_ROOT/lib/shared/init.sh" --version v0.17.0 # TODO: Install and configure the tools your adventure needs using the shared setup scripts in /lib. -# Every script accepts a --version flag to pin a specific tool version — use this instead of +# Every script accepts a --version flag or per-tool version flags (e.g. kubernetes uses +# --kind-version, --kubectl-version, etc.) to pin a specific tool version — use this instead of # editing the shared script or duplicating install logic in this file. # # Examples: -# "\$REPO_ROOT/lib/kubernetes/init.sh" # "\$REPO_ROOT/lib/argocd/init.sh" --version v3.5.0 # "\$REPO_ROOT/lib/argocd/init.sh" --read-only --version v3.5.0 # "\$REPO_ROOT/lib/kubernetes/init.sh" --kubectl-version v1.35.0 --helm-version v4.1.0 From f50815b6477f9bd6b73aab367f1170b2210efae8 Mon Sep 17 00:00:00 2001 From: Sinduri Guntupalli Date: Wed, 15 Apr 2026 12:40:54 +0200 Subject: [PATCH 3/3] fix: use ARGOCD_VERSION placeholder in kustomization.yaml and fix lint CI regex - Replace hardcoded v3.2.0 with ARGOCD_VERSION placeholder in argocd kustomization.yaml resource URL so applying the manifests directly without going through init.sh fails intentionally - Update sed pattern in argocd/init.sh from v[^/]* to [^/]* to match the placeholder string correctly - Fix continuation-line skip in lint-init-versions.yaml: replace broken ERE regex with glob pattern *\ which correctly identifies backslash continuation lines in multi-line kubernetes/init.sh calls - Add explanatory comment to lint-init-versions.yaml explaining why the check exists alongside runtime --version validation Signed-off-by: Sinduri Guntupalli --- .github/workflows/lint-init-versions.yaml | 5 ++++- lib/argocd/init.sh | 2 +- lib/argocd/manifests/kustomization.yaml | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/lint-init-versions.yaml b/.github/workflows/lint-init-versions.yaml index 1c8b612e..2dd8519f 100644 --- a/.github/workflows/lint-init-versions.yaml +++ b/.github/workflows/lint-init-versions.yaml @@ -1,3 +1,6 @@ +# This check exists to catch missing --version flags at PR time rather than when a +# contributor's Codespace silently fails to start. Failing fast here gives a much +# better experience than debugging a broken environment after the fact. name: Lint init script versions on: @@ -27,7 +30,7 @@ jobs: # Skip continuation lines (they carry the version flags for kubernetes/init.sh) - [[ "$line" =~ \\[[:space:]]*$ ]] && continue + [[ "$line" == *\\ ]] && continue [[ "$line" =~ ^[[:space:]]+-- ]] && continue # The line calls an init script — check it carries a version flag diff --git a/lib/argocd/init.sh b/lib/argocd/init.sh index 61a7ba28..117c3725 100755 --- a/lib/argocd/init.sh +++ b/lib/argocd/init.sh @@ -51,7 +51,7 @@ kubectl create namespace argocd manifests_tmp="$(mktemp -d)" trap 'rm -rf "${manifests_tmp}"' EXIT cp -r "$SCRIPT_DIR/manifests/." "${manifests_tmp}/" -sed -i "s|argoproj/argo-cd/v[^/]*/manifests/install.yaml|argoproj/argo-cd/${version}/manifests/install.yaml|" \ +sed -i "s|argoproj/argo-cd/[^/]*/manifests/install.yaml|argoproj/argo-cd/${version}/manifests/install.yaml|" \ "${manifests_tmp}/kustomization.yaml" kubectl apply -k "${manifests_tmp}" diff --git a/lib/argocd/manifests/kustomization.yaml b/lib/argocd/manifests/kustomization.yaml index f0b7ded1..1ec91a1d 100644 --- a/lib/argocd/manifests/kustomization.yaml +++ b/lib/argocd/manifests/kustomization.yaml @@ -3,11 +3,11 @@ kind: Kustomization namespace: argocd -# The version in the URL below is substituted at deploy time by init.sh using the -# --version flag. Do not bump the version here directly — update the callers in -# .devcontainer/**/post-create.sh instead. +# ARGOCD_VERSION is a placeholder substituted by init.sh at deploy time via sed. +# Applying this kustomization directly without going through init.sh will fail +# intentionally, because kubectl cannot resolve the literal placeholder as a URL. resources: - - https://raw.githubusercontent.com/argoproj/argo-cd/v3.2.0/manifests/install.yaml + - https://raw.githubusercontent.com/argoproj/argo-cd/ARGOCD_VERSION/manifests/install.yaml patches: - path: overlays/argocd-server-service.yaml