diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0784f83..372e59a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,6 +58,7 @@ jobs: # Claim a unique version by pushing a git tag BEFORE building. # Retry up to 5 times if another CI run took our N. + TAG_CLAIMED=false for ATTEMPT in 1 2 3 4 5; do git fetch --tags --force EXISTING=$(git tag -l "*-${YEAR_MONTH}.*" | wc -l | tr -d ' ') @@ -68,14 +69,20 @@ jobs: git tag -a "$TAG" -m "Release $TAG" if git push origin "$TAG" 2>/dev/null; then echo "Claimed tag $TAG (attempt $ATTEMPT)" + TAG_CLAIMED=true break else echo "Tag $TAG already exists, retrying... (attempt $ATTEMPT)" git tag -d "$TAG" - sleep 1 + sleep 2 fi done + if [ "$TAG_CLAIMED" != "true" ]; then + echo "::error::Failed to claim a unique version tag after 5 attempts" + exit 1 + fi + echo "channel=${CHANNEL}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "versioned_tag=${TAG}" >> "$GITHUB_OUTPUT" diff --git a/app/api/admin.py b/app/api/admin.py index 36d2181..a62c48b 100644 --- a/app/api/admin.py +++ b/app/api/admin.py @@ -65,10 +65,12 @@ async def discover_tables( if source_type == "keboola": from connectors.keboola.client import KeboolaClient - import os from app.instance_config import get_value - url = get_value("keboola", "url", default="") - token = os.environ.get(get_value("keboola", "token_env", default="KEBOOLA_STORAGE_TOKEN"), "") + url = get_value("data_source", "keboola", "url", default="") + token_env = get_value("data_source", "keboola", "token_env", default="KEBOOLA_STORAGE_TOKEN") + token = os.environ.get(token_env, "") if token_env else "" + if not token: + token = os.environ.get("KEBOOLA_STORAGE_TOKEN", "") client = KeboolaClient(token=token, url=url) tables = client.discover_all_tables() return {"tables": tables, "count": len(tables), "source": "keboola"} diff --git a/src/db.py b/src/db.py index 1146e67..cf59420 100644 --- a/src/db.py +++ b/src/db.py @@ -269,8 +269,17 @@ def _ensure_schema(conn: duckdb.DuckDBPyConnection) -> None: try: db_path = Path(os.environ.get("DATA_DIR", "./data")) / "state" / "system.duckdb" if db_path.exists(): + # Flush WAL to main DB file before copying + try: + conn.execute("CHECKPOINT") + except Exception: + pass # CHECKPOINT may fail on read-only or in-memory DBs snapshot = db_path.parent / "system.duckdb.pre-migrate" shutil.copy2(str(db_path), str(snapshot)) + # Also copy WAL if it still exists (belt and suspenders) + wal_path = Path(str(db_path) + ".wal") + if wal_path.exists(): + shutil.copy2(str(wal_path), str(snapshot) + ".wal") logger.info("Pre-migration snapshot saved: %s", snapshot) except Exception as e: logger.warning("Could not create pre-migration snapshot: %s", e)