Skip to content

Commit 9d12a3d

Browse files
committed
Add DMG creation, signing, and notarization to macOS workflow
- Replace `.tar.gz` artifacts with signed and notarized `.dmg`. - Update release workflow and Homebrew Cask to use `.dmg` format. - Refine packaging scripts for DMG handling and artifact generation. - Update `README.md` with `.dmg` as the primary macOS artifact.
1 parent dc9ea27 commit 9d12a3d

File tree

4 files changed

+93
-27
lines changed

4 files changed

+93
-27
lines changed

.github/workflows/macos.yml

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,53 @@ jobs:
187187
# Check with spctl to see what Gatekeeper thinks
188188
spctl --assess --verbose=4 --type execute ./target/gluonfx/x86_64-darwin/${{ env.APP_NAME }}.app || true
189189
190+
- name: Create and sign DMG
191+
run: |
192+
echo "=== Creating DMG ==="
193+
# Create a temporary directory for DMG content
194+
mkdir -p dmg_content
195+
cp -r ./target/gluonfx/x86_64-darwin/${{ env.APP_NAME }}.app dmg_content/
196+
197+
# Create DMG
198+
hdiutil create -volname "${{ env.APP_NAME }}" -srcfolder dmg_content -ov -format UDZO Swaggerific_x86_64.dmg
199+
200+
echo "=== Signing DMG ==="
201+
codesign --force --verify --verbose \
202+
--sign "Developer ID Application: Ozkan Pakdil (${{ env.TEAM_ID }})" \
203+
--timestamp \
204+
Swaggerific_x86_64.dmg
205+
206+
- name: Notarize the DMG
207+
run: |
208+
echo "=== Submitting DMG for notarization ==="
209+
xcrun notarytool submit Swaggerific_x86_64.dmg \
210+
--key ~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8 \
211+
--key-id ${{ secrets.APPLE_API_KEY_ID }} \
212+
--issuer ${{ secrets.APPLE_API_ISSUER_ID }} \
213+
--wait > notarization_dmg_output.txt 2>&1 || true
214+
215+
cat notarization_dmg_output.txt
216+
217+
# Extract submission ID
218+
SUBMISSION_ID=$(grep -o 'id: [a-f0-9-]*' notarization_dmg_output.txt | head -1 | cut -d' ' -f2)
219+
echo "Submission ID: $SUBMISSION_ID"
220+
221+
if grep -q "status: Accepted" notarization_dmg_output.txt; then
222+
echo "=== Notarization successful! ==="
223+
xcrun stapler staple Swaggerific_x86_64.dmg
224+
else
225+
echo "=== Notarization failed, fetching log ==="
226+
if [ -n "$SUBMISSION_ID" ]; then
227+
xcrun notarytool log "$SUBMISSION_ID" \
228+
--key ~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8 \
229+
--key-id ${{ secrets.APPLE_API_KEY_ID }} \
230+
--issuer ${{ secrets.APPLE_API_ISSUER_ID }} \
231+
notarization_dmg_log.json || true
232+
cat notarization_dmg_log.json || true
233+
fi
234+
exit 1
235+
fi
236+
190237
- name: Create and sign installer package
191238
run: |
192239
echo "=== Creating signed .pkg installer ==="
@@ -289,10 +336,8 @@ jobs:
289336
- name: Prepare staging artifacts
290337
run: |
291338
cp -r ./target/gluonfx/x86_64-darwin/${{ env.APP_NAME }}.app staging/
292-
tar -czvf staging/swaggerific_x86_64-darwin.tar.gz -C target/gluonfx/x86_64-darwin ${{ env.APP_NAME }}.app
293-
cp -r SwaggerificInstaller.pkg staging/
294-
295-
339+
cp Swaggerific_x86_64.dmg staging/
340+
cp SwaggerificInstaller.pkg staging/
296341
297342
- name: Upload
298343
uses: actions/upload-artifact@v4
@@ -307,14 +352,15 @@ jobs:
307352
name: "MacOS Development Build (Signed & Notarized)"
308353
prerelease: true
309354
files: |
310-
staging/*
355+
staging/*.dmg
356+
staging/*.pkg
311357
env:
312358
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
313359

314360
- name: Update Homebrew Cask
315361
run: |
316-
# Calculate SHA256 of the tar.gz file
317-
SHA256=$(shasum -a 256 staging/swaggerific_x86_64-darwin.tar.gz | awk '{print $1}')
362+
# Calculate SHA256 of the dmg file
363+
SHA256=$(shasum -a 256 staging/Swaggerific_x86_64.dmg | awk '{print $1}')
318364
echo "SHA256: $SHA256"
319365
320366
# Update the cask file with the new SHA256
@@ -323,7 +369,7 @@ jobs:
323369
version "${{ env.APP_VERSION }}"
324370
sha256 "$SHA256"
325371
326-
url "https://github.com/ozkanpakdil/swaggerific/releases/download/latest_macos/swaggerific_x86_64-darwin.tar.gz",
372+
url "https://github.com/ozkanpakdil/swaggerific/releases/download/latest_macos/Swaggerific_x86_64.dmg",
327373
verified: "github.com/ozkanpakdil/swaggerific"
328374
name "Swaggerific"
329375
desc "Simple GUI app for working with Swagger/OpenAPI"

.github/workflows/package-and-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ jobs:
9696
if: "!startsWith(github.ref, 'refs/tags/')"
9797
with:
9898
tag_name: "latest"
99-
name: "Latest Development Zip Package"
99+
name: "Latest Development Package"
100100
prerelease: true
101101
files: |
102102
dist/*.zip

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Follow [here](https://bsky.app/profile/swaggerific.bsky.social) for new releases
1212

1313
## Install via Homebrew (macOS)
1414

15-
Swaggerific is available as a Homebrew Cask for macOS (Intel x86_64). The app is **signed and notarized** with an Apple Developer ID certificate.
15+
Swaggerific is available as a Homebrew Cask for macOS (Intel x86_64). The app is **signed and notarized** with an Apple Developer ID certificate in a DMG package.
1616

1717
1) Tap this repository:
1818

@@ -41,11 +41,11 @@ brew uninstall --cask swaggerific
4141
Notes:
4242
- This cask targets Intel (x86_64) macOS builds.
4343
- The app is signed and notarized, so it should open without Gatekeeper warnings.
44-
- It pulls the latest prebuilt app bundle from the `latest_macos` GitHub release.
44+
- It pulls the latest prebuilt DMG from the `latest_macos` GitHub release.
4545

4646
## Packaging artifacts
4747

48-
The macOS packaging script `build-macos-arm64.sh` places generated artifacts under the `staging/` directory (tar.gz, .pkg, and installer .pkg). The `staging/` folder is ignored by Git.
48+
The macOS packaging script `build-macos-arm64.sh` places generated artifacts under the `staging/` directory (DMG, .pkg, and installer .pkg). The `staging/` folder is ignored by Git.
4949

5050
### Local Signing and Notarization
5151

@@ -118,8 +118,6 @@ A user interface (UI) designed to interact with APIs using Swagger or OpenAPI js
118118
mvn -Djava.awt.headless=false -Dtestfx.robot=glass -Dsurefire.parallel=none test
119119
```
120120

121-
test
122-
123121
### Run agent
124122

125123
```shell

build-macos-arm64.sh

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,19 @@ echo "The app has been signed and is located at: $STAGED_APP"
210210
echo "You can now try to open it manually to verify it works."
211211
read -p "Press Enter to continue with packaging and notarization, or Ctrl+C to abort..."
212212

213-
ARCHIVE_NAME="swaggerific_aarch64-darwin.tar.gz"
214-
echo "Creating archive $ARCHIVE_NAME ..."
215-
# Use staged (signed) app for archive
216-
tar -czvf "$STAGING_DIR/$ARCHIVE_NAME" -C "$STAGING_DIR" "swaggerific.app"
213+
# --- DMG Creation ---
214+
DMG_NAME="Swaggerific_aarch64.dmg"
215+
echo "Creating DMG $DMG_NAME ..."
216+
mkdir -p "$STAGING_DIR/dmg_content"
217+
cp -r "$STAGED_APP" "$STAGING_DIR/dmg_content/"
218+
hdiutil create -volname "Swaggerific" -srcfolder "$STAGING_DIR/dmg_content" -ov -format UDZO "$STAGING_DIR/$DMG_NAME"
219+
rm -rf "$STAGING_DIR/dmg_content"
220+
221+
echo "=== Signing DMG ==="
222+
codesign --force --verify --verbose \
223+
--sign "$SIGNING_IDENTITY" \
224+
--timestamp \
225+
"$STAGING_DIR/$DMG_NAME"
217226

218227
PKG_NAME="Swaggerific.pkg"
219228
INSTALLER_NAME="SwaggerificInstaller.pkg"
@@ -274,6 +283,22 @@ if [[ ${#AUTH_ARGS[@]} -gt 0 ]]; then
274283
xcrun stapler staple "$STAGED_APP"
275284
rm "$APP_ZIP"
276285

286+
# 1b. Notarize the DMG
287+
echo "Submitting DMG for notarization..."
288+
xcrun notarytool submit "$STAGING_DIR/$DMG_NAME" "${AUTH_ARGS[@]}" --wait > notarization_dmg_output.txt 2>&1 || true
289+
cat notarization_dmg_output.txt
290+
SUBMISSION_ID=$(grep -o 'id: [a-f0-9-]*' notarization_dmg_output.txt | head -1 | cut -d' ' -f2)
291+
if ! grep -q "status: Accepted" notarization_dmg_output.txt; then
292+
echo "=== DMG notarization failed, fetching log ==="
293+
if [[ -n "${SUBMISSION_ID:-}" ]]; then
294+
xcrun notarytool log "$SUBMISSION_ID" "${AUTH_ARGS[@]}" notarization_dmg_log.json || true
295+
cat notarization_dmg_log.json || true
296+
fi
297+
exit 1
298+
fi
299+
echo "Stapling notarization ticket to DMG..."
300+
xcrun stapler staple "$STAGING_DIR/$DMG_NAME"
301+
277302
# 2. Notarize the installer package
278303
echo "Submitting installer for notarization..."
279304
xcrun notarytool submit "$STAGED_INSTALLER" "${AUTH_ARGS[@]}" --wait > notarization_pkg_output.txt 2>&1 || true
@@ -293,27 +318,24 @@ if [[ ${#AUTH_ARGS[@]} -gt 0 ]]; then
293318
echo "Stapling notarization ticket to installer..."
294319
xcrun stapler staple "$STAGED_INSTALLER"
295320

296-
# 3. Update the tar.gz with the stapled app
297-
echo "Re-creating archive $ARCHIVE_NAME with stapled app..."
298-
tar -czvf "$STAGING_DIR/$ARCHIVE_NAME" -C "$STAGING_DIR" "swaggerific.app"
299-
321+
# 3. Done
300322
echo "Notarization and stapling complete."
301323
fi
302324

303325
echo "Done. Artifacts:"
304-
echo " - $STAGING_DIR/$ARCHIVE_NAME"
326+
echo " - $STAGING_DIR/$DMG_NAME"
305327
echo " - $STAGING_DIR/$PKG_NAME"
306328
echo " - $STAGING_DIR/$INSTALLER_NAME"
307329

308330
# ------------------------
309331
# Simple upload to GitHub Release (latest_macos)
310332
# ------------------------
311-
ARCHIVE_PATH="$STAGING_DIR/$ARCHIVE_NAME"
312333
if command -v gh >/dev/null 2>&1; then
313-
echo "Uploading $ARCHIVE_PATH to https://github.com/$GITHUB_REPO/releases/tag/$RELEASE_TAG ..."
334+
echo "Uploading artifacts to https://github.com/$GITHUB_REPO/releases/tag/$RELEASE_TAG ..."
314335
# Ensure release exists (no frills); if it doesn't, print a hint and skip
315336
if gh release view "$RELEASE_TAG" --repo "$GITHUB_REPO" >/dev/null 2>&1; then
316-
gh release upload "$RELEASE_TAG" "$ARCHIVE_PATH" --repo "$GITHUB_REPO" --clobber || true
337+
gh release upload "$RELEASE_TAG" "$STAGING_DIR/$DMG_NAME" --repo "$GITHUB_REPO" --clobber || true
338+
gh release upload "$RELEASE_TAG" "$STAGING_DIR/$INSTALLER_NAME" --repo "$GITHUB_REPO" --clobber || true
317339
echo "Upload complete."
318340
else
319341
echo "Release tag '$RELEASE_TAG' does not exist on $GITHUB_REPO. Create it first, then re-run."
@@ -322,7 +344,7 @@ if command -v gh >/dev/null 2>&1; then
322344
else
323345
echo "GitHub CLI (gh) not found. To upload manually run:"
324346
echo " gh auth login"
325-
echo " gh release upload $RELEASE_TAG $ARCHIVE_PATH --repo $GITHUB_REPO --clobber"
347+
echo " gh release upload $RELEASE_TAG $STAGING_DIR/$DMG_NAME --repo $GITHUB_REPO --clobber"
326348
fi
327349

328350

0 commit comments

Comments
 (0)