#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT_DIR="${ROOT_DIR:-$(cd "${SCRIPT_DIR}/../.." && pwd)}" PROVIDER_MAIN="${ROOT_DIR}/provider/main.go" PROFILE_DIR="${PROFILE_DIR:-}" normalize_api_endpoint() { local endpoint="$1" endpoint="${endpoint%/}" # ⛔ LEGACY: deck-api.ngcloud.ru ЗАКРЫВАЕТСЯ. if [[ -z "$endpoint" ]]; then echo "https://lk-api-gateway.ngcloud.ru/api/v1/svc" return fi # Keep as-is: both legacy proxy (index.cfm) and new REST gateway are valid. # No forced /index.cfm normalization — the downstream tools auto-detect. echo "$endpoint" } if [[ "${1:-}" == "--profile" ]]; then PROFILE_DIR="${2:-}" shift 2 fi if [[ -n "$PROFILE_DIR" ]]; then if [[ ! -d "$PROFILE_DIR" ]]; then echo "Error: profile directory not found: $PROFILE_DIR" >&2 exit 2 fi PROFILE_ENV_FILE="${PROFILE_DIR}/profile.env" if [[ -f "$PROFILE_ENV_FILE" ]]; then set -a # shellcheck disable=SC1090 source "$PROFILE_ENV_FILE" set +a fi fi resolve_root_path() { local path_value="$1" if [[ -z "$path_value" ]]; then echo "" return fi if [[ "$path_value" = /* ]]; then echo "$path_value" return fi echo "${ROOT_DIR}/${path_value}" } VERSION="${1:-}" if [[ -z "$VERSION" ]]; then VERSION="${VERSION:-}" fi if [[ -z "$VERSION" ]]; then VERSION=$(grep -E 'version string' "$PROVIDER_MAIN" | sed -E 's/.*"([0-9.]+)".*/\1/') fi if [[ -z "$VERSION" ]]; then echo "Error: unable to detect version from $PROVIDER_MAIN" >&2 exit 2 fi REGISTRY_HOST="${REGISTRY_HOST:-tf-registry.containerk8s.services.ngcloud.ru}" NAMESPACE="${NAMESPACE:-nubes}" PROVIDER_NAME="${PROVIDER_NAME:-nubes}" export REGISTRY_HOST NAMESPACE PROVIDER_NAME VERSION S3CFG_REGISTRY="${S3CFG_REGISTRY:-${ROOT_DIR}/secrets/.s3cfg_registry}" S3CFG_REGISTRY="$(resolve_root_path "$S3CFG_REGISTRY")" TMP_DOCS_DIR="" if [[ -n "$PROFILE_DIR" ]]; then # ⛔ NEVER merge with docs/ — ONLY generated docs from docs_gen// DOCS_GEN_DIR="${DOCS_GEN_DIR:-generated/test}" DOCS_GEN_DIR="$(resolve_root_path "$DOCS_GEN_DIR")" if [[ -d "$DOCS_GEN_DIR" ]]; then export MKDOCS_DOCS_DIR="$DOCS_GEN_DIR" else echo "Error: DOCS_GEN_DIR not found: $DOCS_GEN_DIR" >&2 exit 2 fi fi # ⛔ LEGACY: deck-api.ngcloud.ru ЗАКРЫВАЕТСЯ. Default = Gateway. DOCS_API_ENDPOINT="${NUBES_API_ENDPOINT:-https://lk-api-gateway.ngcloud.ru/api/v1/svc}" DOCS_API_ENDPOINT="$(normalize_api_endpoint "$DOCS_API_ENDPOINT")" if [[ -n "${MKDOCS_DOCS_DIR:-}" ]]; then export DOCS_GUIDE_VERSION="$VERSION" export DOCS_GUIDE_API_ENDPOINT="$DOCS_API_ENDPOINT" export DOCS_GUIDE_FILE="${MKDOCS_DOCS_DIR}/guides/getting-started.md" python3 - <<'PY' import os import re from pathlib import Path guide_path = Path(os.environ["DOCS_GUIDE_FILE"]) if guide_path.exists(): text = guide_path.read_text(encoding="utf-8") text = re.sub( r'(version\s*=\s*")([0-9.]+)("\s*#\s*Поставьте нужную вам версию провайдера)', lambda m: f'{m.group(1)}{os.environ["DOCS_GUIDE_VERSION"]}{m.group(3)}', text, count=1, ) text = re.sub( r'(api_endpoint\s*=\s*")([^"]+)(")', lambda m: f'{m.group(1)}{os.environ["DOCS_GUIDE_API_ENDPOINT"]}{m.group(3)}', text, count=1, ) guide_path.write_text(text, encoding="utf-8") PY fi load_s3cfg_registry() { local cfg="$1" if [[ ! -f "$cfg" ]]; then echo "Error: S3 config not found: $cfg" >&2 exit 2 fi local access_key secret_key host_base use_https endpoint access_key=$(awk -F '=' '/^\s*access_key\s*=/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}' "$cfg") secret_key=$(awk -F '=' '/^\s*secret_key\s*=/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}' "$cfg") host_base=$(awk -F '=' '/^\s*host_base\s*=/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit}' "$cfg") use_https=$(awk -F '=' '/^\s*use_https\s*=/ {gsub(/^[ \t]+|[ \t]+$/, "", $2); print tolower($2); exit}' "$cfg") if [[ -z "${S3_ACCESS_KEY:-}" && -n "$access_key" ]]; then export S3_ACCESS_KEY="$access_key" fi if [[ -z "${S3_SECRET_KEY:-}" && -n "$secret_key" ]]; then export S3_SECRET_KEY="$secret_key" fi if [[ -z "${S3_ENDPOINT:-}" && -n "$host_base" ]]; then if [[ "$host_base" == http* ]]; then endpoint="$host_base" else if [[ "$use_https" == "false" || "$use_https" == "0" || "$use_https" == "no" ]]; then endpoint="http://${host_base}" else endpoint="https://${host_base}" fi fi export S3_ENDPOINT="$endpoint" fi if [[ -z "${S3_ENDPOINT:-}" || -z "${S3_ACCESS_KEY:-}" || -z "${S3_SECRET_KEY:-}" ]]; then echo "Error: S3 credentials are not set (S3_ENDPOINT/S3_ACCESS_KEY/S3_SECRET_KEY)" >&2 exit 2 fi } TMP_CFG="${ROOT_DIR}/.mkdocs.tmp.yml" export ROOT_DIR # Copy 30_registry assets into docs dir so guides/nav work when docs_dir is external if [[ -n "${MKDOCS_DOCS_DIR:-}" ]]; then if [[ -d "${ROOT_DIR}/docs/30_registry" ]]; then mkdir -p "${MKDOCS_DOCS_DIR}/30_registry" cp -r "${ROOT_DIR}/docs/30_registry/"* "${MKDOCS_DOCS_DIR}/30_registry/" 2>/dev/null || true fi fi python3 - <<'PY' import os import re import yaml from pathlib import Path registry_host = os.environ["REGISTRY_HOST"] namespace = os.environ["NAMESPACE"] name = os.environ["PROVIDER_NAME"] version = os.environ["VERSION"] root_dir = Path(os.environ["ROOT_DIR"]) cfg_path = root_dir / "mkdocs.yml" text = cfg_path.read_text(encoding="utf-8") text = re.sub( r"^site_url:\s*.*$", f"site_url: https://{registry_host}/docs/{namespace}/{name}/{version}/", text, flags=re.M, ) docs_dir = os.environ.get("MKDOCS_DOCS_DIR", "").strip() if docs_dir: if re.search(r"^docs_dir:\s*.*$", text, flags=re.M): text = re.sub(r"^docs_dir:\s*.*$", f"docs_dir: {docs_dir}", text, flags=re.M) else: text += f"\ndocs_dir: {docs_dir}\n" # Inject resources_nav from _nav_fragment.yml into nav section docs_dir_path = Path(docs_dir) if docs_dir else None nav_fragment_path = docs_dir_path / "_nav_fragment.yml" if docs_dir_path else None if nav_fragment_path and nav_fragment_path.exists(): config = yaml.safe_load(text) fragment = yaml.safe_load(nav_fragment_path.read_text(encoding="utf-8")) resources_nav = fragment.get("resources_nav", []) if resources_nav: nav = config.get("nav", []) for i, item in enumerate(nav): if isinstance(item, dict) and "Ресурсы" in item: # Replace "Ресурсы" children with generated categories item["Ресурсы"] = resources_nav break config["nav"] = nav text = yaml.dump(config, allow_unicode=True, default_flow_style=False, sort_keys=False) (root_dir / ".mkdocs.tmp.yml").write_text(text, encoding="utf-8") PY build_docs() { local docs_build_mode docs_build_mode="${DOCS_BUILD_MODE:-auto}" if [[ -n "${MKDOCS_DOCS_DIR:-}" && "$docs_build_mode" == "auto" ]]; then docs_build_mode="local" fi if [[ "$docs_build_mode" != "local" ]] && command -v docker >/dev/null 2>&1; then local docker_err docker_err="$(mktemp)" if docker run --rm -v "${ROOT_DIR}:/docs" squidfunk/mkdocs-material build -f "/docs/.mkdocs.tmp.yml" -d site 2>"$docker_err"; then rm -f "$docker_err" return 0 fi if grep -q "error while creating mount source path" "$docker_err"; then echo "Warning: docker mount issue detected, using local mkdocs" >&2 else cat "$docker_err" >&2 echo "Warning: docker build failed, trying local mkdocs" >&2 fi rm -f "$docker_err" fi local venv_python venv_python="${ROOT_DIR}/.venv/bin/python" if [[ -x "$venv_python" ]]; then if "$venv_python" -m mkdocs --version >/dev/null 2>&1; then (cd "$ROOT_DIR" && "$venv_python" -m mkdocs build -f "$TMP_CFG" -d site) return 0 fi echo "Warning: mkdocs module is missing in .venv, installing pinned versions" >&2 "$venv_python" -m pip install --disable-pip-version-check -q "mkdocs==1.6.1" "mkdocs-material==9.7.3" (cd "$ROOT_DIR" && "$venv_python" -m mkdocs build -f "$TMP_CFG" -d site) return 0 fi if command -v mkdocs >/dev/null 2>&1 && mkdocs --version >/dev/null 2>&1; then (cd "$ROOT_DIR" && mkdocs build -f "$TMP_CFG" -d site) return 0 fi echo "Error: mkdocs is not installed or not runnable." >&2 echo "Install once: python3 -m venv .venv && .venv/bin/python -m pip install mkdocs==1.6.1 mkdocs-material==9.7.3" >&2 exit 2 } trap 'rm -f "$TMP_CFG"' EXIT build_docs : : load_s3cfg_registry "$S3CFG_REGISTRY" (cd "$ROOT_DIR" && ./scripts/publish-docs.sh site "$REGISTRY_HOST" "$NAMESPACE" "$PROVIDER_NAME" "$VERSION") echo "Docs published for ${VERSION}"