ci: Testfassung als DMG bei jedem Lauf bereitstellen #1
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: Release | |
| # Läuft, wenn ein Versions-Tag geschoben wird, etwa: git tag v1.0.0 && git push --tags | |
| on: | |
| push: | |
| tags: ['v*'] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: 'Versions-Tag, z. B. v1.0.0' | |
| required: true | |
| permissions: | |
| contents: write | |
| jobs: | |
| release: | |
| runs-on: macos-26 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Version bestimmen | |
| id: version | |
| run: | | |
| TAG="${{ github.event.inputs.tag || github.ref_name }}" | |
| echo "tag=$TAG" >> "$GITHUB_OUTPUT" | |
| echo "number=${TAG#v}" >> "$GITHUB_OUTPUT" | |
| - name: Abhängigkeiten installieren | |
| run: brew install libusb create-dmg | |
| - name: Kernlogik testen | |
| # Ein Release ohne grüne Tests gibt es nicht. | |
| run: swift test --package-path SphairaCoreTests | |
| - name: Release bauen | |
| run: | | |
| xcodebuild build \ | |
| -scheme "Sphaira Connect" \ | |
| -configuration Release \ | |
| -destination 'platform=macOS,arch=arm64' \ | |
| -derivedDataPath build | |
| - name: App verpacken | |
| id: package | |
| run: | | |
| APP="build/Build/Products/Release/Sphaira Connect.app" | |
| test -d "$APP" || { echo "App-Bundle nicht gefunden"; exit 1; } | |
| # Die Signatur muss die Verpackung überleben — ditto ist der von Apple | |
| # vorgesehene Weg, zip zerstört Symlinks und erweiterte Attribute. | |
| ZIP="Sphaira-Connect-${{ steps.version.outputs.number }}-arm64.zip" | |
| ditto -c -k --sequesterRsrc --keepParent "$APP" "$ZIP" | |
| # DMG mit Fensterlayout und Verknüpfung auf den Programme-Ordner. | |
| # create-dmg braucht ein Quellverzeichnis, das NUR die App enthält. | |
| mkdir -p dmg-src && cp -R "$APP" dmg-src/ | |
| DMG="Sphaira-Connect-${{ steps.version.outputs.number }}-arm64.dmg" | |
| create-dmg \ | |
| --volname "Sphaira Connect" \ | |
| --window-pos 200 120 --window-size 620 400 \ | |
| --icon-size 128 \ | |
| --icon "Sphaira Connect.app" 165 190 \ | |
| --app-drop-link 455 190 \ | |
| --no-internet-enable \ | |
| "$DMG" dmg-src/ | |
| echo "zip=$ZIP" >> "$GITHUB_OUTPUT" | |
| echo "dmg=$DMG" >> "$GITHUB_OUTPUT" | |
| echo "sha_zip=$(shasum -a 256 "$ZIP" | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" | |
| echo "sha_dmg=$(shasum -a 256 "$DMG" | cut -d' ' -f1)" >> "$GITHUB_OUTPUT" | |
| - name: Verpackte Bundles prüfen | |
| run: | | |
| # ZIP: entpacken und Signatur prüfen | |
| rm -rf verify && mkdir verify | |
| ditto -x -k "${{ steps.package.outputs.zip }}" verify | |
| codesign --verify --verbose=2 "verify/Sphaira Connect.app" | |
| # DMG: einhängen und dieselbe Prüfung, damit nicht nur das ZIP getestet ist | |
| hdiutil attach -nobrowse -quiet "${{ steps.package.outputs.dmg }}" | |
| test -L "/Volumes/Sphaira Connect/Applications" || { echo "FEHLER: Verknüpfung zum Programme-Ordner fehlt."; exit 1; } | |
| codesign --verify --verbose=2 "/Volumes/Sphaira Connect/Sphaira Connect.app" | |
| # Ad-hoc signiert heißt: keine Team-Kennung. Steht dort eine, ist | |
| # versehentlich ein Entwicklerkonto in den Build geraten. | |
| if codesign -dv "/Volumes/Sphaira Connect/Sphaira Connect.app" 2>&1 | grep -q '^TeamIdentifier=[^n]'; then | |
| hdiutil detach "/Volumes/Sphaira Connect" -quiet | |
| echo "FEHLER: Das Bundle trägt eine Apple-Team-Kennung." | |
| exit 1 | |
| fi | |
| hdiutil detach "/Volumes/Sphaira Connect" -quiet | |
| - name: Anmerkungen zusammenstellen | |
| id: notes | |
| run: | | |
| NOTES_DIR="release_notes/v${{ steps.version.outputs.number }}" | |
| { | |
| if [ -d "$NOTES_DIR" ]; then | |
| cat "$NOTES_DIR"/macos_build_*.md 2>/dev/null || true | |
| echo | |
| fi | |
| echo "## Installation" | |
| echo | |
| echo "**DMG** öffnen und die App in den Programme-Ordner ziehen" | |
| echo "(oder das ZIP entpacken). Beim ersten Start Rechtsklick →" | |
| echo "**Öffnen**: Die App ist ad-hoc signiert und nicht notarisiert," | |
| echo "sonst verweigert Gatekeeper den Start." | |
| echo | |
| echo "| Datei | SHA-256 |" | |
| echo "|---|---|" | |
| echo "| \`${{ steps.package.outputs.dmg }}\` | \`${{ steps.package.outputs.sha_dmg }}\` |" | |
| echo "| \`${{ steps.package.outputs.zip }}\` | \`${{ steps.package.outputs.sha_zip }}\` |" | |
| } > RELEASE_NOTES.md | |
| - name: Veröffentlichen | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release create "${{ steps.version.outputs.tag }}" \ | |
| "${{ steps.package.outputs.dmg }}" \ | |
| "${{ steps.package.outputs.zip }}" \ | |
| --title "Sphaira Connect ${{ steps.version.outputs.number }}" \ | |
| --notes-file RELEASE_NOTES.md |