diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4dc2ecb..5a2a1b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -60,3 +60,27 @@ jobs: - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 + + github-release: + name: Publish GitHub Release + needs: publish + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Download distributions + uses: actions/download-artifact@v4 + with: + name: dist + path: dist/ + + - name: Create GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + --repo "${GITHUB_REPOSITORY}" \ + --title "${GITHUB_REF_NAME}" \ + --verify-tag \ + --notes "See [HISTORY.rst](https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_REF_NAME}/HISTORY.rst) for changelog." \ + dist/* diff --git a/HISTORY.rst b/HISTORY.rst index 19749dd..b443c97 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,15 @@ History ======= +1.3.1 (2026-09-09) +------------------ + +* Added ``max_length_unit`` to ``SchemaDiscoveryColumn``, typed by the new ``LengthUnit`` enum + (``chars`` or ``bytes``), reporting the unit a column's ``max_length`` is counted in. + It is ``None`` for results from older servers that do not report a unit. + +Requires server version 3.26.17 + 1.3.0 (2026-09-04) ------------------ diff --git a/RELEASING.rst b/RELEASING.rst index a2b40cb..473b3e6 100644 --- a/RELEASING.rst +++ b/RELEASING.rst @@ -68,31 +68,10 @@ Releasing to PyPI You can verify that the release appears at https://pypi.org/project/datamasque-python/, and Read the Docs has built the new tag at https://datamasque-python.readthedocs.io/. -5. Create the GitHub Release (see below). - -Creating the GitHub Release -=========================== - -Do this after the PyPI publish has succeeded, -so the release never points at a version nobody can install. - -1. On the repository home page, - find **Releases** in the right-hand sidebar under the *About* box, - and click it, - then **Draft a new release**. -2. **Choose a tag** — pick the existing tag you pushed as part of releasing to PyPI. - Don't let GitHub create a new one; the tag should already exist from the release flow. -3. Set the target to ``main``. -4. Title it the same as the tag, e.g. ``v1.2.2``. -5. Paste the ``HISTORY.rst`` entry for this version into the body, converted to Markdown. - **Generate release notes** is a reasonable starting point for the commit list, - but the hand-written changelog is what users read. -6. Leave *Set as a pre-release* unticked for a normal release. -7. Click **Publish release**. - -Creating releases can also be done from the ``gh`` CLI:: - - gh release create v1.2.2 --title v1.2.2 --notes-file notes.md +5. The GitHub Release is created automatically once the PyPI publish succeeds. + ``release.yml`` runs a ``github-release`` job that creates the release for the pushed tag, + attaches the built distributions, and links to ``HISTORY.rst`` at that tag for the changelog. + Nothing to do by hand; just confirm it appears under **Releases** on the repository home page. Releasing a dev build to TestPyPI ================================= diff --git a/datamasque/client/__init__.py b/datamasque/client/__init__.py index cd9fea7..ea8e0c9 100644 --- a/datamasque/client/__init__.py +++ b/datamasque/client/__init__.py @@ -73,6 +73,7 @@ ForeignKeyRef, InDataDiscoveryConfig, InDataDiscoveryRule, + LengthUnit, ReferencingForeignKey, RulesetGenerationRequest, RulesetGenerationWithRGConfigRequest, @@ -239,6 +240,7 @@ "InvalidRulesetError", "JsonPath", "LengthEntry", + "LengthUnit", "LengthsStatistics", "LicenseInfo", "Locator", diff --git a/datamasque/client/models/discovery.py b/datamasque/client/models/discovery.py index 3e5f1fb..bacbc8d 100644 --- a/datamasque/client/models/discovery.py +++ b/datamasque/client/models/discovery.py @@ -367,6 +367,13 @@ class ReferencingForeignKey(BaseModel): referencing_column: str # Dotted path: "schema.table.column". +class LengthUnit(Enum): + """The unit a column's declared width (`max_length`) is counted in.""" + + chars = "chars" + bytes = "bytes" + + class SchemaDiscoveryColumn(BaseModel): """Column-level data in a schema discovery result.""" @@ -374,6 +381,8 @@ class SchemaDiscoveryColumn(BaseModel): data_type: Optional[str] = None max_length: Optional[int] = None + # None when the server does not report a unit (older runs count chars). + max_length_unit: Optional[LengthUnit] = None foreign_keys: list[ForeignKeyRef] discovery_matches: list[DiscoveryMatch] numeric_precision: Optional[int] = None diff --git a/pyproject.toml b/pyproject.toml index 6a68cd1..c907a34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "datamasque-python" -version = "1.3.0" +version = "1.3.1" description = "Official Python client for the DataMasque data-masking API." authors = [ { name = "DataMasque Ltd" }, diff --git a/tests/test_discovery.py b/tests/test_discovery.py index f73c902..83f9348 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -21,6 +21,7 @@ FileRulesetGenerationRequest, FileRulesetGenerationWithRGConfigRequest, InDataDiscoveryConfig, + LengthUnit, RGConfig, RGConfigId, RulesetGenerationRequest, @@ -795,6 +796,22 @@ def test_schema_discovery_result_parses_safe_data_preview(): assert preview.statistics_common.count_distinct == 988 +def test_schema_discovery_result_parses_max_length_unit() -> None: + row = _schema_discovery_row(1, "name") + row["data"]["max_length"] = 10 + row["data"]["max_length_unit"] = "bytes" + result = SchemaDiscoveryResult.model_validate(row) + assert result.data.max_length == 10 + assert result.data.max_length_unit is LengthUnit.bytes + + +def test_schema_discovery_result_without_max_length_unit_is_none() -> None: + row = _schema_discovery_row(1, "name") + assert "max_length_unit" not in row["data"] + result = SchemaDiscoveryResult.model_validate(row) + assert result.data.max_length_unit is None + + def test_list_schema_discovery_results_follows_pagination(client): run_id = RunId(42) page1 = { diff --git a/uv.lock b/uv.lock index 0d45760..c53fc85 100644 --- a/uv.lock +++ b/uv.lock @@ -419,7 +419,7 @@ toml = [ [[package]] name = "datamasque-python" -version = "1.3.0" +version = "1.3.1" source = { editable = "." } dependencies = [ { name = "pydantic" },