name: Build Fritzing on Windows on: push: branches: [ master ] workflow_dispatch: env: QT_VERSION: '6.5.3' QT_ARCH: 'win64_msvc2019_64' QT_INSTALL_DIR: 'C:\Qt' jobs: build: runs-on: windows-2022 steps: # ── 0. Checkout repositories ────────────────────────────────────────── - name: Checkout fritzing-build uses: actions/checkout@v4 with: path: fritzing-build - name: Checkout fritzing-app uses: actions/checkout@v4 with: repository: fritzing/fritzing-app path: fritzing-app - name: Checkout fritzing-parts uses: actions/checkout@v4 with: repository: fritzing/fritzing-parts path: fritzing-parts # ── 1. Setup MSVC 2022 environment ──────────────────────────────────── - name: Setup MSVC environment uses: ilammy/msvc-dev-cmd@v1 with: arch: amd64 # ── 2. Install Qt via aqtinstall ────────────────────────────────────── - name: Cache Qt installation id: qt-cache uses: actions/cache@v4 with: path: ${{ env.QT_INSTALL_DIR }} key: qt-${{ env.QT_VERSION }}-${{ env.QT_ARCH }}-all - name: Install Qt via aqtinstall if: steps.qt-cache.outputs.cache-hit != 'true' run: | pip install aqtinstall aqt install-qt windows desktop ${{ env.QT_VERSION }} ${{ env.QT_ARCH }} ` -m all ` --outputdir ${{ env.QT_INSTALL_DIR }} shell: pwsh - name: Set Qt environment variables run: | $QtPath = "${{ env.QT_INSTALL_DIR }}\${{ env.QT_VERSION }}\msvc2019_64" echo "Qt6_DIR=$QtPath" >> $env:GITHUB_ENV echo "$QtPath\bin" >> $env:GITHUB_PATH echo "CMAKE_PREFIX_PATH=$QtPath" >> $env:GITHUB_ENV shell: pwsh # ── 3. Cache built dependencies ────────────────────────────────────── - name: Cache dependencies id: deps-cache uses: actions/cache@v4 with: path: | zlib libgit2 quazip-1.4 quazip-${{ env.QT_VERSION }}-1.4intuisphere Clipper1-6.4.2 boost_1_85_0 svgpp-1.3.1 ngspice-42 key: deps-manual-v1-${{ runner.os }} # ── 4. Build ZLib ───────────────────────────────────────────────────── - name: Download ZLib if: steps.deps-cache.outputs.cache-hit != 'true' run: | Invoke-WebRequest -Uri "https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz" ` -OutFile zlib.tar.gz tar -xzf zlib.tar.gz Rename-Item zlib-1.3 zlib Remove-Item zlib.tar.gz shell: pwsh - name: Build ZLib if: steps.deps-cache.outputs.cache-hit != 'true' working-directory: zlib run: | mkdir build cd build cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release .. nmake copy zconf.h .. shell: cmd # ── 5. Build libgit2 ────────────────────────────────────────────────── - name: Clone libgit2 if: steps.deps-cache.outputs.cache-hit != 'true' run: git clone --depth 1 https://github.com/libgit2/libgit2.git libgit2 shell: bash - name: Build libgit2 if: steps.deps-cache.outputs.cache-hit != 'true' working-directory: libgit2 run: | set ZLIB_ROOT=%GITHUB_WORKSPACE%\zlib mkdir build64 cd build64 cmake -G "NMake Makefiles" ^ -DCMAKE_BUILD_TYPE=Release ^ -DBUILD_SHARED_LIBS=OFF ^ -DUSE_BUNDLED_ZLIB=OFF ^ -DZLIB_LIBRARY="%ZLIB_ROOT%\build\zlibstatic.lib" ^ -DZLIB_INCLUDE_DIR="%ZLIB_ROOT%" ^ .. nmake mkdir Release copy git2.lib Release\ shell: cmd # ── 6. Build QuaZip ─────────────────────────────────────────────────── - name: Download QuaZip if: steps.deps-cache.outputs.cache-hit != 'true' run: | Invoke-WebRequest -Uri "https://github.com/stachenov/quazip/archive/refs/tags/v1.4.tar.gz" ` -OutFile quazip.tar.gz tar -xzf quazip.tar.gz # GitHub archives extract as quazip-1.4 by default Remove-Item quazip.tar.gz shell: pwsh - name: Build QuaZip if: steps.deps-cache.outputs.cache-hit != 'true' working-directory: quazip-1.4 run: | $ZlibRoot = "$env:GITHUB_WORKSPACE\zlib" $QtPath = "${{ env.QT_INSTALL_DIR }}\${{ env.QT_VERSION }}\msvc2019_64" New-Item -ItemType Directory -Force -Path build Push-Location build cmake -G "NMake Makefiles" ` -DCMAKE_PREFIX_PATH="$QtPath" ` -DZLIB_LIBRARY="$ZlibRoot\build\zlibstatic.lib" ` -DZLIB_INCLUDE_DIR="$ZlibRoot" ` -DCMAKE_BUILD_TYPE=Release .. nmake Pop-Location shell: pwsh - name: Setup QuaZip sibling directory if: steps.deps-cache.outputs.cache-hit != 'true' run: | $QuazipSibling = "quazip-${{ env.QT_VERSION }}-1.4intuisphere" New-Item -ItemType Directory -Force -Path "$QuazipSibling\lib" New-Item -ItemType Directory -Force -Path "$QuazipSibling\include\QuaZip-Qt6-1.4\quazip" # Copy built libraries Copy-Item "quazip-1.4\build\quazip\quazip1-qt6.lib" "$QuazipSibling\lib\" Copy-Item "quazip-1.4\build\quazip\quazip1-qt6.dll" "$QuazipSibling\lib\" -ErrorAction SilentlyContinue # Copy header files Copy-Item "quazip-1.4\quazip\*.h" "$QuazipSibling\include\QuaZip-Qt6-1.4\quazip\" shell: pwsh # ── 7. Setup Clipper ────────────────────────────────────────────────── - name: Download and build Clipper if: steps.deps-cache.outputs.cache-hit != 'true' run: | curl.exe -L -o clipper.zip "https://sourceforge.net/projects/polyclipping/files/clipper_ver6.4.2.zip/download" Expand-Archive -Path clipper.zip -DestinationPath clipper-src Remove-Item clipper.zip # Create the expected directory structure New-Item -ItemType Directory -Force -Path "Clipper1-6.4.2\include\polyclipping" New-Item -ItemType Directory -Force -Path "Clipper1-6.4.2\lib" # Find and copy source files $cppDir = Get-ChildItem -Path "clipper-src" -Recurse -Filter "clipper.hpp" | Select-Object -First 1 -ExpandProperty DirectoryName if ($cppDir) { Copy-Item "$cppDir\clipper.hpp" "Clipper1-6.4.2\include\polyclipping\" Copy-Item "$cppDir\clipper.cpp" "Clipper1-6.4.2\include\polyclipping\" } # Build clipper as a static library Push-Location "Clipper1-6.4.2" cl /c /O2 /EHsc /MD /Iinclude\polyclipping include\polyclipping\clipper.cpp lib /OUT:polyclipping.lib clipper.obj Move-Item polyclipping.lib lib\ Remove-Item clipper.obj -ErrorAction SilentlyContinue Pop-Location Remove-Item "clipper-src" -Recurse -Force -ErrorAction SilentlyContinue shell: pwsh # ── 8. Download header-only and pre-built dependencies ──────────────── - name: Download Boost if: steps.deps-cache.outputs.cache-hit != 'true' run: | Invoke-WebRequest -Uri "https://archives.boost.io/release/1.85.0/source/boost_1_85_0.tar.gz" ` -OutFile boost.tar.gz tar -xzf boost.tar.gz Remove-Item boost.tar.gz shell: pwsh - name: Download SVG++ if: steps.deps-cache.outputs.cache-hit != 'true' run: | Invoke-WebRequest -Uri "https://github.com/svgpp/svgpp/archive/refs/tags/v1.3.1.tar.gz" ` -OutFile svgpp.tar.gz tar -xzf svgpp.tar.gz Remove-Item svgpp.tar.gz shell: pwsh - name: Download ngspice if: steps.deps-cache.outputs.cache-hit != 'true' run: | curl.exe -L -o ngspice.7z "https://sourceforge.net/projects/ngspice/files/ng-spice-rework/old-releases/42/ngspice-42_dll_64.7z/download" 7z x ngspice.7z -ongspice-extract # Move contents to expected location if (Test-Path "ngspice-extract\Spice64_dll") { Move-Item "ngspice-extract\Spice64_dll" "ngspice-42" } elseif (Test-Path "ngspice-extract\ngspice-42") { Move-Item "ngspice-extract\ngspice-42" . } else { Rename-Item "ngspice-extract" "ngspice-42" } Remove-Item ngspice.7z -ErrorAction SilentlyContinue Remove-Item ngspice-extract -Recurse -Force -ErrorAction SilentlyContinue shell: pwsh # ── 9. Verify directory structure ───────────────────────────────────── - name: Verify dependency layout run: | echo "=== Directory Structure ===" echo "--- libgit2 ---" Get-ChildItem "libgit2\include\git2.h" -ErrorAction SilentlyContinue Get-ChildItem "libgit2\build64\Release\git2.lib" -ErrorAction SilentlyContinue echo "--- QuaZip ---" $qz = "quazip-${{ env.QT_VERSION }}-1.4intuisphere" Get-ChildItem "$qz\lib\*" -ErrorAction SilentlyContinue Get-ChildItem "$qz\include\QuaZip-Qt6-1.4\quazip\*.h" -ErrorAction SilentlyContinue | Select-Object -First 3 echo "--- Clipper ---" Get-ChildItem "Clipper1-6.4.2\include\polyclipping\*" -ErrorAction SilentlyContinue Get-ChildItem "Clipper1-6.4.2\lib\*" -ErrorAction SilentlyContinue echo "--- Boost ---" Test-Path "boost_1_85_0\boost\version.hpp" echo "--- SVG++ ---" Test-Path "svgpp-1.3.1\include" echo "--- ngspice ---" Test-Path "ngspice-42\include" shell: pwsh # ── 10. Configure Fritzing (qmake) ─────────────────────────────────── - name: Clean qmake cache working-directory: fritzing-app run: | if (Test-Path .qmake.cache) { Remove-Item .qmake.cache } if (Test-Path .qmake.stash) { Remove-Item .qmake.stash } shell: pwsh - name: Configure Fritzing (qmake) working-directory: fritzing-app run: | $QtPath = "${{ env.QT_INSTALL_DIR }}\${{ env.QT_VERSION }}\msvc2019_64" & "$QtPath\bin\qmake.exe" phoenix.pro shell: pwsh - name: Build Fritzing (nmake) working-directory: fritzing-app run: nmake release shell: cmd # ── 11. Deploy Qt runtime DLLs ─────────────────────────────────────── - name: Deploy Qt (windeployqt) working-directory: fritzing-app/release run: windeployqt Fritzing.exe shell: cmd # ── 12. Upload build artifact ──────────────────────────────────────── - name: Upload build artifact uses: actions/upload-artifact@v4 with: name: fritzing-windows-x64 path: fritzing-app/release/ retention-days: 14