rangebar 7.1.2__tar.gz → 11.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rangebar-7.1.2 → rangebar-11.4.0}/.gitignore +2 -0
- rangebar-11.4.0/.mcp.json +18 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/.mise.toml +142 -59
- rangebar-11.4.0/.pre-commit-config.yaml +33 -0
- rangebar-11.4.0/CHANGELOG.md +539 -0
- rangebar-11.4.0/CLAUDE.md +227 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/Cargo.lock +503 -39
- {rangebar-7.1.2 → rangebar-11.4.0}/Cargo.toml +27 -6
- {rangebar-7.1.2 → rangebar-11.4.0}/PKG-INFO +49 -33
- {rangebar-7.1.2 → rangebar-11.4.0}/README.md +42 -28
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/CLAUDE.md +53 -22
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/Cargo.toml +6 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/README.md +7 -7
- rangebar-11.4.0/crates/rangebar-core/src/arrow_export.rs +344 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/checkpoint.rs +75 -3
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/fixed_point.rs +3 -3
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/lib.rs +11 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/processor.rs +317 -73
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/test_utils/mod.rs +5 -5
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/types.rs +26 -15
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/tests/cross_boundary_validation.rs +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/tests/cross_year_boundary_test.rs +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/tests/incomplete_bar_continuation_proof.rs +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/Cargo.toml +7 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/README.md +1 -1
- rangebar-11.4.0/crates/rangebar-providers/src/binance/checksum.rs +397 -0
- rangebar-11.4.0/crates/rangebar-providers/src/binance/historical.rs +755 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/binance/mod.rs +11 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/exness/builder.rs +12 -9
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/lib.rs +3 -2
- rangebar-11.4.0/crates/rangebar-streaming/CHANGELOG.md +6 -0
- rangebar-11.4.0/crates/rangebar-streaming/Cargo.toml +42 -0
- rangebar-11.4.0/crates/rangebar-streaming/README.md +132 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/indicators.rs +364 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/lib.rs +32 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/processor.rs +513 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/replay_buffer.rs +359 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/stats.rs +565 -0
- rangebar-11.4.0/crates/rangebar-streaming/src/universal.rs +353 -0
- rangebar-11.4.0/docs/MEMORY_REMEDIATION_PLAN.md +348 -0
- rangebar-11.4.0/docs/adr/2026-01-31-realtime-streaming-api.md +202 -0
- rangebar-11.4.0/docs/analysis/2025-10-10-flash-crash.md +375 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/api.md +422 -13
- rangebar-11.4.0/docs/migration-v8.md +117 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/rangebar_core_api.md +8 -8
- rangebar-11.4.0/docs/research/labeling-for-ml.md +773 -0
- rangebar-11.4.0/docs/research/price-action-patterns.md +313 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/README.md +11 -12
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/binance_csv_example.py +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/with_clickhouse_cache.py +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/pyproject.toml +94 -9
- rangebar-11.4.0/python/rangebar/__init__.py +215 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/__init__.pyi +299 -9
- rangebar-11.4.0/python/rangebar/checkpoint.py +472 -0
- rangebar-11.4.0/python/rangebar/cli.py +298 -0
- rangebar-11.4.0/python/rangebar/clickhouse/CLAUDE.md +136 -0
- rangebar-11.4.0/python/rangebar/clickhouse/bulk_operations.py +309 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/cache.py +124 -427
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/preflight.py +11 -5
- rangebar-11.4.0/python/rangebar/clickhouse/query_operations.py +345 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/schema.sql +44 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/tunnel.py +22 -7
- rangebar-11.4.0/python/rangebar/constants.py +255 -0
- rangebar-11.4.0/python/rangebar/conversion.py +177 -0
- rangebar-11.4.0/python/rangebar/exceptions.py +207 -0
- rangebar-11.4.0/python/rangebar/exness.py +364 -0
- rangebar-11.4.0/python/rangebar/hooks.py +311 -0
- rangebar-11.4.0/python/rangebar/logging.py +171 -0
- rangebar-11.4.0/python/rangebar/notify/__init__.py +15 -0
- rangebar-11.4.0/python/rangebar/notify/pushover.py +155 -0
- rangebar-11.4.0/python/rangebar/notify/telegram.py +271 -0
- rangebar-11.4.0/python/rangebar/orchestration/__init__.py +20 -0
- rangebar-11.4.0/python/rangebar/orchestration/count_bounded.py +797 -0
- rangebar-11.4.0/python/rangebar/orchestration/helpers.py +397 -0
- rangebar-11.4.0/python/rangebar/orchestration/models.py +76 -0
- rangebar-11.4.0/python/rangebar/orchestration/precompute.py +498 -0
- rangebar-11.4.0/python/rangebar/orchestration/range_bars.py +726 -0
- rangebar-11.4.0/python/rangebar/orchestration/tick_fetcher.py +226 -0
- rangebar-11.4.0/python/rangebar/ouroboros.py +454 -0
- rangebar-11.4.0/python/rangebar/processors/__init__.py +22 -0
- rangebar-11.4.0/python/rangebar/processors/api.py +383 -0
- rangebar-11.4.0/python/rangebar/processors/core.py +510 -0
- rangebar-11.4.0/python/rangebar/resource_guard.py +342 -0
- rangebar-11.4.0/python/rangebar/storage/checksum_registry.py +218 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/storage/parquet.py +38 -8
- rangebar-11.4.0/python/rangebar/streaming.py +300 -0
- rangebar-11.4.0/python/rangebar/validation/__init__.py +69 -0
- rangebar-11.4.0/python/rangebar/validation/cache_staleness.py +277 -0
- rangebar-11.4.0/python/rangebar/validation/continuity.py +664 -0
- rangebar-11.4.0/python/rangebar/validation/gap_classification.py +294 -0
- rangebar-11.4.0/python/rangebar/validation/post_storage.py +317 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/validation/tier1.py +1 -1
- rangebar-11.4.0/scripts/analyze_flash_crash.py +206 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/build-release.sh +57 -27
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/cache_status.py +6 -6
- rangebar-11.4.0/scripts/check-release-config.sh +102 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/publish-to-pypi.sh +47 -15
- rangebar-11.4.0/scripts/regenerate_cache.py +114 -0
- rangebar-11.4.0/scripts/semantic-release.sh +47 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/validate_microstructure_features.py +2 -2
- rangebar-11.4.0/src/lib.rs +2291 -0
- rangebar-11.4.0/tests/conftest.py +50 -0
- rangebar-11.4.0/tests/test_cache_schema_evolution.py +409 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_clickhouse.py +4 -0
- rangebar-11.4.0/tests/test_clickhouse_integration.py +728 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_get_n_range_bars.py +165 -76
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_get_range_bars_e2e.py +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_issue_5_reproduction.py +1 -1
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_microstructure_features.py +1 -1
- rangebar-11.4.0/tests/test_ouroboros.py +907 -0
- rangebar-11.4.0/tests/test_polars_only_downstream.py +433 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_preflight.py +22 -14
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_rust_bindings.py +111 -5
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_storage.py +47 -0
- rangebar-11.4.0/tests/test_streaming.py +528 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/uv.lock +134 -634
- rangebar-7.1.2/.link-check-results.md +0 -12
- rangebar-7.1.2/.pre-commit-config.yaml +0 -51
- rangebar-7.1.2/CHANGELOG.md +0 -371
- rangebar-7.1.2/CLAUDE.md +0 -174
- rangebar-7.1.2/crates/rangebar-providers/src/binance/historical.rs +0 -212
- rangebar-7.1.2/python/rangebar/__init__.py +0 -3636
- rangebar-7.1.2/python/rangebar/exness.py +0 -198
- rangebar-7.1.2/python/rangebar/validation/__init__.py +0 -16
- rangebar-7.1.2/src/lib.rs +0 -1163
- rangebar-7.1.2/tests/test_clickhouse_integration.py +0 -348
- {rangebar-7.1.2 → rangebar-11.4.0}/.releaserc.yml +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/LICENSE +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/benches/rangebar_bench.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/build.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/CHANGELOG.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/test_data_loader.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/test_utils/generators.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/src/timestamp.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-core/tests/cross_date_real_data_validation.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/CHANGELOG.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/binance/symbols.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/binance/websocket.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/exness/client.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/exness/conversion.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/exness/mod.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/crates/rangebar-providers/src/exness/types.rs +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/deny.toml +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/ARCHITECTURE.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/CONTEXT.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/development/PERFORMANCE.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/docs/development/RELEASE.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/backtesting_integration.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/basic_usage.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/get_range_bars_example.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/examples/validate_output.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/package-lock.json +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/package.json +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/CLAUDE.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/__init__.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/client.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/config.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/clickhouse/mixin.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/storage/__init__.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/python/rangebar/validation/tier2.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/rust-toolchain.toml +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/rustfmt.toml +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/cache_clear.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/dependency_monitor.sh +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/profiling_tools.sh +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/publish-wheels.sh +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/run_large_scale_benchmark.sh +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/validate_clickhouse.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/validate_memory_efficiency.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/scripts/validate_n_range_bars.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/test_data/BTCUSDT/BTCUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/test_data/ETHUSDT/ETHUSDT_aggTrades_20250901.csv +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/test_data/README.md +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/fixtures/.gitignore +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/fixtures/BTCUSDT-aggTrades-2024-01-01.zip +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_e2e_optimized.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_edge_cases.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_examples.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_issues_7_8.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_python_api.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_real_data.py +0 -0
- {rangebar-7.1.2 → rangebar-11.4.0}/tests/test_validation_presets.py +0 -0
|
@@ -98,6 +98,7 @@ tmp/
|
|
|
98
98
|
.lycheecache
|
|
99
99
|
logs/
|
|
100
100
|
node_modules/
|
|
101
|
+
bun.lock
|
|
101
102
|
|
|
102
103
|
# ClickHouse server runtime data (created when running `clickhouse server` locally)
|
|
103
104
|
data/
|
|
@@ -112,3 +113,4 @@ user_defined/
|
|
|
112
113
|
format_schemas/
|
|
113
114
|
access/
|
|
114
115
|
test_data/
|
|
116
|
+
.claude/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"mise": {
|
|
4
|
+
"command": "mise",
|
|
5
|
+
"args": ["mcp"],
|
|
6
|
+
"env": {
|
|
7
|
+
"MISE_EXPERIMENTAL": "1"
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"shell": {
|
|
11
|
+
"command": "uvx",
|
|
12
|
+
"args": ["mcp-shell-server"],
|
|
13
|
+
"env": {
|
|
14
|
+
"ALLOW_COMMANDS": "mise,git,jq,cargo,uv,maturin,pytest,cat,ls,grep,head,tail,fd"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -1,14 +1,45 @@
|
|
|
1
1
|
[env]
|
|
2
|
-
#
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# GitHub Account Isolation (CRITICAL for multi-account setups)
|
|
4
|
+
# =============================================================================
|
|
3
5
|
# See: ADR 2025-12-17-github-multi-account-authentication
|
|
6
|
+
#
|
|
7
|
+
# This ensures all gh CLI and git operations use the correct GitHub identity.
|
|
8
|
+
# The git remote MUST use SSH with host alias: git@github.com-terrylica:...
|
|
4
9
|
GH_ACCOUNT = "terrylica"
|
|
5
10
|
GH_CONFIG_DIR = "{{ env.HOME }}/.config/gh/profiles/terrylica"
|
|
6
11
|
|
|
7
|
-
# GitHub
|
|
12
|
+
# GitHub token for gh CLI operations (uses file-based loading to prevent process storms)
|
|
13
|
+
# ADR: 2026-01-15-mise-env-token-loading-patterns.md
|
|
14
|
+
# NOTE: For semantic-release, use `mise run release:version` which fetches
|
|
15
|
+
# the PAT from Doppler dynamically to avoid stale token issues.
|
|
8
16
|
GH_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-terrylica') | trim }}"
|
|
9
17
|
GITHUB_TOKEN = "{{ read_file(path=env.HOME ~ '/.claude/.secrets/gh-token-terrylica') | trim }}"
|
|
10
18
|
|
|
11
|
-
#
|
|
19
|
+
# =============================================================================
|
|
20
|
+
# Doppler Configuration (SSoT for secrets)
|
|
21
|
+
# =============================================================================
|
|
22
|
+
# PyPI: doppler secrets get PYPI_TOKEN --project claude-config --config prd
|
|
23
|
+
# GitHub PAT: doppler secrets get GH_TOKEN_TERRYLICA --project main --config dev
|
|
24
|
+
DOPPLER_PYPI_PROJECT = "claude-config"
|
|
25
|
+
DOPPLER_PYPI_CONFIG = "prd"
|
|
26
|
+
|
|
27
|
+
# =============================================================================
|
|
28
|
+
# ClickHouse Cache Configuration (SSoT for cache hosts)
|
|
29
|
+
# =============================================================================
|
|
30
|
+
# RANGEBAR_CH_HOSTS: SSH aliases for ClickHouse hosts (comma-separated)
|
|
31
|
+
# RANGEBAR_CH_PRIMARY: Preferred host when multiple available
|
|
32
|
+
# RANGEBAR_MODE: "auto" (default), "local", or "cloud"
|
|
33
|
+
#
|
|
34
|
+
# AUTO mode: Try localhost first, then SSH tunnel to remote hosts
|
|
35
|
+
# LOCAL mode: Only use localhost:8123 (fails if unavailable)
|
|
36
|
+
# CLOUD mode: Only use CLICKHOUSE_HOST env var (for cloud deployments)
|
|
37
|
+
RANGEBAR_CH_HOSTS = "bigblack"
|
|
38
|
+
RANGEBAR_CH_PRIMARY = "bigblack"
|
|
39
|
+
|
|
40
|
+
# =============================================================================
|
|
41
|
+
# Build Configuration
|
|
42
|
+
# =============================================================================
|
|
12
43
|
BENCH_DATA_DIR = "{{ env.PWD }}/bench-data"
|
|
13
44
|
PROFILE_DATA_DIR = "{{ env.PWD }}/profile-data"
|
|
14
45
|
|
|
@@ -28,7 +59,7 @@ LINUX_MIN_RUST_VERSION = "1.90"
|
|
|
28
59
|
# =============================================================================
|
|
29
60
|
|
|
30
61
|
[tools]
|
|
31
|
-
python = "3.
|
|
62
|
+
python = "3.13"
|
|
32
63
|
rust = "1.90"
|
|
33
64
|
node = "22" # Required for semantic-release
|
|
34
65
|
uv = "latest" # Required for publish workflow
|
|
@@ -250,7 +281,7 @@ run = "./scripts/publish-wheels.sh"
|
|
|
250
281
|
|
|
251
282
|
[tasks."release:local"]
|
|
252
283
|
description = "Build local wheel only (macOS ARM64)"
|
|
253
|
-
run = "maturin build --
|
|
284
|
+
run = "maturin build --profile wheel"
|
|
254
285
|
|
|
255
286
|
[tasks."release:sdist"]
|
|
256
287
|
description = "Build source distribution"
|
|
@@ -261,8 +292,19 @@ run = "maturin sdist"
|
|
|
261
292
|
# =============================================================================
|
|
262
293
|
|
|
263
294
|
[tasks."release:macos-arm64"]
|
|
264
|
-
description = "Build macOS ARM64
|
|
265
|
-
run = "
|
|
295
|
+
description = "Build macOS ARM64 wheels for Python 3.13 (native)"
|
|
296
|
+
run = """
|
|
297
|
+
echo "=== Building macOS ARM64 wheels (Python 3.13) ==="
|
|
298
|
+
for pyver in python3.13; do
|
|
299
|
+
if command -v $pyver &> /dev/null; then
|
|
300
|
+
echo "Building for $pyver..."
|
|
301
|
+
maturin build --profile wheel -i $pyver
|
|
302
|
+
else
|
|
303
|
+
echo "WARN: $pyver not found, skipping"
|
|
304
|
+
fi
|
|
305
|
+
done
|
|
306
|
+
echo "OK: macOS ARM64 wheels built"
|
|
307
|
+
"""
|
|
266
308
|
|
|
267
309
|
[tasks."release:linux-preflight"]
|
|
268
310
|
description = "Verify Linux build host availability"
|
|
@@ -279,10 +321,10 @@ echo "OK: Remote Rust version: $REMOTE_RUST"
|
|
|
279
321
|
"""
|
|
280
322
|
|
|
281
323
|
[tasks."release:linux"]
|
|
282
|
-
description = "Build Linux x86_64
|
|
324
|
+
description = "Build Linux x86_64 wheels for Python 3.13 on remote host (Docker manylinux)"
|
|
283
325
|
depends = ["release:linux-preflight"]
|
|
284
326
|
run = """
|
|
285
|
-
echo "=== Building Linux x86_64
|
|
327
|
+
echo "=== Building Linux x86_64 Wheels (Docker manylinux, Python 3.13) ==="
|
|
286
328
|
PROJECT_DIR="$(pwd)"
|
|
287
329
|
REMOTE_DIR="${LINUX_BUILD_DIR}-$$"
|
|
288
330
|
|
|
@@ -297,11 +339,12 @@ rsync -az --delete \
|
|
|
297
339
|
"$PROJECT_DIR/" "$LINUX_BUILD_USER@$LINUX_BUILD_HOST:$REMOTE_DIR/"
|
|
298
340
|
|
|
299
341
|
# Build using manylinux Docker container for glibc compatibility
|
|
300
|
-
|
|
342
|
+
# Build for Python 3.13 only (abi3 removed, need per-version wheels)
|
|
343
|
+
ssh "$LINUX_BUILD_USER@$LINUX_BUILD_HOST" 'cd '"$REMOTE_DIR"' && docker run --rm -v $(pwd):/io -w /io quay.io/pypa/manylinux2014_x86_64 bash -c "yum install -y openssl-devel perl-IPC-Cmd && curl --proto =https --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y && source ~/.cargo/env && /opt/python/cp313-cp313/bin/pip install maturin && /opt/python/cp313-cp313/bin/maturin build --profile wheel --compatibility manylinux2014 -i /opt/python/cp313-cp313/bin/python"'
|
|
301
344
|
|
|
302
345
|
mkdir -p dist/
|
|
303
346
|
scp "$LINUX_BUILD_USER@$LINUX_BUILD_HOST:$REMOTE_DIR/target/wheels/*manylinux*.whl" dist/
|
|
304
|
-
echo "OK: Linux
|
|
347
|
+
echo "OK: Linux wheels built"
|
|
305
348
|
"""
|
|
306
349
|
|
|
307
350
|
# =============================================================================
|
|
@@ -333,25 +376,46 @@ echo "OK: Preflight passed"
|
|
|
333
376
|
description = "Synchronize with remote (Phase 2)"
|
|
334
377
|
depends = ["release:preflight"]
|
|
335
378
|
run = """
|
|
379
|
+
#!/usr/bin/env bash
|
|
380
|
+
set -euo pipefail
|
|
381
|
+
|
|
336
382
|
echo "=== SYNC ==="
|
|
383
|
+
|
|
384
|
+
# Ensure SSH remote for terrylica account
|
|
385
|
+
REMOTE_URL=$(git remote get-url origin)
|
|
386
|
+
if [[ ! "$REMOTE_URL" =~ github.com-terrylica ]]; then
|
|
387
|
+
echo "Fixing remote URL for terrylica identity..."
|
|
388
|
+
git remote set-url origin "git@github.com-terrylica:terrylica/rangebar-py.git"
|
|
389
|
+
fi
|
|
390
|
+
|
|
337
391
|
git pull --rebase origin main || { echo "FAIL: Pull failed"; exit 1; }
|
|
338
392
|
git push origin main || { echo "FAIL: Push failed"; exit 1; }
|
|
339
393
|
echo "OK: Synced"
|
|
340
394
|
"""
|
|
341
395
|
|
|
396
|
+
[tasks."release:check-config"]
|
|
397
|
+
description = "Verify release configuration (GitHub, Doppler, SSH)"
|
|
398
|
+
run = "./scripts/check-release-config.sh"
|
|
399
|
+
|
|
342
400
|
[tasks."release:build-all"]
|
|
343
|
-
description = "Build all platform wheels (Phase 3)"
|
|
401
|
+
description = "Build all platform wheels + sdist (Phase 3 - runs AFTER version bump)"
|
|
402
|
+
depends = ["release:version"]
|
|
344
403
|
run = """
|
|
345
404
|
echo "=== BUILD ALL PLATFORMS ==="
|
|
346
405
|
mise run release:macos-arm64
|
|
347
406
|
mise run release:linux
|
|
348
|
-
|
|
349
|
-
|
|
407
|
+
mise run release:sdist
|
|
408
|
+
# Copy macOS wheel and sdist to dist/ (Linux wheel already lands there via scp)
|
|
409
|
+
VERSION=$(grep -A5 '\\[workspace.package\\]' Cargo.toml | grep '^version' | head -1 | sed 's/.*= "\\(.*\\)"/\\1/')
|
|
410
|
+
cp -n target/wheels/rangebar-${VERSION}-*.whl dist/ 2>/dev/null || true
|
|
411
|
+
cp -n target/wheels/rangebar-${VERSION}.tar.gz dist/ 2>/dev/null || true
|
|
412
|
+
echo "OK: All wheels + sdist built"
|
|
413
|
+
ls -la dist/rangebar-${VERSION}* 2>/dev/null || true
|
|
350
414
|
"""
|
|
351
415
|
|
|
352
416
|
[tasks."release:postflight"]
|
|
353
|
-
description = "Verify and publish (Phase 4)"
|
|
354
|
-
depends = ["smoke"]
|
|
417
|
+
description = "Verify and publish (Phase 4 - runs AFTER builds)"
|
|
418
|
+
depends = ["smoke", "release:build-all"]
|
|
355
419
|
run = """
|
|
356
420
|
echo "=== POSTFLIGHT ==="
|
|
357
421
|
WHEEL_COUNT=$(find dist/ -name "*.whl" 2>/dev/null | wc -l | tr -d ' ')
|
|
@@ -362,58 +426,31 @@ echo "To publish: mise run publish"
|
|
|
362
426
|
"""
|
|
363
427
|
|
|
364
428
|
[tasks."release:version"]
|
|
365
|
-
description = "Bump version via semantic-release
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
echo "Installing npm dependencies..."
|
|
369
|
-
npm install
|
|
370
|
-
fi
|
|
371
|
-
npm run release
|
|
372
|
-
"""
|
|
429
|
+
description = "Bump version via semantic-release with Doppler GitHub token"
|
|
430
|
+
depends = ["release:sync"]
|
|
431
|
+
run = "./scripts/semantic-release.sh"
|
|
373
432
|
|
|
374
433
|
[tasks."release:dry"]
|
|
375
434
|
description = "Preview what semantic-release would do (no changes)"
|
|
376
|
-
run = ""
|
|
377
|
-
if [ ! -d node_modules ]; then
|
|
378
|
-
echo "Installing npm dependencies..."
|
|
379
|
-
npm install
|
|
380
|
-
fi
|
|
381
|
-
echo "=== DRY RUN: Previewing release ==="
|
|
382
|
-
npx semantic-release --dry-run --no-ci
|
|
383
|
-
"""
|
|
435
|
+
run = "bun install --silent 2>/dev/null && GH_CONFIG_DIR=$HOME/.config/gh/profiles/terrylica GITHUB_TOKEN=$(gh auth token) bun run semantic-release --dry-run --no-ci"
|
|
384
436
|
|
|
385
437
|
[tasks."release:pypi"]
|
|
386
|
-
description = "Publish to PyPI using Doppler credentials (local-only)"
|
|
438
|
+
description = "Publish to PyPI using Doppler credentials (local-only, ADR-0027)"
|
|
439
|
+
depends = ["release:build-all"]
|
|
387
440
|
run = "./scripts/publish-to-pypi.sh"
|
|
388
441
|
|
|
389
442
|
[tasks."release:full"]
|
|
390
|
-
description = "Full
|
|
443
|
+
description = "Full release workflow: version bump → build → smoke → publish to PyPI"
|
|
444
|
+
# Dependency chain enforced via task-level depends:
|
|
445
|
+
# preflight → sync → version → build-all → postflight
|
|
446
|
+
# ↓
|
|
447
|
+
# release:pypi (publish)
|
|
448
|
+
# mise resolves the full DAG automatically.
|
|
449
|
+
depends = ["release:postflight", "release:pypi"]
|
|
391
450
|
run = """
|
|
392
|
-
echo
|
|
393
|
-
|
|
394
|
-
echo
|
|
395
|
-
echo "=== Phase 1: PREFLIGHT ==="
|
|
396
|
-
mise run release:preflight
|
|
397
|
-
|
|
398
|
-
echo ""
|
|
399
|
-
echo "=== Phase 2: SYNC ==="
|
|
400
|
-
mise run release:sync
|
|
401
|
-
|
|
402
|
-
echo ""
|
|
403
|
-
echo "=== Phase 3: VERSION (semantic-release) ==="
|
|
404
|
-
mise run release:version
|
|
405
|
-
|
|
406
|
-
echo ""
|
|
407
|
-
echo "=== Phase 4: BUILD ==="
|
|
408
|
-
mise run release:build-all
|
|
409
|
-
|
|
410
|
-
echo ""
|
|
411
|
-
echo "=== Phase 5: POSTFLIGHT ==="
|
|
412
|
-
mise run release:postflight
|
|
413
|
-
|
|
414
|
-
echo ""
|
|
415
|
-
echo "=== COMPLETE ==="
|
|
416
|
-
echo "Run 'mise run publish' to publish to PyPI"
|
|
451
|
+
echo '========================================='
|
|
452
|
+
echo ' Release complete and published to PyPI!'
|
|
453
|
+
echo '========================================='
|
|
417
454
|
"""
|
|
418
455
|
|
|
419
456
|
# =============================================================================
|
|
@@ -440,3 +477,49 @@ print("OK: basic processing works")
|
|
|
440
477
|
[tasks.smoke]
|
|
441
478
|
description = "Run all smoke tests"
|
|
442
479
|
depends = ["smoke:import", "smoke:process"]
|
|
480
|
+
|
|
481
|
+
# =============================================================================
|
|
482
|
+
# Checksum Verification Tasks (Issue #43)
|
|
483
|
+
# =============================================================================
|
|
484
|
+
|
|
485
|
+
[tasks."test:checksum"]
|
|
486
|
+
description = "Test Rust checksum verification module"
|
|
487
|
+
run = "cargo nextest run -p rangebar-providers checksum"
|
|
488
|
+
|
|
489
|
+
[tasks."test:checksum:integration"]
|
|
490
|
+
description = "Integration test with real Binance data (requires network)"
|
|
491
|
+
run = """
|
|
492
|
+
python -c '
|
|
493
|
+
from rangebar import get_range_bars
|
|
494
|
+
import logging
|
|
495
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
496
|
+
|
|
497
|
+
# Test with checksum verification (should see checksum events in logs)
|
|
498
|
+
df = get_range_bars("BTCUSDT", "2024-01-01", "2024-01-01", verify_checksum=True)
|
|
499
|
+
print(f"Downloaded {len(df)} bars with checksum verification")
|
|
500
|
+
'
|
|
501
|
+
"""
|
|
502
|
+
|
|
503
|
+
[tasks."checksum:audit"]
|
|
504
|
+
description = "Audit Tier 1 cache for unverified files"
|
|
505
|
+
run = """
|
|
506
|
+
python -c '
|
|
507
|
+
from rangebar.storage.checksum_registry import ChecksumRegistry
|
|
508
|
+
registry = ChecksumRegistry()
|
|
509
|
+
count = registry.get_verified_count("BTCUSDT")
|
|
510
|
+
print(f"BTCUSDT verified dates: {count}")
|
|
511
|
+
'
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
[tasks."checksum:pushover-test"]
|
|
515
|
+
description = "Send test Pushover alert to verify credentials"
|
|
516
|
+
run = """
|
|
517
|
+
python -c '
|
|
518
|
+
from rangebar.notify.pushover import send_critical_alert
|
|
519
|
+
result = send_critical_alert(
|
|
520
|
+
title="🧪 RB Test Alert",
|
|
521
|
+
message="Checksum verification test - ignore this alert.",
|
|
522
|
+
)
|
|
523
|
+
print(f"Pushover alert sent: {result}")
|
|
524
|
+
'
|
|
525
|
+
"""
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Pre-commit hooks for rangebar-py
|
|
2
|
+
# ADR-005: Automated Release Management
|
|
3
|
+
#
|
|
4
|
+
# Philosophy: Only checks that catch BUGS, not cosmetic formatting
|
|
5
|
+
#
|
|
6
|
+
# REMOVED (cosmetic, no bug-catching value):
|
|
7
|
+
# - black (Python formatting)
|
|
8
|
+
# - fmt (Rust formatting)
|
|
9
|
+
# - end-of-file-fixer
|
|
10
|
+
# - trailing-whitespace
|
|
11
|
+
#
|
|
12
|
+
# MOVED TO PRE-PUSH (too slow for commits):
|
|
13
|
+
# - clippy (Rust linting) - runs on `git push` via global hook
|
|
14
|
+
#
|
|
15
|
+
# Install: pre-commit install
|
|
16
|
+
# Run manually: pre-commit run --all-files
|
|
17
|
+
|
|
18
|
+
repos:
|
|
19
|
+
# Python linting (fast, catches bugs)
|
|
20
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
21
|
+
rev: v0.8.4
|
|
22
|
+
hooks:
|
|
23
|
+
- id: ruff
|
|
24
|
+
args: [--fix, --exit-non-zero-on-fix]
|
|
25
|
+
|
|
26
|
+
# Config validation (prevents broken builds)
|
|
27
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
28
|
+
rev: v5.0.0
|
|
29
|
+
hooks:
|
|
30
|
+
- id: check-yaml
|
|
31
|
+
- id: check-toml
|
|
32
|
+
- id: check-added-large-files
|
|
33
|
+
args: [--maxkb=1024] # Prevent committing files >1MB
|