Build v0.16.4.0 #18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| run-name: Build v${{ vars.CURRENT_VERSION }} | |
| on: | |
| #push: | |
| # branches: | |
| # - main | |
| # paths-ignore: | |
| # - 'README.md' | |
| workflow_dispatch: | |
| inputs: | |
| windows_runner: | |
| description: 'Windows Runner' | |
| required: true | |
| default: 'windows-latest' | |
| type: choice | |
| options: | |
| - windows-latest | |
| - self-hosted | |
| retention_days_artifacts: | |
| description: 'Retention Days for Artifacts' | |
| required: false | |
| default: 1 | |
| type: number | |
| env: | |
| VERSION: ${{vars.CURRENT_VERSION}} | |
| RETENTION_DAYS_ARTIFACTS: ${{ inputs.retention_days_artifacts || 1 }} | |
| jobs: | |
| set-version: | |
| name: Increment Version | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| actions: write | |
| outputs: | |
| version: ${{ steps.setver.outputs.version }} | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_VARIABLES_PAT }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| - name: Set Next Version | |
| id: setver | |
| shell: pwsh | |
| run: | | |
| $CurrentVersion = [System.Version]::Parse("${{ vars.CURRENT_VERSION }}") | |
| echo "Resolved current version: $CurrentVersion" | |
| $NextVersion = "$($CurrentVersion.Major).$($CurrentVersion.Minor).$($CurrentVersion.Build + 1).0" | |
| echo "Next version will be: $NextVersion" | |
| gh variable set CURRENT_VERSION --body $NextVersion | |
| run-tests: | |
| name: Run Tests | |
| runs-on: ubuntu-latest | |
| needs: set-version | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.x' | |
| - name: Run Tests | |
| run: | | |
| dotnet test -c Release | |
| build-mac-binaries: | |
| name: Apple Build | |
| runs-on: macos-latest | |
| needs: set-version | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.x' | |
| - name: Publish DesktopClient + Agent (ARM64) | |
| run: | | |
| # Clean Resources folder | |
| rm -f "./ControlR.Agent.Common/Resources/*.zip" | |
| # Build DesktopClient | |
| dotnet publish "./ControlR.DesktopClient/" -c Release -r osx-arm64 --self-contained -o "./ControlR.DesktopClient/bin/publish/osx-arm64/" -p:Version=$VERSION -p:FileVersion=$VERSION | |
| sudo codesign --force --deep --entitlements "./.build/Mac/ControlR.entitlements" --sign - "./ControlR.DesktopClient/bin/publish/osx-arm64/ControlR.DesktopClient" | |
| pwsh "./.build/Mac/CreateMacApp.ps1" -OutputDir "./ControlR.DesktopClient/bin/publish/osx-arm64/" | |
| ditto -c -k --sequesterRsrc "./ControlR.DesktopClient/bin/publish/osx-arm64/" "./ControlR.DesktopClient/bin/publish/osx-arm64/ControlR.app.zip" | |
| # Copy DesktopClient ZIP to Agent Resources | |
| mkdir -p "./ControlR.Agent.Common/Resources" | |
| cp "./ControlR.DesktopClient/bin/publish/osx-arm64/ControlR.app.zip" "./ControlR.Agent.Common/Resources/ControlR.app.zip" | |
| # Build Agent | |
| dotnet publish "./ControlR.Agent/" -c Release -r osx-arm64 --self-contained -o "./ControlR.Agent/bin/publish/osx-arm64/" -p:PublishSingleFile=true -p:UseAppHost=true -p:Version=$VERSION -p:FileVersion=$VERSION -p:IncludeAllContentForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:IncludeAppSettingsInSingleFile=true | |
| sudo codesign --force --deep --entitlements "./.build/Mac/ControlR.entitlements" --sign - "./ControlR.Agent/bin/publish/osx-arm64/ControlR.Agent" | |
| - name: Publish DesktopClient + Agent (x64) | |
| run: | | |
| # Clean Resources folder | |
| rm -f "./ControlR.Agent.Common/Resources/*.zip" | |
| # Build DesktopClient | |
| dotnet publish "./ControlR.DesktopClient/" -c Release -r osx-x64 --self-contained -o "./ControlR.DesktopClient/bin/publish/osx-x64/" -p:Version=$VERSION -p:FileVersion=$VERSION | |
| sudo codesign --force --deep --entitlements "./.build/Mac/ControlR.entitlements" --sign - "./ControlR.DesktopClient/bin/publish/osx-x64/ControlR.DesktopClient" | |
| pwsh "./.build/Mac/CreateMacApp.ps1" -OutputDir "./ControlR.DesktopClient/bin/publish/osx-x64/" | |
| ditto -c -k --sequesterRsrc "./ControlR.DesktopClient/bin/publish/osx-x64/" "./ControlR.DesktopClient/bin/publish/osx-x64/ControlR.app.zip" | |
| # Copy DesktopClient ZIP to Agent Resources | |
| mkdir -p "./ControlR.Agent.Common/Resources" | |
| mv "./ControlR.DesktopClient/bin/publish/osx-x64/ControlR.app.zip" "./ControlR.Agent.Common/Resources/ControlR.app.zip" | |
| # Build Agent | |
| dotnet publish "./ControlR.Agent/" -c Release -r osx-x64 --self-contained -o "./ControlR.Agent/bin/publish/osx-x64/" -p:PublishSingleFile=true -p:UseAppHost=true -p:Version=$VERSION -p:FileVersion=$VERSION -p:IncludeAllContentForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:IncludeAppSettingsInSingleFile=true | |
| sudo codesign --force --deep --entitlements "./.build/Mac/ControlR.entitlements" --sign - "./ControlR.Agent/bin/publish/osx-x64/ControlR.Agent" | |
| - name: Upload Agent (macOS ARM64) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Agent-macOS-ARM64 | |
| path: ControlR.Agent/bin/publish/osx-arm64/ControlR.Agent | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| - name: Upload Agent (macOS x64) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Agent-macOS-x64 | |
| path: ControlR.Agent/bin/publish/osx-x64/ControlR.Agent | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| build-windows-binaries: | |
| name: Windows Build (${{ matrix.arch }}) | |
| runs-on: ${{ inputs.windows_runner || 'windows-latest' }} | |
| environment: secure-signing | |
| needs: [set-version] | |
| permissions: | |
| id-token: write | |
| contents: read | |
| strategy: | |
| matrix: | |
| arch: [win-x86, win-x64] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.x' | |
| - name: Pack ControlR.ApiClient (Release) | |
| run: dotnet build ControlR.ApiClient/ControlR.ApiClient.csproj -c Release -p:Version=${{ env.VERSION }} | |
| - name: Find ApiClient nupkg | |
| id: find-nupkg | |
| shell: pwsh | |
| run: | | |
| $searchDir = 'ControlR.ApiClient\bin\Release' | |
| Write-Host "Searching for nupkg in $searchDir" | |
| if (!(Test-Path $searchDir)) { | |
| Write-Error "Directory $searchDir not found" | |
| exit 1 | |
| } | |
| $pkg = Get-ChildItem -Path $searchDir -Filter 'ControlR.ApiClient*.nupkg' -File | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | |
| if (-not $pkg) { | |
| Write-Error 'ApiClient nupkg not found in Release folder.' | |
| exit 1 | |
| } | |
| Write-Host "Found package: $($pkg.FullName)" | |
| echo "APICLIENT_NUPKG=$($pkg.FullName)" >> $env:GITHUB_OUTPUT | |
| - name: Upload ApiClient NuGet | |
| if: matrix.arch == 'win-x64' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ApiClientNuGet | |
| path: ${{ steps.find-nupkg.outputs.APICLIENT_NUPKG }} | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| # ===== Azure Login with OIDC ===== | |
| - name: Azure Login | |
| uses: azure/login@v2 | |
| with: | |
| client-id: ${{ secrets.AZURE_CLIENT_ID }} | |
| tenant-id: ${{ secrets.AZURE_TENANT_ID }} | |
| subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} | |
| # ===== Install AzureSignTool ===== | |
| - name: Install AzureSignTool | |
| shell: pwsh | |
| run: | | |
| dotnet tool install --global AzureSignTool | |
| # ===== Build Windows ===== | |
| - name: Build DesktopClient (${{ matrix.arch }}) | |
| shell: pwsh | |
| run: | | |
| # Clean Resources folder | |
| Remove-Item -Path "ControlR.Agent.Common\Resources\*.zip" -Force -ErrorAction SilentlyContinue | |
| # Build DesktopClient | |
| dotnet publish ControlR.DesktopClient\ -c Release -r ${{ matrix.arch }} --self-contained -o ControlR.DesktopClient\bin\publish\${{ matrix.arch }}\ -p:Version=$env:VERSION -p:FileVersion=$env:VERSION | |
| - name: Sign DesktopClient (${{ matrix.arch }}) | |
| shell: pwsh | |
| run: | | |
| AzureSignTool sign ` | |
| --du="${{ vars.SIGNING_DESCRIPTION_URL }}" ` | |
| --fd=sha256 ` | |
| --kvu="${{ secrets.AZURE_KEY_VAULT_URI }}" ` | |
| --kvc="${{ secrets.AZURE_KEY_VAULT_CERTIFICATE_NAME }}" ` | |
| --kvm ` | |
| --tr=http://timestamp.digicert.com ` | |
| --td=sha256 ` | |
| "${{ github.workspace }}\ControlR.DesktopClient\bin\publish\${{ matrix.arch }}\ControlR.DesktopClient.exe" | |
| - name: Package and Prepare DesktopClient (${{ matrix.arch }}) | |
| shell: pwsh | |
| run: | | |
| # Create staging directory | |
| New-Item -Path ".build\staging-desktop\${{ matrix.arch }}" -ItemType Directory -Force | Out-Null | |
| # Create ZIP | |
| Compress-Archive -Path "ControlR.DesktopClient\bin\publish\${{ matrix.arch }}\*" -DestinationPath ".build\staging-desktop\${{ matrix.arch }}\ControlR.DesktopClient.zip" -Force | |
| # Copy to Agent Resources | |
| New-Item -Path "ControlR.Agent.Common\Resources" -ItemType Directory -Force | Out-Null | |
| Copy-Item ".build\staging-desktop\${{ matrix.arch }}\ControlR.DesktopClient.zip" "ControlR.Agent.Common\Resources\ControlR.DesktopClient.zip" -Force | |
| - name: Build Agent (${{ matrix.arch }}) | |
| shell: pwsh | |
| run: | | |
| New-Item -Path "ControlR.Web.Server\wwwroot\downloads\${{ matrix.arch }}" -ItemType Directory -Force | Out-Null | |
| dotnet publish ControlR.Agent\ -c Release -r ${{ matrix.arch }} -o ControlR.Web.Server\wwwroot\downloads\${{ matrix.arch }}\ -p:PublishSingleFile=true -p:UseAppHost=true -p:Version=$env:VERSION -p:FileVersion=$env:VERSION -p:IncludeAllContentForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:IncludeAppSettingsInSingleFile=true | |
| - name: Sign Agent (${{ matrix.arch }}) | |
| shell: pwsh | |
| run: | | |
| AzureSignTool sign ` | |
| --du="${{ vars.SIGNING_DESCRIPTION_URL }}" ` | |
| --fd=sha256 ` | |
| --kvu="${{ secrets.AZURE_KEY_VAULT_URI }}" ` | |
| --kvc="${{ secrets.AZURE_KEY_VAULT_CERTIFICATE_NAME }}" ` | |
| --kvm ` | |
| --tr=http://timestamp.digicert.com ` | |
| --td=sha256 ` | |
| "${{ github.workspace }}\ControlR.Web.Server\wwwroot\downloads\${{ matrix.arch }}\ControlR.Agent.exe" | |
| - name: Upload Agent (${{ matrix.arch }}) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Agent-${{ matrix.arch }} | |
| path: ControlR.Web.Server\wwwroot\downloads\${{ matrix.arch }}\ControlR.Agent.exe | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| build-linux-binaries: | |
| name: Linux Build | |
| runs-on: ubuntu-latest | |
| needs: [set-version] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.x' | |
| - name: Build DesktopClient (linux-x64) | |
| run: | | |
| # Clean Resources folder | |
| rm -f "./ControlR.Agent.Common/Resources/*.zip" | |
| # Build DesktopClient | |
| dotnet publish ./ControlR.DesktopClient/ -c Release -r linux-x64 --self-contained -o ./ControlR.DesktopClient/bin/publish/linux-x64/ -p:Version=$VERSION -p:FileVersion=$VERSION | |
| # Create staging directory | |
| mkdir -p ".build/staging-desktop/linux-x64" | |
| # Create ZIP | |
| cd ./ControlR.DesktopClient/bin/publish/linux-x64/ | |
| zip -r ../../../../.build/staging-desktop/linux-x64/ControlR.DesktopClient.zip . | |
| cd ../../../.. | |
| # Copy to Agent Resources | |
| mkdir -p "./ControlR.Agent.Common/Resources" | |
| cp ".build/staging-desktop/linux-x64/ControlR.DesktopClient.zip" "./ControlR.Agent.Common/Resources/ControlR.DesktopClient.zip" | |
| - name: Build Agent (linux-x64) | |
| run: | | |
| mkdir -p "./ControlR.Web.Server/wwwroot/downloads/linux-x64" | |
| dotnet publish ./ControlR.Agent/ -c Release -r linux-x64 -o ./ControlR.Web.Server/wwwroot/downloads/linux-x64/ -p:PublishSingleFile=true -p:UseAppHost=true -p:Version=$VERSION -p:FileVersion=$VERSION -p:IncludeAllContentForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:IncludeAppSettingsInSingleFile=true | |
| - name: Upload Agent (linux-x64) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Agent-linux-x64 | |
| path: ControlR.Web.Server/wwwroot/downloads/linux-x64/ControlR.Agent | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| build-web-server: | |
| name: Build Web Server | |
| runs-on: windows-latest | |
| needs: [build-windows-binaries, build-linux-binaries, build-mac-binaries, run-tests] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| clean: true | |
| fetch-depth: 0 | |
| submodules: recursive | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.x' | |
| - name: Download Agent (win-x86) | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: Agent-win-x86 | |
| path: ControlR.Web.Server\wwwroot\downloads\win-x86\ | |
| - name: Download Agent (win-x64) | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: Agent-win-x64 | |
| path: ControlR.Web.Server\wwwroot\downloads\win-x64\ | |
| - name: Download Agent (linux-x64) | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: Agent-linux-x64 | |
| path: ControlR.Web.Server\wwwroot\downloads\linux-x64\ | |
| - name: Download Agent (macOS ARM64) | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: Agent-macOS-ARM64 | |
| path: ControlR.Web.Server\wwwroot\downloads\osx-arm64\ | |
| - name: Download Agent (macOS x64) | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: Agent-macOS-x64 | |
| path: ControlR.Web.Server\wwwroot\downloads\osx-x64\ | |
| - name: Create Version.txt | |
| shell: pwsh | |
| run: | | |
| Set-Content -Path "ControlR.Web.Server\wwwroot\downloads\Version.txt" -Value $env:VERSION -Force -Encoding UTF8 | |
| - name: Build Web Server | |
| shell: pwsh | |
| run: | | |
| New-Item -Path "ControlR.Server\bin\publish" -ItemType Directory -Force | Out-Null | |
| dotnet publish ControlR.Web.Server\ -p:ExcludeApp_Data=true --runtime linux-x64 --configuration Release -p:Version=$env:VERSION -p:FileVersion=$env:VERSION --output ControlR.Server\bin\publish --self-contained true | |
| - name: Verify Agent Binaries | |
| shell: pwsh | |
| run: | | |
| $TestPaths = @( | |
| "ControlR.Server\bin\publish\wwwroot\downloads\Version.txt", | |
| "ControlR.Server\bin\publish\wwwroot\downloads\win-x86\ControlR.Agent.exe", | |
| "ControlR.Server\bin\publish\wwwroot\downloads\win-x64\ControlR.Agent.exe", | |
| "ControlR.Server\bin\publish\wwwroot\downloads\linux-x64\ControlR.Agent", | |
| "ControlR.Server\bin\publish\wwwroot\downloads\osx-arm64\ControlR.Agent", | |
| "ControlR.Server\bin\publish\wwwroot\downloads\osx-x64\ControlR.Agent", | |
| "ControlR.Server\bin\publish\novnc\vnc.html" | |
| ) | |
| foreach ($TestPath in $TestPaths) { | |
| if (!(Test-Path $TestPath)) { | |
| Write-Error "$TestPath not found." | |
| exit 1 | |
| } | |
| } | |
| - name: Upload Server | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: Server | |
| path: ControlR.Server\bin\publish | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} | |
| - name: Upload docker-compose | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: DockerCompose | |
| path: docker-compose\docker-compose.yml | |
| retention-days: ${{ env.RETENTION_DAYS_ARTIFACTS }} |