CHANGELOG
v0.5.0 (2026-03-29)
Build System
- Simplify dependencies and add project metadata
(
946e2ba)
Remove dbt-core, pydantic, jinja2, pyyaml dependencies. Add MIT license, project URLs, and authors to pyproject.toml. Move zensical from docs dependency group to dev.
Chores
- Remove fdl_common dbt macros package
(
605a3d4)
Continuous Integration
Documentation
-
Add concept pages and global install instructions (
35180ad) -
Add "Why fdl" page explaining the Frozen DuckLake pattern and motivation - Add Roadmap page with vision toward a package manager for Frozen DuckLake - Add global install instructions (uv tool / pipx) to quickstart
-
Migrate from mkdocs to zensical (
5b8359c)
Replace mkdocs-material with zensical as the documentation engine. Replace changelog symlink with pymdownx.snippets include.
- Rewrite documentation for target-based architecture
(
e48b8e3)
Restructure docs to match new target-based config model. Migrate from mkdocs to zensical. Add guide, reference, and resources sections with new content.
-
Update CLAUDE.md and add CONTRIBUTING.md (
28d12f1) -
Update README, CLAUDE.md, and CONTRIBUTING.md (
0c48dff)
Features
-
Add --version flag, improve gc output (
2046a11) -
Add push conflict detection and --force flag (
3db0216) -
Track pushed_at timestamp in .fdl/meta.json (local + remote) - Push rejects when remote was updated since last pull - --force overrides conflict detection - Pull syncs meta.json from remote for next push check
-
Rewrite to target-based architecture (
a17d8ec)
Replace 3-layer config (env → workspace → user) with single fdl.toml and ${VAR} environment variable expansion.
BREAKING CHANGE: - remote renamed to target across all commands - FDL_ATTACH_PATH renamed to
FDL_CATALOG - gc command renamed to prune - fdl run now requires TARGET argument -
metadata command removed - create_destination() removed from ducklake module - User/workspace
config files (~/.fdl/config, .fdl/config) no longer read
New features: - fdl sql TARGET QUERY — execute SQL against the catalog - fdl init prompts
interactively for target config - S3Config dataclass for typed credential handling
Refactoring
-
Make load_toml strict and remove datasource_name fallback (
63ca8ed) -
load_toml → _load_toml: internal function, raises FileNotFoundError - set_value: catch FileNotFoundError for new file creation - datasource_name: require name in fdl.toml, no directory name fallback
-
Replace print with rich console output (
3958b6b) -
Replace prune with checkpoint command (
6433bcd) -
Use DuckLake CHECKPOINT statement via connect() context manager - Remove S3-only restriction, works on any target - Extract is_stale pure function and read_remote_pushed_at to meta.py - Add stale catalog check before maintenance (reuses push conflict detection)
-
Unify branding to Frozen DuckLake (
cd148ca) -
Rename "Frozen Data Lake" to "Frozen DuckLake" across all files - Normalize casing: FDL → fdl - Remove "Git-like" messaging - Update site_name to "fdl — Frozen DuckLake CLI"
Testing
- Add FDL_DATA_PATH injection test
(
2644ae9)
Verify fdl run injects FDL_DATA_PATH ending with ducklake.duckdb.files/
- Add integration and unit tests (89 tests)
(
1d01ffe)
Integration tests (tests/integration/): - test_init: default catalog, invalid name, existing toml, double init, rollback, sqlite - test_config: get, set, list-all, env var reference, s3 credentials, missing key, without init - test_sql: data persistence, invalid sql - test_run: env injection, no-overwrite, separator, exit code propagation - test_push: catalog copy, sqlite conversion, meta.json, conflict detection, force push - test_pull: catalog restore, meta.json sync, pull-then-push, empty target - test_prune: local target rejection, orphan deletion, dry-run - test_serve: CORS, range request, HEAD, OPTIONS, 404
Unit tests (tests/): - test_config: set_value, get_all, datasource_name, storage/data_path/ catalog_path, resolve_target, target_s3_config, ducklake_url, fdl_env_dict - test_init_module: ducklake_data_path, default_target_url - test_s3: S3Config endpoint_host - test_serve: CORSRangeHandler
-
Add Phase 1 pure function tests (
a118610) -
test_init_module.py: ducklake_data_path, default_target_url - test_s3.py: S3Config endpoint_host
-
Add S3 target integration tests for push and pull (
c6caf1d) -
push uploads catalog to S3 - push conflict detection on S3 - pull restores catalog from S3
v0.4.0 (2026-03-27)
Continuous Integration
- Add GitHub Pages deployment workflow
(
ebad8ba)
Build and deploy docs on push to main (docs/**, mkdocs.yml, CHANGELOG.md) and manual dispatch.
Documentation
-
Add MkDocs Material documentation site (
7f00206) -
mkdocs.yml with Material theme (light/dark, code copy, search) - 6 pages: index, quickstart, CLI reference, configuration, dlt integration, changelog - Changelog page symlinked to CHANGELOG.md - Update README.md with project overview and commands - Add site/ to .gitignore
-
Update GitHub Pages actions and set custom site URL (
5fe951b)
Features
- Add fdl gc command with --dry-run support
(
9e5d451)
fdl gc origin --dry-run # list orphaned files and sizes fdl gc origin # interactive deletion with confirmation fdl gc origin --force # delete without confirmation fdl gc origin --older-than 7 # only files older than 7 days
v0.3.3 (2026-03-27)
Bug Fixes
- Include fdl.toml in config value resolution
(
2e6c921)
_get_config_value now checks project config (fdl.toml) before workspace and user config, matching resolve_remote's 3-layer lookup.
v0.3.2 (2026-03-26)
Bug Fixes
- Expand env vars in remote URLs
(
38341e3)
resolve_remote() now calls os.path.expandvars() so that fdl.toml remotes like s3://${FDL_S3_BUCKET} are expanded.
v0.3.1 (2026-03-26)
Bug Fixes
- Remove .fdl/ pre-check from pull command
(
4e2023b)
pull.py already creates .fdl/ via mkdir(parents=True). The check broke CI where .fdl/ is gitignored and doesn't exist before pull.
v0.3.0 (2026-03-26)
Chores
- Bump frozen-ducklake to 0.2.1
(
b359533)
Features
- Require fdl init before pull, remove --sqlite fallback
(
b21369e)
pull no longer auto-initializes the catalog. Users must run fdl init first. Removes --sqlite option from pull.
-
Rewrite fdl init with fdl.toml scaffolding and rollback (
e5e6454) -
name argument required (like git init
) - generates fdl.toml with name and optional catalog type - auto-creates .gitignore entry for .fdl/ - rolls back fdl.toml and .fdl/ on failure - set_value now auto-detects top-level vs sectioned keys
Refactoring
- Move datasource/URL resolution from DatasetConfig to config module
(
6ff1ff2)
datasource_name(), public_url(), ducklake_url() are now in config.py with 3-layer resolution (env var → workspace → user config). DatasetConfig no longer holds public_url or ducklake_url.
-
Resolve storage in create_destination, add FDL_S3_ENDPOINT_HOST (
26bcec8) -
create_destination defaults to config.storage() instead of hardcoded .fdl - s3_env_dict now derives FDL_S3_ENDPOINT_HOST (scheme-less) for DuckDB
v0.2.1 (2026-03-26)
Bug Fixes
- Update outdated docstring in create_destination
(
ad31665)
Continuous Integration
- Merge publish into release workflow
(
22ba582)
GITHUB_TOKEN tags don't trigger other workflows. Run PyPI publish in the same job after semantic-release.
- Switch release to manual trigger (workflow_dispatch)
(
0186734)
v0.2.0 (2026-03-26)
Bug Fixes
Chores
- Update uv.lock
(
1331865)
Features
- Named remotes, fdl run/config/serve, FDL_* env vars
(
d749935)
BREAKING CHANGE: push/pull now require named remotes instead of URLs. s3_url removed from dataset.yml, replaced by fdl.toml remotes. DUCKLAKE_STORAGE renamed to FDL_STORAGE. S3 env vars prefixed with FDL_S3_.
Named remotes: - push/pull require explicit remote name (e.g. origin, local) - Remotes defined in fdl.toml (project), .fdl/config (workspace), ~/.fdl/config (user) - No built-in remotes; all user-defined via fdl config
fdl run: - Sets FDL_STORAGE, FDL_DATA_PATH, FDL_ATTACH_PATH for pipeline execution - S3 credentials loaded from config (env var → workspace → user) - Usage: fdl run [REMOTE] -- COMMAND
fdl config: - git config-like settings management - fdl config key value (user), fdl config --local key value (workspace)
fdl serve: - HTTP server with CORS + Range request support - Optional remote arg: fdl serve (project .fdl/) or fdl serve REMOTE
Other changes: - DIST_DIR renamed to FDL_DIR - S3 endpoint now stored with https:// scheme - gc.py: add OVERRIDE_DATA_PATH for v1.0 compatibility
Breaking Changes
- Push/pull now require named remotes instead of URLs. s3_url removed from dataset.yml, replaced by fdl.toml remotes. DUCKLAKE_STORAGE renamed to FDL_STORAGE. S3 env vars prefixed with FDL_S3_.