refactor(env): centralize runtime environment in scripts/meta/env.sh (SPOT)

- Move all environment detection, defaults, and exports into scripts/meta/env.sh
- Use BASH_ENV in Makefile to auto-source env.sh for all recipes
- Remove duplicated env logic from Makefile (VENV, PYTHON, CI detection, inventory)
- Make env setup safe under set -euo pipefail (-u compatible)
- Ensure consistent behavior across local, act, and GitHub Actions runs

No functional behavior change intended.

https://chatgpt.com/share/69820891-2238-800f-ad70-bae7e442c028
This commit is contained in:
kevinveenbirkenbach committed 2026-02-03 15:39:03 +01:00
1 parent 308326ae75
commit 81ddadc2d2
2 files changed
+164 -113

No files matched your search

+34 -113
View File
@@ -2,89 +2,39 @@
SHELL := /bin/bash
.SHELLFLAGS := -euo pipefail -c
VENV_BASE ?= $(if $(VIRTUAL_ENV),$(dir $(VIRTUAL_ENV)),/opt/venvs)
VENV_NAME ?= infinito
VENV_FALLBACK := $(VENV_BASE)/$(VENV_NAME)
VENV := $(if $(VIRTUAL_ENV),$(VIRTUAL_ENV),$(VENV_FALLBACK))
# ------------------------------------------------------------
# SPOT: Global environment is defined in scripts/meta/env.sh
# ------------------------------------------------------------
ENV_SH ?= $(CURDIR)/scripts/meta/env.sh
export ENV_SH
PYTHON := $(VENV)/bin/python
PIP := $(PYTHON) -m pip
export PYTHON
export PIP
# Ensure repo root is importable (so module_utils/, filter_plugins/ etc. work)
PYTHONPATH ?= .
export PYTHONPATH
ifdef NIX_CONFIG
export NIX_CONFIG
endif
# Ensure TEST_DEPLOY_TYPE is available for the default inventory dir.
TEST_DEPLOY_TYPE ?= server
export TEST_DEPLOY_TYPE
# --- Test filtering (unittest discover) ---
TEST_PATTERN ?= test*.py
export TEST_PATTERN
# Distro
INFINITO_DISTRO ?= arch
INFINITO_CONTAINER ?= infinito_nexus_$(INFINITO_DISTRO)
export INFINITO_DISTRO
export INFINITO_CONTAINER
# Detirmene Environment
RUNNING_ON_ACT ?= false
RUNNING_ON_GITHUB ?= false
ifeq ($(GITHUB_ACTIONS),true)
RUNNING_ON_GITHUB = true
ifeq ($(ACT),true)
RUNNING_ON_ACT = true
RUNNING_ON_GITHUB = false
endif
endif
export RUNNING_ON_ACT RUNNING_ON_GITHUB
INVENTORY_DIR ?= $(shell \
RUNNING_ON_ACT="$(RUNNING_ON_ACT)" \
RUNNING_ON_GITHUB="$(RUNNING_ON_GITHUB)" \
HOME="$(HOME)" \
bash scripts/inventory/resolve.sh \
)
export INVENTORY_DIR
# Overwrite defaults
ifeq ($(RUNNING_ON_GITHUB),true)
# -------- Real GitHub Actions CI --------
INFINITO_PULL_POLICY ?= always
INFINITO_IMAGE_TAG ?= latest
INFINITO_IMAGE ?= ghcr.io/$(GITHUB_REPOSITORY_OWNER)/infinito-$(INFINITO_DISTRO):$(INFINITO_IMAGE_TAG)
INFINITO_NO_BUILD ?= 1
INFINITO_DOCKER_VOLUME ?= /mnt/docker
INFINITO_DOCKER_MOUNT ?= /var/lib/docker
export INFINITO_DOCKER_VOLUME INFINITO_DOCKER_MOUNT
export INFINITO_IMAGE_TAG
export INFINITO_NO_BUILD
export INFINITO_PULL_POLICY
export INFINITO_IMAGE
INFINITO_COMPILE ?= 0
# For non-interactive bash, BASH_ENV is sourced before executing the command.
# This makes env.sh apply automatically to *all* Make recipes.
ifneq ("$(wildcard $(ENV_SH))","")
export BASH_ENV := $(ENV_SH)
else
INFINITO_COMPILE ?= 1
$(error Missing env file: $(ENV_SH))
endif
export INFINITO_COMPILE
.PHONY: \
setup setup-clean install install-ansible install-venv install-python \
test test-lint test-unit test-integration test-deploy test-deploy-app\
clean down \
test test-lint test-unit test-integration test-deploy test-deploy-app \
clean clean-sudo down \
list tree mig dockerignore \
print-python lint-ansible \
dns-setup dns-remove
dns-setup dns-remove \
dev-environment-bootstrap dev-environment-teardown \
apparmor-teardown apparmor-restore \
trust-ca \
docker-restart docker-up docker-down docker-stop \
build build-missing build-no-cache build-no-cache-all \
ci-deploy-discover ci-deploy-app ci-discover-output \
test-act-all test-act-app \
test-local-reset test-local-run-all test-local-cleanup test-local-web-purge \
test-local-rapid test-local-rapid-fresh test-local-full \
format bootstrap setup-development
dev-environment-bootstrap: apparmor-teardown dns-setup
dev-environment-teardown: apparmor-restore dns-remove
dns-setup:
@@ -93,8 +43,6 @@ dns-setup:
dns-remove:
@bash scripts/dns/remove.sh
.PHONY: apparmor-teardown apparmor-restore
apparmor-teardown:
@echo "==> AppArmor: full teardown (local dev)"
@sudo bash scripts/administration/apparmor/teardown.sh
@@ -103,13 +51,9 @@ apparmor-restore:
@echo "==> AppArmor: restore profiles"
@sudo bash scripts/administration/apparmor/restore.sh
.PHONY: trust-ca
trust-ca:
@bash scripts/administration/trust_ca.sh
clean:
@echo "Removing ignored git files"
@if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then \
@@ -121,7 +65,7 @@ clean:
clean-sudo:
@echo "Removing ignored git files with sudo"
sudo git clean -fdX; \
sudo git clean -fdX;
docker-restart:
@$(PYTHON) -m cli.deploy.development restart --distro "$(INFINITO_DISTRO)"
@@ -137,11 +81,11 @@ docker-stop:
list:
@echo "Generating the roles list"
$(PYTHON) -m cli.build.roles_list
@$(PYTHON) -m cli.build.roles_list
tree:
@echo "Generating Tree"
$(PYTHON) -m cli.build.tree -D 2
@$(PYTHON) -m cli.build.tree -D 2
mig: list tree
@echo "Creating meta data for meta infinity graph"
@@ -204,7 +148,6 @@ format:
ruff check . --fix
# --- Tests (separated) ---
test: test-lint test-unit test-integration lint-ansible test-deploy
@echo "✅ Full test (setup + tests) executed."
@@ -245,57 +188,35 @@ ci-discover-output:
echo "apps_json=$$apps"
test-act-all:
@TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_DISTRO="$(INFINITO_DISTRO)" \
bash scripts/tests/deploy/act/all.sh
@bash scripts/tests/deploy/act/all.sh
test-act-app:
@APP="$(APP)" \
TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_DISTRO="$(INFINITO_DISTRO)" \
bash scripts/tests/deploy/act/app.sh
@bash scripts/tests/deploy/act/app.sh
test-local-reset:
@TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_DISTRO="$(INFINITO_DISTRO)" \
PYTHON=python3 \
@PYTHON=python3 \
bash scripts/tests/deploy/local/reset.sh
test-local-run-all:
@TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_DISTRO="$(INFINITO_DISTRO)" \
DEBUG="$(DEBUG)" \
LIMIT_HOST="$(LIMIT_HOST)" \
INVENTORY_DIR="$(INVENTORY_DIR)" \
bash scripts/tests/deploy/local/run-all.sh
@bash scripts/tests/deploy/local/run-all.sh
test-local-cleanup:
@APP="$(APP)" \
INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \
bash scripts/tests/deploy/local/cleanup.sh
@bash scripts/tests/deploy/local/cleanup.sh
test-local-web-purge:
INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \
bash scripts/tests/deploy/local/purge_web.sh
@bash scripts/tests/deploy/local/purge_web.sh
test-local-rapid:
@APP="$(APP)" \
TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_CONTAINER="$(INFINITO_CONTAINER)" \
DEBUG=true \
@DEBUG=true \
bash scripts/tests/deploy/local/rapid.sh
test-local-rapid-fresh: test-local-cleanup test-local-rapid
test-local-full:
@echo "=== local full deploy (type=$(TEST_DEPLOY_TYPE), distro=$(INFINITO_DISTRO)) ==="
@TEST_DEPLOY_TYPE="$(TEST_DEPLOY_TYPE)" \
INFINITO_DISTRO="$(INFINITO_DISTRO)" \
bash scripts/tests/deploy/local/all.sh
@bash scripts/tests/deploy/local/all.sh
# Backwards compatible target (kept)
lint-ansible:
@echo "📑 Checking Ansible syntax…"
ansible-playbook -i localhost, -c local $(foreach f,$(wildcard group_vars/all/*.yml),-e @$(f)) playbook.yml --syntax-check
+130
View File
@@ -0,0 +1,130 @@
#!/usr/bin/env bash
# shellcheck shell=bash
#
# scripts/meta/env.sh
#
# This file is meant to be sourced automatically (e.g. via BASH_ENV from Makefile)
# or manually:
# source scripts/meta/env.sh
#
# It defines and exports Infinito runtime env vars with sensible defaults.
# It is safe to run under: set -euo pipefail (including `-u`).
set -euo pipefail
# Prevent double-loading
if [[ "${INFINITO_ENV_LOADED:-}" == "1" ]]; then
return 0
fi
export INFINITO_ENV_LOADED="1"
# ------------------------------------------------------------
# Helpers
# ------------------------------------------------------------
_is_true() { [[ "${1:-}" == "1" || "${1:-}" == "true" ]]; }
# ------------------------------------------------------------
# Venv / Python (safe under "set -u")
# ------------------------------------------------------------
_virtual_env="${VIRTUAL_ENV:-}"
if [[ -n "${_virtual_env}" ]]; then
: "${VENV_BASE:=${VENV_BASE:-$(dirname "${_virtual_env}")/}}"
else
: "${VENV_BASE:=${VENV_BASE:-/opt/venvs}}"
fi
: "${VENV_NAME:=infinito}"
: "${VENV_FALLBACK:=${VENV_BASE%/}/${VENV_NAME}}"
: "${VENV:=${_virtual_env:-$VENV_FALLBACK}}"
_default_python="${VENV%/}/bin/python"
if [[ -x "${_default_python}" ]]; then
: "${PYTHON:=${_default_python}}"
else
: "${PYTHON:=python3}"
fi
: "${PIP:=${PYTHON} -m pip}"
export VENV_BASE VENV_NAME VENV_FALLBACK VENV
export PYTHON PIP
# Ensure repo root is importable (so module_utils/, filter_plugins/ etc. work)
: "${PYTHONPATH:=.}"
export PYTHONPATH
# ------------------------------------------------------------
# CI detection
# ------------------------------------------------------------
: "${RUNNING_ON_ACT:=false}"
: "${RUNNING_ON_GITHUB:=false}"
if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then
RUNNING_ON_GITHUB="true"
if [[ "${ACT:-}" == "true" ]]; then
RUNNING_ON_ACT="true"
RUNNING_ON_GITHUB="false"
fi
fi
export RUNNING_ON_ACT RUNNING_ON_GITHUB
# ------------------------------------------------------------
# Defaults
# ------------------------------------------------------------
: "${TEST_DEPLOY_TYPE:=server}"
export TEST_DEPLOY_TYPE
: "${TEST_PATTERN:=test*.py}"
export TEST_PATTERN
: "${INFINITO_DISTRO:=arch}"
: "${INFINITO_CONTAINER:=infinito_nexus_${INFINITO_DISTRO}}"
export INFINITO_DISTRO INFINITO_CONTAINER
# Common distro list (used by build-no-cache-all)
: "${DISTROS:=arch debian ubuntu fedora centos}"
export DISTROS
# ------------------------------------------------------------
# Inventory dir (needs resolve script)
# ------------------------------------------------------------
if [[ -z "${INVENTORY_DIR:-}" ]]; then
INVENTORY_DIR="$(
RUNNING_ON_ACT="${RUNNING_ON_ACT}" \
RUNNING_ON_GITHUB="${RUNNING_ON_GITHUB}" \
HOME="${HOME:-}" \
bash scripts/inventory/resolve.sh
)"
fi
export INVENTORY_DIR
# ------------------------------------------------------------
# GitHub CI overrides
# ------------------------------------------------------------
if [[ "${RUNNING_ON_GITHUB}" == "true" ]]; then
: "${INFINITO_PULL_POLICY:=always}"
: "${INFINITO_IMAGE_TAG:=latest}"
# Owner can come from GitHub Actions or be provided explicitly (fallback).
_owner="${GITHUB_REPOSITORY_OWNER:-${OWNER:-}}"
: "${INFINITO_IMAGE:=ghcr.io/${_owner}/infinito-${INFINITO_DISTRO}:${INFINITO_IMAGE_TAG}}"
: "${INFINITO_NO_BUILD:=1}"
: "${INFINITO_DOCKER_VOLUME:=/mnt/docker}"
: "${INFINITO_DOCKER_MOUNT:=/var/lib/docker}"
: "${INFINITO_COMPILE:=0}"
export INFINITO_PULL_POLICY INFINITO_IMAGE_TAG INFINITO_IMAGE INFINITO_NO_BUILD
export INFINITO_DOCKER_VOLUME INFINITO_DOCKER_MOUNT
export INFINITO_COMPILE
else
: "${INFINITO_COMPILE:=1}"
export INFINITO_COMPILE
fi
# NIX_CONFIG is optional; export if set
if [[ -n "${NIX_CONFIG:-}" ]]; then
export NIX_CONFIG
fi