Release #29
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 | |
| # Build a DMG and publish it to a tagged GitHub Release. | |
| # | |
| # Triggers: | |
| # • push of a v* tag → versioned, published release with the DMG | |
| # • workflow_dispatch (tag) → re-run the build for an existing tag | |
| # | |
| # Tagging itself is automated: every Sources-bearing commit on main is | |
| # auto-tagged by .github/workflows/auto-tag.yml, which pushes the new tag | |
| # and dispatches this workflow. For larger bumps use Bump & Release. | |
| # | |
| # `https://github.com/<owner>/<repo>/releases/latest` always redirects to | |
| # the newest published release, which is the stable URL the in-app | |
| # UpdateChecker uses and what should appear in the Install section of the | |
| # README. | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Existing tag to release (e.g. v0.1.0)" | |
| required: true | |
| permissions: | |
| contents: write | |
| concurrency: | |
| # One in-flight run per release target. Different tags are independent | |
| # so simultaneous releases don't supersede each other in the queue. | |
| group: release-${{ inputs.tag || github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| release: | |
| name: Build & publish DMG | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| ref: ${{ inputs.tag || github.ref }} | |
| fetch-depth: 0 | |
| - name: Plan release | |
| id: plan | |
| run: | | |
| REF="${{ inputs.tag || github.ref_name }}" | |
| if [[ "$REF" != v* ]]; then | |
| echo "::error::Expected a v* tag, got '$REF'." | |
| exit 1 | |
| fi | |
| VERSION="${REF#v}" | |
| { | |
| echo "tag=$REF" | |
| echo "version=$VERSION" | |
| echo "dmg_name=YouMenuTube-${VERSION}.dmg" | |
| } >> "$GITHUB_OUTPUT" | |
| echo "Plan → tag=$REF version=$VERSION" | |
| - name: Show toolchain | |
| run: | | |
| xcodebuild -version | |
| swift --version | |
| - name: Install tooling | |
| run: brew install xcodegen create-dmg | |
| - name: Generate Xcode project | |
| run: xcodegen generate --quiet | |
| - name: Resolve Swift packages | |
| run: | | |
| xcodebuild -resolvePackageDependencies \ | |
| -project YouMenuTube.xcodeproj \ | |
| -scheme YouMenuTube | |
| - name: Build (Release, ad-hoc signed) | |
| run: | | |
| xcodebuild \ | |
| -project YouMenuTube.xcodeproj \ | |
| -scheme YouMenuTube \ | |
| -configuration Release \ | |
| -destination 'platform=macOS' \ | |
| -derivedDataPath build \ | |
| CODE_SIGN_IDENTITY="-" \ | |
| CODE_SIGN_STYLE=Manual \ | |
| CODE_SIGNING_REQUIRED=YES \ | |
| CODE_SIGNING_ALLOWED=YES \ | |
| build | |
| - name: Locate built .app | |
| id: app | |
| run: | | |
| APP=$(find build/Build/Products/Release -maxdepth 1 -name "*.app" | head -1) | |
| if [[ -z "$APP" ]]; then | |
| echo "No .app produced under build/Build/Products/Release!" >&2 | |
| exit 1 | |
| fi | |
| echo "path=$APP" >> "$GITHUB_OUTPUT" | |
| echo "Built: $APP" | |
| - name: Re-sign deeply (ad-hoc) | |
| run: codesign --force --deep --sign - "${{ steps.app.outputs.path }}" | |
| - name: Verify signature | |
| run: codesign --display --verbose=2 "${{ steps.app.outputs.path }}" || true | |
| - name: Package DMG | |
| run: | | |
| DMG="${{ steps.plan.outputs.dmg_name }}" | |
| create-dmg \ | |
| --volname "YouMenuTube ${{ steps.plan.outputs.version }}" \ | |
| --window-size 540 380 \ | |
| --icon-size 96 \ | |
| --icon "YouMenuTube.app" 140 180 \ | |
| --app-drop-link 400 180 \ | |
| --no-internet-enable \ | |
| --skip-jenkins \ | |
| "$DMG" \ | |
| "${{ steps.app.outputs.path }}" | |
| echo "Built $DMG ($(du -h "$DMG" | cut -f1))" | |
| - name: Publish release | |
| uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3 | |
| with: | |
| tag_name: ${{ steps.plan.outputs.tag }} | |
| name: ${{ steps.plan.outputs.tag }} | |
| draft: false | |
| prerelease: false | |
| generate_release_notes: true | |
| files: YouMenuTube-*.dmg | |
| body: | | |
| ## Install | |
| Download the `.dmg` below, open it, drag **YouMenuTube.app** into `/Applications`. | |
| > ⚠️ **First launch**: this build is **ad-hoc signed** (no paid Apple Developer ID), so Gatekeeper will refuse a normal double-click. Either: | |
| > - Right-click the app → **Open** → **Open** again in the prompt, *or* | |
| > - System Settings → Privacy & Security → "YouMenuTube was blocked …" → **Open Anyway**. | |
| > | |
| > Subsequent launches work normally. | |
| See the [README](https://github.com/${{ github.repository }}#install) for full install / disclaimer / privacy notes. |