feat: Update version to 0.9.1, enhance release notes generation, and add changelog
Some checks are pending
Tests & Quality Checks / Test on Python 3.11 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-1 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.10 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.11-2 (push) Waiting to run
Tests & Quality Checks / Test on Python 3.12-2 (push) Waiting to run
Tests & Quality Checks / Build Artifacts (push) Blocked by required conditions
Tests & Quality Checks / Build Artifacts-1 (push) Blocked by required conditions

This commit is contained in:
claudi 2026-04-15 17:00:28 +02:00
parent 55f2ddf4b1
commit 1054266d0e
7 changed files with 150 additions and 17 deletions

View file

@ -2,7 +2,7 @@
# Application # Application
APP_NAME=WebDrop Bridge APP_NAME=WebDrop Bridge
APP_VERSION=0.9.0 APP_VERSION=0.9.1
# Web App # Web App
WEBAPP_URL=file:///./webapp/index.html WEBAPP_URL=file:///./webapp/index.html

15
CHANGELOG.md Normal file
View file

@ -0,0 +1,15 @@
# Changelog
All notable changes to this project will be documented in this file.
## [0.9.1] - 2026-04-15
### Changed
- Improved release publishing so release descriptions can be generated from the changelog.
- Updated the release workflow to use a clearer, user-facing summary for update information.
- Added "in App" Branding Management instead of using separated Brand Builds.
### Fixed
- Removed the generic placeholder release description from published releases.
- Added a reliable fallback message when no detailed notes are available.
- instead of using "Profiles" and "Configurations" use setups for more clarity.

View file

@ -34,6 +34,18 @@ function Get-CurrentVersion {
return (& $pythonExe -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$projectRoot/build/scripts').resolve())); from version_utils import get_current_version; print(get_current_version())").Trim() return (& $pythonExe -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$projectRoot/build/scripts').resolve())); from version_utils import get_current_version; print(get_current_version())").Trim()
} }
function Get-ReleaseNotes {
param([string]$Version)
$notes = & $pythonExe -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$projectRoot/build/scripts').resolve())); from version_utils import get_release_notes; print(get_release_notes('$Version'))"
if ($LASTEXITCODE -ne 0) {
return "## WebDrop Bridge v$Version`n`nThis release package contains the latest improvements, fixes, and installer updates for this version."
}
return ($notes | Out-String).Trim()
}
function Get-LocalReleaseData { function Get-LocalReleaseData {
$arguments = @($brandHelper, "local-release-data", "--platform", "windows", "--version", $Version) $arguments = @($brandHelper, "local-release-data", "--platform", "windows", "--version", $Version)
if ($Brands) { if ($Brands) {
@ -127,10 +139,11 @@ $headers = @{
$releaseLookupUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases/tags/v$Version" $releaseLookupUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases/tags/v$Version"
$releaseUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases" $releaseUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases"
$releaseBody = Get-ReleaseNotes -Version $Version
$releaseData = @{ $releaseData = @{
tag_name = "v$Version" tag_name = "v$Version"
name = "WebDropBridge v$Version" name = "WebDropBridge v$Version"
body = "Shared branded release for WebDrop Bridge v$Version" body = $releaseBody
draft = $false draft = $false
prerelease = $false prerelease = $false
} | ConvertTo-Json } | ConvertTo-Json

View file

@ -40,6 +40,10 @@ if [ -z "$VERSION" ]; then
VERSION="$(python3 -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$PROJECT_ROOT/build/scripts').resolve())); from version_utils import get_current_version; print(get_current_version())")" VERSION="$(python3 -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$PROJECT_ROOT/build/scripts').resolve())); from version_utils import get_current_version; print(get_current_version())")"
fi fi
get_release_notes() {
python3 -c "from pathlib import Path; import sys; sys.path.insert(0, str(Path(r'$PROJECT_ROOT/build/scripts').resolve())); from version_utils import get_release_notes; print(get_release_notes('$VERSION'))"
}
LOCAL_ARGS=("$BRAND_HELPER" "local-release-data" "--platform" "macos" "--version" "$VERSION") LOCAL_ARGS=("$BRAND_HELPER" "local-release-data" "--platform" "macos" "--version" "$VERSION")
if [ ${#BRANDS[@]} -gt 0 ]; then if [ ${#BRANDS[@]} -gt 0 ]; then
LOCAL_ARGS+=("--brands" "${BRANDS[@]}") LOCAL_ARGS+=("--brands" "${BRANDS[@]}")
@ -186,15 +190,19 @@ else
fi fi
if [ -z "$RELEASE_ID" ]; then if [ -z "$RELEASE_ID" ]; then
RELEASE_DATA=$(cat <<EOF RELEASE_BODY="$(get_release_notes)"
{ RELEASE_DATA=$(RELEASE_BODY="$RELEASE_BODY" VERSION="$VERSION" python3 - <<'PY'
"tag_name": "v$VERSION", import json
"name": "WebDropBridge v$VERSION", import os
"body": "Shared branded release for WebDrop Bridge v$VERSION",
"draft": false, print(json.dumps({
"prerelease": false "tag_name": f"v{os.environ['VERSION']}",
} "name": f"WebDropBridge v{os.environ['VERSION']}",
EOF "body": os.environ["RELEASE_BODY"],
"draft": False,
"prerelease": False,
}))
PY
) )
HTTP_CODE=$(curl -s -o "$RELEASE_RESPONSE_FILE" -w "%{http_code}" -X POST \ HTTP_CODE=$(curl -s -o "$RELEASE_RESPONSE_FILE" -w "%{http_code}" -X POST \
-H "Authorization: Basic $BASIC_AUTH" \ -H "Authorization: Basic $BASIC_AUTH" \

View file

@ -33,17 +33,68 @@ def get_current_version() -> str:
init_file = project_root / "src" / "webdrop_bridge" / "__init__.py" init_file = project_root / "src" / "webdrop_bridge" / "__init__.py"
if not init_file.exists(): if not init_file.exists():
raise FileNotFoundError( raise FileNotFoundError(f"Cannot find __init__.py at {init_file}")
f"Cannot find __init__.py at {init_file}"
)
content = init_file.read_text(encoding="utf-8") content = init_file.read_text(encoding="utf-8")
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content) match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
if not match: if not match:
raise ValueError( raise ValueError(
f"Could not find __version__ in {init_file}. " f"Could not find __version__ in {init_file}. " 'Expected: __version__ = "X.Y.Z"'
"Expected: __version__ = \"X.Y.Z\""
) )
return match.group(1) return match.group(1)
def extract_release_notes(changelog_content: str, version: str) -> str | None:
"""Extract the notes for a specific version from changelog content.
Args:
changelog_content: Full text of CHANGELOG.md
version: Version to extract, e.g. "0.9.1"
Returns:
The section content for that version, or None if not found.
"""
version_header = re.compile(
rf"^##\s*\[?{re.escape(version)}\]?(?:\s*-\s*.+)?\s*$",
re.MULTILINE,
)
match = version_header.search(changelog_content)
if not match:
return None
section_start = match.end()
next_header = re.search(r"^##\s+", changelog_content[section_start:], re.MULTILINE)
section_end = section_start + next_header.start() if next_header else len(changelog_content)
section = changelog_content[section_start:section_end].strip()
return section or None
def get_release_notes(version: str, project_root: Path | None = None) -> str:
"""Build a readable release body for publishing.
Prefers the matching version section from CHANGELOG.md. If no changelog
entry exists yet, falls back to a generic but user-facing description.
Args:
version: Release version string.
project_root: Optional project root override for testing.
Returns:
Release notes text suitable for Forgejo/GitHub release bodies.
"""
root = project_root or get_project_root()
changelog_file = root / "CHANGELOG.md"
if changelog_file.exists():
content = changelog_file.read_text(encoding="utf-8")
notes = extract_release_notes(content, version)
if notes:
return f"## WebDrop Bridge v{version}\n\n{notes}"
return (
f"## WebDrop Bridge v{version}\n\n"
"This release package contains the latest improvements, fixes, "
"and installer updates for this version."
)

View file

@ -1,6 +1,6 @@
"""WebDrop Bridge - Qt-based desktop application for intelligent drag-and-drop file handling.""" """WebDrop Bridge - Qt-based desktop application for intelligent drag-and-drop file handling."""
__version__ = "0.9.0" __version__ = "0.9.1"
__author__ = "WebDrop Team" __author__ = "WebDrop Team"
__license__ = "MIT" __license__ = "MIT"

View file

@ -0,0 +1,46 @@
"""Tests for build script version utilities."""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "build" / "scripts"))
from version_utils import get_release_notes
class TestReleaseNotes:
"""Test release note extraction for published releases."""
def test_get_release_notes_from_changelog(self, tmp_path):
"""Extract only the selected version section from the changelog."""
changelog = tmp_path / "CHANGELOG.md"
changelog.write_text(
"""## [0.9.1] - 2026-04-15
### Added
- Better update text
- New installer checks
### Fixed
- Upload retries
## [0.9.0] - 2026-04-01
### Added
- Older changes
""",
encoding="utf-8",
)
notes = get_release_notes("0.9.1", project_root=tmp_path)
assert "Better update text" in notes
assert "New installer checks" in notes
assert "Older changes" not in notes
def test_get_release_notes_uses_fallback_when_missing(self, tmp_path):
"""Return a readable fallback when no changelog entry exists."""
notes = get_release_notes("0.9.1", project_root=tmp_path)
assert "WebDrop Bridge v0.9.1" in notes
assert "release package" in notes.lower()