[1.1.0] Added icons #130
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build jb_updater | |
| on: | |
| push: | |
| branches: [ "**" ] | |
| tags: [ "v*.*.*" ] | |
| pull_request: | |
| workflow_dispatch: { } | |
| permissions: | |
| contents: write | |
| # ========================================================= | |
| # =============== BUILD JOBS ========================== | |
| # ========================================================= | |
| jobs: | |
| linux: | |
| name: Linux x86_64 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: crystal-lang/install-crystal@v1 | |
| with: | |
| crystal: latest | |
| - name: Install Linux dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libxml2-dev libssl-dev libpcre2-dev libgc-dev liblzma-dev libgtk-3-dev | |
| - name: Install shards | |
| working-directory: jb_updater | |
| run: shards install | |
| - name: Run Ameba linter | |
| working-directory: jb_updater | |
| run: ./bin/lint | |
| - name: Run specs | |
| working-directory: jb_updater | |
| run: crystal spec -v | |
| - name: Build binaries (CLI + GUI) | |
| working-directory: jb_updater | |
| run: | | |
| crystal build src/main.cr --release --no-debug -o jb_updater | |
| crystal build src/gui/main_gui.cr --release --no-debug -o jb_updater_gui | |
| - name: Smoke test — CLI binary loads | |
| working-directory: jb_updater | |
| run: ./jb_updater --help | |
| - name: Package artifacts | |
| run: | | |
| tar -czf jb_updater-cli-linux-x86_64.tar.gz -C jb_updater jb_updater | |
| tar -czf jb_updater-gui-linux-x86_64.tar.gz -C jb_updater jb_updater_gui | |
| mkdir -p jb_updater-bundle | |
| cp jb_updater/jb_updater jb_updater-bundle/ | |
| cp jb_updater/jb_updater_gui jb_updater-bundle/ | |
| cp jb_updater/assets/jb_updater.svg jb_updater-bundle/ | |
| tar -czf jb_updater-bundle-linux-x86_64.tar.gz -C jb_updater-bundle . | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-cli-linux-x86_64 | |
| path: jb_updater-cli-linux-x86_64.tar.gz | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-gui-linux-x86_64 | |
| path: jb_updater-gui-linux-x86_64.tar.gz | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-bundle-linux-x86_64 | |
| path: jb_updater-bundle-linux-x86_64.tar.gz | |
| macos: | |
| name: macOS ${{ matrix.arch }} | |
| strategy: | |
| matrix: | |
| include: | |
| - arch: arm64 | |
| runs_on: macos-latest | |
| - arch: x86_64 | |
| runs_on: macos-15-intel | |
| runs-on: ${{ matrix.runs_on }} | |
| env: | |
| ARCH: ${{ matrix.arch }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: crystal-lang/install-crystal@v1 | |
| with: | |
| crystal: latest | |
| - name: Install OpenSSL 3 | |
| run: brew install openssl@3 | |
| - name: Install shards | |
| working-directory: jb_updater | |
| run: shards install | |
| - name: Run Ameba linter | |
| working-directory: jb_updater | |
| run: ./bin/lint | |
| - name: Run specs | |
| working-directory: jb_updater | |
| run: crystal spec -v | |
| - name: Build binaries (CLI + GUI) | |
| working-directory: jb_updater | |
| run: | | |
| brew_prefix=$(brew --prefix openssl@3) | |
| unset PKG_CONFIG_PATH | |
| export PKG_CONFIG_PATH="${brew_prefix}/lib/pkgconfig" | |
| echo "Using OpenSSL from ${brew_prefix}" | |
| crystal build src/main.cr --release --no-debug \ | |
| --link-flags "-L${brew_prefix}/lib -I${brew_prefix}/include" \ | |
| -o jb_updater | |
| crystal build src/gui/main_gui.cr --release --no-debug \ | |
| --link-flags "-L${brew_prefix}/lib -I${brew_prefix}/include" \ | |
| -o jb_updater_gui | |
| - name: Bundle OpenSSL runtime dylibs | |
| working-directory: jb_updater | |
| run: | | |
| brew_prefix=$(brew --prefix openssl@3) | |
| for dylib in libcrypto.3.dylib libssl.3.dylib; do | |
| cp "$brew_prefix/lib/$dylib" . | |
| install_name_tool -id "@loader_path/$dylib" "$dylib" | |
| for dep in $(otool -L "$dylib" | grep "/opt/homebrew\|/usr/local" | awk '{print $1}'); do | |
| install_name_tool -change "$dep" "@loader_path/$(basename $dep)" "$dylib" | |
| done | |
| done | |
| for exe in jb_updater jb_updater_gui; do | |
| for dep in $(otool -L "$exe" | grep "/opt/homebrew\|/usr/local" | awk '{print $1}'); do | |
| install_name_tool -change "$dep" "@loader_path/$(basename $dep)" "$exe" | |
| done | |
| done | |
| - name: Smoke test — CLI binary loads | |
| working-directory: jb_updater | |
| run: | | |
| ./jb_updater --help | |
| echo "---" | |
| echo "Checking dylib paths..." | |
| # Skip binary name line, filter out system paths and @loader_path refs. | |
| # Any remaining lines are non-system absolute paths → fail. | |
| otool -L jb_updater | tail -n +2 | grep -v -e "/usr/lib" -e "/System" -e "@loader_path" && { echo "::error::Found absolute dylib paths"; exit 1; } || echo "All dylib paths use @loader_path" | |
| - name: Package artifacts | |
| run: | | |
| cd jb_updater | |
| # CLI archive — include bundled dylibs | |
| tar -czf ../jb_updater-cli-macos-${ARCH}.tar.gz jb_updater libcrypto.3.dylib libssl.3.dylib | |
| # Bundle: binaries + dylibs | |
| mkdir -p ../jb_updater-bundle | |
| cp jb_updater jb_updater_gui libcrypto.3.dylib libssl.3.dylib ../jb_updater-bundle/ | |
| cd .. | |
| zip -ry jb_updater-bundle-macos-${ARCH}.zip jb_updater-bundle | |
| # .app bundle with dylibs + icon inside | |
| APP_ROOT="JBUpdater.app/Contents" | |
| mkdir -p "$APP_ROOT/MacOS" "$APP_ROOT/Resources" | |
| cp jb_updater/jb_updater_gui "$APP_ROOT/MacOS/" | |
| cp jb_updater/jb_updater "$APP_ROOT/MacOS/" | |
| cp jb_updater/libcrypto.3.dylib "$APP_ROOT/MacOS/" | |
| cp jb_updater/libssl.3.dylib "$APP_ROOT/MacOS/" | |
| cp jb_updater/assets/jb_updater.icns "$APP_ROOT/Resources/" | |
| cat > "$APP_ROOT/Info.plist" <<'PLIST' | |
| <?xml version="1.0" encoding="UTF-8"?> | |
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
| <plist version="1.0"><dict> | |
| <key>CFBundleName</key><string>JB Updater</string> | |
| <key>CFBundleIdentifier</key><string>com.example.jb-updater</string> | |
| <key>CFBundleVersion</key><string>1.0</string> | |
| <key>CFBundleExecutable</key><string>jb_updater_gui</string> | |
| <key>CFBundleIconFile</key><string>jb_updater</string> | |
| <key>LSMinimumSystemVersion</key><string>11.0</string> | |
| <key>NSHighResolutionCapable</key><true/> | |
| </dict></plist> | |
| PLIST | |
| zip -ry jb_updater-app-macos-${ARCH}.zip JBUpdater.app | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-cli-macos-${{ matrix.arch }} | |
| path: jb_updater-cli-macos-${{ matrix.arch }}.tar.gz | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-app-macos-${{ matrix.arch }} | |
| path: jb_updater-app-macos-${{ matrix.arch }}.zip | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-bundle-macos-${{ matrix.arch }} | |
| path: jb_updater-bundle-macos-${{ matrix.arch }}.zip | |
| windows: | |
| name: Windows x86_64 | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: crystal-lang/install-crystal@v1 | |
| with: | |
| crystal: latest | |
| # Ensure MSVC build environment is set up (cl, link, mt, etc.) | |
| - name: Set up MSVC Developer Command Prompt | |
| uses: ilammy/msvc-dev-cmd@v1 | |
| - name: Install shards | |
| working-directory: jb_updater | |
| run: shards install | |
| - name: Run Ameba linter | |
| working-directory: jb_updater | |
| run: ./bin/lint | |
| - name: Run specs | |
| working-directory: jb_updater | |
| run: crystal spec -v | |
| - name: Build binaries (CLI + GUI) | |
| working-directory: jb_updater | |
| run: | | |
| crystal build src/main.cr --release --no-debug -o jb_updater.exe | |
| crystal build src/gui/main_gui.cr --release --no-debug --link-flags=/SUBSYSTEM:WINDOWS -o jb_updater_gui.exe | |
| - name: Bundle Crystal runtime DLLs | |
| shell: pwsh | |
| run: | | |
| # Crystal runtime DLLs must ship alongside the EXEs on Windows, | |
| # otherwise the process exits with 0xC0000135 (STATUS_DLL_NOT_FOUND). | |
| $crystalPath = (Get-Command crystal).Source | |
| $crystalRoot = Split-Path (Split-Path $crystalPath -Parent) -Parent | |
| $dllSource = Join-Path $crystalRoot "embedded" "bin" | |
| if (Test-Path $dllSource) { | |
| Copy-Item "$dllSource\*.dll" jb_updater\ | |
| Write-Host "Copied DLLs from $dllSource" | |
| Get-ChildItem jb_updater\*.dll | ForEach-Object { Write-Host " → $($_.Name)" } | |
| } else { | |
| Write-Host "::warning::Crystal DLL directory not found at $dllSource" | |
| } | |
| - name: Smoke test — CLI binary loads | |
| working-directory: jb_updater | |
| run: | | |
| # Verify the CLI binary starts (proves all DLLs resolve correctly). | |
| # 0xC0000135 would kill the process before any output. | |
| .\jb_updater.exe --help | |
| shell: cmd | |
| - name: Verify GUI DLLs are present | |
| working-directory: jb_updater | |
| shell: pwsh | |
| run: | | |
| # Can't run the GUI binary on headless CI (no display), but we can | |
| # confirm all DLLs exist alongside the GUI EXE. | |
| $exe = "jb_updater_gui.exe" | |
| $dlls = @(Get-ChildItem *.dll) | |
| if (-not (Test-Path $exe)) { | |
| Write-Host "::error::$exe not found" | |
| exit 1 | |
| } | |
| Write-Host "$exe found, $($dlls.Count) DLLs present:" | |
| $dlls | ForEach-Object { Write-Host " → $($_.Name) ($( '{0:N0}' -f $_.Length ) bytes)" } | |
| - name: Package artifacts | |
| run: | | |
| Compress-Archive -Path jb_updater\jb_updater.exe, jb_updater\*.dll -DestinationPath jb_updater-cli-windows-x86_64.zip | |
| Compress-Archive -Path jb_updater\jb_updater_gui.exe, jb_updater\*.dll -DestinationPath jb_updater-gui-windows-x86_64.zip | |
| New-Item -ItemType Directory -Force -Path jb_updater-bundle | Out-Null | |
| Copy-Item jb_updater\*.exe, jb_updater\*.dll jb_updater-bundle\ | |
| Compress-Archive -Path jb_updater-bundle\* -DestinationPath jb_updater-bundle-windows-x86_64.zip | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-cli-windows-x86_64 | |
| path: jb_updater-cli-windows-x86_64.zip | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-gui-windows-x86_64 | |
| path: jb_updater-gui-windows-x86_64.zip | |
| - uses: actions/upload-artifact@v4 | |
| with: | |
| name: jb_updater-bundle-windows-x86_64 | |
| path: jb_updater-bundle-windows-x86_64.zip | |
| # ========================================================= | |
| # =============== RELEASE JOB ========================= | |
| # ========================================================= | |
| release: | |
| name: Create GitHub Release | |
| needs: [ linux, macos, windows ] | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/') | |
| steps: | |
| - name: Verify branch or tag | |
| run: | | |
| echo "Triggered by $GITHUB_EVENT_NAME for ref $GITHUB_REF" | |
| if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" && "$GITHUB_REF_NAME" != "master" ]]; then | |
| echo "⚠️ Manual releases are allowed only from master branch." | |
| exit 1 | |
| fi | |
| - name: Download all build artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: ./all-artifacts | |
| - name: Flatten artifacts | |
| run: | | |
| mkdir -p release-assets | |
| find ./all-artifacts -type f -exec mv {} ./release-assets/ \; | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| files: release-assets/* | |
| generate_release_notes: true |