Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:

- name: Build app bundle
run: |
QT_QPA_PLATFORM=offscreen python tools/create_icon.py --png-iconset assets/AppIcon.iconset
QT_QPA_PLATFORM=offscreen python tools/create_icon.py --source assets/app-icon-source.png --macos-iconset assets/AppIcon.iconset
iconutil -c icns assets/AppIcon.iconset -o assets/pdfreader_by_sparsh.icns
pyinstaller --windowed --onedir --noupx --name "OpenReader" --argv-emulation --icon "assets/pdfreader_by_sparsh.icns" main.py

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ jobs:

- name: Build macOS app
run: |
QT_QPA_PLATFORM=offscreen python tools/create_icon.py --png-iconset assets/AppIcon.iconset
QT_QPA_PLATFORM=offscreen python tools/create_icon.py --source assets/app-icon-source.png --macos-iconset assets/AppIcon.iconset
iconutil -c icns assets/AppIcon.iconset -o assets/pdfreader_by_sparsh.icns
pyinstaller --windowed --onedir --noupx --name "OpenReader" --argv-emulation --icon "assets/pdfreader_by_sparsh.icns" main.py

Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## v1.2.1 — First Public Microsoft Store Release Candidate — 2026-06-18

- **Version:** Bumped `__version__` to `1.2.1`.
- **MSIX version:** `1.2.1.0`.
- **Purpose:** First public Microsoft Store release candidate.
- **UI/Branding only:** New application icon (1024×1024 source). No architectural changes.
- **Assets regenerated:** Windows .ico, MSIX brand images (44×44, 71×71, 150×150, 310×150, 620×300), macOS .iconset.
- **About dialog cleaned up:** Removed beta/dev/validation wording. Shows clean "OpenReader — Version 1.2.1 — Release Notes".
- **Frozen identity unchanged:** `SparshSam.OpenReader`, `CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0`, PFN `SparshSam.OpenReader_yh0byntbzd2qw`.

## v1.2.0-beta.6 — MSIX Update Validation — 2026-06-18

- **Version:** Bumped `__version__` to `1.2.0-beta.6-dev`.
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ OpenReader is a **stable, local-first desktop PDF utility** built with Python, P

The app is intentionally local-first: PDFs are opened, rendered, searched, merged, split, annotated, and compressed on your computer — no uploads, no accounts, no telemetry.

**v1.2.0-beta.6** (current release) validates the MSIX update pipeline ahead of Microsoft Store submission. Windows distribution uses MSIX/App Installer with Windows-native updates — the app never replaces itself. The beta.5 → beta.6 in-place MSIX upgrade has been confirmed on Windows 11. See the [changelog](CHANGELOG.md) and [roadmap](ROADMAP.md) for what's new and what's next.
**v1.2.1** (current release) is the first public Microsoft Store release candidate. Windows distribution uses MSIX/App Installer with Windows-native updates — the app never replaces itself. See the [changelog](CHANGELOG.md) and [roadmap](ROADMAP.md) for what's new and what's next.

## Download

Expand All @@ -64,11 +64,11 @@ Windows may show a SmartScreen warning because community builds are not code-sig

**v1.2.0 update change:** In-app self-updating has been removed. OpenReader now uses **Windows-native updates** — the app never downloads or runs installers.

- **Existing v1.0.x and v1.1.x users must manually install a v1.2.0 beta MSIX once.** Future updates are handled by Windows App Installer or the Microsoft Store.
- **Existing v1.0.x and v1.1.x users** must manually install a v1.2.0+ MSIX once. Future updates are handled by the Microsoft Store or Windows App Installer.
- **v1.2.0+ users:** Windows App Installer manages updates on launch and in the background. The app's Help → Check for Updates opens the GitHub Releases page in your browser.
- Source builds should be updated with `git pull` and rebuilt locally.

> **⚠️ Production auto-updates via App Installer are not yet proven.** The beta.5 → beta.6 in-place MSIX upgrade has been validated locally with test signing, but the hosted App Installer workflow (automatic updates from a web endpoint) and Microsoft Store-managed updates require a Store submission. Until then, users update by downloading the latest MSIX from GitHub and installing manually.
> **ℹ️ Microsoft Store-managed updates** will provide automatic updates after Store approval. Until then, users update by downloading the latest MSIX from GitHub Releases and installing manually (Developer Mode required for unsigned packages).

## Features

Expand Down Expand Up @@ -331,14 +331,13 @@ sudo pacman -S tesseract tesseract-data-eng
- [x] Add App Installer template for Windows-managed updates
- [x] Update GitHub Actions workflow to build MSIX
- [x] Add architecture docs (`docs/windows-distribution.md`, `docs/updater-architecture.md`)
- [x] Validate MSIX install and in-place upgrade (beta.5 → beta.6, confirmed on Windows 11)
- [ ] **Store submission**next milestone. Store signing replaces self-procured code-signing cert.
- [x] Validate MSIX install and in-place upgrade (confirmed on Windows 11)
- [x] Store submission — v1.2.1 is the first Microsoft Store release candidate

### Near-Term
Items in active or planned development.

- **Local AI summarization** — generate document summaries and extract key points using a local LLM (e.g. Ollama, llama.cpp); no data ever leaves your machine
- **Microsoft Store release** — signed MSIX distribution through the Microsoft Store, removing SmartScreen warnings and enabling Store-managed automatic updates
- **Stronger sandboxing guidance** — documented approaches for running the app in an OS sandbox when opening documents from untrusted sources

### Long-Term Vision
Expand Down
19 changes: 10 additions & 9 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ OpenReader uses semantic version tags to publish packaged builds.

## Version Source of Truth

- Development source keeps `__version__` in `main.py` as a `-dev` version.
- Packaged release builds inject the release version from the Git tag.
- Tags must use the format `vMAJOR.MINOR.PATCH`, for example `v1.2.0`.
- The injected runtime version removes the leading `v`, so `v1.2.0` becomes `__version__ = "1.2.0"` in packaged builds.
- `__version__` in `main.py` is the canonical source. Set it to the next release version.
- Tags must use the format `vMAJOR.MINOR.PATCH`, for example `v1.2.1`.
- The injected runtime version removes the leading `v`, so `v1.2.1` becomes `__version__ = "1.2.1"` in packaged builds.
- CI injects the tag version for release builds via `scripts/inject_version.py`.

## Release Architecture (v1.2.0+)

Expand Down Expand Up @@ -45,8 +45,8 @@ no separate code-signing certificate is needed.
4. Create and push a semantic version tag:

```bash
git tag v1.2.0
git push origin v1.2.0
git tag v1.2.1
git push origin v1.2.1
```

5. GitHub Actions runs `.github/workflows/release.yml`.
Expand Down Expand Up @@ -97,9 +97,10 @@ curl https://api.github.com/repos/sparshsam/pdfreader-by-sparsh/releases/latest

The MSIX package is currently unsigned. The distribution plan is:

1. **Short term** — Submit the unsigned MSIX to the Microsoft Store. The Store
signs the package automatically with its Store identity.
2. **Beta/sideloading** — Unsigned MSIX from GitHub Releases requires Windows
1. **Microsoft Store** — Submit the unsigned MSIX to the Microsoft Store. The Store
signs the package automatically with its Store identity. **v1.2.1 is the first
Store release candidate.**
2. **Sideloading** — Unsigned MSIX from GitHub Releases requires Windows
Developer Mode. Local test-signing scripts are in `packaging/msix/`.
3. **No self-procured code-signing cert** — The Store handles production signing.
Do not purchase a separate code-signing certificate.
Expand Down
4 changes: 2 additions & 2 deletions VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ OpenReader follows [Semantic Versioning 2.0](https://semver.org/):

The current version is tracked in the `__version__` variable in `main.py`.

- **Source builds** — use a `-dev` suffix (e.g., `1.2.0-beta.2-dev`).
- **Packaged releases** — the version is injected from the Git tag during the release workflow (see `scripts/inject_version.py`).
- **Source builds** — update `__version__` in `main.py` to match the target release.
- **Packaged releases** — the version can be overridden from the Git tag during the CI release workflow (see `scripts/inject_version.py`).

## Tag Format

Expand Down
Binary file added assets/AppIcon.iconset/icon_128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_128x128@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_16x16@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_256x256@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_32x32@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/AppIcon.iconset/icon_512x512@2x.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/app-icon-source.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-150x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-310x150.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-44x44.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-620x300.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/icon-71x71.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/pdfreader_by_sparsh.ico
Binary file not shown.
8 changes: 6 additions & 2 deletions docs/msix-update-validation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# MSIX Update Validation Guide
# MSIX Update Validation Guide (Archived)

**Purpose:** Validate that MSIX updates work correctly for OpenReader.
> **ℹ️ Historical record.** MSIX beta validation (beta.5 → beta.6) completed
> successfully. v1.2.1 is the first Microsoft Store release candidate — Store-managed
> updates replace sideloaded MSIX update testing.

**Purpose:** Validate that MSIX updates work correctly for OpenReader (historical).

**Test versions:**
- v1.2.0-beta.5 (MSIX 1.2.0.5) — first installable MSIX baseline
Expand Down
16 changes: 8 additions & 8 deletions docs/store-submission-checklist.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Microsoft Store Submission Checklist — OpenReader

**Target version:** v1.2.0 stable (MSIX version `1.2.0.0`)
**Target version:** v1.2.1 stable (MSIX version `1.2.1.0`)
**Store ID:** `9MXDVW2645LL`
**PFN:** `SparshSam.OpenReader_yh0byntbzd2qw`
**Status:** 🔜 Ready for submission (privacy policy published)
**Privacy policy URL:** https://sparshsam.github.io/pdfreader-by-sparsh/privacy/
**Upload artifact:** `OpenReader.msix` from v1.2.0 GitHub Release (built by release.yml workflow)
**Upload artifact:** `OpenReader.msix` from v1.2.1 GitHub Release (built by release.yml workflow)

---

Expand All @@ -24,7 +24,7 @@ Get-AppxPackage SparshSam.OpenReader | Select Name, Version, PackageFamilyName
```text
Name Version PackageFamilyName
---- ------- -----------------
SparshSam.OpenReader 1.2.0.0 SparshSam.OpenReader_yh0byntbzd2qw
SparshSam.OpenReader 1.2.1.0 SparshSam.OpenReader_yh0byntbzd2qw
```

### 1.2 Manifest Audit
Expand All @@ -44,7 +44,7 @@ Select-Xml -Path .\msix-check\AppxManifest.xml -XPath "//*[local-name()='Identit

- [ ] `<Identity Name="SparshSam.OpenReader">`
- [ ] `<Publisher="CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0">`
- [ ] Version is `1.2.0.0`
- [ ] Version is `1.2.1.0`
- [ ] `<DisplayName>OpenReader</DisplayName>`
- [ ] `<PublisherDisplayName>Sparsh Sam</PublisherDisplayName>`
- [ ] Executable is `OpenReader.exe`
Expand Down Expand Up @@ -111,7 +111,7 @@ Start-Process "OpenReader"
1. Navigate to **Partner Center** → OpenReader → **Packages**
2. Upload the **unsigned** `OpenReader.msix` from the GitHub Release
3. The Store will automatically sign the package with its Store identity
4. Set `1.2.0.0` as the version in Partner Center (must match manifest)
4. Set `1.2.1.0` as the version in Partner Center (must match manifest)
5. Submit for certification

> **ℹ️** Upload the MSIX produced by the GitHub Actions release workflow directly.
Expand Down Expand Up @@ -150,7 +150,7 @@ Start-Process "OpenReader"
| **`runFullTrust` capability** | Store may ask why a desktop app needs full trust | Expected for Win32 desktop bridge apps. Document in submission notes: *"Desktop PDF reader using PySide6 — requires full trust for file system access and window management."* |
| **App description claims** | Store may reject if claims are unrealistic | Keep description factual and shipping-feature-only. Remove roadmap items from Store description. |
| **Unsplash/mock screenshots** | Store requires real app screenshots | Use actual app screenshots from `assets/` |
| **Version mismatch** | Upload rejected if manifest version ≠ Partner Center version | Verify `1.2.0.0` matches everywhere |
| **Version mismatch** | Upload rejected if manifest version ≠ Partner Center version | Verify `1.2.1.0` matches everywhere |
| **Store ID reuse** | Cannot reuse Store ID for a different app | Reserved ID `9MXDVW2645LL` is tied to OpenReader — do not reassign |

### 4.2 Certification Notes for Submission
Expand Down Expand Up @@ -203,7 +203,7 @@ Get-AppxPackage SparshSam.OpenReader | Select Name, Version, PackageFamilyName
```text
Name Version PackageFamilyName
---- ------- -----------------
SparshSam.OpenReader 1.2.0.0 SparshSam.OpenReader_yh0byntbzd2qw
SparshSam.OpenReader 1.2.1.0 SparshSam.OpenReader_yh0byntbzd2qw
```

### 5.3 Functional Smoke Test
Expand Down Expand Up @@ -249,7 +249,7 @@ Write-Host "Publisher check: $($matches.Count -gt 0 ? 'PASS' : 'FAIL')"
- [ ] Prepare Winget manifest for `SparshSam.OpenReader` (optional, medium priority)
- [ ] Monitor Partner Center certification report
- [ ] After acceptance: test Store install on clean Windows VM
- [ ] After acceptance: test Store upgrade over existing sideloaded beta.6
- [ ] After acceptance: test Store upgrade over existing sideloaded installation
- [ ] Update `README.md` to reflect Store availability
- [ ] Update `docs/windows-distribution.md` with Store channel details

Expand Down
8 changes: 1 addition & 7 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
)


__version__ = "1.2.0-beta.6-dev"
__version__ = "1.2.1"
GITHUB_REPO = "sparshsam/pdfreader-by-sparsh"
IPC_SERVER_NAME = "OpenReader-IPC"
RECENT_FILES_MAX = 10
Expand Down Expand Up @@ -2784,12 +2784,6 @@ def _show_about(self):
ver_label.setAlignment(Qt.AlignCenter)
layout.addWidget(ver_label)

# MSIX update validation label (beta.4)
msix_label = QLabel("<p style='color:#a6e3a1; font-size:11px; margin:0;'>"
"MSIX update validation &mdash; beta.6</p>")
msix_label.setAlignment(Qt.AlignCenter)
layout.addWidget(msix_label)

layout.addSpacing(8)

# Description
Expand Down
2 changes: 1 addition & 1 deletion packaging/msix/AppInstaller.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<MainPackage
Name="SparshSam.OpenReader"
Publisher="CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0"
Version="1.2.0.0"
Version="1.2.1.0"
ProcessorArchitecture="x64"
Uri="https://downloads.openreader.app/stable/OpenReader.msix" />

Expand Down
2 changes: 1 addition & 1 deletion packaging/msix/AppxManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<Identity
Name="SparshSam.OpenReader"
Publisher="CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0"
Version="1.2.0.0" />
Version="1.2.1.0" />

<Properties>
<DisplayName>OpenReader</DisplayName>
Expand Down
26 changes: 9 additions & 17 deletions packaging/msix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,11 @@ MSIX follows a `major.minor.patch.build` version scheme.

| Git Tag | MSIX Version | Description |
|---------|--------------|-------------|
| `v1.2.0-beta.1` | `1.2.0.0` | Beta release |
| `v1.2.0` | `1.2.0.0` | Stable release (same as beta) |
| `v1.2.1` | `1.2.1.0` | Patch release |
| `v1.2.0` | `1.2.0.0` | Initial MSIX release |
| `v1.2.1` | `1.2.1.0` | First Microsoft Store release candidate |

The CI workflow automatically extracts the version from the Git tag and injects it
into the manifest as `{tag}.0` (padded to 4 parts). Source builds use `1.2.0.0`
as the development version.
into the manifest as `{tag}.0` (padded to 4 parts).

## Visual Assets

Expand Down Expand Up @@ -217,22 +215,16 @@ identity exactly: `CN=E6186421-BF8A-47E0-A89C-0F513DFF91C0`.
# 1. Install the test certificate (requires admin)
.\packaging\msix\install-test-cert.ps1

# 2. Install beta.3 MSIX (baseline)
# Double-click OpenReader.msix from v1.2.0-beta.3 release

# 3. Install beta.4 MSIX (update test)
# Double-click OpenReader.msix from v1.2.0-beta.4 release
# Windows should perform an in-place upgrade
# 2. Install the MSIX package
# Double-click OpenReader.msix from the target release
```

### What to Verify

After installing the beta.3 MSIX and updating to beta.4:

- [ ] MSIX installs without Developer Mode
- [ ] Update is **in-place** (not side-by-side)
- [ ] Package Family Name remains `SparshSam.OpenReader_yh0byntbzd2qw`
- [ ] About dialog shows the beta.4 release label
- [ ] MSIX installs without Developer Mode (when test-signed)
- [ ] Package Family Name is `SparshSam.OpenReader_yh0byntbzd2qw`
- [ ] New branding appears in Start Menu and taskbar
- [ ] About dialog shows the correct version
- [ ] Previous settings (theme, recent files) persist
- [ ] No duplicate application entries in Start Menu or Apps list
- [ ] PDF file associations remain intact
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
PySide6==6.11.1
PyMuPDF==1.27.2.3
pyinstaller==6.20.0
Pillow>=10.0.0
Loading