mirror of
https://github.com/Devolutions/IronRDP.git
synced 2025-12-23 12:26:46 +00:00
Some checks are pending
CI / Check formatting (push) Waiting to run
CI / Check typos (push) Waiting to run
CI / Checks [linux] (push) Blocked by required conditions
CI / Checks [macos] (push) Blocked by required conditions
CI / Checks [windows] (push) Blocked by required conditions
CI / Fuzzing (push) Blocked by required conditions
CI / Web Client (push) Blocked by required conditions
CI / FFI (push) Blocked by required conditions
CI / Success (push) Blocked by required conditions
Coverage / Coverage Report (push) Waiting to run
Release crates / Release crates (push) Waiting to run
Release crates / Open release PR (push) Waiting to run
The `net8.0-ios` workload is out of support and won't build out-of-the-box anymore. Bump the target framework to `net9.0-ios`.
420 lines
15 KiB
YAML
420 lines
15 KiB
YAML
name: Publish NuGet package
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
dry-run:
|
|
description: 'Dry run'
|
|
required: true
|
|
type: boolean
|
|
default: true
|
|
schedule:
|
|
- cron: '21 3 * * 1' # 3:21 AM UTC every Monday
|
|
|
|
jobs:
|
|
preflight:
|
|
name: Preflight
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
dry-run: ${{ steps.get-dry-run.outputs.dry-run }}
|
|
project-version: ${{ steps.get-version.outputs.project-version }}
|
|
package-version: ${{ steps.get-version.outputs.package-version }}
|
|
|
|
steps:
|
|
- name: Checkout ${{ github.repository }}
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Get dry run
|
|
id: get-dry-run
|
|
run: |
|
|
$IsDryRun = '${{ github.event.inputs.dry-run }}' -Eq 'true' -Or '${{ github.event_name }}' -Eq 'schedule'
|
|
|
|
if ($IsDryRun) {
|
|
echo "dry-run=true" >> $Env:GITHUB_OUTPUT
|
|
} else {
|
|
echo "dry-run=false" >> $Env:GITHUB_OUTPUT
|
|
}
|
|
shell: pwsh
|
|
|
|
- name: Get version
|
|
id: get-version
|
|
run: |
|
|
$CsprojXml = [Xml] (Get-Content .\ffi\dotnet\Devolutions.IronRdp\Devolutions.IronRdp.csproj)
|
|
$ProjectVersion = $CsprojXml.Project.PropertyGroup.Version | Select-Object -First 1
|
|
$PackageVersion = $ProjectVersion -Replace "^(\d+)\.(\d+)\.(\d+).(\d+)$", "`$1.`$2.`$3"
|
|
echo "project-version=$ProjectVersion" >> $Env:GITHUB_OUTPUT
|
|
echo "package-version=$PackageVersion" >> $Env:GITHUB_OUTPUT
|
|
shell: pwsh
|
|
|
|
build-native:
|
|
name: Native build
|
|
needs: [preflight]
|
|
runs-on: ${{matrix.runner}}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [win, osx, linux, ios, android]
|
|
arch: [x86, x64, arm, arm64]
|
|
include:
|
|
- os: win
|
|
runner: windows-2022
|
|
- os: osx
|
|
runner: macos-14
|
|
- os: linux
|
|
runner: ubuntu-22.04
|
|
- os: ios
|
|
runner: macos-14
|
|
- os: android
|
|
runner: ubuntu-22.04
|
|
exclude:
|
|
- arch: arm
|
|
os: win
|
|
- arch: arm
|
|
os: osx
|
|
- arch: arm
|
|
os: linux
|
|
- arch: arm
|
|
os: ios
|
|
- arch: x86
|
|
os: win
|
|
- arch: x86
|
|
os: osx
|
|
- arch: x86
|
|
os: linux
|
|
- arch: x86
|
|
os: ios
|
|
|
|
steps:
|
|
- name: Checkout ${{ github.repository }}
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Configure Android NDK
|
|
if: ${{ matrix.os == 'android' }}
|
|
uses: Devolutions/actions-public/cargo-android-ndk@v1
|
|
with:
|
|
android_api_level: "21"
|
|
|
|
- name: Configure macOS deployement target
|
|
if: ${{ matrix.os == 'osx' }}
|
|
run: Write-Output "MACOSX_DEPLOYMENT_TARGET=10.10" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
|
shell: pwsh
|
|
|
|
- name: Configure iOS deployement target
|
|
if: ${{ matrix.os == 'ios' }}
|
|
run: Write-Output "IPHONEOS_DEPLOYMENT_TARGET=12.1" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
|
shell: pwsh
|
|
|
|
- name: Update runner
|
|
if: ${{ matrix.os == 'linux' }}
|
|
run: sudo apt update
|
|
|
|
- name: Install dependencies for rustls
|
|
if: ${{ runner.os == 'Windows' }}
|
|
run: |
|
|
choco install ninja nasm
|
|
|
|
# We need to add the NASM binary folder to the PATH manually.
|
|
# We don't need to do that for ninja.
|
|
Write-Output "PATH=$Env:PATH;$Env:ProgramFiles\NASM" >> $Env:GITHUB_ENV
|
|
|
|
# libclang / LLVM is a requirement for AWS LC.
|
|
# https://aws.github.io/aws-lc-rs/requirements/windows.html#libclang--llvm
|
|
$VSINSTALLDIR = $(vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Llvm.Clang -property installationPath)
|
|
Write-Output "LIBCLANG_PATH=$VSINSTALLDIR\VC\Tools\Llvm\x64\bin" >> $Env:GITHUB_ENV
|
|
|
|
# Install Visual Studio Developer PowerShell Module for cmdlets such as Enter-VsDevShell
|
|
Install-Module VsDevShell -Force
|
|
shell: pwsh
|
|
|
|
# No pre-generated bindings for Android and iOS.
|
|
# https://aws.github.io/aws-lc-rs/platform_support.html#pre-generated-bindings
|
|
- name: Install bindgen-cli for aws-lc-sys
|
|
if: ${{ matrix.os == 'android' || matrix.os == 'ios' }}
|
|
run: cargo install --force --locked bindgen-cli
|
|
|
|
# For aws-lc-sys. Error returned otherwise:
|
|
# > Unable to generate bindings: ClangDiagnostic("/usr/include/stdint.h:26:10: fatal error: 'bits/libc-header-start.h' file not found\n")
|
|
- name: Install gcc-multilib
|
|
if: ${{ matrix.os == 'android' }}
|
|
run: |
|
|
sudo apt-get update
|
|
sudo apt-get install gcc-multilib
|
|
|
|
- name: Setup LLVM
|
|
if: ${{ matrix.os == 'linux' }}
|
|
uses: Devolutions/actions-public/setup-llvm@v1
|
|
with:
|
|
version: "18.1.8"
|
|
|
|
- name: Setup CBake
|
|
if: ${{ matrix.os == 'linux' }}
|
|
uses: Devolutions/actions-public/setup-cbake@v1
|
|
with:
|
|
cargo_env_scripts: true
|
|
|
|
- name: Build native lib (${{matrix.os}}-${{matrix.arch}})
|
|
run: |
|
|
$DotNetOs = '${{matrix.os}}'
|
|
$DotNetArch = '${{matrix.arch}}'
|
|
$DotNetRid = '${{matrix.os}}-${{matrix.arch}}'
|
|
$RustArch = @{'x64'='x86_64';'arm64'='aarch64';
|
|
'x86'='i686';'arm'='armv7'}[$DotNetArch]
|
|
$RustPlatform = @{'win'='pc-windows-msvc';
|
|
'osx'='apple-darwin';'ios'='apple-ios';
|
|
'linux'='unknown-linux-gnu';'android'='linux-android'}[$DotNetOs]
|
|
$LibPrefix = @{'win'='';'osx'='lib';'ios'='lib';
|
|
'linux'='lib';'android'='lib'}[$DotNetOs]
|
|
$LibSuffix = @{'win'='.dll';'osx'='.dylib';'ios'='.dylib';
|
|
'linux'='.so';'android'='.so'}[$DotNetOs]
|
|
$RustTarget = "$RustArch-$RustPlatform"
|
|
|
|
if (($DotNetOs -eq 'android') -and ($DotNetArch -eq 'arm')) {
|
|
$RustTarget = "armv7-linux-androideabi"
|
|
}
|
|
|
|
rustup target add $RustTarget
|
|
|
|
if ($DotNetOs -eq 'win') {
|
|
$Env:RUSTFLAGS="-C target-feature=+crt-static"
|
|
}
|
|
|
|
$ProjectVersion = '${{ needs.preflight.outputs.project-version }}'
|
|
$PackageVersion = '${{ needs.preflight.outputs.package-version }}'
|
|
|
|
$CargoToml = Get-Content .\ffi\Cargo.toml
|
|
$CargoToml = $CargoToml | ForEach-Object {
|
|
if ($_.StartsWith("version =")) { "version = `"$PackageVersion`"" } else { $_ }
|
|
}
|
|
Set-Content -Path .\ffi\Cargo.toml -Value $CargoToml
|
|
|
|
if ($DotNetOs -eq 'linux') {
|
|
$LinuxArch = @{'x64'='amd64';'arm64'='arm64'}[$DotNetArch]
|
|
$Env:SYSROOT_NAME = "ubuntu-20.04-$LinuxArch"
|
|
. "$HOME/.cargo/cbake/${RustTarget}-enter.ps1"
|
|
$Env:AWS_LC_SYS_CMAKE_BUILDER="true"
|
|
}
|
|
|
|
$CargoParams = @(
|
|
"build",
|
|
"-p", "ffi",
|
|
"--profile", "production-ffi",
|
|
"--target", "$RustTarget"
|
|
)
|
|
|
|
& cargo $CargoParams
|
|
|
|
$OutputLibraryName = "${LibPrefix}ironrdp$LibSuffix"
|
|
$RenamedLibraryName = "${LibPrefix}DevolutionsIronRdp$LibSuffix"
|
|
$OutputLibrary = Join-Path "target" $RustTarget 'production-ffi' $OutputLibraryName
|
|
$OutputPath = Join-Path "dependencies" "runtimes" $DotNetRid "native"
|
|
New-Item -ItemType Directory -Path $OutputPath | Out-Null
|
|
Copy-Item $OutputLibrary $(Join-Path $OutputPath $RenamedLibraryName)
|
|
shell: pwsh
|
|
|
|
- name: Upload native components
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ironrdp-${{matrix.os}}-${{matrix.arch}}
|
|
path: dependencies/runtimes/${{matrix.os}}-${{matrix.arch}}
|
|
|
|
build-universal:
|
|
name: Universal build
|
|
needs: [preflight, build-native]
|
|
runs-on: ubuntu-22.04
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
os: [ osx, ios ]
|
|
|
|
steps:
|
|
- name: Checkout ${{ github.repository }}
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup CCTools
|
|
uses: Devolutions/actions-public/setup-cctools@v1
|
|
|
|
- name: Download native components
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: dependencies/runtimes
|
|
|
|
- name: Lipo native components
|
|
run: |
|
|
Set-Location "dependencies/runtimes"
|
|
# No RID for universal binaries, see: https://github.com/dotnet/runtime/issues/53156
|
|
$OutputPath = Join-Path "${{ matrix.os }}-universal" "native"
|
|
New-Item -ItemType Directory -Path $OutputPath | Out-Null
|
|
$Libraries = Get-ChildItem -Recurse -Path "ironrdp-${{ matrix.os }}-*" -Filter "*.dylib" | Foreach-Object { $_.FullName } | Select -Unique
|
|
$LipoCmd = $(@('lipo', '-create', '-output', (Join-Path -Path $OutputPath -ChildPath "libDevolutionsIronRdp.dylib")) + $Libraries) -Join ' '
|
|
Write-Host $LipoCmd
|
|
Invoke-Expression $LipoCmd
|
|
shell: pwsh
|
|
|
|
- name: Framework
|
|
if: ${{ matrix.os == 'ios' }}
|
|
run: |
|
|
$Version = '${{ needs.preflight.outputs.project-version }}'
|
|
$ShortVersion = '${{ needs.preflight.outputs.package-version }}'
|
|
$BundleName = "libDevolutionsIronRdp"
|
|
$RuntimesDir = Join-Path "dependencies" "runtimes" "ios-universal" "native"
|
|
$FrameworkDir = Join-Path "$RuntimesDir" "$BundleName.framework"
|
|
New-Item -Path $FrameworkDir -ItemType "directory" -Force
|
|
$FrameworkExecutable = Join-Path $FrameworkDir $BundleName
|
|
Copy-Item -Path (Join-Path "$RuntimesDir" "$BundleName.dylib") -Destination $FrameworkExecutable -Force
|
|
|
|
$RPathCmd = $(@('install_name_tool', '-id', "@rpath/$BundleName.framework/$BundleName", "$FrameworkExecutable")) -Join ' '
|
|
Write-Host $RPathCmd
|
|
Invoke-Expression $RPathCmd
|
|
|
|
[xml] $InfoPlistXml = Get-Content (Join-Path "ffi" "dotnet" "Devolutions.IronRdp" "Info.plist")
|
|
Select-Xml -xml $InfoPlistXml -XPath "/plist/dict/key[. = 'CFBundleIdentifier']/following-sibling::string[1]" |
|
|
%{
|
|
$_.Node.InnerXml = "com.devolutions.ironrdp"
|
|
}
|
|
Select-Xml -xml $InfoPlistXml -XPath "/plist/dict/key[. = 'CFBundleExecutable']/following-sibling::string[1]" |
|
|
%{
|
|
$_.Node.InnerXml = $BundleName
|
|
}
|
|
Select-Xml -xml $InfoPlistXml -XPath "/plist/dict/key[. = 'CFBundleVersion']/following-sibling::string[1]" |
|
|
%{
|
|
$_.Node.InnerXml = $Version
|
|
}
|
|
Select-Xml -xml $InfoPlistXml -XPath "/plist/dict/key[. = 'CFBundleShortVersionString']/following-sibling::string[1]" |
|
|
%{
|
|
$_.Node.InnerXml = $ShortVersion
|
|
}
|
|
|
|
# Write the plist *without* a BOM
|
|
$Encoding = New-Object System.Text.UTF8Encoding($false)
|
|
$Writer = New-Object System.IO.StreamWriter((Join-Path $FrameworkDir "Info.plist"), $false, $Encoding)
|
|
$InfoPlistXml.Save($Writer)
|
|
$Writer.Close()
|
|
|
|
# .NET XML document inserts two square brackets at the end of the DOCTYPE tag
|
|
# It's perfectly valid XML, but we're dealing with plists here and dyld will not be able to read the file
|
|
((Get-Content -Path (Join-Path $FrameworkDir "Info.plist") -Raw) -Replace 'PropertyList-1.0.dtd"\[\]', 'PropertyList-1.0.dtd"') | Set-Content -Path (Join-Path $FrameworkDir "Info.plist")
|
|
shell: pwsh
|
|
|
|
- name: Upload native components
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ironrdp-${{ matrix.os }}-universal
|
|
path: dependencies/runtimes/${{ matrix.os }}-universal
|
|
|
|
build-managed:
|
|
name: Managed build
|
|
needs: [build-universal]
|
|
runs-on: windows-2022
|
|
|
|
steps:
|
|
- name: Check out ${{ github.repository }}
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Add msbuild to PATH
|
|
uses: microsoft/setup-msbuild@v2
|
|
|
|
- name: Install ios workload
|
|
run: dotnet workload install ios
|
|
|
|
- name: Prepare dependencies
|
|
run: |
|
|
New-Item -ItemType Directory -Path "dependencies/runtimes" | Out-Null
|
|
shell: pwsh
|
|
|
|
- name: Download native components
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: dependencies/runtimes
|
|
|
|
- name: Rename dependencies
|
|
run: |
|
|
Set-Location "dependencies/runtimes"
|
|
$(Get-Item ".\ironrdp-*") | ForEach-Object { Rename-Item $_ $_.Name.Replace("ironrdp-", "") }
|
|
Get-ChildItem * -Recurse
|
|
shell: pwsh
|
|
|
|
- name: Build Devolutions.IronRdp (managed)
|
|
run: |
|
|
# net8.0 target packaged as Devolutions.IronRdp
|
|
dotnet build .\ffi\dotnet\Devolutions.IronRdp\Devolutions.IronRdp.csproj -c Release
|
|
# net9.0-ios target packaged as Devolutions.IronRdp.iOS
|
|
dotnet build .\ffi\dotnet\Devolutions.IronRdp\Devolutions.IronRdp.csproj -c Release /p:PackageId=Devolutions.IronRdp.iOS
|
|
shell: pwsh
|
|
|
|
- name: Upload managed components
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: ironrdp-nupkg
|
|
path: ffi/dotnet/Devolutions.IronRdp/bin/Release/*.nupkg
|
|
|
|
publish:
|
|
name: Publish NuGet package
|
|
environment: nuget-publish
|
|
if: ${{ needs.preflight.outputs.dry-run == 'false' }}
|
|
needs: [preflight, build-managed]
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
id-token: write
|
|
|
|
steps:
|
|
- name: Download NuGet package artifact
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: ironrdp-nupkg
|
|
path: package
|
|
|
|
- name: NuGet login (OIDC)
|
|
uses: NuGet/login@v1
|
|
id: nuget-login
|
|
with:
|
|
user: ${{ secrets.NUGET_BOT_USERNAME }}
|
|
|
|
- name: Publish to nuget.org
|
|
run: |
|
|
$Files = Get-ChildItem -Recurse package/*.nupkg
|
|
|
|
foreach ($File in $Files) {
|
|
$PushCmd = @(
|
|
'dotnet',
|
|
'nuget',
|
|
'push',
|
|
"$File",
|
|
'--api-key',
|
|
'${{ steps.nuget-login.outputs.NUGET_API_KEY }}',
|
|
'--source',
|
|
'https://api.nuget.org/v3/index.json',
|
|
'--skip-duplicate'
|
|
)
|
|
|
|
Write-Host "Publishing $($File.Name)..."
|
|
$PushCmd = $PushCmd -Join ' '
|
|
Invoke-Expression $PushCmd
|
|
}
|
|
shell: pwsh
|
|
|
|
notify:
|
|
name: Notify failure
|
|
if: ${{ always() && contains(needs.*.result, 'failure') && github.event_name == 'schedule' }}
|
|
needs: [preflight, build-native, build-universal, build-managed]
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_ARCHITECTURE }}
|
|
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
|
|
|
steps:
|
|
- name: Send slack notification
|
|
id: slack
|
|
uses: slackapi/slack-github-action@v1.26.0
|
|
with:
|
|
payload: |
|
|
{
|
|
"blocks": [
|
|
{
|
|
"type": "section",
|
|
"text": {
|
|
"type": "mrkdwn",
|
|
"text": "*${{ github.repository }}* :fire::fire::fire::fire::fire: \n The scheduled build for *${{ github.repository }}* is <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|broken>"
|
|
}
|
|
}
|
|
]
|
|
}
|