This document provides contributors and maintainers with the exact step-by-step instructions for bumping the product version, releasing new versions of FryPDF, and publishing the FryPdf.PluginSdk NuGet package.
FryPDF follows Semantic Versioning 2.0.0 (MAJOR.MINOR.PATCH):
- MAJOR: Breaking user-facing changes, major platform redesigns, or breaking plugin API changes.
- MINOR: New backward-compatible features (e.g. new plugin types, keyboard shortcut managers, viewer capabilities).
- PATCH: Backward-compatible bug fixes, performance optimizations, and UI refinements.
Important
Never blindly bump AssemblyVersion in PdfEditorApp.Core.csproj!
PdfEditorApp.Core carries a fixed AssemblyVersion of 1.0.0.0. This assembly defines the plugin contract. External plugins compiled against FryPdf.PluginSdk bind against this assembly identity.
If AssemblyVersion is changed with every release, previously compiled third-party plugins will fail with TypeLoadException or FileLoadException.
-
Bump
<Version>/<PackageVersion>: Moves with every release (e.g.0.1.1$\to$ 0.1.2or0.2.0). -
Bump
<AssemblyVersion>: Bump ONLY when making an intentional, breaking change to the core plugin contract interface.
When preparing a new release (e.g., bumping from 0.1.1 to X.Y.Z):
Update the default fallback <Version> property in both project files:
-
src/PdfEditorApp/PdfEditorApp.csproj:<Version Condition="'$(Version)' == ''">X.Y.Z</Version>
-
src/PdfEditorApp.Core/PdfEditorApp.Core.csproj:<Version Condition="'$(Version)' == ''">X.Y.Z</Version> <!-- Keep <AssemblyVersion>1.0.0.0</AssemblyVersion> unchanged unless breaking ABI -->
Ensure fallback strings match the new version:
src/PdfEditorApp/Plugins/Cli/HeadlessCliRunner.cs: Update the fallback string in--versionflag handling:var versionString = !string.IsNullOrWhiteSpace(infoVer) ? infoVer.Split('+')[0] : (assembly.GetName().Version?.ToString(3) ?? "X.Y.Z");
src/PdfEditorApp/ViewModels/HomeViewModel.cs: Update the fallback inAppVersion:return "X.Y.Z";
src/PdfEditorApp/ViewModels/MainViewModel.Palette.cs: Update the fallback inAppVersion:return "X.Y.Z";
(Note: LicensingPageView.axaml, AboutDialog.axaml, and HomeView.axaml bind dynamically to AppVersionShort / AppVersionDisplay and do not require manual editing).
packaging/windows/installer.iss:#ifndef MyAppVersion #define MyAppVersion "X.Y.Z" #endifpackaging/windows/msix/build-msix.ps1:param ( [string]$Version = "X.Y.Z", ...
docs/EXTERNAL_PLUGIN_DEVELOPMENT_GUIDE.md: Update the recommended package reference snippet:<PackageReference Include="FryPdf.PluginSdk" Version="X.Y.Z" PrivateAssets="all" />
Before committing and tagging, always perform local verification:
dotnet run --project src/PdfEditorApp -- --versionExpected output:
FryPDF version X.Y.Z (Plugin Architecture Edition)
Ensure all unit and integration tests pass without error or warnings:
dotnet test -c releasegit add -A
git commit -m "chore: bump product version to X.Y.Z for release"Release tags must follow the format vMAJOR.MINOR.PATCH:
git tag -a vX.Y.Z -m "Release vX.Y.Z: <brief summary of key features and fixes>"Push both the release commit on main and the release tag:
git push origin main
git push origin vX.Y.ZPushing a tag matching v* automatically triggers GitHub Actions workflows:
-
.github/workflows/release.yml:- Strips the
vprefix to extractX.Y.Z. - Computes the 4-part version (
X.Y.Z.0) for Windows binaries and MSIX packaging. - Runs full test suite on Ubuntu.
- Windows Runner: Builds win-x64 binaries, creates Inno Setup installer (
FryPDF-Setup-X.Y.Z.exe), builds & signs Windows MSIX package (FryPDF-X.Y.Z-x64.msix). - macOS Runner: Builds osx-arm64 self-contained binary, creates
.appbundle, ad-hoc codesigns, and packages DMG (FryPDF-X.Y.Z-arm64.dmg). - GitHub Release: Automatically creates a published release with release notes and attaches all installer artifacts.
- Strips the
-
.github/workflows/publish-sdk.yml:- Builds and packages
FryPdf.PluginSdk.nupkgand.snupkgwith versionX.Y.Z. - Publishes the updated SDK directly to NuGet.org using OIDC federation.
- Builds and packages