diff --git a/.github/macos-installer/conclusion.html b/.github/macos-installer/conclusion.html
new file mode 100644
index 0000000..9af15bc
--- /dev/null
+++ b/.github/macos-installer/conclusion.html
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+ Installation Successful
+
+ deepdiffdb has been installed to /usr/local/bin/deepdiffdb.
+
+ Open a new Terminal window and run:
+ deepdiffdb --version
+
+ Documentation & guides:
+ iamvirul.github.io/deepdiff-db
+
+
+
diff --git a/.github/macos-installer/distribution.xml b/.github/macos-installer/distribution.xml
new file mode 100644
index 0000000..a6654e3
--- /dev/null
+++ b/.github/macos-installer/distribution.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ __APP_TITLE__
+ com.iamvirul
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ deepdiffdb-component.pkg
+
+
diff --git a/.github/macos-installer/readme.html b/.github/macos-installer/readme.html
new file mode 100644
index 0000000..045751b
--- /dev/null
+++ b/.github/macos-installer/readme.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+ DeepDiff DB — Quick Start
+
+ System Requirements
+
+ - macOS 11 (Big Sur) or later
+ - Administrator password to install to
/usr/local/bin
+
+
+ After Installation
+ Open a new Terminal window and verify the installation:
+ deepdiffdb --version
+
+ Create a config file
+ deepdiffdb init
+
+ Run your first diff
+ deepdiffdb diff --html
+
+ Supported Databases
+
+ - MySQL
+ - PostgreSQL
+ - SQLite
+ - Microsoft SQL Server
+ - Oracle Database
+
+
+
+ Full documentation:
+ iamvirul.github.io/deepdiff-db
+
+
+
diff --git a/.github/macos-installer/welcome.html b/.github/macos-installer/welcome.html
new file mode 100644
index 0000000..0818329
--- /dev/null
+++ b/.github/macos-installer/welcome.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+ Welcome to DeepDiff DB
+
+ This installer will place the deepdiffdb command-line tool
+ in /usr/local/bin on the selected volume.
+
+ What this installer does:
+
+ - Installs the
deepdiffdb binary to /usr/local/bin/
+ - Makes it immediately available in your shell — no PATH changes needed
+
+
+ After installation, open a new Terminal window and run
+ deepdiffdb --version to confirm it is working.
+
+
+
diff --git a/.github/windows-installer.nsi b/.github/windows-installer.nsi
index 415f363..59a7de7 100644
--- a/.github/windows-installer.nsi
+++ b/.github/windows-installer.nsi
@@ -1,12 +1,16 @@
; DeepDiff DB — Windows Installer
; Built by the release workflow; __APP_VERSION__ is substituted at compile time.
;
-; Installs deepdiffdb.exe to %ProgramFiles%\DeepDiffDB, adds that directory
-; to the system PATH, and registers the app in Add/Remove Programs.
+; Uses NSIS Modern UI 2 (bundled with NSIS — no external plugins required).
+; Wizard pages: Welcome → Read Me → Directory → Installing → Finish
Unicode true
SetCompressor /SOLID lzma
+; ── Modern UI 2 ────────────────────────────────────────────────────────────
+!include "MUI2.nsh"
+
+; ── Defines ─────────────────────────────────────────────────────────────────
!define APP_NAME "DeepDiff DB"
!define APP_VERSION "__APP_VERSION__"
!define PUBLISHER "iamvirul"
@@ -15,19 +19,43 @@ SetCompressor /SOLID lzma
!define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\DeepDiffDB"
!define REGKEY "Software\DeepDiffDB"
+; ── MUI Settings ────────────────────────────────────────────────────────────
+!define MUI_ABORTWARNING ; confirm before aborting
+!define MUI_ABORTWARNING_TEXT "Are you sure you want to cancel the installation?"
+
+; Welcome page
+!define MUI_WELCOMEPAGE_TITLE "Welcome to DeepDiff DB ${APP_VERSION} Setup"
+!define MUI_WELCOMEPAGE_TEXT "This wizard will install DeepDiff DB ${APP_VERSION} on your computer.$\r$\n$\r$\nDeepDiff DB is a command-line tool for comparing databases, detecting schema drift, and generating safe SQL migration packs.$\r$\n$\r$\nClick Next to continue."
+
+; Finish page — offer to open the docs in a browser
+!define MUI_FINISHPAGE_TITLE "Installation Complete"
+!define MUI_FINISHPAGE_TEXT "DeepDiff DB ${APP_VERSION} has been installed.$\r$\n$\r$\nOpen a new Command Prompt or PowerShell window and run:$\r$\n$\r$\n deepdiffdb --version$\r$\n$\r$\nto verify the installation."
+!define MUI_FINISHPAGE_LINK "Open documentation"
+!define MUI_FINISHPAGE_LINK_LOCATION "${HOMEPAGE}"
+!define MUI_FINISHPAGE_NOREBOOTSUPPORT
+
+; ── Installer Pages ──────────────────────────────────────────────────────────
+!insertmacro MUI_PAGE_WELCOME
+!insertmacro MUI_PAGE_README "readme.txt" ; generated by workflow at build time
+!insertmacro MUI_PAGE_DIRECTORY
+!insertmacro MUI_PAGE_INSTFILES
+!insertmacro MUI_PAGE_FINISH
+
+; ── Uninstaller Pages ────────────────────────────────────────────────────────
+!insertmacro MUI_UNPAGE_CONFIRM
+!insertmacro MUI_UNPAGE_INSTFILES
+
+; ── Language ─────────────────────────────────────────────────────────────────
+!insertmacro MUI_LANGUAGE "English"
+
+; ── Metadata ─────────────────────────────────────────────────────────────────
Name "${APP_NAME} ${APP_VERSION}"
OutFile "deepdiff-db-v__APP_VERSION__-windows-amd64-installer.exe"
InstallDir "${INSTALL_DIR}"
InstallDirRegKey HKLM "${REGKEY}" "InstallDir"
RequestExecutionLevel admin
-; ── Pages ──────────────────────────────────────────────────────────────────
-Page directory
-Page instfiles
-UninstPage uninstConfirm
-UninstPage instfiles
-
-; ── Install ────────────────────────────────────────────────────────────────
+; ── Install ──────────────────────────────────────────────────────────────────
Section "DeepDiff DB" SecMain
SectionIn RO
SetOutPath "$INSTDIR"
@@ -42,8 +70,6 @@ Section "DeepDiff DB" SecMain
StrCpy $1 $0 "" -1 ; last char of current PATH
StrCmp $1 ";" 0 +2
StrCpy $0 $0 -1 ; strip trailing semicolon
- ; Check whether INSTDIR already appears (simple prefix/suffix check is fine
- ; because users rarely change the install location)
Push "$0"
Push "$INSTDIR"
Call StrContains
@@ -71,7 +97,7 @@ Section "DeepDiff DB" SecMain
WriteRegStr HKLM "${REGKEY}" "InstallDir" "$INSTDIR"
SectionEnd
-; ── Uninstall ──────────────────────────────────────────────────────────────
+; ── Uninstall ────────────────────────────────────────────────────────────────
Section "Uninstall"
Delete "$INSTDIR\deepdiffdb.exe"
Delete "$INSTDIR\README.md"
@@ -82,7 +108,6 @@ Section "Uninstall"
; Remove install dir from system PATH
ReadRegStr $0 HKLM \
"SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path"
- ; Strip "$INSTDIR;" and ";$INSTDIR" variants
Push "$0"
Push "$INSTDIR;"
Push ""
@@ -103,9 +128,8 @@ Section "Uninstall"
DeleteRegKey HKLM "${REGKEY}"
SectionEnd
-; ── Helper: StrContains ────────────────────────────────────────────────────
+; ── Helper: StrContains ──────────────────────────────────────────────────────
; Stack: [haystack] [needle] → [match-start or ""]
-; Searches haystack for needle; pushes "" if not found.
Function StrContains
Exch $1 ; needle
Exch
@@ -113,8 +137,8 @@ Function StrContains
Push $2
Push $3
Push $4
- StrLen $3 $1 ; needle length
- StrLen $4 $0 ; haystack length
+ StrLen $3 $1
+ StrLen $4 $0
IntOp $4 $4 - $3
StrCpy $2 0
loop:
@@ -137,7 +161,7 @@ Function StrContains
Push $R0
FunctionEnd
-; ── Helper: StrReplaceAll ──────────────────────────────────────────────────
+; ── Helper: StrReplaceAll ────────────────────────────────────────────────────
; Stack (top→bottom): [haystack] [find] [replace] → [result]
Function StrReplaceAll
Exch $2 ; replace
@@ -145,10 +169,10 @@ Function StrReplaceAll
Exch $1 ; find
Exch 2
Exch $0 ; haystack
- Push $3 ; working copy
- Push $4 ; needle length
- Push $5 ; result accumulator
- Push $6 ; position
+ Push $3
+ Push $4
+ Push $5
+ Push $6
StrCpy $5 ""
StrLen $4 $1
StrCpy $3 $0
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f4327d3..84cb355 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -49,8 +49,8 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
HOMEBREW_TAP_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
- macos-dmg:
- name: Build macOS DMG (${{ matrix.arch }})
+ macos-pkg:
+ name: Build macOS Installer (${{ matrix.arch }})
runs-on: macos-latest
needs: goreleaser # wait for the release to be created first
strategy:
@@ -82,30 +82,52 @@ jobs:
-o deepdiffdb \
./cmd/deepdiffdb
- - name: Create DMG
+ - name: Build .pkg installer
run: |
VERSION="${GITHUB_REF_NAME}"
- DMG_NAME="deepdiff-db-${VERSION}-darwin-${{ matrix.arch }}.dmg"
-
- # --- staging folder ---
+ VER_CLEAN="${VERSION#v}" # v1.4.1 → 1.4.1
+ ARCH="${{ matrix.arch }}"
+ PKG_NAME="deepdiff-db-${VERSION}-darwin-${ARCH}.pkg"
+ DMG_NAME="deepdiff-db-${VERSION}-darwin-${ARCH}.dmg"
+
+ # ── 1. Payload: mirrors the install layout on the target volume ──
+ # pkgbuild --install-location / means pkg-payload/ is the root.
+ # Binary lands at /usr/local/bin/deepdiffdb after install.
+ mkdir -p pkg-payload/usr/local/bin
+ cp deepdiffdb pkg-payload/usr/local/bin/deepdiffdb
+
+ # ── 2. Component package ─────────────────────────────────────────
+ pkgbuild \
+ --root pkg-payload \
+ --install-location / \
+ --identifier com.iamvirul.deepdiffdb \
+ --version "${VER_CLEAN}" \
+ deepdiffdb-component.pkg
+
+ # ── 3. Distribution XML — substitute version placeholders ────────
+ mkdir -p dist-resources
+ sed \
+ -e "s/__APP_VERSION__/${VER_CLEAN}/g" \
+ -e "s/__APP_TITLE__/DeepDiff DB ${VER_CLEAN}/g" \
+ .github/macos-installer/distribution.xml > dist-resources/distribution.xml
+
+ # Copy HTML resource pages referenced by the distribution XML
+ cp .github/macos-installer/welcome.html dist-resources/welcome.html
+ cp .github/macos-installer/readme.html dist-resources/readme.html
+ cp .github/macos-installer/conclusion.html dist-resources/conclusion.html
+
+ # ── 4. Distribution package (the installer wizard the user sees) ─
+ productbuild \
+ --distribution dist-resources/distribution.xml \
+ --resources dist-resources \
+ --package-path . \
+ "${PKG_NAME}"
+
+ # ── 5. Wrap the .pkg in a DMG for a familiar download experience ─
+ # Users mount the DMG → double-click the .pkg → wizard launches.
mkdir -p dmg-stage
- cp deepdiffdb dmg-stage/
- cp README.md dmg-stage/
- cp deepdiffdb.config.yaml.example dmg-stage/
-
- # Simple install helper
- cat > dmg-stage/install.sh << 'INSTALL'
- #!/usr/bin/env bash
- set -e
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
- DEST="/usr/local/bin/deepdiffdb"
- echo "Installing deepdiffdb → ${DEST}"
- sudo install -m 755 "${SCRIPT_DIR}/deepdiffdb" "${DEST}"
- echo "Installed: $(deepdiffdb --version)"
- INSTALL
- chmod +x dmg-stage/install.sh
-
- # Create read-only compressed DMG with hdiutil (built-in on macOS)
+ cp "${PKG_NAME}" dmg-stage/
+
hdiutil create \
-volname "DeepDiff DB ${VERSION}" \
-srcfolder dmg-stage \
@@ -150,21 +172,61 @@ jobs:
./cmd/deepdiffdb
- name: Install NSIS
- run: choco install nsis --no-progress -y
+ shell: bash
+ run: |
+ choco install nsis --no-progress -y
+ # Chocolatey's PATH update does not propagate to later steps.
+ # Append the NSIS directory explicitly so makensis is found.
+ echo "C:/Program Files (x86)/NSIS" >> "$GITHUB_PATH"
- - name: Prepare NSIS script
+ - name: Prepare NSIS script and resources
shell: bash
run: |
VERSION="${GITHUB_REF_NAME}"
- VER_CLEAN="${VERSION#v}" # strip leading 'v': v1.4.0 → 1.4.0
+ VER_CLEAN="${VERSION#v}" # strip leading 'v': v1.4.1 → 1.4.1
+
# Substitute the __APP_VERSION__ placeholder in the template
sed "s/__APP_VERSION__/${VER_CLEAN}/g" \
.github/windows-installer.nsi > installer.nsi
+
+ # MUI2 README page — must exist at makensis compile time.
+ # Plain text is sufficient; MUI2 renders it in a scrollable text box.
+ # <<-'EOF' strips leading tabs so YAML indentation doesn't bleed into
+ # the generated file; content lines below are indented with tabs.
+ cat > readme.txt <<-'EOF'
+ DeepDiff DB - Quick Start
+ =========================
+
+ After installation, open a new Command Prompt or PowerShell window and run:
+
+ deepdiffdb --version
+
+ Create a config file:
+
+ deepdiffdb init
+
+ Run your first diff:
+
+ deepdiffdb diff --html
+
+ Supported Databases
+ -------------------
+ MySQL, PostgreSQL, SQLite, Microsoft SQL Server, Oracle Database
+
+ Documentation
+ -------------
+ https://iamvirul.github.io/deepdiff-db/
+
+ Source Code
+ -----------
+ https://github.com/iamvirul/deepdiff-db
+ EOF
+
echo "INSTALLER_NAME=deepdiff-db-${VERSION}-windows-amd64-installer.exe" \
>> "$GITHUB_ENV"
- name: Compile installer
- shell: cmd
+ shell: bash
run: makensis installer.nsi
- name: Upload installer to GitHub release
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9926602..236188e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,12 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [1.4.2] - 2026-05-03
+
+### Added
+
+- **macOS `.pkg` installer wizard** — macOS release artifacts are now proper installer packages (`.pkg` inside a `.dmg`) built with `pkgbuild` + `productbuild`. Users get a full native installer wizard (Introduction, Read Me, Destination Select, Install, Summary) identical to the JDK installer experience. The binary is placed in `/usr/local/bin/deepdiffdb` on the selected volume with no manual PATH changes required.
+
+### Fixed
+
+- **Windows `makensis` not found** — The `choco install nsis` step did not propagate the NSIS directory to subsequent GitHub Actions steps. Fixed by appending `C:/Program Files (x86)/NSIS` to `$GITHUB_PATH` so `makensis` is resolved correctly.
+
## [1.4.1] - 2026-05-03
### Added
-- **macOS DMG release artifacts** — `darwin/amd64` and `darwin/arm64` DMGs are now published to every GitHub release alongside the existing tarballs. Each DMG includes the binary, `README.md`, `deepdiffdb.config.yaml.example`, and an `install.sh` helper that copies the binary to `/usr/local/bin`.
-- **Windows installer release artifact** — A native NSIS installer (`deepdiff-db-vX.Y.Z-windows-amd64-installer.exe`) is published to every GitHub release. It installs `deepdiffdb.exe` to `%ProgramFiles%\DeepDiffDB`, adds that directory to the system PATH (idempotent, no reboot required), registers the app in Add/Remove Programs, and includes a full uninstaller.
+- **macOS DMG release artifacts** — `darwin/amd64` and `darwin/arm64` DMGs published to every GitHub release alongside the existing tarballs.
+- **Windows installer release artifact** — A native NSIS installer (`deepdiff-db-vX.Y.Z-windows-amd64-installer.exe`) is published to every GitHub release. Installs `deepdiffdb.exe` to `%ProgramFiles%\DeepDiffDB`, adds that directory to the system PATH (idempotent, no reboot required), registers the app in Add/Remove Programs, and includes a full uninstaller.
## [1.4.0] - 2026-05-03
@@ -490,7 +500,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- PostgreSQL schema-aware queries
- MySQL foreign key check handling
-[Unreleased]: https://github.com/iamvirul/deepdiff-db/compare/v1.4.0...HEAD
+[Unreleased]: https://github.com/iamvirul/deepdiff-db/compare/v1.4.2...HEAD
+[1.4.2]: https://github.com/iamvirul/deepdiff-db/compare/v1.4.1...v1.4.2
[1.4.1]: https://github.com/iamvirul/deepdiff-db/compare/v1.4.0...v1.4.1
[1.4.0]: https://github.com/iamvirul/deepdiff-db/compare/v1.3.0...v1.4.0
[1.3.0]: https://github.com/iamvirul/deepdiff-db/compare/v1.2.0...v1.3.0