diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f259fa3 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,49 @@ +name: Build (PR) + +on: + workflow_dispatch: + pull_request: + branches: + - main + push: + branches: + - main + +env: + DEVELOPER_DIR: /Applications/Xcode_15.0.app/Contents/Developer + +jobs: + build: + name: Build and Publish Release + runs-on: macOS-13 + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install certificates + env: + MAC_SIGN_CERT: ${{ secrets.MAC_SIGN_CERT }} + MAC_SIGN_PW: ${{ secrets.MAC_SIGN_PW }} + KEYCHAIN_TIMEOUT: 21600 + run: | + MAC_CERT_P12="$RUNNER_TEMP/mac_cert.p12" + KEYCHAIN_DB="$RUNNER_TEMP/keychain.keychain-db" + KEYCHAIN_PW=$(openssl rand -base64 24) + + security create-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_DB" + security set-keychain-settings -lut "$KEYCHAIN_TIMEOUT" "$KEYCHAIN_DB" + security unlock-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_DB" + + echo -n "$MAC_SIGN_CERT" | base64 --decode -o "$MAC_CERT_P12" + security import "$MAC_CERT_P12" -P "$MAC_SIGN_PW" -A -t cert -f pkcs12 -k "$KEYCHAIN_DB" + security list-keychain -d user -s "$KEYCHAIN_DB" + + - name: Build + env: + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + set -o pipefail && xcodebuild build -project "TimeMachineStatus.xcodeproj" \ + -scheme "TimeMachineStatus" \ + -configuration "Release" \ + -derivedDataPath "$RUNNER_TEMP/DerivedData" \ + DEVELOPMENT_TEAM=$APPLE_TEAM_ID diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..cc829af --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,95 @@ +name: Build & Publish + +on: + workflow_dispatch: + +env: + DEVELOPER_DIR: /Applications/Xcode_15.0.app/Contents/Developer + +jobs: + build: + name: Build and Publish Release + runs-on: macOS-13 + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Tooling + run: | + brew install create-dmg + + - name: Install certificates + env: + DEV_SIGN_CERT: ${{ secrets.DEV_SIGN_CERT }} + DEV_SIGN_PW: ${{ secrets.DEV_SIGN_PW }} + MAC_SIGN_CERT: ${{ secrets.MAC_SIGN_CERT }} + MAC_SIGN_PW: ${{ secrets.MAC_SIGN_PW }} + KEYCHAIN_TIMEOUT: 21600 + run: | + DEV_CERT_P12="$RUNNER_TEMP/dev_cert.p12" + MAC_CERT_P12="$RUNNER_TEMP/mac_cert.p12" + KEYCHAIN_DB="$RUNNER_TEMP/keychain.keychain-db" + KEYCHAIN_PW=$(openssl rand -base64 24) + + security create-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_DB" + security set-keychain-settings -lut "$KEYCHAIN_TIMEOUT" "$KEYCHAIN_DB" + security unlock-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_DB" + + echo -n "$DEV_SIGN_CERT" | base64 --decode -o "$DEV_CERT_P12" + security import "$DEV_CERT_P12" -P "$DEV_SIGN_PW" -A -t cert -f pkcs12 -k "$KEYCHAIN_DB" + echo -n "$MAC_SIGN_CERT" | base64 --decode -o "$MAC_CERT_P12" + security import "$MAC_CERT_P12" -P "$MAC_SIGN_PW" -A -t cert -f pkcs12 -k "$KEYCHAIN_DB" + security list-keychain -d user -s "$KEYCHAIN_DB" + + - name: Build + env: + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + set -o pipefail && xcodebuild archive -project "TimeMachineStatus.xcodeproj" \ + -scheme "TimeMachineStatus" \ + -configuration "Release" \ + -derivedDataPath "$RUNNER_TEMP/DerivedData" \ + -archivePath "$RUNNER_TEMP/TimeMachineStatus.xcarchive" \ + DEVELOPMENT_TEAM=$APPLE_TEAM_ID + + - name: Sign + env: + CODE_SIGN_IDENTITY: ${{ secrets.CODE_SIGN_IDENTITY }} + run: | + codesign \ + --sign "$CODE_SIGN_IDENTITY" \ + -vvv --verbose --strict \ + --options=runtime \ + --prefix com.lukaspistrol.TimeMachineStatus \ + --force --deep --timestamp \ + "$RUNNER_TEMP/TimeMachineStatus.xcarchive/Products/Applications/TimeMachineStatus.app" + + - name: Create DMG + env: + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + run: | + xcrun notarytool store-credentials TimeMachineStatus \ + --apple-id "$APPLE_ID" \ + --team-id "$APPLE_TEAM_ID" \ + --password "$APPLE_ID_PASSWORD" + create-dmg \ + --volname "TimeMachineStatus" \ + --volicon "$RUNNER_TEMP/TimeMachineStatus.xcarchive/Products/Applications/TimeMachineStatus.app/Contents/Resources/AppIcon.icns" \ + --window-pos 200 120 \ + --window-size 800 400 \ + --icon-size 100 \ + --icon "TimeMachineStatus.app" 200 190 \ + --hide-extension "TimeMachineStatus.app" \ + --app-drop-link 600 185 \ + --notarize "TimeMachineStatus" \ + --skip-jenkins \ + "$RUNNER_TEMP/TimeMachineStatus.dmg" \ + "$RUNNER_TEMP/TimeMachineStatus.xcarchive/Products/Applications/TimeMachineStatus.app" + + - name: Clean up keychain and provisioning profile + if: ${{ always() }} + run: | + security delete-keychain "$RUNNER_TEMP/keychain.keychain-db" + rm -rf "~/Library/MobileDevice/Provisioning Profiles" diff --git a/.gitignore b/.gitignore index 330d167..e8426f5 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,5 @@ fastlane/test_output # https://github.com/johnno1962/injectionforxcode iOSInjectionProject/ + +.env diff --git a/TimeMachineStatus.xcodeproj/project.pbxproj b/TimeMachineStatus.xcodeproj/project.pbxproj index 8435111..b955072 100644 --- a/TimeMachineStatus.xcodeproj/project.pbxproj +++ b/TimeMachineStatus.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 28A0021D2AFBBFC300E2A01E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A0021C2AFBBFC300E2A01E /* SettingsView.swift */; }; 28A0021F2AFBBFC400E2A01E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 28A0021E2AFBBFC400E2A01E /* Assets.xcassets */; }; 28A002222AFBBFC400E2A01E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 28A002212AFBBFC400E2A01E /* Preview Assets.xcassets */; }; - 28A002472AFBC09000E2A01E /* SFSymbolsMacro in Frameworks */ = {isa = PBXBuildFile; productRef = 28A002462AFBC09000E2A01E /* SFSymbolsMacro */; }; 28A0024A2AFBC91500E2A01E /* ShellOut in Frameworks */ = {isa = PBXBuildFile; productRef = 28A002492AFBC91500E2A01E /* ShellOut */; }; 28A0024D2AFC02DA00E2A01E /* Bool+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A0024C2AFC02DA00E2A01E /* Bool+.swift */; }; 28A0024F2AFC030500E2A01E /* Symbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A0024E2AFC030500E2A01E /* Symbols.swift */; }; @@ -138,7 +137,6 @@ 281822622AFD40920067E564 /* Logging in Frameworks */, 28A0024A2AFBC91500E2A01E /* ShellOut in Frameworks */, 28263FA32B023FFE00F74655 /* ServiceManagement.framework in Frameworks */, - 28A002472AFBC09000E2A01E /* SFSymbolsMacro in Frameworks */, 281822652AFD438B0067E564 /* LoggingOSLog in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -356,7 +354,6 @@ ); name = TimeMachineStatus; packageProductDependencies = ( - 28A002462AFBC09000E2A01E /* SFSymbolsMacro */, 28A002492AFBC91500E2A01E /* ShellOut */, 281822612AFD40920067E564 /* Logging */, 281822642AFD438B0067E564 /* LoggingOSLog */, @@ -395,7 +392,6 @@ ); mainGroup = 28A0020E2AFBBFC300E2A01E; packageReferences = ( - 28A002452AFBC09000E2A01E /* XCRemoteSwiftPackageReference "SFSymbolsMacro" */, 28A002482AFBC91500E2A01E /* XCRemoteSwiftPackageReference "ShellOut" */, 281822602AFD40920067E564 /* XCRemoteSwiftPackageReference "swift-log" */, 281822632AFD438B0067E564 /* XCRemoteSwiftPackageReference "swift-log-oslog" */, @@ -771,14 +767,6 @@ minimumVersion = 0.2.2; }; }; - 28A002452AFBC09000E2A01E /* XCRemoteSwiftPackageReference "SFSymbolsMacro" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/lukepistrol/SFSymbolsMacro.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.5.0; - }; - }; 28A002482AFBC91500E2A01E /* XCRemoteSwiftPackageReference "ShellOut" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/JohnSundell/ShellOut.git"; @@ -800,11 +788,6 @@ package = 281822632AFD438B0067E564 /* XCRemoteSwiftPackageReference "swift-log-oslog" */; productName = LoggingOSLog; }; - 28A002462AFBC09000E2A01E /* SFSymbolsMacro */ = { - isa = XCSwiftPackageProductDependency; - package = 28A002452AFBC09000E2A01E /* XCRemoteSwiftPackageReference "SFSymbolsMacro" */; - productName = SFSymbolsMacro; - }; 28A002492AFBC91500E2A01E /* ShellOut */ = { isa = XCSwiftPackageProductDependency; package = 28A002482AFBC91500E2A01E /* XCRemoteSwiftPackageReference "ShellOut" */; diff --git a/TimeMachineStatus.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TimeMachineStatus.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1c8ec6b..dd4c70e 100644 --- a/TimeMachineStatus.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/TimeMachineStatus.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,14 +1,5 @@ { "pins" : [ - { - "identity" : "sfsymbolsmacro", - "kind" : "remoteSourceControl", - "location" : "https://github.com/lukepistrol/SFSymbolsMacro.git", - "state" : { - "revision" : "ad2183d29dc928f7f9cd5dc6efcc4546efc7857b", - "version" : "0.5.1" - } - }, { "identity" : "shellout", "kind" : "remoteSourceControl", @@ -35,15 +26,6 @@ "revision" : "176d41d46429e79c806333025b226e0c50a0c602", "version" : "0.2.2" } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", - "state" : { - "revision" : "6ad4ea24b01559dde0773e3d091f1b9e36175036", - "version" : "509.0.2" - } } ], "version" : 2 diff --git a/TimeMachineStatus/Symbols.swift b/TimeMachineStatus/Symbols.swift index 38ed042..78a74cd 100644 --- a/TimeMachineStatus/Symbols.swift +++ b/TimeMachineStatus/Symbols.swift @@ -10,9 +10,7 @@ // import SwiftUI -import SFSymbolsMacro -@SFSymbol enum Symbols: String { case checkmarkCircleFill = "checkmark.circle.fill" case exclamationMarkTriangleFill = "exclamationmark.triangle.fill" @@ -26,4 +24,20 @@ enum Symbols: String { case timeMachine = "clock.arrow.circlepath" case wandAndStarsInverse = "wand.and.stars.inverse" case xmarkCircleFill = "xmark.circle.fill" + + var image: Image { + Image(systemName: self.rawValue) + } + + var name: String { + self.rawValue + } + + func nsImage(accessibilityDescription: String? = nil) -> NSImage { + return NSImage(systemSymbolName: self.rawValue, accessibilityDescription: accessibilityDescription)! + } + + func callAsFunction() -> String { + return self.rawValue + } }