Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions .github/workflows/build-offline-installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,54 @@ on:
- ".github/workflows/build-offline-installer.yml"
- "build.sh"
- "install.sh"
- "install-v2.sh"
- "versions.env"
- "README.md"
- "docs/**"
- "images/**"
- "charts/**"
pull_request:
paths:
- ".github/workflows/build-offline-installer.yml"
- "build.sh"
- "install.sh"
- "install-v2.sh"
- "versions.env"
- "README.md"
- "docs/**"
- "images/**"
- "charts/**"

permissions:
contents: write

jobs:
validate:
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Shell syntax
run: bash -n build.sh install.sh install-v2.sh

- name: Validate image metadata
run: |
jq empty images/image.json
test "$(jq '[.[] | select(.arch == "amd64")] | length' images/image.json)" -gt 0
test "$(jq '[.[] | select(.arch == "arm64")] | length' images/image.json)" -gt 0

- name: Validate installer help
run: |
chmod +x install.sh install-v2.sh
./install.sh --help | tee /tmp/help.txt
grep -q "kube-prometheus-stack.*90.2.0" /tmp/help.txt
grep -q -- "--values-file" /tmp/help.txt
grep -q -- "--stack-label-key" /tmp/help.txt
grep -q -- "--grafana-admin-user" /tmp/help.txt
grep -q -- "--prometheus-storage-access-mode" /tmp/help.txt
grep -q -- "--registry-secret" /tmp/help.txt

build:
needs: validate
runs-on: ubuntu-24.04
strategy:
fail-fast: false
Expand All @@ -49,12 +78,22 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.19.0

- name: Ensure executable permissions
run: chmod +x build.sh install.sh
run: chmod +x build.sh install.sh install-v2.sh

- name: Build installer
run: ./build.sh --arch "${{ matrix.arch }}"

- name: Verify checksum
run: |
cd dist
sha256sum -c "prometheus-stack-installer-${{ matrix.arch }}.run.sha256"

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
Expand Down
125 changes: 74 additions & 51 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,44 @@
set -Eeuo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck disable=SC1091
source "${ROOT_DIR}/versions.env"

TEMP_DIR="${ROOT_DIR}/.build-payload"
PAYLOAD_DIR="${TEMP_DIR}/payload"
PAYLOAD_FILE="${TEMP_DIR}/payload.tar.gz"
DIST_DIR="${ROOT_DIR}/dist"
IMAGES_DIR="${ROOT_DIR}/images"
IMAGE_JSON="${IMAGES_DIR}/image.json"
INSTALLER_TEMPLATE="${ROOT_DIR}/install.sh"
INSTALLER_TEMPLATE="${ROOT_DIR}/install-v2.sh"
INSTALLER_BASENAME="prometheus-stack-installer"
CHART_SRC_DIR="${ROOT_DIR}/charts/kube-prometheus-stack"
CHART_OCI="oci://ghcr.io/prometheus-community/charts/kube-prometheus-stack"

ARCH="amd64"
PLATFORM="linux/amd64"
BUILD_ALL_ARCH="false"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

log() {
echo -e "${CYAN}[INFO]${NC} $*"
}

success() {
echo -e "${GREEN}[OK]${NC} $*"
}

die() {
echo -e "${RED}[ERROR]${NC} $*" >&2
exit 1
}

cleanup() {
rm -rf "${TEMP_DIR}"
}
log() { echo -e "${CYAN}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[OK]${NC} $*"; }
die() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }

cleanup() { rm -rf "${TEMP_DIR}"; }
trap cleanup EXIT

usage() {
cat <<'EOF'
cat <<EOF
Usage:
./build.sh [--arch amd64|arm64|all]

Build BOM:
installer ${APP_VERSION}
kube-prometheus-stack ${KUBE_PROMETHEUS_STACK_VERSION}

Examples:
./build.sh --arch amd64
./build.sh --arch arm64
Expand All @@ -56,22 +50,10 @@ EOF

normalize_arch() {
case "$1" in
amd64|amd|x86_64)
ARCH="amd64"
PLATFORM="linux/amd64"
BUILD_ALL_ARCH="false"
;;
arm64|arm|aarch64)
ARCH="arm64"
PLATFORM="linux/arm64"
BUILD_ALL_ARCH="false"
;;
all)
BUILD_ALL_ARCH="true"
;;
*)
die "Unsupported arch: $1"
;;
amd64|amd|x86_64) ARCH="amd64"; PLATFORM="linux/amd64"; BUILD_ALL_ARCH="false" ;;
arm64|arm|aarch64) ARCH="arm64"; PLATFORM="linux/arm64"; BUILD_ALL_ARCH="false" ;;
all) BUILD_ALL_ARCH="true" ;;
*) die "Unsupported arch: $1" ;;
esac
}

Expand All @@ -83,30 +65,69 @@ parse_args() {
normalize_arch "$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
die "Unknown argument: $1"
;;
-h|--help) usage; exit 0 ;;
*) die "Unknown argument: $1" ;;
esac
done
}

check_requirements() {
command -v jq >/dev/null 2>&1 || die "jq is required"
command -v docker >/dev/null 2>&1 || die "docker is required"
command -v helm >/dev/null 2>&1 || die "helm is required"
command -v sha256sum >/dev/null 2>&1 || die "sha256sum is required"
[[ -f "${INSTALLER_TEMPLATE}" ]] || die "install.sh is missing"
[[ -f "${INSTALLER_TEMPLATE}" ]] || die "install-v2.sh is missing"
[[ -f "${IMAGE_JSON}" ]] || die "images/image.json is missing"
[[ -d "${CHART_SRC_DIR}" ]] || die "charts/kube-prometheus-stack is missing"
grep -q '^__PAYLOAD_BELOW__$' "${INSTALLER_TEMPLATE}" || die "install.sh is missing __PAYLOAD_BELOW__ marker"
[[ -f "${ROOT_DIR}/versions.env" ]] || die "versions.env is missing"
grep -q '^__PAYLOAD_BELOW__$' "${INSTALLER_TEMPLATE}" || die "install-v2.sh is missing __PAYLOAD_BELOW__ marker"
}

prepare_directories() {
rm -rf "${TEMP_DIR}"
mkdir -p "${PAYLOAD_DIR}/charts" "${PAYLOAD_DIR}/images" "${DIST_DIR}"
mkdir -p "${PAYLOAD_DIR}/charts" "${PAYLOAD_DIR}/images" "${PAYLOAD_DIR}/crds" "${DIST_DIR}"
}

prepare_chart() {
log "Pulling kube-prometheus-stack ${KUBE_PROMETHEUS_STACK_VERSION}"
helm pull "${CHART_OCI}" \
--version "${KUBE_PROMETHEUS_STACK_VERSION}" \
--untar \
--untardir "${PAYLOAD_DIR}/charts"

local chart_file="${PAYLOAD_DIR}/charts/kube-prometheus-stack/Chart.yaml"
[[ -f "${chart_file}" ]] || die "Pulled chart is missing Chart.yaml"

local actual_version
actual_version="$(awk '/^version:/ {print $2; exit}' "${chart_file}")"
[[ "${actual_version}" == "${KUBE_PROMETHEUS_STACK_VERSION}" ]] \
|| die "Chart version mismatch: expected=${KUBE_PROMETHEUS_STACK_VERSION}, actual=${actual_version}"

helm lint "${PAYLOAD_DIR}/charts/kube-prometheus-stack" >/dev/null
success "Prepared kube-prometheus-stack ${actual_version}"
}

prepare_crds() {
local chart_root="${PAYLOAD_DIR}/charts/kube-prometheus-stack"
local unpacked_crd_dir="${chart_root}/charts/crds/crds"
local source_dir=""

if [[ -d "${unpacked_crd_dir}" ]]; then
source_dir="${unpacked_crd_dir}"
else
local crd_archive
crd_archive="$(find "${chart_root}/charts" -maxdepth 1 -type f -name 'crds-*.tgz' -print -quit)"
[[ -n "${crd_archive}" ]] || die "Unable to locate CRD subchart in pulled chart"

local extract_dir="${TEMP_DIR}/crds-subchart"
mkdir -p "${extract_dir}"
tar -xzf "${crd_archive}" -C "${extract_dir}"
source_dir="${extract_dir}/crds/crds"
fi

[[ -d "${source_dir}" ]] || die "Unable to locate CRD manifests"
cp "${source_dir}"/*.yaml "${PAYLOAD_DIR}/crds/"
compgen -G "${PAYLOAD_DIR}/crds/*.yaml" >/dev/null || die "No CRD manifests were copied"
success "Prepared bundled CRD manifests"
}

image_name_tag_from_ref() {
Expand Down Expand Up @@ -162,9 +183,6 @@ package_payload() {
local installer_path="${DIST_DIR}/${INSTALLER_BASENAME}-${arch}.run"
local checksum_path="${installer_path}.sha256"

log "Copying chart payload"
cp -R "${CHART_SRC_DIR}" "${PAYLOAD_DIR}/charts/"

log "Creating payload archive"
tar -C "${PAYLOAD_DIR}" -czf "${PAYLOAD_FILE}" .
tar -tzf "${PAYLOAD_FILE}" >/dev/null
Expand All @@ -173,7 +191,10 @@ package_payload() {
cat "${INSTALLER_TEMPLATE}" "${PAYLOAD_FILE}" > "${installer_path}"
chmod +x "${installer_path}"

sha256sum "${installer_path}" | awk '{print $1}' > "${checksum_path}"
(
cd "${DIST_DIR}"
sha256sum "$(basename "${installer_path}")" > "$(basename "${checksum_path}")"
)
success "Generated $(basename "${installer_path}")"
}

Expand All @@ -196,6 +217,8 @@ build_one() {
PLATFORM="${platform}"

prepare_directories
prepare_chart
prepare_crds
prepare_images "${arch}" "${platform}"
package_payload "${arch}"
show_result "${arch}"
Expand Down
38 changes: 38 additions & 0 deletions docs/VERSION-BOM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Prometheus Stack Version BOM

Release target: `app_prometheus-stack v0.2.0`

| Component | Version |
|---|---:|
| kube-prometheus-stack | 90.2.0 |
| Prometheus Operator | 0.93.1 |
| Prometheus | 3.14.0-distroless |
| Alertmanager | 0.34.0 |
| Grafana Helm chart | 13.2.4 |
| Grafana | 13.2.1-distroless |
| kube-state-metrics Helm chart | 8.4.2 |
| kube-state-metrics | 2.20.0 |
| prometheus-node-exporter Helm chart | 4.57.0 |
| node-exporter | 1.12.1 |
| Thanos | 0.42.4 |
| k8s-sidecar | 2.11.2 |
| kube-rbac-proxy | 0.22.1 |
| kube-webhook-certgen | 1.8.8 |
| Grafana image renderer | v5.10.3 |

## Build model

The release artifact no longer depends on the vendored chart directory being manually kept in sync.
`build.sh` pulls the exact `kube-prometheus-stack` OCI chart version declared in `versions.env`,
embeds it into the `.run` package, and verifies the chart version before packaging.

## Upgrade behavior

- First install: bundled CRDs are applied first, phase 1 installs the operator, and phase 2 installs the complete stack.
- Existing Helm release: bundled CRDs are applied with server-side apply, then a single full-stack Helm upgrade is executed.
- `--skip-crd-upgrade` is available for controlled exception cases.

## Parameter model

Top-level platform defaults are exposed through `-h/--help` and can be overridden by CLI.
For settings not modeled directly by the installer, `--values-file` can be repeated to add site-specific Helm values.
Loading
Loading