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 ^
+) > 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