Skip to content
Merged
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
28 changes: 28 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: 2
updates:
- package-ecosystem: uv
directory: /
schedule:
interval: cron
cronjob: 12 4 * * *
timezone: Europe/Warsaw
open-pull-requests-limit: 1
versioning-strategy: increase-if-necessary
allow:
- dependency-name: costs
dependency-type: all
- dependency-name: goal
dependency-type: all
- dependency-name: pfix
dependency-type: all
- dependency-name: code2llm
dependency-type: all
groups:
internal-packages:
patterns:
- costs
- goal
- pfix
- code2llm
commit-message:
prefix: deps
29 changes: 29 additions & 0 deletions .github/internal-dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schema": "goal.internal-dependencies/v1",
"packages": [
{
"name": "costs",
"repository": "semcod/costs",
"registry": "pypi",
"versioning": "semver"
},
{
"name": "goal",
"repository": "semcod/goal",
"registry": "pypi",
"versioning": "semver"
},
{
"name": "pfix",
"repository": "semcod/pfix",
"registry": "pypi",
"versioning": "semver"
},
{
"name": "code2llm",
"repository": "semcod/code2llm",
"registry": "pypi",
"versioning": "semver"
}
]
}
36 changes: 36 additions & 0 deletions .github/workflows/internal-dependency-freshness.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Internal dependency freshness

on:
schedule:
- cron: "47 5 * * *"
workflow_dispatch:
pull_request:
paths:
- pyproject.toml
- uv.lock
- .github/internal-dependencies.json
- .github/workflows/internal-dependency-freshness.yml

permissions:
contents: read

jobs:
freshness:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- name: Install released checker
run: python -m pip install "goal==2.2.0"
- name: Verify published stable targets
run: goal dependencies --catalog .github/internal-dependencies.json --check > dependency-freshness.json
- name: Retain freshness evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: dependency-freshness
path: dependency-freshness.json
if-no-files-found: ignore
30 changes: 30 additions & 0 deletions .github/workflows/test-locked.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Locked tests

on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.13"]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- run: python -m pip install uv
- name: Install locked test dependencies
run: uv sync --locked --extra dev --extra click --extra rich --python "${{ matrix.python-version }}"
- name: Test supported Python versions
run: uv run --no-sync python -m pytest -q
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,3 +430,7 @@ _Last updated by [taskill](https://github.com/oqlos/taskill) at 2026-04-25 18:20
> No changes since the last taskill run: there are no new commits and no changed files. TODO.md remains unchanged.

<!-- taskill:status:end -->

## Dependency maintenance

See [dependency updates and Python tool groups](docs/dependencies.md) for locked tests, daily updates and freshness checks.
28 changes: 28 additions & 0 deletions docs/dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Internal dependency updates

This repository owns its dependency configuration and this guide. The shared checker is maintained in [semcod/goal](https://github.com/semcod/goal/blob/84f18540d14c24cc8ff5b7f202d2874344779ecc/docs/internal-dependencies.md). Documentation follows the repository ownership principle in [wellmanifest/docs](https://github.com/wellmanifest/docs/blob/f64de5806577769672ebc1730d2e144b4c7671ec/README.md).

## Python support and tools

Application Python support remains `>=3.10`. Goal is used as a development/release tool; source inspection found no Goal imports or executable invocation in the application Python code. Its old declarations (runtime, dev) moved to an `automation` dependency group requiring Python >=3.12. The normal dev/test installation remains usable on the application's minimum Python version.

```sh
uv sync --locked --extra dev
uv sync --locked --group automation --python 3.12
```

The second command selects an automation environment; use a separate UV_PROJECT_ENVIRONMENT when keeping application and tool environments side by side. `clickmd` itself is excluded from the registry catalog when it is the local editable package.

## Daily updates and verification

[Dependabot configuration](../.github/dependabot.yml) checks the explicit internal package allowlist daily, including weekends, and groups updates in one PR. It includes transitive dependencies and may widen a manifest constraint when needed. Local or Git sources require separate review.

[Freshness CI](../.github/workflows/internal-dependency-freshness.yml) compares uv.lock with the highest published stable three-part versions using Goal 2.2.0. It runs daily, manually and on dependency PRs, has read-only repository permissions and retains JSON evidence. Resolver failures and mismatched targets stay visible. A successful audit says nothing about an already installed development or production environment.

[Locked tests](../.github/workflows/test-locked.yml) run on Python 3.10 and 3.13 before merge. Update creation does not grant merge approval. The `>=` declarations alone do not refresh uv.lock; environments must be synchronized after a tested update is merged.

## Delivery record

This change updates the internal packages to the registry targets observed on 2026-09-05, preserves application Python support and adds the scheduled checks above. Test and publication results are recorded in this repository's PR and Actions checks. The ecosystem rollout history is maintained in [costs documentation](https://github.com/semcod/costs/tree/main/docs/dependencies).

The minimum-Python test run also exposed invalid nested f-string syntax in JSON highlighting. The renderer now formats quoted keys and values with Python 3.10-compatible expressions; the existing renderer suite checks the behavior.
13 changes: 7 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ classifiers = [
"Typing :: Typed",
]
requires-python = ">=3.10"
dependencies = [
"goal>=2.1.218",
"costs>=0.1.20",
"pfix>=0.1.60",
]
dependencies = ["costs>=0.1.20", "pfix>=0.1.60"]

[project.optional-dependencies]
click = ["click>=8.0,<9.0"]
Expand All @@ -44,7 +40,6 @@ dev = [
"black>=23.0",
"build>=1.0",
"twine>=5.0",
"goal>=2.1.218",
"costs>=0.1.20",
"pfix>=0.1.60",
]
Expand Down Expand Up @@ -124,3 +119,9 @@ max_commits = 500

# Cost thresholds for badge colors (USD)
badge_color_thresholds = { low = 1.0, medium = 5.0, high = 10.0, critical = 50.0 }

[tool.uv.dependency-groups]
automation = {requires-python = ">=3.12"}

[dependency-groups]
automation = ["goal>=2.2.0"]
4 changes: 2 additions & 2 deletions src/clickmd/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,8 @@ def _highlight_yaml(self, line: str) -> str:

def _highlight_json(self, line: str) -> str:
result = line
result = re.sub(r'"([^"]+)":', lambda m: f"{self._c('cyan', f'\"{m.group(1)}\"')}:" , result)
result = re.sub(r':\s*"([^"]*)"', lambda m: f": {self._c('green', f'\"{m.group(1)}\"')}" , result)
result = re.sub(r'"([^"]+)":', lambda m: self._c("cyan", m.group(0)[:-1]) + ":", result)
result = re.sub(r':\s*"([^"]*)"', lambda m: ": " + self._c("green", '"' + m.group(1) + '"'), result)
result = re.sub(r":\s*(\d+)", lambda m: f": {self._c('magenta', m.group(1))}" , result)
result = re.sub(r":\s*(true|false)", lambda m: f": {self._c('yellow', m.group(1))}" , result)
result = re.sub(r":\s*null", f": {self._c('gray', 'null')}", result)
Expand Down
50 changes: 27 additions & 23 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading