Skip to content

Commit e874e8a

Browse files
authored
Merge pull request #323 from browserstack/fix/local-dev-test-bootstrap
fix(dev): bootstrap config.json + secrets and unblock test container
2 parents 6744335 + 6aca98b commit e874e8a

3 files changed

Lines changed: 85 additions & 3 deletions

File tree

Makefile

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
APP_UID := $(shell id -u)
22

3-
setup_mounts:
3+
## make setup : Bootstrap local secret env files + config.json from samples (idempotent)
4+
.PHONY: setup
5+
setup: setup_secrets setup_config
6+
7+
setup_secrets:
8+
@bash scripts/bootstrap_secrets.sh
9+
10+
# config.json is gitignored and baked into the image, but the `.:/srv/code/dev`
11+
# bind mount shadows the baked copy, so a fresh clone must materialise it locally
12+
# or settings.py fails with FileNotFoundError. Idempotent: existing file is kept.
13+
setup_config:
14+
@if [ ! -f config.json ]; then \
15+
cp config.json.sample config.json; \
16+
echo " created config.json from sample"; \
17+
fi
18+
19+
setup_mounts: setup_secrets setup_config
420
@mkdir -p mounts/db
521
@mkdir -p mounts/mysql_db
622
@mkdir -p mounts/logs
@@ -27,7 +43,7 @@ dev: setup_mounts
2743
## make build : Build and start docker containers - (web and db)
2844
.PHONY: build
2945
build: export APPUID = $(APP_UID)
30-
build:
46+
build: setup_secrets setup_config
3147
@docker-compose up --build -d web
3248

3349
## make build_only : Only build the web container

pytest.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
DJANGO_SETTINGS_MODULE = EnigmaAutomation.settings
33
; # -- recommended but optional:
44
; python_files = tests.py test_*.py *_tests.py
5-
addopts = --ignore=mounts
5+
# -p no:pylama disables pylama's pytest11 plugin, whose pytest_collect_file(path,...)
6+
# hook uses an argument removed in pytest 9 (it aborts collection otherwise).
7+
# Linting still runs via standalone `python -m pylama` (see [pylama] below).
8+
addopts = --ignore=mounts -p no:pylama
69

710
[pylama]
811
skip = env/*

scripts/bootstrap_secrets.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Create local secret env files (secrets/*.env) from their committed
4+
# *.env.sample templates. Idempotent: existing files are left untouched.
5+
#
6+
# Secrets are gitignored, so a fresh clone / CI runner has only the samples.
7+
# Running `make dev` (or build/test) without the real files fails with
8+
# "env file ... not found". This script bootstraps them for local dev.
9+
#
10+
# Coupling: MYSQL_ROOT_PASSWORD must be identical in ops_mysql_dev.env and
11+
# ops_app_celery.env or the app/celery containers cannot auth to MySQL.
12+
# We generate the password once and reuse it (and reuse an existing one if
13+
# only some files are present) to keep them in sync.
14+
15+
set -euo pipefail
16+
17+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18+
SECRETS_DIR="$(cd "${SCRIPT_DIR}/../secrets" && pwd)"
19+
20+
randstr() { LC_ALL=C tr -dc 'A-Za-z0-9' < /dev/urandom | head -c "$1"; }
21+
22+
# Extract a KEY=value from a file, or empty string if absent.
23+
readval() {
24+
local key="$1" file="$2"
25+
[ -f "$file" ] && sed -n "s/^${key}=//p" "$file" | head -n1 || true
26+
}
27+
28+
# Precedence: env override (CI/deterministic) > existing file (stay consistent
29+
# with an already-initialised MySQL volume) > freshly generated random value.
30+
PW="${MYSQL_ROOT_PASSWORD:-}"
31+
[ -n "$PW" ] || PW="$(readval MYSQL_ROOT_PASSWORD "${SECRETS_DIR}/ops_mysql_dev.env")"
32+
[ -n "$PW" ] || PW="$(readval MYSQL_ROOT_PASSWORD "${SECRETS_DIR}/ops_app_celery.env")"
33+
[ -n "$PW" ] || PW="$(randstr 24)"
34+
35+
TOKEN="${APP_TOKEN:-}"
36+
[ -n "$TOKEN" ] || TOKEN="$(readval TOKEN "${SECRETS_DIR}/ops_app_dev.env")"
37+
[ -n "$TOKEN" ] || TOKEN="$(readval TOKEN "${SECRETS_DIR}/ops_app_test.env")"
38+
[ -n "$TOKEN" ] || TOKEN="$(randstr 32)"
39+
40+
created=0
41+
gen() {
42+
local out="$1"; shift
43+
if [ -f "${SECRETS_DIR}/${out}" ]; then
44+
return 0
45+
fi
46+
# Remaining args: sed substitution expressions.
47+
local sed_args=()
48+
for expr in "$@"; do sed_args+=(-e "$expr"); done
49+
sed "${sed_args[@]}" "${SECRETS_DIR}/${out}.sample" > "${SECRETS_DIR}/${out}"
50+
echo " created secrets/${out}"
51+
created=1
52+
}
53+
54+
gen ops_mysql_dev.env "s|__CHANGE_ME__|${PW}|g"
55+
gen ops_app_celery.env "s|__CHANGE_ME__|${PW}|g"
56+
gen ops_app_dev.env "s|__CHANGE_ME__|${TOKEN}|g"
57+
gen ops_app_test.env "s|__CHANGE_ME__|${TOKEN}|g"
58+
59+
if [ "$created" -eq 1 ]; then
60+
echo "Local secret env files ready. These are gitignored — edit values as needed."
61+
else
62+
echo "Secret env files already present — nothing to do."
63+
fi

0 commit comments

Comments
 (0)