Skip to content

Commit 83d88b3

Browse files
committed
feat: add initial structured-data t-string backends and release automation
1 parent 5fb21ea commit 83d88b3

10,381 files changed

Lines changed: 85115 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: Bug report
3+
about: Report a problem in the JSON, TOML, YAML, or bindings layers
4+
title: ""
5+
labels: bug
6+
assignees: ""
7+
---
8+
9+
## Summary
10+
11+
Describe the bug clearly and concisely.
12+
13+
## Reproduction
14+
15+
Provide a minimal template and the exact call that triggers the issue.
16+
17+
```python
18+
from json_tstring import render_text
19+
20+
value = "example"
21+
print(render_text(t'{"value": {value}}'))
22+
```
23+
24+
## Expected behavior
25+
26+
Describe what you expected to happen.
27+
28+
## Environment
29+
30+
- OS:
31+
- Python version:
32+
- Package version(s):
33+
- Backend/profile:
34+
35+
## Additional context
36+
37+
Include traceback output, rendered text, or links to related issues if helpful.
38+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
name: Feature request
3+
about: Suggest an API, parser, conformance, or tooling improvement
4+
title: ""
5+
labels: enhancement
6+
assignees: ""
7+
---
8+
9+
## Problem
10+
11+
Describe the current limitation or workflow problem.
12+
13+
## Proposed solution
14+
15+
Describe the behavior or API you would like to see.
16+
17+
## Alternatives considered
18+
19+
Describe any workarounds or alternative approaches you have considered.
20+
21+
## Additional context
22+
23+
Include examples, related specs, or prior art if relevant.
24+

.github/dependabot.yaml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: github-actions
4+
directory: "/"
5+
schedule:
6+
interval: weekly
7+
day: monday
8+
time: "10:00"
9+
timezone: Asia/Tokyo
10+
11+
- package-ecosystem: cargo
12+
directory: "/rust"
13+
schedule:
14+
interval: weekly
15+
day: monday
16+
time: "10:00"
17+
timezone: Asia/Tokyo
18+
19+
- package-ecosystem: pip
20+
directory: "/"
21+
schedule:
22+
interval: weekly
23+
day: monday
24+
time: "10:00"
25+
timezone: Asia/Tokyo
26+
27+
- package-ecosystem: pip
28+
directory: "/json-tstring"
29+
schedule:
30+
interval: weekly
31+
day: monday
32+
time: "10:00"
33+
timezone: Asia/Tokyo
34+
35+
- package-ecosystem: pip
36+
directory: "/toml-tstring"
37+
schedule:
38+
interval: weekly
39+
day: monday
40+
time: "10:00"
41+
timezone: Asia/Tokyo
42+
43+
- package-ecosystem: pip
44+
directory: "/yaml-tstring"
45+
schedule:
46+
interval: weekly
47+
day: monday
48+
time: "10:00"
49+
timezone: Asia/Tokyo
50+
51+
- package-ecosystem: pip
52+
directory: "/tstring-core"
53+
schedule:
54+
interval: weekly
55+
day: monday
56+
time: "10:00"
57+
timezone: Asia/Tokyo
58+
59+
- package-ecosystem: pip
60+
directory: "/rust/python-bindings"
61+
schedule:
62+
interval: weekly
63+
day: monday
64+
time: "10:00"
65+
timezone: Asia/Tokyo

.github/scripts/wait_for_crate.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
3+
import json
4+
import sys
5+
import time
6+
import tomllib
7+
import urllib.error
8+
import urllib.request
9+
from pathlib import Path
10+
11+
12+
def workspace_version() -> str:
13+
cargo_toml = Path("rust/Cargo.toml")
14+
with cargo_toml.open("rb") as handle:
15+
data = tomllib.load(handle)
16+
return data["workspace"]["package"]["version"]
17+
18+
19+
def crate_is_visible(crate_name: str, version: str) -> bool:
20+
request = urllib.request.Request(
21+
f"https://crates.io/api/v1/crates/{crate_name}",
22+
headers={"User-Agent": "tstring-structured-data-release-check"},
23+
)
24+
with urllib.request.urlopen(request, timeout=15) as response:
25+
payload = json.load(response)
26+
return any(entry["num"] == version for entry in payload.get("versions", []))
27+
28+
29+
def main() -> int:
30+
if len(sys.argv) != 2:
31+
print("usage: wait_for_crate.py <crate-name>", file=sys.stderr)
32+
return 2
33+
34+
crate_name = sys.argv[1]
35+
version = workspace_version()
36+
deadline = time.time() + 900
37+
38+
while time.time() < deadline:
39+
try:
40+
if crate_is_visible(crate_name, version):
41+
print(f"{crate_name} {version} is visible on crates.io")
42+
return 0
43+
except urllib.error.URLError as err:
44+
print(f"crates.io lookup failed: {err}", file=sys.stderr)
45+
46+
print(f"waiting for {crate_name} {version} to appear on crates.io")
47+
time.sleep(15)
48+
49+
print(f"timed out waiting for {crate_name} {version} to appear on crates.io", file=sys.stderr)
50+
return 1
51+
52+
53+
if __name__ == "__main__":
54+
raise SystemExit(main())

.github/workflows/changelog.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Update CHANGELOG
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
jobs:
9+
update-changelog:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
steps:
14+
- uses: actions/checkout@v5
15+
with:
16+
ref: main
17+
token: ${{ secrets.PAT }}
18+
19+
- name: Get release info and update CHANGELOG
20+
env:
21+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
22+
run: |
23+
set -euo pipefail
24+
25+
TAG="${{ github.event.release.tag_name }}"
26+
DATE=$(gh release view "$TAG" --json publishedAt --jq '.publishedAt | split("T")[0]')
27+
BODY=$(gh release view "$TAG" --json body --jq '.body // ""')
28+
printf '%s\n' "$BODY" > release_body.md
29+
python3 scripts/validate_release_notes.py release_body.md
30+
31+
{
32+
echo "## [$TAG](https://github.com/${{ github.repository }}/releases/tag/$TAG) - $DATE"
33+
echo ""
34+
printf '%s\n' "$BODY"
35+
echo ""
36+
echo "---"
37+
echo ""
38+
} > new_entry.md
39+
40+
if [ ! -f CHANGELOG.md ]; then
41+
{
42+
echo "# Changelog"
43+
echo ""
44+
echo "All notable changes to this project are documented in this file."
45+
echo "This changelog is automatically generated from GitHub Releases."
46+
echo ""
47+
echo "---"
48+
echo ""
49+
} > CHANGELOG.md
50+
fi
51+
52+
awk '/^---$/ && !found {found=1; print > "header.md"; next} !found {print > "header.md"} found {print > "old_entries.md"}' CHANGELOG.md
53+
touch old_entries.md
54+
cat header.md new_entry.md old_entries.md > CHANGELOG.md
55+
rm -f header.md new_entry.md old_entries.md release_body.md
56+
57+
- name: Commit and push
58+
run: |
59+
git config user.name "github-actions[bot]"
60+
git config user.email "github-actions[bot]@users.noreply.github.com"
61+
git add CHANGELOG.md
62+
git diff --cached --quiet || git commit -m "docs: update CHANGELOG.md for ${{ github.event.release.tag_name }}"
63+
git push

.github/workflows/ci.yml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
name: Workspace CI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
10+
concurrency:
11+
group: workspace-ci-${{ github.ref }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
checks:
16+
runs-on: ubuntu-latest
17+
permissions:
18+
contents: read
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v5
22+
23+
- name: Set up uv
24+
uses: astral-sh/setup-uv@v7
25+
with:
26+
enable-cache: true
27+
python-version: "3.14"
28+
29+
- name: Set up Rust
30+
uses: dtolnay/rust-toolchain@1.94.0
31+
32+
- name: Sync development dependencies
33+
run: uv sync --group dev
34+
35+
- name: Run Rust tests
36+
run: PYO3_PYTHON="$GITHUB_WORKSPACE/.venv/bin/python3" cargo test --manifest-path rust/Cargo.toml --workspace --tests
37+
38+
- name: Run Python tests
39+
run: uv run --group dev pytest json-tstring/tests toml-tstring/tests yaml-tstring/tests -q
40+
41+
- name: Check formatting
42+
run: uv run --group dev ruff format --check json-tstring toml-tstring yaml-tstring tstring-core rust/python-bindings/python
43+
44+
- name: Run Ruff
45+
run: uv run --group dev ruff check json-tstring/src toml-tstring/src yaml-tstring/src tstring-core/src rust/python-bindings/python/tstring_bindings
46+
47+
- name: Run type checks
48+
run: uv run --group dev ty check json-tstring/src json-tstring/tests toml-tstring/src toml-tstring/tests yaml-tstring/src yaml-tstring/tests tstring-core/src rust/python-bindings/python
49+
50+
- name: Build distributions
51+
run: |
52+
uv build tstring-core --out-dir dist
53+
uv build json-tstring --out-dir dist
54+
uv build toml-tstring --out-dir dist
55+
uv build yaml-tstring --out-dir dist
56+
uv build rust/python-bindings --out-dir dist
57+
58+
- name: Check distribution metadata
59+
run: uvx twine check dist/*
60+
61+
- name: Upload distributions
62+
uses: actions/upload-artifact@v4
63+
with:
64+
name: python-distributions
65+
path: dist/*
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: json-tstring CI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
paths:
7+
- ".github/workflows/json-tstring-ci.yml"
8+
- "conformance/**"
9+
- "json-tstring/**"
10+
- "rust/**"
11+
- "tstring-core/**"
12+
pull_request:
13+
paths:
14+
- ".github/workflows/json-tstring-ci.yml"
15+
- "conformance/**"
16+
- "json-tstring/**"
17+
- "rust/**"
18+
- "tstring-core/**"
19+
20+
jobs:
21+
checks:
22+
runs-on: ubuntu-latest
23+
defaults:
24+
run:
25+
working-directory: json-tstring
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v5
29+
30+
- name: Set up uv
31+
uses: astral-sh/setup-uv@v7
32+
with:
33+
enable-cache: true
34+
python-version: "3.14"
35+
working-directory: json-tstring
36+
37+
- name: Set up Rust
38+
uses: dtolnay/rust-toolchain@1.94.0
39+
40+
- name: Sync development dependencies
41+
run: uv sync --group dev
42+
43+
- name: Check formatting
44+
run: uv run --group dev ruff format --check . ../tstring-core
45+
46+
- name: Run lint
47+
run: uv run --group dev ruff check . ../tstring-core
48+
49+
- name: Run type checker
50+
run: uv run --group dev ty check src tests ../tstring-core/src ../examples/_display.py ../examples/json_api_payload.py
51+
52+
- name: Run tests
53+
run: uv run --group dev pytest
54+
55+
- name: Run Rust parser tests
56+
run: PYO3_PYTHON="$GITHUB_WORKSPACE/.venv/bin/python3" cargo test --manifest-path ../rust/Cargo.toml -p tstring-json --tests

0 commit comments

Comments
 (0)