Building from source

How to build SidebarFavorites with Xcode and XcodeGen, and how to make a signed, notarized DMG. Read it if you want to run your own build or contribute. To use the app, install it instead.

On this page

Requirements

You need these tools to build the app. Signing and notarization are only needed for a DMG you want to give to other people. To use the app without building it, see Install.

RequirementVersionWhy
macOS13 or laterThe app’s minimum system is macOS 13, and the project targets it.
Xcode15 or laterIt provides the compiler and xcodebuild.
XcodeGenNo minimum statedIt generates the Xcode project from project.yml.
Developer ID Application certificateOptionalSigns the DMG so that Gatekeeper accepts it. Without it the DMG is signed ad hoc.
Notarization profileOptionalLets the script submit the app and the DMG to Apple for notarization.

Build the app

These commands build the Release configuration. Run them in Terminal, one at a time.

  1. Clone the repository.

    Terminal

    git clone https://github.com/ivg-design/SidebarFavorites.git
  2. Open the project folder.

    Terminal

    cd SidebarFavorites
  3. Install XcodeGen with Homebrew, if you do not have it.

    Terminal

    brew install xcodegen
  4. Generate the Xcode project.

    Terminal

    xcodegen generate

    You seeXcodeGen creates SidebarFavorites.xcodeproj in the project folder.

  5. Build the SidebarFavoritesManager scheme.

    Terminal

    xcodebuild -scheme SidebarFavoritesManager -configuration Release

    Every build raises the build number in SidebarFavoritesManager/Info.plist by one, so that file shows as changed in Git afterwards.

    You seexcodebuild prints BUILD SUCCEEDED when the app is built. The product is named SidebarFavorites Manager.app.

Make a distributable DMG

The release script builds the app, signs it, optionally notarizes it, and packs it into a disk image with an Applications shortcut. It runs xcodegen itself, so you do not need to generate the project first.

  1. Run the release script from the project folder.

    Terminal

    ./scripts/build-release.sh
  2. Wait while the script works through its stages.

    It deletes the build folder, generates the project, builds the Release configuration, signs the helper programs and the app, notarizes and staples the app if notarization is available, builds the DMG and signs it, notarizes and staples the DMG, then verifies the signatures and prints the Gatekeeper result for each.

  3. Find the DMG.

    The line after the path says whether the DMG was notarized and stapled or NOT notarized.

    You seeThe script ends with Build Complete and prints the DMG path and size. The file is build/DMG/SidebarFavorites-<version>.dmg inside the project folder, where the version comes from Info.plist.

The script reads these environment variables. Put them before the command, for example NOTARIZE=0 ./scripts/build-release.sh.

VariableWhat it doesDefault
SIGN_IDENTITYNames the certificate to sign with, for example Developer ID Application: Your Name (TEAMID).The first Developer ID Application identity in your keychain, or ad-hoc signing if there is none.
NOTARIZESet to 0 to skip notarization even when everything for it is available.Unset. The script notarizes when it has a Developer ID identity and a notarization profile.
NOTARY_PROFILENames the keychain profile that holds your notarization credentials.SidebarFavoritesNotary
NOTARY_PROFILE_EXPLICITWhen set to anything, the script uses only the profile named in NOTARY_PROFILE and does not look for a fallback profile called eXLib-notary.Unset.

Set up notarization

Notarization is Apple’s scan of a signed app. A notarized DMG opens without the Gatekeeper warning. The script notarizes only when it has a Developer ID Application identity and a stored profile. You create the profile once for each Mac, and the script finds it by name.

  1. Create an app-specific password for your Apple ID.

    Create it on the Apple ID account website, under Sign-In and Security. Notarization cannot use your normal Apple ID password.

  2. Store the credentials in your keychain.

    Terminal

    xcrun notarytool store-credentials SidebarFavoritesNotary \    --apple-id "[email protected]" \    --team-id "TEAMID" \    --password "app-specific-password"

    Replace [email protected], TEAMID and app-specific-password with your own values. The password stays in your keychain and is never written to a file.

    You seenotarytool saves the credentials under the profile name SidebarFavoritesNotary.

  3. Run the release script again.

    Terminal

    ./scripts/build-release.sh

    You seeThe script prints Found notarization profile and notarizes the app and the DMG, which can take a few minutes each.

If it does not work

What you seeCauseFix
The script stops at Generating Xcode project... with xcodegen: command not found.XcodeGen is not installed.Run brew install xcodegen, then run the script again.
WARNING: No ‘Developer ID Application’ signing identity found in the keychain.The keychain holds no Developer ID Application certificate.Install the certificate, or set SIGN_IDENTITY. Without one, the script signs ad hoc, skips notarization, and Gatekeeper blocks the DMG until a user approves it in System Settings.
NOTE: No notarization keychain profile named ‘SidebarFavoritesNotary’ was found.The profile does not exist on this Mac, or NOTARY_PROFILE names a different one.Follow Set up notarization. Until then the script continues and makes a DMG that is not notarized.
Notarization explicitly disabled (NOTARIZE=0).NOTARIZE=0 is set in your environment.Unset it to notarize.
ERROR: App notarization failed. or ERROR: DMG notarization failed.Apple rejected the submission.Run the xcrun notarytool log command that the script prints, and read the reasons.
ERROR: Build failed - app not foundThe Release build did not produce the app.Read the xcodebuild output above the message, and fix the first error.
ERROR: could not remove buildA previous build left files that your account cannot delete.Remove the build folder yourself, as the message says, then run the script again.