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
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:
parent
55f2ddf4b1
commit
1054266d0e
7 changed files with 150 additions and 17 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Application
|
||||
APP_NAME=WebDrop Bridge
|
||||
APP_VERSION=0.9.0
|
||||
APP_VERSION=0.9.1
|
||||
|
||||
# Web App
|
||||
WEBAPP_URL=file:///./webapp/index.html
|
||||
|
|
|
|||
15
CHANGELOG.md
Normal file
15
CHANGELOG.md
Normal 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.
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
||||
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 {
|
||||
$arguments = @($brandHelper, "local-release-data", "--platform", "windows", "--version", $Version)
|
||||
if ($Brands) {
|
||||
|
|
@ -127,10 +139,11 @@ $headers = @{
|
|||
|
||||
$releaseLookupUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases/tags/v$Version"
|
||||
$releaseUrl = "$ForgejoUrl/api/v1/repos/$Repo/releases"
|
||||
$releaseBody = Get-ReleaseNotes -Version $Version
|
||||
$releaseData = @{
|
||||
tag_name = "v$Version"
|
||||
name = "WebDropBridge v$Version"
|
||||
body = "Shared branded release for WebDrop Bridge v$Version"
|
||||
body = $releaseBody
|
||||
draft = $false
|
||||
prerelease = $false
|
||||
} | ConvertTo-Json
|
||||
|
|
|
|||
|
|
@ -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())")"
|
||||
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")
|
||||
if [ ${#BRANDS[@]} -gt 0 ]; then
|
||||
LOCAL_ARGS+=("--brands" "${BRANDS[@]}")
|
||||
|
|
@ -186,15 +190,19 @@ else
|
|||
fi
|
||||
|
||||
if [ -z "$RELEASE_ID" ]; then
|
||||
RELEASE_DATA=$(cat <<EOF
|
||||
{
|
||||
"tag_name": "v$VERSION",
|
||||
"name": "WebDropBridge v$VERSION",
|
||||
"body": "Shared branded release for WebDrop Bridge v$VERSION",
|
||||
"draft": false,
|
||||
"prerelease": false
|
||||
}
|
||||
EOF
|
||||
RELEASE_BODY="$(get_release_notes)"
|
||||
RELEASE_DATA=$(RELEASE_BODY="$RELEASE_BODY" VERSION="$VERSION" python3 - <<'PY'
|
||||
import json
|
||||
import os
|
||||
|
||||
print(json.dumps({
|
||||
"tag_name": f"v{os.environ['VERSION']}",
|
||||
"name": f"WebDropBridge v{os.environ['VERSION']}",
|
||||
"body": os.environ["RELEASE_BODY"],
|
||||
"draft": False,
|
||||
"prerelease": False,
|
||||
}))
|
||||
PY
|
||||
)
|
||||
HTTP_CODE=$(curl -s -o "$RELEASE_RESPONSE_FILE" -w "%{http_code}" -X POST \
|
||||
-H "Authorization: Basic $BASIC_AUTH" \
|
||||
|
|
|
|||
|
|
@ -33,17 +33,68 @@ def get_current_version() -> str:
|
|||
init_file = project_root / "src" / "webdrop_bridge" / "__init__.py"
|
||||
|
||||
if not init_file.exists():
|
||||
raise FileNotFoundError(
|
||||
f"Cannot find __init__.py at {init_file}"
|
||||
)
|
||||
raise FileNotFoundError(f"Cannot find __init__.py at {init_file}")
|
||||
|
||||
content = init_file.read_text(encoding="utf-8")
|
||||
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
|
||||
|
||||
if not match:
|
||||
raise ValueError(
|
||||
f"Could not find __version__ in {init_file}. "
|
||||
"Expected: __version__ = \"X.Y.Z\""
|
||||
f"Could not find __version__ in {init_file}. " 'Expected: __version__ = "X.Y.Z"'
|
||||
)
|
||||
|
||||
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."
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"""WebDrop Bridge - Qt-based desktop application for intelligent drag-and-drop file handling."""
|
||||
|
||||
__version__ = "0.9.0"
|
||||
__version__ = "0.9.1"
|
||||
__author__ = "WebDrop Team"
|
||||
__license__ = "MIT"
|
||||
|
||||
|
|
|
|||
46
tests/unit/test_version_utils.py
Normal file
46
tests/unit/test_version_utils.py
Normal 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()
|
||||
Loading…
Add table
Add a link
Reference in a new issue