diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 710fd8e5b..1ee6689d6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,23 +29,28 @@ jobs: runs-on: "ubuntu-20.04" target: "x86_64-unknown-linux-gnu" platform: "x86_64-linux" + release-ext: "zip" - name: "linux-arm64" runs-on: ["self-hosted", "Linux", "ARM64", "ubuntu20.04"] # Array of tags for ARM64 target: "aarch64-unknown-linux-gnu" platform: "arm64-linux" + release-ext: "zip" - name: "macos-x86_64" runs-on: "macos-13" target: "x86_64-apple-darwin" platform: "x86_64-mac" + release-ext: "dmg" - name: "macos-arm64" runs-on: "macos-latest" target: "aarch64-apple-darwin" platform: "arm64-mac" + release-ext: "dmg" - name: "Windows" runs-on: "ubuntu-20.04" target: "x86_64-pc-windows-gnu" platform: "windows" ext: ".exe" + release-ext: "zip" runs-on: ${{ matrix.runs-on }} @@ -116,6 +121,16 @@ jobs: if: ${{ matrix.target == 'x86_64-pc-windows-gnu' }} run: curl -OL https://www.sqlite.org/2024/sqlite-dll-win-x64-3460100.zip && sudo unzip -o sqlite-dll-win-x64-3460100.zip -d winlibs && sudo chown -R runner:docker winlibs/ && pwd && ls -lah && cd winlibs && x86_64-w64-mingw32-dlltool -d sqlite3.def -l libsqlite3.a && ls -lah && cd .. + - name: Set VERSION + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "VERSION=${{ inputs.tag }}" >> $GITHUB_ENV + elif [ "${{ github.event_name }}" == "release" ]; then + echo "VERSION=${{ github.event.release.tag_name }}" >> $GITHUB_ENV + else + echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + fi + - name: Build project run: | cargo build --release --target ${{ matrix.target }} @@ -125,20 +140,93 @@ jobs: AR_x86_64_pc_windows_gnu: x86_64-w64-mingw32-ar CFLAGS_x86_64_pc_windows_gnu: "-O2" + # Install the Apple certificate + - name: Install the Apple certificate + if: contains(matrix.target, 'apple-darwin') + env: + BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE }} + P12_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }} + run: | + # create variables + CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + + # import certificate from secrets + echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH + + # create temporary keychain + security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # import certificate to keychain + security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH + + # List the keychains and set the temporary one as default + security list-keychains -d user -s $KEYCHAIN_PATH login.keychain-db + security default-keychain -s $KEYCHAIN_PATH + + # Set key partition list to allow codesign to access the key without prompting + CODE_SIGN_IDENTITY=$(security find-identity -v -p codesigning $KEYCHAIN_PATH | grep -oE '"(.*)"' | sed 's/"//g') + security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH + + # Export CODE_SIGN_IDENTITY for use in subsequent steps + echo "CODE_SIGN_IDENTITY=$CODE_SIGN_IDENTITY" >> $GITHUB_ENV + + # Sign the binary for macOS + - name: Sign binary + if: contains(matrix.target, 'apple-darwin') + run: | + codesign --strict --timestamp --options runtime --sign "$CODE_SIGN_IDENTITY" dash-evo-tool/dash-evo-tool${{ matrix.ext }} + + # Verify binary code signing + - name: Verify binary code signing + if: contains(matrix.target, 'apple-darwin') + run: | + codesign --verify --strict --verbose=2 dash-evo-tool/dash-evo-tool${{ matrix.ext }} + + # Package release - name: Package release + run: "${GITHUB_WORKSPACE}/scripts/pack.sh ${{ env.VERSION }} ${{ matrix.platform }} ${{ matrix.ext }}" + + # Sign the .dmg for macOS + - name: Sign .dmg + if: contains(matrix.target, 'apple-darwin') run: | - zip -r dash-evo-tool-${{ matrix.platform }}.zip dash-evo-tool/ + codesign --strict --timestamp --options runtime --sign "$CODE_SIGN_IDENTITY" dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }} + + # Verify .dmg code signing + - name: Verify .dmg code signing + if: contains(matrix.target, 'apple-darwin') + run: | + codesign --verify --strict --verbose=2 dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }} + + # Notarize MacOS Release Build using xcrun notarytool + - name: Notarize MacOS Release Build + if: contains(matrix.target, 'apple-darwin') + run: | + xcrun notarytool submit "dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }}" \ + --apple-id "${{ secrets.APPLE_ID }}" \ + --password "${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}" \ + --team-id "${{ secrets.APPLE_TEAM_ID }}" \ + --wait + + # Staple Notarization Ticket + - name: Staple Notarization Ticket + if: contains(matrix.target, 'apple-darwin') + run: xcrun stapler staple "dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }}" - name: Attest uses: actions/attest-build-provenance@v1 with: - subject-path: 'dash-evo-tool-${{ matrix.platform }}.zip' + subject-path: 'dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }}' - name: Upload build artifact uses: actions/upload-artifact@v4 with: - name: dash-evo-tool-${{ matrix.platform }}.zip - path: dash-evo-tool-${{ matrix.platform }}.zip + name: dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }} + path: dist/dash-evo-tool-${{ matrix.platform }}.${{ matrix.release-ext }} release: name: Create GitHub Release @@ -156,11 +244,11 @@ jobs: - name: Download MacOS AMD64 Artifact uses: actions/download-artifact@v4 with: - name: dash-evo-tool-x86_64-mac.zip + name: dash-evo-tool-x86_64-mac.dmg - name: Download MacOS ARM64 Artifact uses: actions/download-artifact@v4 with: - name: dash-evo-tool-arm64-mac.zip + name: dash-evo-tool-arm64-mac.dmg - name: Download Windows Artifact uses: actions/download-artifact@v4 with: @@ -175,8 +263,8 @@ jobs: files: | ./dash-evo-tool-x86_64-linux.zip ./dash-evo-tool-arm64-linux.zip - ./dash-evo-tool-x86_64-mac.zip - ./dash-evo-tool-arm64-mac.zip + ./dash-evo-tool-x86_64-mac.dmg + ./dash-evo-tool-arm64-mac.dmg ./dash-evo-tool-windows.zip draft: false prerelease: true \ No newline at end of file diff --git a/scripts/pack.sh b/scripts/pack.sh new file mode 100755 index 000000000..d4127ee59 --- /dev/null +++ b/scripts/pack.sh @@ -0,0 +1,146 @@ +#!/bin/bash + +set -e + +VERSION="$1" +PLATFORM="$2" +EXT="$3" + +if [ -z "PLATFORM" ]; then + echo "Error" + exit 1 +fi + +create_zip_package() { + echo "Building ZIP for $PLATFORM version $VERSION" + echo "extention is:$EXT" + + zip -r $DIST_DIR/dash-evo-tool-"$PLATFORM".zip $BUILD_DIR + + echo "Finished. Dist folder:" + ls "$DIST_DIR" +} + +create_dmg_package() { + echo "Building DMG for $PLATFORM version $VERSION" + echo "extention is:$EXT" + + APP_BUNDLE_NAME="$APP_NAME.app" + APP_BUNDLE_DIR="$BUILD_DIR/$APP_BUNDLE_NAME" + CONTENTS_DIR="$APP_BUNDLE_DIR/Contents" + MACOS_DIR="$CONTENTS_DIR/MacOS" + RESOURCES_DIR="$CONTENTS_DIR/Resources" + + # Create directories for the .app bundle + mkdir -p "$APP_BUNDLE_DIR" + mkdir -p "$MACOS_DIR" + mkdir -p "$RESOURCES_DIR" + + # Copy the binary into the app bundle + cp "$BUILD_DIR/$APP_NAME" "$MACOS_DIR/" + + ICON_SOURCE="$ROOT_PATH/mac_os/AppIcons/appstore.png" + ICONSET_DIR="$BUILD_DIR/AppIcon.iconset" + mkdir -p "$ICONSET_DIR" + + sips -z 16 16 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_16x16.png" + sips -z 32 32 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_16x16@2x.png" + sips -z 32 32 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_32x32.png" + sips -z 64 64 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_32x32@2x.png" + sips -z 128 128 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_128x128.png" + sips -z 256 256 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_128x128@2x.png" + sips -z 256 256 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_256x256.png" + sips -z 512 512 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_256x256@2x.png" + sips -z 512 512 "$ICON_SOURCE" --out "$ICONSET_DIR/icon_512x512.png" + cp "$ICON_SOURCE" "$ICONSET_DIR/icon_512x512@2x.png" + + # Convert iconset to .icns + iconutil -c icns "$ICONSET_DIR" -o "$RESOURCES_DIR/AppIcon.icns" + + # Clean up the iconset directory + rm -rf "$ICONSET_DIR" +# Create a minimal Info.plist file + cat < "$CONTENTS_DIR/Info.plist" + + + + + CFBundleName + $APP_NAME + CFBundleDisplayName + $APP_NAME + CFBundleExecutable + $APP_NAME + CFBundleIdentifier + com.example.$APP_NAME + CFBundleVersion + $VERSION + CFBundlePackageType + APPL + CFBundleSignature + ???? + LSMinimumSystemVersion + 10.9 + CFBundleIconFile + AppIcon.icns + + +EOF + + # Create the .dmg directory structure + DMG_DIR="$BUILD_DIR/dmg_content" + mkdir -p "$DMG_DIR" + + # Copy the .app bundle into the dmg content directory + cp -R "$APP_BUNDLE_DIR" "$DMG_DIR/" + + # Create a symbolic link to the Applications folder + ln -s /Applications "$DMG_DIR/Applications" + + # Create the .dmg file + hdiutil create -volname "$APP_NAME Installer" \ + -srcfolder "$DMG_DIR" \ + -ov -format UDZO \ + "$DIST_DIR/$APP_NAME-$PLATFORM.dmg" + echo "Finished. Dist folder:" + ls "$DIST_DIR" +} + +echo "Starting" + +FULL_PATH=$(realpath "$0") +DIR_PATH=$(dirname "$FULL_PATH") +ROOT_PATH=$(dirname "$DIR_PATH") + +APP_NAME="dash-evo-tool" +BUILD_DIR="$ROOT_PATH/dash-evo-tool" +DIST_DIR="$ROOT_PATH/dist" + +mkdir -p "$DIST_DIR" + +case "$PLATFORM" in + x86_64-mac) + create_dmg_package + ;; + arm64-mac) + create_dmg_package + ;; + x86_64-linux) + create_zip_package + ;; + arm64-linux) + create_zip_package + ;; + windows) + create_zip_package + ;; + *) + echo "Invalid command." + echo "$cmd_usage" + exit 1 + ;; +esac + +rm -rf "$BUILD_DIR" +echo "Done." \ No newline at end of file