diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 8f5f1d6..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug, triage -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Environment (please complete the following information):** - - OS and Architecture: [e.g. MacOS, Apple Silicon/aarch64) - - Scope Version [e.g. 0.1.0] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..f82a4f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,65 @@ +name: Bug report +description: Create a report to help us improve +title: "[Bug]: " +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: textarea + id: bug-description + attributes: + label: Describe the bug + description: A clear and concise description of what the bug is + validations: + required: true + - type: textarea + id: reproduction + attributes: + label: Steps to reproduce + description: How can we reproduce this issue? + placeholder: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected behavior + description: What did you expect to happen? + validations: + required: true + - type: input + id: os + attributes: + label: Operating System and Architecture + description: What OS and architecture are you using? + placeholder: "e.g. MacOS, Apple Silicon/aarch64" + validations: + required: true + - type: input + id: version + attributes: + label: Scope Version + description: What version of Scope are you running? + placeholder: "e.g. 0.1.0" + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: Screenshots + description: If applicable, add screenshots to help explain your problem + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: Add any other context about the problem here + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 8e0ee3c..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for Scope -title: '' -labels: enhancement, triage -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..ced2c23 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,38 @@ +name: Feature request +description: Suggest an idea for Scope +title: "[Feature]: " +labels: ["enhancement", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to suggest a feature! + - type: textarea + id: problem + attributes: + label: Is your feature request related to a problem? + description: A clear and concise description of what the problem is + placeholder: "I'm always frustrated when [...]" + validations: + required: true + - type: textarea + id: solution + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen + validations: + required: true + - type: textarea + id: alternatives + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered + validations: + required: false + - type: textarea + id: additional + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here + validations: + required: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fc917be..1ed1388 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,7 @@ on: env: CARGO_TERM_COLOR: always + APP_BUNDLE_ID: "com.scopeclient.desktop" jobs: get-version: @@ -175,6 +176,10 @@ jobs: needs: get-version name: Build macOS (Intel) runs-on: macos-latest + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + KEYCHAIN_PASSWORD: $(openssl rand -base64 32) steps: - uses: actions/checkout@v4 with: @@ -214,7 +219,7 @@ jobs: CFBundleDisplayName Scope CFBundleIdentifier - com.scope.app + ${{ env.APP_BUNDLE_ID }} CFBundleVersion ${{ needs.get-version.outputs.version }} CFBundlePackageType @@ -233,6 +238,25 @@ jobs: EOF + - name: Import Apple Developer Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + rm certificate.p12 + + - name: Sign App Bundle + run: | + codesign --force --options runtime --sign "Apple Development" Scope.app + codesign --verify --verbose Scope.app + - name: Create DMG run: | hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope-${{ needs.get-version.outputs.version }}_intel.dmg @@ -247,6 +271,10 @@ jobs: needs: get-version name: Build macOS (Silicon) runs-on: macos-latest + env: + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + KEYCHAIN_PASSWORD: $(openssl rand -base64 32) steps: - uses: actions/checkout@v4 with: @@ -286,7 +314,7 @@ jobs: CFBundleDisplayName Scope CFBundleIdentifier - com.scope.app + ${{ env.APP_BUNDLE_ID }} CFBundleVersion ${{ needs.get-version.outputs.version }} CFBundlePackageType @@ -305,6 +333,25 @@ jobs: EOF + - name: Import Apple Developer Certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + rm certificate.p12 + + - name: Sign App Bundle + run: | + codesign --force --options runtime --sign "Apple Development" Scope.app + codesign --verify --verbose Scope.app + - name: Create DMG run: | hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope-${{ needs.get-version.outputs.version }}_silicon.dmg diff --git a/.scripts/linux.sh b/.scripts/linux.sh new file mode 100644 index 0000000..22a0148 --- /dev/null +++ b/.scripts/linux.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +if [ -f .env ]; then + export $(cat .env | grep -v '^#' | xargs) +fi + +set -e + +echo "Building Scope..." +cargo build --release + +echo "Creating AppImage structure..." +mkdir -p AppDir/usr/share/applications +mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps/ +mkdir -p AppDir/usr/bin + +cat > AppDir/usr/share/applications/scope.desktop << EOF +[Desktop Entry] +Name=Scope +Exec=scope +Icon=scope +Type=Application +Categories=Development; +EOF + +echo "Copying files..." +cp target/release/scope AppDir/usr/bin/ +cp .github/scope-round-200.png AppDir/usr/share/icons/hicolor/256x256/apps/scope.png + +echo "Installing AppImage dependencies..." +sudo apt-get update +sudo apt-get install -y libfuse2 + +echo "Creating AppImage..." +wget -O linuxdeploy-x86_64.AppImage https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage +chmod +x linuxdeploy-x86_64.AppImage +./linuxdeploy-x86_64.AppImage --appdir AppDir --output appimage + +VERSION=$(grep '^version = ' src/ui/Cargo.toml | cut -d '"' -f2) +mv Scope*.AppImage ../Scope-${VERSION}.AppImage +rm -rf AppDir linuxdeploy-x86_64.AppImage + +echo "Build complete! AppImage is ready: Scope-${VERSION}.AppImage" diff --git a/.scripts/macOS.sh b/.scripts/macOS.sh new file mode 100755 index 0000000..d57b5e1 --- /dev/null +++ b/.scripts/macOS.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +# APPLE_CERTIFICATE - Your Apple Developer certificate +# APPLE_CERTIFICATE_PASSWORD - Password for your certificate +# APPLE_ID - Your Apple ID email +# APPLE_ID_PASSWORD - Your Apple ID password +# KEYCHAIN_PASSWORD - Password for the keychain +# APP_BUNDLE_ID - Your app bundle identifier (e.g., "com.scope.app") + +if [ -f .env ]; then + export $(cat .env | grep -v '^#' | xargs) +fi + +set -e + +required_vars=("APPLE_CERTIFICATE" "APPLE_CERTIFICATE_PASSWORD" "APPLE_ID" "APPLE_ID_PASSWORD" "KEYCHAIN_PASSWORD" "APP_BUNDLE_ID") +for var in "${required_vars[@]}"; do + if [ -z "${!var}" ]; then + exit 1 + fi +done + +echo "Building Scope..." +cargo build --release + +echo "Creating app bundle..." +mkdir -p Scope.app/Contents/{MacOS,Resources} +cp target/release/scope Scope.app/Contents/MacOS/ +cp .github/scope-round-200.png Scope.app/Contents/Resources/scope.icns + +cat > Scope.app/Contents/Info.plist << EOF + + + + + CFBundleName + Scope + CFBundleDisplayName + Scope + CFBundleIdentifier + ${APP_BUNDLE_ID} + CFBundleVersion + $(grep '^version = ' src/ui/Cargo.toml | cut -d '"' -f2) + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleExecutable + scope + CFBundleIconFile + scope.icns + LSMinimumSystemVersion + 10.13 + NSHighResolutionCapable + + + +EOF + +echo "Setting up certificate..." +rm -f certificate.p12 +echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12 2>/dev/null +security import certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A 2>/dev/null + +SIGNING_IDENTITY=$(security find-identity -v -p codesigning | grep "Apple Development" | head -1 | awk -F '"' '{print $2}') + +if [ -z "$SIGNING_IDENTITY" ]; then + exit 1 +fi + +echo "Using signing identity: $SIGNING_IDENTITY" +echo "Signing application..." +codesign --force --options runtime --sign "$SIGNING_IDENTITY" Scope.app 2>/dev/null + +rm -f certificate.p12 + +echo "Creating DMG..." +hdiutil create -volname "Scope" -srcfolder Scope.app -ov -format UDZO Scope.dmg + +echo "Signing DMG..." +codesign --force --sign "$APPLE_CERTIFICATE" Scope.dmg 2>/dev/null + +echo "Notarizing DMG..." +xcrun notarytool submit Scope.dmg --apple-id "$APPLE_ID" --password "$APPLE_ID_PASSWORD" --team-id "$APPLE_CERTIFICATE" --wait + +echo "Stapling notarization..." +xcrun stapler staple Scope.dmg + +echo "Build complete! Signed and notarized DMG is ready: Scope.dmg" diff --git a/.scripts/windows.bat b/.scripts/windows.bat new file mode 100644 index 0000000..d9ec5b4 --- /dev/null +++ b/.scripts/windows.bat @@ -0,0 +1,66 @@ +@echo off +setlocal enabledelayedexpansion + +if exist .env ( + for /f "tokens=*" %%a in (.env) do set %%a +) + +echo Building Scope... +cargo build --release + +echo Creating installer directory structure... +mkdir installer\bin + +echo Copying files... +copy target\release\scope.exe installer\bin\ +copy .github\scope-round-200.png installer\scope.ico + +echo Creating WiX files... +( +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +echo ^ +) > scope.wxs + +echo Building MSI... +candle scope.wxs +light -ext WixUIExtension scope.wixobj + +echo Cleaning up build files... +rmdir /s /q installer +del scope.wxs +del scope.wixobj +del scope.wixpdb + +echo Build complete! MSI installer is ready: scope.msi