-
Notifications
You must be signed in to change notification settings - Fork 0
harden even more #30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
harden even more #30
Changes from all commits
b0d15d8
d81c0d5
83b5e62
9df1c40
c005613
85f47f9
d491506
e2c4477
8564fd1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -47,6 +47,17 @@ jobs: | |||||||
| - name: Sync dependencies | ||||||||
| run: uv sync --dev | ||||||||
|
|
||||||||
| - name: Generate .env and secrets | ||||||||
| run: ./scripts/manage.sh create-env --non-interactive --force | ||||||||
|
|
||||||||
| - name: Preflight stack bring-up | ||||||||
| run: | | ||||||||
| set -euo pipefail | ||||||||
| cleanup() { ./scripts/manage.sh down >/dev/null 2>&1 || true; } | ||||||||
| trap cleanup EXIT | ||||||||
| ./scripts/manage.sh build-image | ||||||||
| ./scripts/manage.sh up | ||||||||
|
|
||||||||
| - name: Run core_data smoke workflow | ||||||||
| run: uv run python -m pytest -k full_workflow | ||||||||
|
|
||||||||
|
|
@@ -56,6 +67,17 @@ jobs: | |||||||
| docker ps -a | ||||||||
| docker compose logs || true | ||||||||
|
|
||||||||
| - name: Collect diagnostics bundle | ||||||||
| if: failure() | ||||||||
| run: ./scripts/collect_diagnostics.sh --output diagnostics-smoke-${{ matrix.profile_name }} | ||||||||
|
|
||||||||
| - name: Upload diagnostics bundle | ||||||||
| if: failure() | ||||||||
| uses: actions/upload-artifact@v4 | ||||||||
| with: | ||||||||
| name: diagnostics-smoke-${{ matrix.profile_name }} | ||||||||
| path: diagnostics-smoke-${{ matrix.profile_name }} | ||||||||
|
|
||||||||
| - name: Upload generated backups | ||||||||
| if: always() | ||||||||
| uses: actions/upload-artifact@v4 | ||||||||
|
|
@@ -102,6 +124,17 @@ jobs: | |||||||
| - name: Sync dependencies | ||||||||
| run: uv sync --dev | ||||||||
|
|
||||||||
| - name: Generate .env and secrets | ||||||||
| run: ./scripts/manage.sh create-env --non-interactive --force | ||||||||
|
|
||||||||
| - name: Preflight stack bring-up | ||||||||
| run: | | ||||||||
| set -euo pipefail | ||||||||
| cleanup() { ./scripts/manage.sh down >/dev/null 2>&1 || true; } | ||||||||
| trap cleanup EXIT | ||||||||
|
Comment on lines
+132
to
+134
|
||||||||
| set -euo pipefail | |
| cleanup() { ./scripts/manage.sh down >/dev/null 2>&1 || true; } | |
| trap cleanup EXIT |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exposing credentials in plaintext environment variables is a security risk. While this is a test environment, it's better practice to avoid plaintext passwords in CI configuration files.
Consider using GitHub secrets or at minimum, use the PGPASSFILE mechanism instead of PGPASSWORD.
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,86 @@ | ||||||||
| #!/usr/bin/env bash | ||||||||
| # SPDX-FileCopyrightText: 2025 Blackcat Informatics® Inc. | ||||||||
| # SPDX-License-Identifier: MIT | ||||||||
|
|
||||||||
| set -euo pipefail | ||||||||
|
|
||||||||
| output_dir="diagnostics" | ||||||||
| logs_tail=${CORE_DATA_DIAG_LOG_TAIL:-400} | ||||||||
|
|
||||||||
| usage() { | ||||||||
| cat <<'USAGE' | ||||||||
| Usage: collect_diagnostics.sh [--output DIR] | ||||||||
| Gather docker/container state, sanitized env vars, and service logs to help debug CI failures. | ||||||||
| USAGE | ||||||||
| } | ||||||||
|
|
||||||||
| while [[ $# -gt 0 ]]; do | ||||||||
| case "$1" in | ||||||||
| --output) | ||||||||
| output_dir=$2 | ||||||||
| shift 2 | ||||||||
| ;; | ||||||||
| -h | --help) | ||||||||
| usage | ||||||||
| exit 0 | ||||||||
| ;; | ||||||||
| *) | ||||||||
| echo "[diagnostics] Unknown argument: $1" >&2 | ||||||||
| exit 1 | ||||||||
| ;; | ||||||||
| esac | ||||||||
| done | ||||||||
|
|
||||||||
| mkdir -p "${output_dir}" | ||||||||
| timestamp=$(date -Iseconds) | ||||||||
|
|
||||||||
| run_cmd() { | ||||||||
| local name=$1 | ||||||||
| shift | ||||||||
| if command -v "$1" >/dev/null 2>&1; then | ||||||||
| "$@" >"${output_dir}/${name}.txt" 2>&1 || true | ||||||||
| fi | ||||||||
| } | ||||||||
|
|
||||||||
| run_cmd "docker-ps" docker ps -a | ||||||||
| run_cmd "docker-compose-ls" docker compose ls | ||||||||
| run_cmd "docker-network-ls" docker network ls | ||||||||
|
|
||||||||
| sanitize_env() { | ||||||||
| local source_env=$1 | ||||||||
| local dest=$2 | ||||||||
| if [[ ! -f "${source_env}" ]]; then | ||||||||
| return | ||||||||
| fi | ||||||||
| python3 - "$source_env" "$dest" <<'PY' | ||||||||
| import os | ||||||||
| import re | ||||||||
| import sys | ||||||||
| source, dest = sys.argv[1], sys.argv[2] | ||||||||
| pattern = re.compile(r"(PASSWORD|SECRET|TOKEN|KEY|COOKIE)", re.IGNORECASE) | ||||||||
| with open(source, "r", encoding="utf-8") as fh, open(dest, "w", encoding="utf-8") as out: | ||||||||
| for line in fh: | ||||||||
| if "=" in line and not line.lstrip().startswith("#"): | ||||||||
| key, val = line.rstrip("\n").split("=", 1) | ||||||||
| if pattern.search(key): | ||||||||
| line = f"{key}=<redacted>\n" | ||||||||
| out.write(line) | ||||||||
| PY | ||||||||
| } | ||||||||
|
|
||||||||
| sanitize_env "${ENV_FILE:-${PWD}/.env}" "${output_dir}/env.redacted" | ||||||||
|
|
||||||||
| collect_container_artifacts() { | ||||||||
| local container=$1 | ||||||||
| local safe_name=${container//\//_} | ||||||||
| docker inspect "${container}" >"${output_dir}/${safe_name}--inspect.json" 2>/dev/null || true | ||||||||
| docker logs --tail "${logs_tail}" "${container}" >"${output_dir}/${safe_name}--logs.txt" 2>&1 || true | ||||||||
| } | ||||||||
|
|
||||||||
| containers=$(docker ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'core_data|postgres' || true) | ||||||||
| for name in ${containers}; do | ||||||||
|
Comment on lines
+81
to
+82
|
||||||||
| containers=$(docker ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'core_data|postgres' || true) | |
| for name in ${containers}; do | |
| docker ps -a --format '{{.Names}}' 2>/dev/null | grep -E 'core_data|postgres' | while IFS= read -r name; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
trap cleanup EXITwill execute when this step finishes, immediately tearing down the stack after it's brought up. This means the next step "Run core_data smoke workflow" will try to interact with a stack that has already been brought down, causing the test to fail.Remove the cleanup trap and the set -euo pipefail line from this preflight step, or remove the preflight step entirely if the test suite handles stack bring-up itself.