rekordbox-edit 0.7.0.dev71__tar.gz → 0.7.0.dev72__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.
- rekordbox_edit-0.7.0.dev72/.github/actions/build-release-notes/action.yml +25 -0
- rekordbox_edit-0.7.0.dev72/.github/actions/build-release-notes/build_release_notes.py +169 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/CHANGELOG.md +2 -1
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/PKG-INFO +1 -1
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/pyproject.toml +3 -3
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/uv.lock +1 -1
- rekordbox_edit-0.7.0.dev71/.github/actions/build-release-notes/action.yml +0 -88
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.agent-style/RULES.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.agent-style/claude-code.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/commit-check/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/commitizen-bump/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/commitizen-bump/commitizen-bump.sh +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/e2e/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/install/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/lint/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/test/action.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/workflows/cd.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/workflows/ci.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/workflows/publish.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/workflows/release.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.gitignore +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.pre-commit-config.yaml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.python-version +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.readthedocs.yaml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/AGENTS.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/CLAUDE.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/CONTRIBUTING.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/LICENSE +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/Makefile +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/README.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/codecov.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docker-compose.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/api.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/commands/convert.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/commands/edit.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/commands/search.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/faqs.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/filtering.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/index.md +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/docs/stylesheets/extra.css +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/mkdocs.yml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/_click.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/api/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/api/_utils.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/api/convert.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/api/edit.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/api/search.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/_utils.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/convert.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/edit.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/main.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/cli/search.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/display.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/logger.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/models.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/query.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/rekordbox_edit/utils.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/renovate.json5 +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/ruff.toml +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/api/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/api/test_convert.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/api/test_edit.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/api/test_search.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/api/test_utils.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/test_convert.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/test_edit.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/test_main.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/test_search.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/cli/test_utils.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/conftest.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/Dockerfile +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/__init__.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[macos].json +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/__snapshots__/test_journey/test_search_full_json_snapshot[windows].json +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/__snapshots__/test_journey.ambr +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/conftest.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/01-flac-44_1k-16b.flac +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/02-flac-96k-24b.flac +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/03-alac-44_1k-16b.m4a +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/04-alac-48k-24b.m4a +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/05-aiff-44_1k-16b.aiff +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/06-wav-96k-24b.wav +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/07-mp3-44_1k-320cbr.mp3 +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/08-mp3-44_1k-v0vbr.mp3 +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/09-aac-44_1k-256kbps.m4a +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/audio/10-/303/274/303/261/303/256c/303/266d/303/251-flac-44_1k-16b.flac" +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/macos/master.6.8.6.db +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/windows/master.6.8.6.db +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/test_journey.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/test_display.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/test_logger.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/test_models.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/test_query.py +0 -0
- {rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/test_utils.py +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: "Build Release Notes"
|
|
2
|
+
description: "Generate categorized, per-commit release notes with each commit's PR resolved and its author credited"
|
|
3
|
+
inputs:
|
|
4
|
+
from_tag:
|
|
5
|
+
description: "Tag to start the changelog range from (exclusive). Leave empty for full history."
|
|
6
|
+
required: false
|
|
7
|
+
default: ""
|
|
8
|
+
to_tag:
|
|
9
|
+
description: "Tag to end the changelog range at (inclusive)"
|
|
10
|
+
required: true
|
|
11
|
+
github_token:
|
|
12
|
+
description: "GitHub token for API access"
|
|
13
|
+
required: true
|
|
14
|
+
runs:
|
|
15
|
+
using: "composite"
|
|
16
|
+
steps:
|
|
17
|
+
- name: Generate release notes
|
|
18
|
+
shell: bash
|
|
19
|
+
run: python3 "${GITHUB_ACTION_PATH}/build_release_notes.py"
|
|
20
|
+
env:
|
|
21
|
+
FROM_TAG: ${{ inputs.from_tag }}
|
|
22
|
+
TO_TAG: ${{ inputs.to_tag }}
|
|
23
|
+
OUTPUT_FILE: release-notes.md
|
|
24
|
+
REPO: ${{ github.repository }}
|
|
25
|
+
GH_TOKEN: ${{ inputs.github_token }}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Build categorized release notes from commits, linking each commit's PR.
|
|
3
|
+
|
|
4
|
+
Lists one entry per commit (not per PR) between ``FROM_TAG`` (exclusive) and
|
|
5
|
+
``TO_TAG`` (inclusive). Each entry links the pull request that introduced the
|
|
6
|
+
commit and credits its author. The PR (number and author login) is resolved via
|
|
7
|
+
``GET /repos/{repo}/commits/{sha}/pulls``, which works for both squash and
|
|
8
|
+
rebase merges. Commits with no associated PR fall back to a short-SHA reference
|
|
9
|
+
and the git author name.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
import subprocess
|
|
18
|
+
import sys
|
|
19
|
+
from dataclasses import dataclass, field
|
|
20
|
+
|
|
21
|
+
# Category matchers, evaluated in order; first match wins. Mirrors the
|
|
22
|
+
# conventional-commit types accepted by the project's commitizen schema.
|
|
23
|
+
_BREAKING_TITLE = re.compile(r"^(BREAKING(\(.*\))?:|(\w+)?(\(.*\))?!:)")
|
|
24
|
+
_BREAKING_BODY = re.compile(r"BREAKING[\- ]CHANGE")
|
|
25
|
+
_CATEGORY_TITLE_RULES: list[tuple[str, re.Pattern[str]]] = [
|
|
26
|
+
("## Features", re.compile(r"^feat(\(.*\))?:")),
|
|
27
|
+
("## Fixes", re.compile(r"^fix(?!\(deps\))(\(.*\))?:")),
|
|
28
|
+
(
|
|
29
|
+
"## Chores",
|
|
30
|
+
re.compile(
|
|
31
|
+
r"^(chore(?!\(deps\))|refactor|ci|docs|style|perf|test|build)(\(.*\))?:"
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
("## Dependency Updates", re.compile(r"^(chore|fix)\(deps\):")),
|
|
35
|
+
]
|
|
36
|
+
_BREAKING_TITLE_HEADER = "## Breaking Changes"
|
|
37
|
+
_UNCATEGORIZED_HEADER = "## Uncategorized"
|
|
38
|
+
_CATEGORY_ORDER = [
|
|
39
|
+
_BREAKING_TITLE_HEADER,
|
|
40
|
+
"## Features",
|
|
41
|
+
"## Fixes",
|
|
42
|
+
"## Chores",
|
|
43
|
+
"## Dependency Updates",
|
|
44
|
+
_UNCATEGORIZED_HEADER,
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
# Commits that are noise in a changelog: merge commits are dropped at the
|
|
48
|
+
# ``git log`` level (--no-merges); version-bump commits are filtered here.
|
|
49
|
+
_SKIP_SUBJECT = re.compile(r"^bump:")
|
|
50
|
+
# A trailing "(#NN)" left by squash merges, stripped so it is not duplicated
|
|
51
|
+
# alongside the resolved reference.
|
|
52
|
+
_TRAILING_PR = re.compile(r"\s*\(#\d+\)\s*$")
|
|
53
|
+
|
|
54
|
+
_RECORD_SEP = "\x1e"
|
|
55
|
+
_FIELD_SEP = "\x1f"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dataclass
|
|
59
|
+
class Commit:
|
|
60
|
+
sha: str
|
|
61
|
+
subject: str
|
|
62
|
+
body: str
|
|
63
|
+
author: str
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@dataclass
|
|
67
|
+
class Category:
|
|
68
|
+
header: str
|
|
69
|
+
lines: list[str] = field(default_factory=list)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _run(args: list[str]) -> subprocess.CompletedProcess[str]:
|
|
73
|
+
return subprocess.run(args, capture_output=True, text=True, encoding="utf-8")
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def read_commits(from_tag: str, to_tag: str) -> list[Commit]:
|
|
77
|
+
rng = f"{from_tag}..{to_tag}" if from_tag else to_tag
|
|
78
|
+
fmt = _FIELD_SEP.join(["%H", "%s", "%b", "%an"]) + _RECORD_SEP
|
|
79
|
+
result = _run(["git", "log", "--no-merges", f"--format={fmt}", rng])
|
|
80
|
+
if result.returncode != 0:
|
|
81
|
+
raise SystemExit(f"git log failed for range '{rng}': {result.stderr.strip()}")
|
|
82
|
+
|
|
83
|
+
commits: list[Commit] = []
|
|
84
|
+
for record in result.stdout.split(_RECORD_SEP):
|
|
85
|
+
record = record.strip("\n")
|
|
86
|
+
if not record:
|
|
87
|
+
continue
|
|
88
|
+
sha, subject, body, author = (record.split(_FIELD_SEP) + ["", "", ""])[:4]
|
|
89
|
+
commits.append(
|
|
90
|
+
Commit(
|
|
91
|
+
sha=sha,
|
|
92
|
+
subject=subject.strip(),
|
|
93
|
+
body=body.strip(),
|
|
94
|
+
author=author.strip(),
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
return commits
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def resolve_pr(repo: str, sha: str) -> tuple[int, str] | None:
|
|
101
|
+
"""Return the (number, author_login) of a commit's PR, or None if unresolved."""
|
|
102
|
+
result = _run(["gh", "api", f"repos/{repo}/commits/{sha}/pulls"])
|
|
103
|
+
if result.returncode != 0 or not result.stdout.strip():
|
|
104
|
+
return None
|
|
105
|
+
try:
|
|
106
|
+
prs = json.loads(result.stdout)
|
|
107
|
+
except json.JSONDecodeError:
|
|
108
|
+
return None
|
|
109
|
+
merged = [pr for pr in prs if pr.get("merged_at")]
|
|
110
|
+
chosen = merged[0] if merged else (prs[0] if prs else None)
|
|
111
|
+
if not chosen:
|
|
112
|
+
return None
|
|
113
|
+
login = (chosen.get("user") or {}).get("login", "")
|
|
114
|
+
return chosen["number"], login
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def categorize(commit: Commit) -> str:
|
|
118
|
+
if _BREAKING_TITLE.match(commit.subject) or _BREAKING_BODY.search(commit.body):
|
|
119
|
+
return _BREAKING_TITLE_HEADER
|
|
120
|
+
for header, pattern in _CATEGORY_TITLE_RULES:
|
|
121
|
+
if pattern.match(commit.subject):
|
|
122
|
+
return header
|
|
123
|
+
return _UNCATEGORIZED_HEADER
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def render_line(commit: Commit, repo: str) -> str:
|
|
127
|
+
subject = _TRAILING_PR.sub("", commit.subject)
|
|
128
|
+
pr = resolve_pr(repo, commit.sha)
|
|
129
|
+
if pr is not None:
|
|
130
|
+
number, login = pr
|
|
131
|
+
credit = f"#{number} by @{login}" if login else f"#{number}"
|
|
132
|
+
return f"- {subject} ({credit})"
|
|
133
|
+
return f"- {subject} ({commit.sha[:7]} by {commit.author})"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def build_notes(commits: list[Commit], repo: str) -> str:
|
|
137
|
+
categories = {header: Category(header) for header in _CATEGORY_ORDER}
|
|
138
|
+
for commit in commits:
|
|
139
|
+
if _SKIP_SUBJECT.match(commit.subject):
|
|
140
|
+
continue
|
|
141
|
+
categories[categorize(commit)].lines.append(render_line(commit, repo))
|
|
142
|
+
|
|
143
|
+
sections = [
|
|
144
|
+
f"{cat.header}\n" + "\n".join(cat.lines)
|
|
145
|
+
for header in _CATEGORY_ORDER
|
|
146
|
+
if (cat := categories[header]).lines
|
|
147
|
+
]
|
|
148
|
+
return "\n\n".join(sections) if sections else "_No changes._"
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def main() -> None:
|
|
152
|
+
to_tag = os.environ.get("TO_TAG", "").strip()
|
|
153
|
+
if not to_tag:
|
|
154
|
+
raise SystemExit("TO_TAG is required")
|
|
155
|
+
from_tag = os.environ.get("FROM_TAG", "").strip()
|
|
156
|
+
repo = os.environ.get("REPO") or os.environ.get("GITHUB_REPOSITORY", "")
|
|
157
|
+
if not repo:
|
|
158
|
+
raise SystemExit("REPO (or GITHUB_REPOSITORY) is required")
|
|
159
|
+
output_file = os.environ.get("OUTPUT_FILE", "release-notes.md")
|
|
160
|
+
|
|
161
|
+
commits = read_commits(from_tag, to_tag)
|
|
162
|
+
notes = build_notes(commits, repo)
|
|
163
|
+
with open(output_file, "w", encoding="utf-8") as handle:
|
|
164
|
+
handle.write(notes + "\n")
|
|
165
|
+
print(notes, file=sys.stderr)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
if __name__ == "__main__":
|
|
169
|
+
main()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
## v0.7.0.
|
|
1
|
+
## v0.7.0.dev72 (2026-07-31)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
- ci: more precise changelogs on releases
|
|
4
5
|
- chore: update AGENTS.md
|
|
5
6
|
- docs: pave FAQ page based on convert + analysis research
|
|
6
7
|
- feat(convert): verify source codec against FileType before converting
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rekordbox-edit
|
|
3
|
-
Version: 0.7.0.
|
|
3
|
+
Version: 0.7.0.dev72
|
|
4
4
|
Summary: Tools for managing and modifying a RekordBox library en-masse
|
|
5
5
|
Project-URL: Homepage, https://github.com/jviall/rekordbox-edit
|
|
6
6
|
Project-URL: Repository, https://github.com/jviall/rekordbox-edit
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rekordbox-edit"
|
|
7
|
-
version = "0.7.0.
|
|
7
|
+
version = "0.7.0.dev72"
|
|
8
8
|
description = "Tools for managing and modifying a RekordBox library en-masse"
|
|
9
9
|
authors = [{ name = "James Viall", email= "jamesviall@pm.me"}]
|
|
10
10
|
license = "MIT"
|
|
@@ -91,8 +91,8 @@ message_template = "{{change_type}}{{scope}}: {{message}}"
|
|
|
91
91
|
example = "feat(convert): add new conversion feature"
|
|
92
92
|
schema = "<type>(<scope>): <body>"
|
|
93
93
|
schema_pattern = "^(BREAKING|feat|fix|refactor|ci|test|docs|chore)(\\([^)]*\\))?!?: .+"
|
|
94
|
-
bump_pattern = "^(BREAKING|feat|fix|perf|hotfix|refactor)"
|
|
95
|
-
bump_map = { "BREAKING" = "MAJOR", "feat" = "MINOR", "fix" = "PATCH", "refactor" = "PATCH" }
|
|
94
|
+
bump_pattern = "^((BREAKING[\\-\\ ]CHANGE|BREAKING|feat|fix|perf|hotfix|refactor)(\\(.+\\))?!?):"
|
|
95
|
+
bump_map = { "^.+!$" = "MAJOR", "^BREAKING" = "MAJOR", "^feat" = "MINOR", "^fix" = "PATCH", "^refactor" = "PATCH" }
|
|
96
96
|
|
|
97
97
|
[[tool.commitizen.customize.questions]]
|
|
98
98
|
type = "list"
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
name: "Build Release Notes"
|
|
2
|
-
description: "Generate categorized release notes from conventional commits between two tags"
|
|
3
|
-
inputs:
|
|
4
|
-
from_tag:
|
|
5
|
-
description: "Tag to start the changelog range from (exclusive)"
|
|
6
|
-
required: true
|
|
7
|
-
to_tag:
|
|
8
|
-
description: "Tag to end the changelog range at (inclusive)"
|
|
9
|
-
required: true
|
|
10
|
-
github_token:
|
|
11
|
-
description: "GitHub token for API access"
|
|
12
|
-
required: true
|
|
13
|
-
runs:
|
|
14
|
-
using: "composite"
|
|
15
|
-
steps:
|
|
16
|
-
- uses: mikepenz/release-changelog-builder-action@c9bcd8238b6f41e05561348339429d360b1c0247 # v6.2.3
|
|
17
|
-
with:
|
|
18
|
-
outputFile: release-notes.md
|
|
19
|
-
configurationJson: |
|
|
20
|
-
{
|
|
21
|
-
"categories": [
|
|
22
|
-
{
|
|
23
|
-
"title": "## Breaking Changes",
|
|
24
|
-
"labels": [],
|
|
25
|
-
"rules": [
|
|
26
|
-
{
|
|
27
|
-
"pattern": "^(\\w+)?(\\(.*\\))?!:",
|
|
28
|
-
"on_property": "title"
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"title": "## Features",
|
|
34
|
-
"labels": [],
|
|
35
|
-
"rules": [
|
|
36
|
-
{
|
|
37
|
-
"pattern": "^feat(\\(.*\\))?:",
|
|
38
|
-
"on_property": "title"
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"title": "## Fixes",
|
|
44
|
-
"labels": [],
|
|
45
|
-
"rules": [
|
|
46
|
-
{
|
|
47
|
-
"pattern": "^fix(?!\\(deps\\))(\\(.*\\))?:",
|
|
48
|
-
"on_property": "title"
|
|
49
|
-
}
|
|
50
|
-
]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"title": "## Chores",
|
|
54
|
-
"labels": [],
|
|
55
|
-
"rules": [
|
|
56
|
-
{
|
|
57
|
-
"pattern": "^(chore(?!\\(deps\\))|refactor|ci|docs|style|perf|test|build)(\\(.*\\))?:",
|
|
58
|
-
"on_property": "title"
|
|
59
|
-
}
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"title": "## Dependency Updates",
|
|
64
|
-
"labels": [],
|
|
65
|
-
"rules": [
|
|
66
|
-
{
|
|
67
|
-
"pattern": "^(chore|fix)\\(deps\\):",
|
|
68
|
-
"on_property": "title"
|
|
69
|
-
}
|
|
70
|
-
]
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
"exhaustive": true,
|
|
74
|
-
"sort": {
|
|
75
|
-
"order": "ASC",
|
|
76
|
-
"on_property": "title"
|
|
77
|
-
},
|
|
78
|
-
"template": "#{{CHANGELOG}}\n\n## Uncategorized\n#{{UNCATEGORIZED}}",
|
|
79
|
-
"pr_template": "- #{{TITLE}} (##{{NUMBER}} by @#{{AUTHOR}})",
|
|
80
|
-
"empty_template": "- No changes",
|
|
81
|
-
"tag_resolver": {
|
|
82
|
-
"method": "sort"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
fromTag: ${{ inputs.from_tag }}
|
|
86
|
-
toTag: ${{ inputs.to_tag }}
|
|
87
|
-
env:
|
|
88
|
-
GITHUB_TOKEN: ${{ inputs.github_token }}
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/commit-check/action.yml
RENAMED
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/commitizen-bump/action.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/.github/actions/install/action.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/__snapshots__/test_journey.ambr
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/macos/master.6.8.6.db
RENAMED
|
File without changes
|
{rekordbox_edit-0.7.0.dev71 → rekordbox_edit-0.7.0.dev72}/tests/e2e/fixtures/windows/master.6.8.6.db
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|