diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml index e1435413..1af40768 100644 --- a/.github/workflows/build-android.yml +++ b/.github/workflows/build-android.yml @@ -4,7 +4,7 @@ on: push: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*android.yml' - 'BrickController2/*.props' @@ -14,7 +14,7 @@ on: pull_request: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*android.yml' - 'BrickController2/*.props' @@ -29,12 +29,14 @@ on: permissions: contents: read +env: + TARGET_FRAMEWORK: 'net10.0-android' + PUBLISH_TRIMMED: ${{ (github.event_name == 'release' && github.event.action == 'published') }} + jobs: build-android: runs-on: windows-2025 name: BrickController Android Build - env: - APP_DISPLAY_VERSION: "" steps: @@ -47,6 +49,10 @@ jobs: - name: Install .NET MAUI Workload run: dotnet workload install maui-android + - name: Get App Version from Build Properties + shell: bash + run: echo "APP_VERSION=$(sed -n 's|.*\(.*\).*|\1|p' Directory.Build.props)" >> $GITHUB_ENV + - name: Find Current Release Info if: github.event_name == 'release' && github.event.action == 'published' id: get_release @@ -56,38 +62,59 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set APP_DISPLAY_VERSION for release - if: github.event_name == 'release' && github.event.action == 'published' - shell: bash - run: echo "APP_DISPLAY_VERSION=$(echo '${{ fromJson(steps.get_release.outputs.data).tag_name }}')" >> $GITHUB_ENV - - name: Restore Dependencies run: dotnet restore BrickController2/BrickController2.Android/BrickController2.Android.csproj - name: Setup Android signing shell: bash run: (echo "${{secrets.KEYSTORE}}" | base64 --decode) > BrickController2/BrickController2.Android/keystore.jks - - name: Build MAUI Android + - name: Build MAUI Android (APK) + run: dotnet publish BrickController2/BrickController2.Android/BrickController2.Android.csproj ` + -c Release ` + -f ${{ env.TARGET_FRAMEWORK }} ` + --no-restore ` + -p:ApplicationVersion="${{ github.run_number }}" ` + -p:AndroidSigningKeyPass=${{secrets.KEYSTORE_PASSWORD}} ` + -p:AndroidSigningStorePass=${{secrets.KEYSTORE_PASSWORD}} ` + -p:AndroidPackageFormat=apk + -p:PublishTrimmed=${{ env.PUBLISH_TRIMMED }} + + - name: Build MAUI Android (AAB) for Release + if: github.event_name == 'release' && github.event.action == 'published' run: dotnet publish BrickController2/BrickController2.Android/BrickController2.Android.csproj ` -c Release ` - -f net10.0-android ` + -f ${{ env.TARGET_FRAMEWORK }} ` --no-restore ` - -p:ApplicationDisplayVersion="${{ env.APP_DISPLAY_VERSION }}" ` + -p:ApplicationVersion="${{ github.run_number }}" ` -p:AndroidSigningKeyPass=${{secrets.KEYSTORE_PASSWORD}} ` - -p:AndroidSigningStorePass=${{secrets.KEYSTORE_PASSWORD}} + -p:AndroidSigningStorePass=${{secrets.KEYSTORE_PASSWORD}} ` + -p:AndroidPackageFormat=aab + -p:PublishTrimmed=${{ env.PUBLISH_TRIMMED }} + -p:RunAOTCompilation=${{ env.PUBLISH_TRIMMED }} - name: Upload Android Artifact uses: actions/upload-artifact@v4 with: name: brickcontroller-android-ci-build - path: BrickController2/BrickController2.Android/bin/Release/net10.0-android/com.scn.BrickController2-Signed.apk + path: BrickController2/BrickController2.Android/bin/Release/${{ env.TARGET_FRAMEWORK }}/cz.vico.BrickController-Signed.apk - - name: Upload Artifact to Release + - name: Upload APK Artifact to Release if: github.event_name == 'release' && github.event.action == 'published' uses: actions/upload-release-asset@v1 with: upload_url: ${{ fromJson(steps.get_release.outputs.data).upload_url }} - asset_path: BrickController2/BrickController2.Android/bin/Release/net10.0-android/com.scn.BrickController2-Signed.apk - asset_name: BrickController2_${{env.APP_DISPLAY_VERSION}}.apk + asset_path: BrickController2/BrickController2.Android/bin/Release/${{ env.TARGET_FRAMEWORK }}/cz.vico.BrickController-Signed.apk + asset_name: BrickController_${{env.APP_VERSION}}.apk asset_content_type: application/vnd.android.package-archive env: GITHUB_TOKEN: ${{ secrets.CI_RELEASE_ASSETS_PAT }} + + - name: Upload AAB Artifact to Release + if: github.event_name == 'release' && github.event.action == 'published' + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ fromJson(steps.get_release.outputs.data).upload_url }} + asset_path: BrickController2/BrickController2.Android/bin/Release/${{ env.TARGET_FRAMEWORK }}/cz.vico.BrickController-Signed.aab + asset_name: BrickController_${{env.APP_VERSION}}.aab + asset_content_type: application/x-authorware-bin + env: + GITHUB_TOKEN: ${{ secrets.CI_RELEASE_ASSETS_PAT }} diff --git a/.github/workflows/build-core.yml b/.github/workflows/build-core.yml index 994a4469..49030888 100644 --- a/.github/workflows/build-core.yml +++ b/.github/workflows/build-core.yml @@ -4,7 +4,7 @@ on: push: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*core.yml' - 'BrickController2/*.props' @@ -14,7 +14,7 @@ on: pull_request: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*core.yml' - 'BrickController2/*.props' diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml new file mode 100644 index 00000000..bc457844 --- /dev/null +++ b/.github/workflows/build-ios.yml @@ -0,0 +1,138 @@ +name: Build BrickController iOS + +on: + push: + branches: + - default + - 'release/**' + paths: + - '.github/**/*ios.yml' + - 'BrickController2/*.props' + - 'BrickController2/*.sln' + - 'BrickController2/BrickController2/**' + - 'BrickController2/BrickController2.iOS/**' + pull_request: + branches: + - default + - 'release/**' + paths: + - '.github/**/*ios.yml' + - 'BrickController2/*.props' + - 'BrickController2/*.sln' + - 'BrickController2/BrickController2/**' + - 'BrickController2/BrickController2.iOS/**' + release: + types: + - published + workflow_dispatch: + +permissions: + contents: read + +env: + XCODE_VERSION: '26.2' + TARGET_FRAMEWORK: 'net10.0-ios' + TARGET_RUNTIME: 'ios-arm64' + IOS_TRIM_MODE: ${{ (github.event_name == 'release' && github.event.action == 'published') && 'Full' || 'None' }} + +jobs: + build-ios: + runs-on: macos-26 + name: BrickController iOS Build + + steps: + - uses: actions/checkout@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Install MAUI workload + run: dotnet workload install maui ios + + - name: Set XCode Version + if: runner.os == 'macOS' + shell: bash + run: | + sudo xcode-select -s "/Applications/Xcode_${{ env.XCODE_VERSION }}.app" + echo "MD_APPLE_SDK_ROOT=/Applications/Xcode_${{ env.XCODE_VERSION }}.app" >> $GITHUB_ENV + + - name: Verify Xcode version + run: xcodebuild -version + + - name: Get App Version from Build Properties + shell: bash + run: echo "APP_VERSION=$(sed -n 's|.*\(.*\).*|\1|p' Directory.Build.props)" >> $GITHUB_ENV + + - name: Find Current Release Info + if: github.event_name == 'release' && github.event.action == 'published' + id: get_release + uses: octokit/request-action@v2.x + with: + route: GET /repos/${{ github.repository }}/releases/tags/${{ github.event.release.tag_name }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Import Code-Signing Certificates + uses: Apple-Actions/import-codesign-certs@v1 + with: + p12-file-base64: ${{ secrets.APPLE_SIGNING_CERTIFICATE_BASE64 }} + p12-password: ${{ secrets.APPLE_SIGNING_CERTIFICATE_PASSWORD }} + + - name: Download Apple Provisioning Profiles + uses: Apple-Actions/download-provisioning-profiles@v1 + with: + bundle-id: 'cz.vico.brickcontroller' + issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }} + api-key-id: ${{ secrets.APPSTORE_KEY_ID }} + api-private-key: ${{ secrets.APPSTORE_PRIVATE_KEY }} + + - name: List Keychain Certificates + run: security find-identity -v -p codesigning + + - name: Restore Dependencies + run: dotnet restore BrickController2/BrickController2.iOS/BrickController2.iOS.csproj + - name: Build MAUI iOS + run: >- + dotnet publish BrickController2/BrickController2.iOS/BrickController2.iOS.csproj + --no-restore + -c Release + -f ${{ env.TARGET_FRAMEWORK }} + -r ${{ env.TARGET_RUNTIME }} + -p:ApplicationVersion="${{ github.run_number }}" + -p:ArchiveOnBuild=true + -p:BuildIpa=true + -p:CodesignKey="iPhone Distribution" + -p:CodesignProvision=Automatic + -p:EnableAssemblyILStripping=false + -p:MtouchLink=${{ env.IOS_TRIM_MODE }} + + - name: List build output + run: ls -R BrickController2/BrickController2.iOS/bin/Release/${{ env.TARGET_FRAMEWORK }}/${{ env.TARGET_RUNTIME }}/publish/ + + - name: Upload IOS Artifact + uses: actions/upload-artifact@v4 + with: + name: brickcontroller-ios-ci-build + path: BrickController2/BrickController2.iOS/bin/Release/${{ env.TARGET_FRAMEWORK }}/${{ env.TARGET_RUNTIME }}/publish/BrickController2.iOS.ipa + + - name: Upload Artifact to Release + if: github.event_name == 'release' && github.event.action == 'published' + uses: actions/upload-release-asset@v1 + with: + upload_url: ${{ fromJson(steps.get_release.outputs.data).upload_url }} + asset_path: BrickController2/BrickController2.iOS/bin/Release/${{ env.TARGET_FRAMEWORK }}/${{ env.TARGET_RUNTIME }}/publish/BrickController2.iOS.ipa + asset_name: BrickController_${{env.APP_VERSION}}.ipa + asset_content_type: application/octet-stream + env: + GITHUB_TOKEN: ${{ secrets.CI_RELEASE_ASSETS_PAT }} + + - name: Upload app to TestFlight + if: github.event_name == 'release' && github.event.action == 'published' + uses: Apple-Actions/upload-testflight-build@v1 + with: + app-path: 'BrickController2/BrickController2.iOS/bin/Release/${{ env.TARGET_FRAMEWORK }}/${{ env.TARGET_RUNTIME }}/publish/BrickController2.iOS.ipa' + issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }} + api-key-id: ${{ secrets.APPSTORE_KEY_ID }} + api-private-key: ${{ secrets.APPSTORE_PRIVATE_KEY }} + diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index df304361..4a8bbcd0 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -4,7 +4,7 @@ on: push: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*windows.yml' - 'BrickController2/*.props' @@ -14,7 +14,7 @@ on: pull_request: branches: - default - - 'releases/**' + - 'release/**' paths: - '.github/**/*windows.yml' - 'BrickController2/*.props' @@ -36,9 +36,6 @@ jobs: build-winui: runs-on: windows-2025 name: BrickController WinUI Build - env: - APP_DISPLAY_VERSION: "" - APP_PACKAGE_VERSION: "" steps: - uses: actions/checkout@v4 @@ -50,6 +47,10 @@ jobs: - name: Install .NET MAUI Workload run: dotnet workload install maui-windows + - name: Get App Version from Build Properties + shell: bash + run: echo "APP_VERSION=$(sed -n 's|.*\(.*\).*|\1|p' Directory.Build.props)" >> $GITHUB_ENV + - name: Find Current Release Info if: github.event_name == 'release' && github.event.action == 'published' id: get_release @@ -59,19 +60,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set app version for release - if: github.event_name == 'release' && github.event.action == 'published' - shell: bash - run: | - TAG_NAME=$(echo '${{ fromJson(steps.get_release.outputs.data).tag_name }}') - # Split the tag into parts, remove leading zeros and add missing parts as zeros - IFS='.' read -r -a VERSION_PARTS <<< "$TAG_NAME" - for i in "${!VERSION_PARTS[@]}"; do - VERSION_PARTS[$i]=$(echo "${VERSION_PARTS[$i]}" | sed 's/^0*//') - done - echo "APP_DISPLAY_VERSION=$TAG_NAME" >> $GITHUB_ENV - echo "APP_PACKAGE_VERSION=${VERSION_PARTS[0]:-0}.${VERSION_PARTS[1]:-0}.${VERSION_PARTS[2]:-0}.${VERSION_PARTS[3]:-0}" >> $GITHUB_ENV - - name: Decode Signing Certificate run: | echo "${{ secrets.SIGNING_CERTIFICATE_BASE_64_CONTENT }}" > cert.asc @@ -88,9 +76,7 @@ jobs: -c Release ` -r win-x64 ` -p:Platform=x64 ` - -p:ApplicationDisplayVersion="${{ env.APP_DISPLAY_VERSION }}" ` - -p:ApplicationVersion="0" ` - -p:PackageVersion="${{ env.APP_PACKAGE_VERSION }}" + -p:ApplicationVersion="${{ github.run_number }}" - name: Build MAUI WinUI App run: dotnet publish ${{env.PROJECT_PATH}} ` @@ -113,7 +99,7 @@ jobs: with: upload_url: ${{ fromJson(steps.get_release.outputs.data).upload_url }} asset_path: BrickController2\BrickController2.WinUI\bin\x64\Release\net10.0-windows10.0.19041.0\win-x64\AppPackages\BrickController2.WinUI_${{env.APP_PACKAGE_VERSION}}_Test\BrickController2.WinUI_${{env.APP_PACKAGE_VERSION}}_x64.msix - asset_name: BrickController2_${{env.APP_DISPLAY_VERSION}}.msix + asset_name: BrickController_${{env.APP_VERSION}}.msix asset_content_type: application/vnd.ms-appx env: GITHUB_TOKEN: ${{ secrets.CI_RELEASE_ASSETS_PAT }} diff --git a/BrickController2/BrickController2.Android/BrickController2.Android.csproj b/BrickController2/BrickController2.Android/BrickController2.Android.csproj index decbb114..a1a24d8a 100644 --- a/BrickController2/BrickController2.Android/BrickController2.Android.csproj +++ b/BrickController2/BrickController2.Android/BrickController2.Android.csproj @@ -3,10 +3,11 @@ net10.0-android - 23.0 - 36.0 - Exe + 23.0 + 36.0 + Exe BrickController2.Droid + BrickController true Resource false diff --git a/BrickController2/BrickController2.Android/MainActivity.cs b/BrickController2/BrickController2.Android/MainActivity.cs index e95e65ea..ef9f4021 100644 --- a/BrickController2/BrickController2.Android/MainActivity.cs +++ b/BrickController2/BrickController2.Android/MainActivity.cs @@ -15,7 +15,7 @@ namespace BrickController2.Droid { [Activity( - Label = "BrickController2", + Label = "BrickController", Icon = "@mipmap/ic_launcher", Theme = "@style/MainTheme", MainLauncher = true, diff --git a/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml b/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml index 1fba04c1..6493810f 100644 --- a/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml +++ b/BrickController2/BrickController2.Android/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@  - + @@ -14,5 +14,5 @@ - + \ No newline at end of file diff --git a/BrickController2/BrickController2.WinUI/Package.appxmanifest b/BrickController2/BrickController2.WinUI/Package.appxmanifest index 735b3b00..fbb39c50 100644 --- a/BrickController2/BrickController2.WinUI/Package.appxmanifest +++ b/BrickController2/BrickController2.WinUI/Package.appxmanifest @@ -28,7 +28,7 @@ - + net10.0-ios ios-arm64 - 12.2 + 12.2 Exe - com.scn.BrickController2 - BrickController2.iOS + cz.vico.brickcontroller + BrickController2.iOS true diff --git a/BrickController2/BrickController2.iOS/Info.plist b/BrickController2/BrickController2.iOS/Info.plist index 9e684753..4f8f121a 100644 --- a/BrickController2/BrickController2.iOS/Info.plist +++ b/BrickController2/BrickController2.iOS/Info.plist @@ -23,11 +23,11 @@ MinimumOSVersion 12.2 CFBundleDisplayName - BrickController2 + BrickController CFBundleIdentifier - com.scn.brickcontroller2 + cz.vico.brickcontroller CFBundleName - BrickController2 + BrickController NSBluetoothPeripheralUsageDescription Bluetooth access is required to use SBrick, BuWizz or Powered-Up devices. NSCalendarsUsageDescription @@ -40,10 +40,6 @@ Location access is required to use SBrick, BuWizz or Powered-Up devices. NSCameraUsageDescription Camera is required in order to import a creation via QR code from another application. - CFBundleShortVersionString - 3.4 - CFBundleVersion - 50 NSBluetoothAlwaysUsageDescription Bluetooth access is required to use SBrick, BuWizz or Powered-Up devices. NSContactsUsageDescription diff --git a/BrickController2/BrickController2/UI/Pages/AboutPage.xaml b/BrickController2/BrickController2/UI/Pages/AboutPage.xaml index aadbb30f..793312b1 100644 --- a/BrickController2/BrickController2/UI/Pages/AboutPage.xaml +++ b/BrickController2/BrickController2/UI/Pages/AboutPage.xaml @@ -19,7 +19,8 @@ - diff --git a/BrickController2/BrickController2/UI/ViewModels/ControllerActionPageViewModel.cs b/BrickController2/BrickController2/UI/ViewModels/ControllerActionPageViewModel.cs index 9e75d47d..d6b8bfa4 100644 --- a/BrickController2/BrickController2/UI/ViewModels/ControllerActionPageViewModel.cs +++ b/BrickController2/BrickController2/UI/ViewModels/ControllerActionPageViewModel.cs @@ -147,7 +147,7 @@ public override void OnAppearing() } public override void OnDisappearing() { - _preferences.Set("LastSelectedDeviceId", _selectedDevice!.Id, "com.scn.BrickController2.ControllerActionPage"); + _preferences.Set("LastSelectedDeviceId", _selectedDevice!.Id, "ControllerActionPage"); base.OnDisappearing(); } diff --git a/Directory.Build.props b/Directory.Build.props index 98015fcd..65ea4036 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -21,6 +21,6 @@ 3.4 - 50 + 51 \ No newline at end of file diff --git a/README.md b/README.md index 64954c3a..635dc302 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -# BrickController 2 +# BrickController -Cross platform mobile application for controlling your creations using a bluetooth gamepad. +Cross-platform application, forked from [BrickController 2](https://github.com/imurvai/brickcontroller2), for controlling LEGO® and compatible brick creations using a Bluetooth gamepad. + +This app lets you control your motorized builds — whether made from LEGO® or other compatible brick systems—using a standard Bluetooth game controller. ## Supported platforms @@ -38,7 +40,7 @@ Cross platform mobile application for controlling your creations using a bluetoo ## Project details -BrickController 2 is a MAUI application and can be compiled using Visual Studio 2026 (Professional, Enterprise and Community Editions) +BrickController is a MAUI application and can be compiled using Visual Studio 2026 (Professional, Enterprise and Community Editions) or Visual Studio for Mac. ## 3rd party libraries used @@ -53,3 +55,4 @@ or Visual Studio for Mac. ## Author István Murvai +Vít Německý