Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions duckdb_packaging/setuptools_scm_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import os
import re
from datetime import datetime, timezone
from typing import Protocol

# Import from our own versioning module to avoid duplication
Expand Down Expand Up @@ -72,15 +73,19 @@ def _bump_dev_version(base_version: str, distance: int) -> str:
raise ValueError(msg)
major, minor, patch, post, rc = parse_version(base_version)

# Use date-based versioning for dev builds (YYYYMMDD format)
# This allows daily nightlies even without code changes
date_suffix = datetime.now(timezone.utc).strftime("%Y%m%d")

if post != 0:
# We're developing on top of a post-release
return f"{format_version(major, minor, patch, post=post + 1)}.dev{distance}"
return f"{format_version(major, minor, patch, post=post + 1)}.dev{date_suffix}"
elif rc != 0:
# We're developing on top of an rc
return f"{format_version(major, minor, patch, rc=rc + 1)}.dev{distance}"
return f"{format_version(major, minor, patch, rc=rc + 1)}.dev{date_suffix}"
elif _main_branch_versioning():
return f"{format_version(major, minor + 1, 0)}.dev{distance}"
return f"{format_version(major, minor, patch + 1)}.dev{distance}"
return f"{format_version(major, minor + 1, 0)}.dev{date_suffix}"
return f"{format_version(major, minor, patch + 1)}.dev{date_suffix}"


def forced_version_from_env() -> str:
Expand Down
27 changes: 23 additions & 4 deletions tests/fast/test_versioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import subprocess
import unittest
from datetime import datetime, timezone
from unittest.mock import MagicMock, patch

import pytest
Expand Down Expand Up @@ -108,6 +109,17 @@ def test_roundtrip_conversion(self):
class TestSetupToolsScmIntegration(unittest.TestCase):
"""Test setuptools_scm integration functions."""

def _verify_date_suffix(self, version_string: str) -> None:
"""Helper to verify the date suffix in a dev version is today's date."""
date_part = version_string.split(".dev")[1]
assert len(date_part) == 8, f"Date part should be 8 digits, got {len(date_part)}"
assert date_part.isdigit(), f"Date part should be all digits, got {date_part}"

# Parse the date and verify it's today
parsed_date = datetime.strptime(date_part, "%Y%m%d").date()
today = datetime.now(timezone.utc).date()
assert parsed_date == today, f"Date {parsed_date} should be today {today}"

def test_bump_version_exact_tag(self):
"""Test bump_version with exact tag (distance=0, dirty=False)."""
assert _tag_to_version("1.2.3") == "1.2.3"
Expand All @@ -116,15 +128,21 @@ def test_bump_version_exact_tag(self):
@patch.dict("os.environ", {"MAIN_BRANCH_VERSIONING": "1"})
def test_bump_version_with_distance(self):
"""Test bump_version with distance from tag."""
assert _bump_dev_version("1.2.3", 5) == "1.3.0.dev5"
result = _bump_dev_version("1.2.3", 5)
assert result.startswith("1.3.0.dev")
self._verify_date_suffix(result)

# Post-release development
assert _bump_dev_version("1.2.3.post1", 3) == "1.2.3.post2.dev3"
result = _bump_dev_version("1.2.3.post1", 3)
assert result.startswith("1.2.3.post2.dev")
self._verify_date_suffix(result)

@patch.dict("os.environ", {"MAIN_BRANCH_VERSIONING": "0"})
def test_bump_version_release_branch(self):
"""Test bump_version on bugfix branch."""
assert _bump_dev_version("1.2.3", 5) == "1.2.4.dev5"
result = _bump_dev_version("1.2.3", 5)
assert result.startswith("1.2.4.dev")
self._verify_date_suffix(result)

@patch.dict("os.environ", {"MAIN_BRANCH_VERSIONING": "1"})
def test_bump_version_dirty(self):
Expand All @@ -142,7 +160,8 @@ def test_version_scheme_function(self):
mock_version.dirty = False

result = version_scheme(mock_version)
assert result == "1.3.0.dev5"
assert result.startswith("1.3.0.dev")
self._verify_date_suffix(result)

def test_bump_version_invalid_format(self):
"""Test bump_version with invalid version format."""
Expand Down