feat(builder): load publish credentials from .env.builder
Keep DEB/Docker publish keys out of the project's .env. Scripts and check.py --ready only read .env.builder; empty values count as missing.
This commit is contained in:
@@ -43,6 +43,7 @@ FLOATING_TAGS = (":latest", ":stable")
|
||||
DEB_SHAPE = re.compile(r"^[^_\s]+_[^_\s]+_[^_\s]+\.deb$")
|
||||
VALID_SCRIPT_NAMES = ("upload_deb.sh", "publish_docker.sh")
|
||||
BUILDER_MAKEFILE = "makefile.builder"
|
||||
BUILDER_ENV = ".env.builder"
|
||||
|
||||
PASS = "PASS"
|
||||
FAIL = "FAIL"
|
||||
@@ -279,12 +280,12 @@ def check_secrets_and_tags(report: Report, project: Path) -> None:
|
||||
|
||||
DEB_ENV_KEYS = ("DEB_SERVER_URL", "DEB_TOKEN", "DEB_REPOSITORY")
|
||||
DOCKER_ENV_KEYS = ("DOCKER_REGISTRY",)
|
||||
ENV_KEY_LINE = re.compile(r"^([A-Za-z_][A-Za-z0-9_]*)=")
|
||||
ENV_KEY_LINE = re.compile(r"^([A-Za-z_][A-Za-z0-9_]*)=(.*)$")
|
||||
|
||||
|
||||
def env_file_keys(project: Path) -> set[str]:
|
||||
"""Return key names defined in project `.env`. Never return or print values."""
|
||||
path = project / ".env"
|
||||
"""Return nonempty key names in `.env.builder`. Never return or print values."""
|
||||
path = project / BUILDER_ENV
|
||||
keys: set[str] = set()
|
||||
if not path.is_file():
|
||||
return keys
|
||||
@@ -297,7 +298,10 @@ def env_file_keys(project: Path) -> set[str]:
|
||||
if not stripped or stripped.startswith("#"):
|
||||
continue
|
||||
match = ENV_KEY_LINE.match(stripped)
|
||||
if match:
|
||||
if not match:
|
||||
continue
|
||||
value = match.group(2).strip().strip("'\"")
|
||||
if value:
|
||||
keys.add(match.group(1))
|
||||
return keys
|
||||
|
||||
@@ -364,9 +368,9 @@ def check_ready_env_keys(
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
"blocks publish, not build. Put keys in the environment or project `.env`:",
|
||||
f"blocks publish, not build. Put keys in the environment or {BUILDER_ENV}:",
|
||||
*[f" {key}=" for key in missing],
|
||||
"Do not commit `.env`. Never print values.",
|
||||
f"Do not commit {BUILDER_ENV}. Do not put these keys in `.env`. Never print values.",
|
||||
]
|
||||
)
|
||||
report.add(SKIP, 11, "发布环境变量键名(不读取值)", "\n".join(lines))
|
||||
|
||||
@@ -6,8 +6,8 @@ usage() {
|
||||
}
|
||||
|
||||
# Build and publish a Docker image with buildx. Configuration comes from the
|
||||
# environment first (optionally loaded from the project root .env); flags
|
||||
# override.
|
||||
# environment first (optionally loaded from the project root .env.builder);
|
||||
# flags override. Does not read `.env`.
|
||||
#
|
||||
# Usage:
|
||||
# publish_docker.sh [--registry HOST] [--repository PATH] [--tag TAG] \
|
||||
@@ -30,18 +30,19 @@ usage() {
|
||||
|
||||
project_root=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||||
|
||||
# Load project .env without printing values; explicitly exported shell values keep precedence.
|
||||
if [[ -n "$project_root" && -f "$project_root/.env" ]]; then
|
||||
# Load .env.builder without printing values; shell values win. Do not read `.env`.
|
||||
if [[ -n "$project_root" && -f "$project_root/.env.builder" ]]; then
|
||||
while IFS='=' read -r key value; do
|
||||
key=${key%%[[:space:]]*}
|
||||
[[ -z "$key" || "$key" == \#* ]] && continue
|
||||
if [[ -n "${!key:-}" ]]; then
|
||||
continue # shell value already set: wins over .env
|
||||
continue # shell value already set: wins over .env.builder
|
||||
fi
|
||||
value=${value%\"}; value=${value#\"}; value=${value%\'}; value=${value#\'}
|
||||
[[ -z "$value" ]] && continue
|
||||
printf -v "$key" '%s' "$value"
|
||||
export "$key"
|
||||
done < <(grep -v '^[[:space:]]*$' "$project_root/.env")
|
||||
done < <(grep -v '^[[:space:]]*$' "$project_root/.env.builder")
|
||||
fi
|
||||
|
||||
git_repo_name=
|
||||
@@ -81,7 +82,7 @@ if [[ -n "$registry" && ( "$registry" == *://* || "$registry" == */* ) ]]; then
|
||||
fi
|
||||
if [[ -z "$registry" ]]; then
|
||||
echo "Error: DOCKER_REGISTRY (or --registry) is required." >&2
|
||||
echo "Set it in the environment or the project root .env." >&2
|
||||
echo "Set it in the environment or the project root .env.builder." >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
@@ -15,9 +15,9 @@ Options:
|
||||
-p UPLOAD_PATH Override DEB_UPLOAD_PATH (default: /api/v2/upload/package)
|
||||
-h Show help
|
||||
|
||||
Environment variables may live in the project root .env; this script walks up
|
||||
from the current directory, loads it silently (existing shell values win), and
|
||||
never echoes variable values. The endpoint must accept multipart fields named
|
||||
Environment variables may live in the project root .env.builder; this script
|
||||
loads it silently (existing shell values win), never echoes values, and does
|
||||
not read `.env`. The endpoint must accept multipart fields named
|
||||
package, token, and repository_name. Authentication is read only from
|
||||
DEB_TOKEN so it is not exposed in the process command line.
|
||||
|
||||
@@ -25,21 +25,22 @@ The working tree must be clean to publish; set ALLOW_UNCOMMITTED=1 to override.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Locate project root (.git) upward from cwd for .env loading and git checks.
|
||||
# Locate project root (.git) upward from cwd for .env.builder loading and git checks.
|
||||
project_root=$(git rev-parse --show-toplevel 2>/dev/null || true)
|
||||
|
||||
# Load project .env without printing values; explicitly exported shell values keep precedence.
|
||||
if [[ -n "$project_root" && -f "$project_root/.env" ]]; then
|
||||
# Load .env.builder without printing values; shell values win. Do not read `.env`.
|
||||
if [[ -n "$project_root" && -f "$project_root/.env.builder" ]]; then
|
||||
while IFS='=' read -r key value; do
|
||||
key=${key%%[[:space:]]*}
|
||||
[[ -z "$key" || "$key" == \#* ]] && continue
|
||||
if [[ -n "${!key:-}" ]]; then
|
||||
continue # shell value already set: wins over .env
|
||||
continue # shell value already set: wins over .env.builder
|
||||
fi
|
||||
value=${value%\"}; value=${value#\"}; value=${value%\'}; value=${value#\'}
|
||||
[[ -z "$value" ]] && continue
|
||||
printf -v "$key" '%s' "$value"
|
||||
export "$key"
|
||||
done < <(grep -v '^[[:space:]]*$' "$project_root/.env")
|
||||
done < <(grep -v '^[[:space:]]*$' "$project_root/.env.builder")
|
||||
fi
|
||||
|
||||
server_url=${DEB_SERVER_URL:-}
|
||||
@@ -61,7 +62,7 @@ shift $((OPTIND - 1))
|
||||
|
||||
if [[ -z "$server_url" || -z "$repository" || -z "$token" || $# -eq 0 ]]; then
|
||||
echo "Error: DEB_SERVER_URL, DEB_TOKEN, DEB_REPOSITORY, and at least one file are required." >&2
|
||||
echo "Set them in the environment or the project root .env." >&2
|
||||
echo "Set them in the environment or the project root .env.builder." >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user