Skip to content

Commit f8e46e5

Browse files
authored
Merge pull request #70 from melodee-project/sph-2026-05-01.03
Add version bump script and update changelog and resources
2 parents 7b6945d + d97235f commit f8e46e5

41 files changed

Lines changed: 1403 additions & 255 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Built on .NET 10 with PostgreSQL and first-class container support, it's a great
3939
- **🎉 Party Mode**: Shared listening sessions with a collaborative queue and DJ/Listener roles
4040
- **🎧 User Device Profiles**: Per-user and per-device transcoding profiles for automatic codec/bitrate selection
4141
- **📜 Event Scripting Hooks**: JavaScript-based event scripting for customizing user authentication, media processing, and feature access
42-
- **🐳 Container Ready**: Full Docker/Podman support with PostgreSQL
42+
- **🐳 Pre-built Containers**: Multi-arch Docker images (linux/amd64, linux/arm64) published to GHCR — pull and run with `docker pull ghcr.io/melodee-project/melodee:latest`
4343

4444
## 🌐 Try the Demo
4545

@@ -133,6 +133,25 @@ python3 scripts/run-container-setup.py --start
133133

134134
The script handles preflight checks, runtime detection, secure configuration, building, and startup.
135135

136+
### Pre-built Container Images
137+
138+
Melodee publishes **pre-built, multi-arch images** (linux/amd64, linux/arm64) to GitHub Container Registry on every release. No build step required:
139+
140+
```bash
141+
# Pull the latest pre-built image
142+
docker pull ghcr.io/melodee-project/melodee:latest
143+
144+
# Or pin to a specific version
145+
docker pull ghcr.io/melodee-project/melodee:2.0.1
146+
```
147+
148+
To use pre-built images with compose, set the `MELODEE_IMAGE` environment variable before running `compose up`:
149+
150+
```bash
151+
export MELODEE_IMAGE=ghcr.io/melodee-project/melodee:latest
152+
docker compose up -d
153+
```
154+
136155
📖 **Full installation guide**: [melodee.org/installing](https://melodee.org/installing/)
137156

138157
### 📦 Updating Melodee

compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ services:
1818
retries: 5
1919

2020
melodee.blazor:
21-
image: localhost/melodee:latest
21+
image: ${MELODEE_IMAGE:-localhost/melodee:latest}
2222
build:
2323
context: .
2424
dockerfile: ${DOCKERFILE_PATH:-Dockerfile}

design/docs/VERSION_GUIDE.md

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# Melodee Version Guide
2+
3+
This document outlines how application versioning works in Melodee and the steps required to bump versions following [Semantic Versioning](https://semver.org/) (SemVer).
4+
5+
## Semantic Versioning Overview
6+
7+
Melodee uses the `MAJOR.MINOR.PATCH` format:
8+
9+
| Segment | When to Increment | Example |
10+
|---------|-------------------|---------|
11+
| **MAJOR** | Incompatible API changes, breaking UI/behavior changes, or major architectural shifts | `1.x.x``2.0.0` |
12+
| **MINOR** | New backward-compatible features, new endpoints, new UI pages | `1.2.x``1.3.0` |
13+
| **PATCH** | Bug fixes, security patches, performance improvements, documentation | `1.2.3``1.2.4` |
14+
15+
### Decision Guide
16+
17+
**Increment MAJOR when:**
18+
- Removing or changing existing API endpoints in a breaking way
19+
- Changing database schemas in a non-migratable way
20+
- Removing or renaming configuration settings without backward compatibility
21+
- Dropping support for existing client integrations (OpenSubsonic, Jellyfin-compatible API)
22+
- Major UI overhaul that changes established user workflows
23+
24+
**Increment MINOR when:**
25+
- Adding new API endpoints (non-breaking)
26+
- Adding new UI features or pages (e.g., Party Mode, Jukebox, Podcasts)
27+
- Adding new configuration settings with sensible defaults
28+
- Adding new plugin types or extensibility points
29+
- Adding new localization support
30+
31+
**Increment PATCH when:**
32+
- Fixing bugs in existing functionality
33+
- Updating dependencies for security patches
34+
- Performance optimizations that don't change behavior
35+
- UI/UX polish (styling, accessibility improvements)
36+
- Documentation updates
37+
- CI/CD pipeline fixes
38+
39+
## Current Versioning Architecture
40+
41+
Melodee has **two independent version tracks** that must be kept in sync during releases:
42+
43+
### Track 1: Assembly Version (.csproj files)
44+
45+
Used at runtime, displayed in the About page, and embedded in compiled binaries.
46+
47+
**Files (all 4 must be updated together):**
48+
49+
| File | Property | Current Value |
50+
|------|----------|---------------|
51+
| `src/Melodee.Blazor/Melodee.Blazor.csproj` | `VersionPrefix` | `2.0.0` |
52+
| `src/Melodee.Common/Melodee.Common.csproj` | `VersionPrefix` | `2.0.0` |
53+
| `src/Melodee.Cli/Melodee.Cli.csproj` | `VersionPrefix` | `2.0.0` |
54+
| `src/Melodee.Mql/Melodee.Mql.csproj` | `VersionPrefix` | `2.0.0` |
55+
56+
Each .csproj also defines:
57+
- `VersionSuffix` — auto-generated build timestamp (e.g., `build20260501165851`)
58+
- `AssemblyVersion``$(VersionPrefix).0` (e.g., `2.0.0.0`)
59+
- `FileVersion``$(VersionPrefix).0` (e.g., `2.0.0.0`)
60+
- `InformationalVersion``$(VersionPrefix)+$(VersionSuffix)` (e.g., `2.0.0+build20260501165851`)
61+
62+
The `AppVersionProvider` service strips the suffix and displays only the `VersionPrefix` (e.g., `2.0.0`) in the UI.
63+
64+
### Track 2: Docker Image Tags (GitHub Releases)
65+
66+
Docker images are published to `ghcr.io` and tagged based on **GitHub release tags**.
67+
68+
**Workflow:** `.github/workflows/docker-publish.yml`
69+
70+
**Trigger:** GitHub release published (or manual `workflow_dispatch`)
71+
72+
**Tag patterns:**
73+
- `{{version}}` — full SemVer (e.g., `2.0.0`)
74+
- `{{major}}.{{minor}}` — minor track (e.g., `2.0`)
75+
- `{{major}}` — major track (e.g., `2`)
76+
- `latest` — applied to every release
77+
78+
### Track 3: docs/VERSION (Orphaned)
79+
80+
The file `docs/VERSION` currently contains `0.0.31` and is **not referenced by any code, build, or CI pipeline**. It appears to be a legacy artifact. Consider removing it or integrating it into the release process.
81+
82+
## Step-by-Step Version Bump Procedure
83+
84+
### Prerequisites
85+
86+
- All changes for the release are merged to `main`
87+
- CI pipeline (`.github/workflows/dotnet.yml`) passes on `main`
88+
- You have write access to the repository
89+
90+
### Step 1: Update the Changelog
91+
92+
Edit `docs/pages/changelog.md` and:
93+
94+
1. Replace the `[Unreleased]` section header with the new version and today's date:
95+
```markdown
96+
## [X.Y.Z] - YYYY-MM-DD
97+
```
98+
99+
2. Add a fresh `[Unreleased]` section at the top for future entries:
100+
```markdown
101+
## [Unreleased]
102+
```
103+
104+
3. Categorize all changes since the last release using [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) types:
105+
106+
| Type | Use For |
107+
|------|---------|
108+
| **Added** | New features, endpoints, UI pages, configuration options |
109+
| **Changed** | Modifications to existing functionality or behavior |
110+
| **Deprecated** | Features that will be removed in a future release |
111+
| **Removed** | Features removed in this release |
112+
| **Fixed** | Bug fixes and error corrections |
113+
| **Security** | Vulnerability patches and security hardening |
114+
115+
4. Source changes from:
116+
- Git commit history since the last tag (`git log vX.Y.Z..HEAD --oneline`)
117+
- Merged PRs and their labels
118+
- The GitHub release draft notes
119+
120+
### Step 2: Update Assembly Versions
121+
122+
Edit the `VersionPrefix` in all four .csproj files:
123+
124+
```
125+
src/Melodee.Blazor/Melodee.Blazor.csproj
126+
src/Melodee.Common/Melodee.Common.csproj
127+
src/Melodee.Cli/Melodee.Cli.csproj
128+
src/Melodee.Mql/Melodee.Mql.csproj
129+
```
130+
131+
Change `<VersionPrefix>X.Y.Z</VersionPrefix>` to the new version.
132+
133+
> **Future improvement:** Centralize this in `Directory.Build.props` so all projects inherit a single version definition:
134+
> ```xml
135+
> <Project>
136+
> <PropertyGroup>
137+
> <MelodeeVersion>2.1.0</MelodeeVersion>
138+
> <VersionPrefix>$(MelodeeVersion)</VersionPrefix>
139+
> <VersionSuffix>build$([System.DateTime]::UtcNow.ToString("yyyyMMddHHmmss"))</VersionSuffix>
140+
> <AssemblyVersion>$(VersionPrefix).0</AssemblyVersion>
141+
> <FileVersion>$(VersionPrefix).0</FileVersion>
142+
> <InformationalVersion>$(VersionPrefix)+$(VersionSuffix)</InformationalVersion>
143+
> </PropertyGroup>
144+
> </Project>
145+
> ```
146+
147+
### Step 3: Commit and Open a PR
148+
149+
```bash
150+
git add docs/pages/changelog.md src/*/ docs/VERSION 2>/dev/null || true
151+
git commit -m "chore: release vX.Y.Z"
152+
git push origin <branch>
153+
```
154+
155+
Open a PR targeting `main`. The version bump is reviewed like any other change.
156+
157+
### Step 4: Merge and Tag
158+
159+
After the PR is approved and merged to `main`:
160+
161+
```bash
162+
git checkout main && git pull
163+
git tag -a vX.Y.Z -m "Release vX.Y.Z"
164+
git push origin vX.Y.Z
165+
```
166+
167+
> The tag **must** be created on `main` after merge so the `docker-publish.yml` workflow picks it up.
168+
169+
### Step 5: Create a GitHub Release
170+
171+
1. Go to **GitHub → Releases → Draft a new release**
172+
2. Select the tag `vX.Y.Z`
173+
3. Title: `vX.Y.Z`
174+
4. Description: Copy the changelog entries for this version from `docs/pages/changelog.md` (everything under the `## [X.Y.Z]` header down to the next `##` heading). Use the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) section headings:
175+
176+
```markdown
177+
### Added
178+
- New feature description
179+
180+
### Changed
181+
- Modified behavior description
182+
183+
### Fixed
184+
- Bug fix description
185+
186+
### Security
187+
- Security improvement description
188+
```
189+
190+
5. Click **Publish release**
191+
192+
### Step 6: Verify Docker Image Publication
193+
194+
After publishing the release, the `docker-publish.yml` workflow triggers automatically. Verify:
195+
196+
1. Check the **Actions** tab for the `Docker Publish` workflow run
197+
2. Confirm all platforms build successfully (`linux/amd64`, `linux/arm64`)
198+
3. Verify the multi-platform manifest is created
199+
200+
Pull and test the image:
201+
202+
```bash
203+
docker pull ghcr.io/<owner>/melodee:X.Y.Z
204+
```
205+
206+
### Step 7: Verify the About Page and Changelog
207+
208+
After deploying:
209+
210+
1. Navigate to the **About** page in the Melodee UI and confirm the displayed version matches the new `X.Y.Z`.
211+
2. Navigate to the **Changelog** page on the docs site (`/changelog/`) and confirm the new version entry is visible.
212+
213+
## Version Display Locations
214+
215+
| Location | Source | Format |
216+
|----------|--------|--------|
217+
| About page | `IAppVersionProvider.GetSemVerForDisplay()` | `2.0.0` (prefix only) |
218+
| Admin Dashboard → Server Stats | `Assembly.GetName().Version` | `2.0.0.0` |
219+
| Admin Doctor → Server Info | `Assembly.GetName().Version` | `2.0.0.0` |
220+
| Docker image tags | GitHub release tag | `2.0.0`, `2.0`, `2`, `latest` |
221+
| Assembly metadata | `InformationalVersion` | `2.0.0+build20260501165851` |
222+
223+
## API Versioning (Separate from App Version)
224+
225+
Melodee uses `Asp.Versioning.Mvc` for REST API versioning, which is **independent** of the application SemVer.
226+
227+
- Current API version: `v1`
228+
- Defined in `Program.cs` via `AddApiVersioning()`
229+
- Consumers specify version via URL segment (`/api/v1/...`) or `X-Api-Version` header
230+
- API version bumps are independent of application version bumps
231+
232+
## Automated Version Bumping (Future)
233+
234+
Consider adopting one of these tools for automated version management:
235+
236+
| Tool | Approach | Best For |
237+
|------|----------|----------|
238+
| **GitVersion** | Derives version from Git history/branches | Teams using GitFlow |
239+
| **MinVer** | Uses Git tags as version source | Simple tag-based releases |
240+
| **Nerdbank.GitVersioning** | `version.json` file + Git commits | Precise, deterministic builds |
241+
| **Conventional Commits + release-please** | Auto-generates changelog + releases from commit messages | Automated CI/CD pipelines |
242+
243+
Using **MinVer** as an example, you could replace all manual .csproj version properties with:
244+
245+
```xml
246+
<PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="all" />
247+
```
248+
249+
Then the version is derived entirely from Git tags (`v2.0.0` → assembly version `2.0.0`), eliminating the need to edit .csproj files during releases.

docs/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.31
1+
2.0.1

docs/_data/toc.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,6 @@
6565

6666
- title: About
6767
url: "about"
68+
links:
69+
- title: "Changelog"
70+
url: "changelog"

0 commit comments

Comments
 (0)