name: Release # Every push to main builds the app for Windows, Linux and macOS and publishes (or refreshes) a GitHub # release named after the in src/Packwright.App/Packwright.App.csproj. To cut a new # release, bump that version and push. on: push: branches: [main] paths-ignore: - '**.md' - 'LICENSE' workflow_dispatch: permissions: contents: write concurrency: group: release cancel-in-progress: false env: PROJECT: src/Packwright.App/Packwright.App.csproj APP: Packwright jobs: version: runs-on: ubuntu-latest outputs: version: ${{ steps.read.outputs.version }} steps: - uses: actions/checkout@v4 - id: read run: | version=$(sed -n 's:.*\(.*\).*:\1:p' "$PROJECT" | head -n1) if [ -z "$version" ]; then echo "No found in $PROJECT" >&2; exit 1; fi echo "version=$version" >> "$GITHUB_OUTPUT" build-linux: needs: version runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: 10.0.x - name: Publish run: dotnet publish "$PROJECT" -c Release -r linux-x64 --self-contained true -o publish - name: Add the licenses run: | cp LICENSE THIRD_PARTY_NOTICES.md publish/ mkdir -p publish/licenses cp src/Packwright.Ufs2/LICENSE publish/licenses/UFS2Tool-LICENSE cp third-party/licenses/* publish/licenses/ - name: Build the .deb and .rpm run: | sudo apt-get update -qq sudo apt-get install -y -qq rpm bash installer/linux/build-packages.sh "${{ needs.version.outputs.version }}" publish dist - uses: actions/upload-artifact@v4 with: name: release-linux-packages path: dist/* build-windows-installer: needs: version runs-on: windows-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: 10.0.x - name: Publish shell: bash run: dotnet publish "$PROJECT" -c Release -r win-x64 --self-contained true -o publish - name: Add the licenses shell: bash run: | cp LICENSE THIRD_PARTY_NOTICES.md publish/ mkdir -p publish/licenses cp src/Packwright.Ufs2/LICENSE publish/licenses/UFS2Tool-LICENSE cp third-party/licenses/* publish/licenses/ - name: Install Inno Setup run: choco install innosetup -y --no-progress - name: Build the installer shell: pwsh run: | New-Item -ItemType Directory -Force dist | Out-Null $iscc = Join-Path ${env:ProgramFiles(x86)} 'Inno Setup 6\ISCC.exe' & $iscc "/DAppVersion=${{ needs.version.outputs.version }}" "/DSourceDir=$env:GITHUB_WORKSPACE\publish" "/O$env:GITHUB_WORKSPACE\dist" installer\Packwright.iss if ($LASTEXITCODE -ne 0) { throw "Inno Setup failed ($LASTEXITCODE)" } - uses: actions/upload-artifact@v4 with: name: release-windows-installer path: dist/*.exe build-macos: needs: version runs-on: macos-latest strategy: fail-fast: true matrix: include: - { rid: osx-arm64, label: macos-arm64 } - { rid: osx-x64, label: macos-x64 } steps: - uses: actions/checkout@v4 - uses: actions/setup-dotnet@v4 with: dotnet-version: 10.0.x - name: Publish run: dotnet publish "$PROJECT" -c Release -r ${{ matrix.rid }} --self-contained true -o publish - name: Create the app bundle run: | version="${{ needs.version.outputs.version }}" bundle="Packwright.app" mkdir -p "$bundle/Contents/MacOS" "$bundle/Contents/Resources" cp -R publish/. "$bundle/Contents/MacOS/" chmod +x "$bundle/Contents/MacOS/$APP" cp LICENSE THIRD_PARTY_NOTICES.md "$bundle/Contents/Resources/" mkdir -p "$bundle/Contents/Resources/licenses" cp src/Packwright.Ufs2/LICENSE "$bundle/Contents/Resources/licenses/UFS2Tool-LICENSE" cp third-party/licenses/* "$bundle/Contents/Resources/licenses/" # Icon: build an .icns from the PNG iconset=icon.iconset mkdir "$iconset" for size in 16 32 128 256 512; do double=$((size * 2)) sips -z $size $size src/Packwright.App/Assets/icon.png --out "$iconset/icon_${size}x${size}.png" > /dev/null sips -z $double $double src/Packwright.App/Assets/icon.png --out "$iconset/icon_${size}x${size}@2x.png" > /dev/null done iconutil -c icns "$iconset" -o "$bundle/Contents/Resources/icon.icns" cat > "$bundle/Contents/Info.plist" < CFBundleNamePackwright CFBundleDisplayNamePackwright CFBundleIdentifierio.github.itsmemac.packwright CFBundleVersion${version} CFBundleShortVersionString${version} CFBundleExecutable${APP} CFBundleIconFileicon CFBundlePackageTypeAPPL LSMinimumSystemVersion13.0 NSHighResolutionCapable PLIST - name: Sign ad hoc # Apple Silicon refuses to start unsigned code. An ad-hoc signature is enough to run locally; # the app is not notarized, so the first launch still needs right click, then Open. run: codesign --force --deep --sign - "Packwright.app" - name: Build the disk image # The disk image holds the app and a shortcut to Applications: open it and drag the app across. run: | mkdir dist dmgroot name="$APP-v${{ needs.version.outputs.version }}-${{ matrix.label }}" ditto "Packwright.app" "dmgroot/Packwright.app" ln -s /Applications dmgroot/Applications hdiutil create -volname "Packwright" -srcfolder dmgroot -ov -format UDZO "dist/$name.dmg" - uses: actions/upload-artifact@v4 with: name: release-${{ matrix.label }} path: dist/* release: needs: [version, build-linux, build-windows-installer, build-macos] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: pattern: release-* merge-multiple: true path: dist - name: Checksums and notes run: | version="${{ needs.version.outputs.version }}" (cd dist && sha256sum * > SHA256SUMS.txt) # The notes file for this version (release-notes/.md), when there is one, goes first: it is what # the app's update window shows under "what is new". { echo "## Packwright v${version}" echo if [ -f "release-notes/${version}.md" ]; then cat "release-notes/${version}.md"; echo; fi } > notes.md cat >> notes.md <.deb\` / \`sudo dnf install ./.rpm\`. It adds a menu entry and a \`packwright\` command, and is removed with your package manager. Verify a download with \`SHA256SUMS.txt\`. **License and source:** GPL-3.0, with no warranty. Packwright grew out of PS5 PKG Tool by pearlxcore (GPL-3.0), whose engines still power parts of it; the changes and every bundled component are listed in THIRD_PARTY_NOTICES.md, and the license texts are in the \`licenses\` folder of the installed app. The source for this release is the \`v${version}\` tag of this repository. NOTES - name: Publish the release env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | tag="v${{ needs.version.outputs.version }}" # Replace an earlier release of the same version so the tag points at this build. gh release delete "$tag" --cleanup-tag --yes 2>/dev/null || true gh release create "$tag" dist/* \ --target "$GITHUB_SHA" \ --title "Packwright $tag" \ --notes-file notes.md \ --latest