Skip to content

fix(dgw): resolve sspi dependency conflict by updating IronRDP to 0.7 #5011

fix(dgw): resolve sspi dependency conflict by updating IronRDP to 0.7

fix(dgw): resolve sspi dependency conflict by updating IronRDP to 0.7 #5011

Workflow file for this run

name: CI
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
sccache:
description: Enable sccache for Rust compilation caching
required: false
type: boolean
default: true
workflow_call:
inputs:
ref:
description: The commit SHA to build
required: false
type: string
sccache:
description: Enable sccache for Rust compilation caching
required: false
type: boolean
default: true
jobs:
preflight:
name: preflight
runs-on: ubuntu-latest
outputs:
ref: ${{ steps.get-commit.outputs.ref }}
version: ${{ steps.get-version.outputs.version }}
rust-profile: ${{ steps.rust-profile.outputs.rust-profile }}
sccache: ${{ steps.sccache.outputs.enabled }}
jetsocat-build-matrix: ${{ steps.setup-matrix.outputs.jetsocat-build-matrix }}
gateway-build-matrix: ${{ steps.setup-matrix.outputs.gateway-build-matrix }}
agent-build-matrix: ${{ steps.setup-matrix.outputs.agent-build-matrix }}
steps:
- name: Setup matrix
id: setup-matrix
run: |
$Jobs = @()
$Archs = @( 'x86_64', 'arm64' )
$Platforms = @( 'linux', 'windows' )
$Platforms | ForEach-Object {
$Runner = switch ($_) { 'windows' { 'windows-2022' } 'linux' { 'ubuntu-22.04' } }
foreach ($Arch in $Archs) {
if ($Arch -Eq 'arm64' -And $_ -Eq 'windows') {
continue
}
$Jobs += @{
arch = $Arch
os = $_
runner = $Runner }
}
}
$GatewayMatrix = ConvertTo-JSON $Jobs -Compress
echo "gateway-build-matrix=$GatewayMatrix" >> $Env:GITHUB_OUTPUT
$Jobs = @()
$Platforms | ForEach-Object {
$Runner = switch ($_) { 'windows' { 'windows-2022' } 'linux' { 'ubuntu-22.04' } }
foreach ($Arch in $Archs) {
$Jobs += @{
arch = $Arch
os = $_
runner = $Runner }
}
}
$AgentMatrix = ConvertTo-JSON $Jobs -Compress
echo "agent-build-matrix=$AgentMatrix" >> $Env:GITHUB_OUTPUT
$Jobs = @()
$Platforms += 'macos'
$Platforms | ForEach-Object {
$Runner = switch ($_) { 'windows' { 'windows-2022' } 'macos' { 'macos-14' } 'linux' { 'ubuntu-22.04' } }
foreach ($Arch in $Archs) {
$Jobs += @{
arch = $Arch
os = $_
runner = $Runner }
}
}
$JetsocatMatrix = ConvertTo-JSON $Jobs -Compress
echo "jetsocat-build-matrix=$JetsocatMatrix" >> $Env:GITHUB_OUTPUT
shell: pwsh
## The SHA to build might be passed via workflow_call, otherwise the current commit is used
- name: Get commit
id: get-commit
run: |
$Ref = '${{ inputs.ref }}'
if (-Not $Ref) {
$Ref = '${{ github.sha }}'
}
echo "ref=$Ref" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ steps.get-commit.outputs.ref }}
- name: Get version
id: get-version
run: |
$Version = Get-Content VERSION -TotalCount 1
echo "version=$Version" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Install nightly rustfmt
run: rustup component add --toolchain nightly rustfmt
- name: Check formatting
run: |
cargo +nightly fmt --all -- --check
if ! [ $? -eq 0 ] ; then
echo "::error::Bad formatting, please run 'cargo +nightly fmt --all'"
exit 1
fi
- name: Configure rust profile
id: rust-profile
run: |
$CargoProfile = "release"
if ("${{ github.ref }}" -Eq "refs/heads/master") {
echo "::notice::Building production profile"
$CargoProfile = "production"
}
echo "rust-profile=$CargoProfile" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Configure sccache
id: sccache
run: |
# Enable sccache by default; only disable if explicitly set to false
# This handles push/pull_request triggers where inputs.sccache is undefined
$Enabled = if ("${{ inputs.sccache }}" -eq "false") { "false" } else { "true" }
echo "enabled=$Enabled" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Upload version artifact
uses: actions/upload-artifact@v4
with:
name: version
path: VERSION
lints:
name: lints [${{ matrix.os }}]
needs: [preflight]
runs-on: ${{ matrix.runner }}
strategy:
matrix:
os: [windows, linux]
include:
- os: windows
runner: windows-2022
- os: linux
runner: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Check clippy
shell: pwsh
run: |
cargo clippy --workspace --tests -- -D warnings
if ($LASTEXITCODE -ne 0) {
Write-Output "::error::Clippy warnings detected, please run 'cargo clippy --workspace --tests' and fix all warnings"
exit 1
}
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
tests:
name: tests [${{ matrix.os }} ${{ matrix.arch }}]
needs: [preflight]
runs-on: ${{ matrix.runner }}
strategy:
matrix:
arch: [x86_64]
os: [windows, linux]
include:
- os: windows
runner: windows-2022
- os: linux
runner: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Configure Linux runner
if: ${{ matrix.os == 'linux' }}
run: |
sudo apt-get update
sudo apt-get -o Acquire::Retries=3 install libsystemd-dev
- name: Tests
run: ./ci/tlk.ps1 test -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile 'dev'
shell: pwsh
env:
AWS_LC_SYS_NO_ASM: true
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
check-dependencies:
name: Check no ${{ matrix.banned }} in ${{ matrix.package }} [${{ matrix.target }}]
needs: [preflight]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
banned: [aws-lc-rs]
target: [x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc]
package: [devolutions-gateway, jetsocat]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Check
run: ./ci/check-crate-is-not-in-the-tree.ps1 -Package '${{ matrix.package }}' -UnwantedDependency '${{ matrix.banned }}' -Target '${{ matrix.target }}'
shell: pwsh
jetsocat:
name: jetsocat [${{ matrix.os }} ${{ matrix.arch }}]
needs: [preflight]
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include: ${{ fromJson(needs.preflight.outputs.jetsocat-build-matrix) }}
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Setup LLVM
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-llvm@v1
with:
version: "18.1.8"
- name: Setup CBake
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-cbake@v1
with:
sysroots: |
- ubuntu-18.04-amd64
- ubuntu-18.04-arm64
cargo_env_scripts: true
- name: Configure Linux (arm) runner
if: ${{ matrix.os == 'linux' && matrix.arch == 'arm64' }}
run: |
rustup target add aarch64-unknown-linux-gnu
echo "STRIP_EXECUTABLE=llvm-strip" >> $GITHUB_ENV
- name: Configure Windows runner
if: ${{ runner.os == 'Windows' }}
run: |
# NASM is required by aws-lc-rs (used as rustls crypto backend)
choco install nasm
# We need to add the NASM binary folder to the PATH manually.
Write-Output "$Env:ProgramFiles\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# 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" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# Install Visual Studio Developer PowerShell Module for cmdlets such as Enter-VsDevShell
Install-Module VsDevShell -Force
shell: pwsh
- name: Configure Windows (arm) runner
if: ${{ runner.os == 'Windows' && matrix.arch == 'arm64' }}
run: |
rustup target add aarch64-pc-windows-msvc
shell: pwsh
- name: Configure macOS (intel) runner
if: ${{ matrix.os == 'macos' && matrix.arch == 'x86_64' }}
run: |
sudo rm -rf /Library/Developer/CommandLineTools
rustup target add x86_64-apple-darwin
- name: Build
id: build
run: |
$StagingPath = Join-Path $Env:RUNNER_TEMP "staging"
$TargetOutputPath = Join-Path $StagingPath ${{ matrix.os }} ${{ matrix.arch }}
$ExecutableFileName = 'jetsocat_${{ runner.os }}_${{ needs.preflight.outputs.version }}_${{ matrix.arch }}'
if ($Env:RUNNER_OS -eq "Windows") {
$ExecutableFileName = "$($ExecutableFileName).exe"
$Env:CARGO_NO_DEFAULT_FEATURES = "true"
$Env:CARGO_FEATURES = "native-tls"
}
if ($Env:RUNNER_OS -eq "Linux") {
$LinuxArch = @{'x86_64'='amd64';'arm64'='arm64'}['${{ matrix.arch }}']
$RustArch = @{'x86_64'='x86_64';'arm64'='aarch64'}['${{ matrix.arch }}']
$RustTarget = "$RustArch-unknown-linux-gnu"
$Env:SYSROOT_NAME = "ubuntu-18.04-$LinuxArch"
. "$HOME/.cargo/cbake/${RustTarget}-enter.ps1"
$Env:AWS_LC_SYS_CMAKE_BUILDER="true"
}
$Env:TARGET_OUTPUT_PATH = $TargetOutputPath
$Env:JETSOCAT_EXECUTABLE = Join-Path $TargetOutputPath $ExecutableFileName
$Env:CARGO_PACKAGE = "jetsocat"
./ci/tlk.ps1 build -Product jetsocat -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
echo "staging-path=$StagingPath" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: jetsocat-${{ matrix.os }}-${{ matrix.arch }}
path: ${{ steps.build.outputs.staging-path }}
jetsocat-merge:
name: jetsocat merge artifacts
runs-on: ubuntu-latest
needs: [preflight, jetsocat]
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: jetsocat
pattern: jetsocat-*
delete-merged: true
jetsocat-lipo:
name: jetsocat macos universal
runs-on: ubuntu-24.04
needs: [preflight, jetsocat, jetsocat-merge]
steps:
- uses: actions/download-artifact@v4
with:
name: jetsocat
- name: Setup CCTools
uses: Devolutions/actions-public/setup-cctools@v1
- name: Lipo
run: |
$OutputPath = Join-Path "macos" "universal"
New-Item -ItemType Directory -Path $OutputPath | Out-Null
$Binaries = Get-ChildItem -Recurse -Path "macos" -Filter "jetsocat_*" | Foreach-Object { $_.FullName } | Select -Unique
$LipoCmd = $(@('lipo', '-create', '-output', (Join-Path -Path $OutputPath -ChildPath "jetsocat_macOS_${{ needs.preflight.outputs.version }}_universal")) + $Binaries) -Join ' '
Write-Host $LipoCmd
Invoke-Expression $LipoCmd
shell: pwsh
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: jetsocat
path: .
overwrite: true
devolutions-gateway-webapp:
name: Devolutions Gateway Web Apps
# DEVOLUTIONSBOT_TOKEN is a repository secret, and it can't be used by PRs originating from forks.
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
needs: [preflight]
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Check out Devolutions/actions
uses: actions/checkout@v4
with:
repository: Devolutions/actions
ref: v1
token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }}
path: ./.github/workflows
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'pnpm'
cache-dependency-path: webapp/pnpm-lock.yaml
- name: Setup .npmrc config file
uses: ./.github/workflows/npmrc-setup
with:
npm_token: ${{ secrets.ARTIFACTORY_NPM_TOKEN }}
- name: Configure additional Artifactory auth
run: |
echo "//devolutions.jfrog.io/artifactory/api/npm/npm/:_auth=${{ secrets.ARTIFACTORY_NPM_TOKEN }}" >> .npmrc
echo "//devolutions.jfrog.io/artifactory/api/npm/npm/:always-auth=true" >> .npmrc
working-directory: webapp
- name: Install dependencies
run: pnpm install --frozen-lockfile
working-directory: webapp
- name: Build packages (libraries)
run: pnpm build:libs
working-directory: webapp
- name: Build applications
run: pnpm build:apps
working-directory: webapp
- name: Check code quality
run: pnpm check
working-directory: webapp
- name: Upload gateway-ui artifact
uses: actions/upload-artifact@v4
with:
name: webapp-client
path: webapp/dist/gateway-ui/
- name: Upload recording-player artifact
uses: actions/upload-artifact@v4
with:
name: webapp-player
path: webapp/dist/recording-player/
devolutions-gateway-powershell:
name: devolutions-gateway-powershell
needs: [preflight]
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Install Pester
id: prepare
run: Install-Module Pester -RequiredVersion 5.6.0
shell: pwsh
- name: Build module
run: |
$PSModuleVersion = "${{ needs.preflight.outputs.version }}"
./powershell/build.ps1
$PSModuleName = "DevolutionsGateway"
$PSModuleParentPath = Join-Path "powershell" "package"
Write-Host "PSModuleOutputPath = $PSModuleParentPath"
$PSStagingPath = Join-Path "powershell-staging" "PowerShell"
Write-Host "PSStagingPath = $PSStagingPath"
New-Item -Path $PSStagingPath -ItemType Directory | Out-Null
$PSModuleTarFilePath = Join-Path $PSStagingPath "$PSModuleName-ps-$PSModuleVersion.tar"
Write-Host "PSModuleTarFilePath = $PSModuleTarFilePath"
tar -cvf "$PSModuleTarFilePath" -C "$PSModuleParentPath" "$PSModuleName"
shell: pwsh
- name: Pester tests
run: |
./powershell/run-tests.ps1
shell: pwsh
- uses: actions/upload-artifact@v4
with:
name: devolutions-gateway-powershell
path: powershell-staging
devolutions-gateway:
name: devolutions-gateway [${{ matrix.os }} ${{ matrix.arch }}]
if: ${{ always() }}
needs: [preflight, devolutions-gateway-powershell, devolutions-gateway-webapp]
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include: ${{ fromJson(needs.preflight.outputs.gateway-build-matrix) }}
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Download webapp-client
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/download-artifact@v4
with:
name: webapp-client
path: webapp/dist/gateway-ui
- name: Download webapp-player
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/download-artifact@v4
with:
name: webapp-player
path: webapp/dist/recording-player
- name: Download devolutions-gateway-powershell
uses: actions/download-artifact@v4
with:
name: devolutions-gateway-powershell
path: powershell-staging
- name: Download Cadeau
run: |
$Platform = @{'windows'='win'; 'linux'='linux'}['${{ matrix.os }}']
$Arch = @{'x86_64'='x64';'arm64'='arm64'}['${{ matrix.arch }}']
./ci/download-cadeau.ps1 -Platform $Platform -Architecture $Arch
shell: pwsh
- name: Load dynamic variables
id: load-variables
run: |
$PackageVersion = "${{ needs.preflight.outputs.version }}"
$StagingPath = Join-Path $Env:RUNNER_TEMP "staging"
$TargetOutputPath = Join-Path $StagingPath ${{ matrix.os }} ${{ matrix.arch }}
$ExecutableFileName = "DevolutionsGateway_${{ runner.os }}_${PackageVersion}_${{ matrix.arch }}"
if ($Env:RUNNER_OS -eq "Windows") {
$ExecutableFileName = "$($ExecutableFileName).exe"
$PackageFileName = "DevolutionsGateway-${{ matrix.arch }}-${PackageVersion}.msi"
$DGatewayPackage = Join-Path $TargetOutputPath $PackageFileName
echo "dgateway-package=$DGatewayPackage" >> $Env:GITHUB_OUTPUT
}
$DGatewayExecutable = Join-Path $TargetOutputPath $ExecutableFileName
echo "staging-path=$StagingPath" >> $Env:GITHUB_OUTPUT
echo "target-output-path=$TargetOutputPath" >> $Env:GITHUB_OUTPUT
echo "dgateway-executable=$DGatewayExecutable" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Setup LLVM
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-llvm@v1
with:
version: "18.1.8"
- name: Setup CBake
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-cbake@v1
with:
sysroots: |
- ubuntu-18.04-amd64
- ubuntu-18.04-arm64
cargo_env_scripts: true
- name: Configure Linux runner
if: ${{ matrix.os == 'linux' }}
run: |
sudo apt-get update
sudo apt-get -o Acquire::Retries=3 install python3-wget python3-setuptools libsystemd-dev dh-make
- name: Configure Linux (arm) runner
if: ${{ matrix.os == 'linux' && matrix.arch == 'arm64' }}
run: |
sudo dpkg --add-architecture arm64
sudo apt-get -o Acquire::Retries=3 install -qy binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu qemu-user
rustup target add aarch64-unknown-linux-gnu
echo "STRIP_EXECUTABLE=aarch64-linux-gnu-strip" >> $GITHUB_ENV
- name: Install fpm
if: ${{ matrix.os == 'Linux' }}
run: sudo gem install --no-document fpm
- name: Configure Windows runner
if: ${{ matrix.os == 'windows' }}
run: |
# https://github.com/actions/runner-images/issues/9667
choco uninstall wixtoolset
choco install wixtoolset --version 3.14.0 --allow-downgrade --no-progress --force
# WiX is installed on Windows runners but not in the PATH
Write-Output "C:\Program Files (x86)\WiX Toolset v3.14\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# NASM is required by aws-lc-rs (used as rustls crypto backend)
choco install nasm
# Install Visual Studio Developer PowerShell Module for cmdlets such as Enter-VsDevShell
Install-Module VsDevShell -Force
# We need to add the NASM binary folder to the PATH manually.
Write-Output "$Env:ProgramFiles\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
shell: pwsh
- name: Find mc.exe
id: find_mc
if: ${{ matrix.os == 'windows' }}
run: |
Enter-VsDevShell
$path = (Get-Command -Type Application mc).Source | Split-Path -Parent
Write-Output "windows_sdk_ver_bin_path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
shell: pwsh
- name: Build
run: |
if ($Env:RUNNER_OS -eq "Linux") {
$LinuxArch = @{'x86_64'='amd64';'arm64'='arm64'}['${{ matrix.arch }}']
$RustArch = @{'x86_64'='x86_64';'arm64'='aarch64'}['${{ matrix.arch }}']
$RustTarget = "$RustArch-unknown-linux-gnu"
$Env:SYSROOT_NAME = "ubuntu-18.04-$LinuxArch"
. "$HOME/.cargo/cbake/${RustTarget}-enter.ps1"
$Env:AWS_LC_SYS_CMAKE_BUILDER="true"
}
if ($Env:RUNNER_OS -eq "Windows") {
$Env:WindowsSdkVerBinPath = '${{ steps.find_mc.outputs.windows_sdk_ver_bin_path }}'
}
./ci/tlk.ps1 build -Product gateway -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
shell: pwsh
env:
CARGO_PACKAGE: devolutions-gateway
DGATEWAY_EXECUTABLE: ${{ steps.load-variables.outputs.dgateway-executable }}
TARGET_OUTPUT_PATH: ${{ steps.load-variables.outputs.target-output-path }}
- name: Add msbuild to PATH
if: ${{ matrix.os == 'windows' }}
uses: microsoft/setup-msbuild@v2
- name: Package
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
run: |
Set-PSDebug -Trace 1
if ($Env:RUNNER_OS -eq "Windows") {
$Env:DGATEWAY_PACKAGE = "${{ steps.load-variables.outputs.dgateway-package }}"
$Env:DGATEWAY_LIB_XMF_PATH = Join-Path "native-libs" "xmf.dll" | Resolve-Path
$PSStagingPath = Join-Path (Get-Location) "powershell-staging"
Write-Host "PSStagingPath = $PSStagingPath"
$PSModuleOutputPath = Join-Path $PSStagingPath "DevolutionsGateway"
$PSModuleTarFilePath = Get-ChildItem -Path "$PSStagingPath/PowerShell" "*-ps-*.tar" | Select-Object -First 1
tar -xvf "$PSModuleTarFilePath" -C "$PSStagingPath"
Get-ChildItem -Path "$PSStagingPath" -Recurse
$Env:DGATEWAY_PSMODULE_PATH = $PSModuleOutputPath
} else {
$Env:DGATEWAY_LIB_XMF_PATH = Join-Path "native-libs" "libxmf.so" | Resolve-Path
}
$Env:DGATEWAY_WEBCLIENT_PATH = Join-Path "webapp" "dist" "gateway-ui" | Resolve-Path
$Env:DGATEWAY_WEBPLAYER_PATH = Join-Path "webapp" "dist" "recording-player" | Resolve-Path
./ci/tlk.ps1 package -Product gateway -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
shell: pwsh
env:
DGATEWAY_EXECUTABLE: ${{ steps.load-variables.outputs.dgateway-executable }}
TARGET_OUTPUT_PATH: ${{ steps.load-variables.outputs.target-output-path }}
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: devolutions-gateway-${{ matrix.os }}-${{ matrix.arch }}
path: ${{ steps.load-variables.outputs.staging-path }}
devolutions-gateway-merge:
name: devolutions gateway merge artifacts
# The job is skipped for PRs coming from forks because the devolutions-gateway job would have been skipped (if always() wasn’t used). Another GitHub action oddity.
if: ${{ always() }}
needs: [preflight, devolutions-gateway]
runs-on: ubuntu-latest
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: devolutions-gateway
pattern: devolutions-gateway-*
delete-merged: true
devolutions-pedm-desktop:
name: devolutions-pedm-desktop
runs-on: windows-latest
needs: [preflight]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Build
run: ./dotnet/DesktopAgent/build.ps1
shell: pwsh
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: devolutions-pedm-desktop
path: ./dotnet/DesktopAgent/bin/Release/net48/*
devolutions-agent:
name: devolutions-agent [${{ matrix.os }} ${{ matrix.arch }}]
needs: [preflight, devolutions-pedm-desktop]
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include: ${{ fromJson(needs.preflight.outputs.agent-build-matrix) }}
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Load dynamic variables
id: load-variables
run: |
$PackageVersion = "${{ needs.preflight.outputs.version }}"
$StagingPath = Join-Path $Env:RUNNER_TEMP "staging"
$SymbolsPath = Join-Path $Env:RUNNER_TEMP "symbols"
New-Item -ItemType Directory $StagingPath
New-Item -ItemType Directory $SymbolsPath
$TargetOutputPath = Join-Path $StagingPath ${{ matrix.os }} ${{ matrix.arch }}
$ExecutableFileName = "DevolutionsAgent_${{ runner.os }}_${PackageVersion}_${{ matrix.arch }}"
if ($Env:RUNNER_OS -eq "Windows") {
$ExecutableFileName = "$($ExecutableFileName).exe"
$PackageFileName = "DevolutionsAgent-${{ matrix.arch }}-${PackageVersion}.msi"
$DAgentPackage = Join-Path $TargetOutputPath $PackageFileName
echo "dagent-package=$DAgentPackage" >> $Env:GITHUB_OUTPUT
$DAgentPedmShellExtDll = Join-Path $TargetOutputPath "DevolutionsPedmShellExt.dll"
echo "dagent-pedm-shell-ext-dll=$DAgentPedmShellExtDll" >> $Env:GITHUB_OUTPUT
$DAgentPedmShellExtMsix = Join-Path $TargetOutputPath "DevolutionsPedmShellExt.msix"
echo "dagent-pedm-shell-ext-msix=$DAgentPedmShellExtMsix" >> $Env:GITHUB_OUTPUT
$DAgentSessionExecutable = Join-Path $TargetOutputPath "DevolutionsSession.exe"
echo "dagent-session-executable=$DAgentSessionExecutable" >> $Env:GITHUB_OUTPUT
}
$DAgentExecutable = Join-Path $TargetOutputPath $ExecutableFileName
echo "staging-path=$StagingPath" >> $Env:GITHUB_OUTPUT
echo "symbols-path=$SymbolsPath" >> $Env:GITHUB_OUTPUT
echo "target-output-path=$TargetOutputPath" >> $Env:GITHUB_OUTPUT
echo "dagent-executable=$DAgentExecutable" >> $Env:GITHUB_OUTPUT
shell: pwsh
- name: Download devolutions-pedm-desktop
if: ${{ matrix.os == 'windows' }}
uses: actions/download-artifact@v4
with:
name: devolutions-pedm-desktop
path: devolutions-pedm-desktop
- name: Download tun2socks
id: tun2socks
if: ${{ matrix.os == 'windows' }}
run: |
$Arch = @{'x86_64'='x64';'arm64'='arm64'}['${{ matrix.arch }}']
$Destination = Join-Path $PWD "tun2socks"
./ci/download-tun2socks.ps1 -Architecture $Arch -Destination $Destination
$Tun2SocksExecutablePath = Join-Path $Destination "tun2socks.exe"
$WintunLibraryPath = Join-Path $Destination "wintun.dll"
echo "tun2socks-executable-path=$Tun2SocksExecutablePath" >> $Env:GITHUB_OUTPUT
echo "wintun-library-path=$WintunLibraryPath" >> $Env:GITHUB_OUTPUT
@($Tun2SocksExecutablePath, $WintunLibraryPath) | % {
if (-Not (Test-Path $_)) { throw "$_ not found" }
}
shell: pwsh
- name: Upload tun2socks artifacts
if: ${{ matrix.os == 'windows' }}
uses: actions/upload-artifact@v4
with:
name: tun2socks-${{ matrix.os }}-${{ matrix.arch }}
path: tun2socks/
- name: Setup LLVM
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-llvm@v1
with:
version: "18.1.8"
- name: Setup CBake
if: ${{ runner.os == 'Linux' }}
uses: Devolutions/actions-public/setup-cbake@v1
with:
sysroots: |
- ubuntu-18.04-amd64
- ubuntu-18.04-arm64
cargo_env_scripts: true
- name: Configure Linux runner
if: ${{ matrix.os == 'linux' }}
run: |
sudo apt-get update
sudo apt-get -o Acquire::Retries=3 install python3-wget python3-setuptools libsystemd-dev dh-make
- name: Configure Linux (arm) runner
if: ${{ matrix.os == 'linux' && matrix.arch == 'arm64' }}
run: |
sudo dpkg --add-architecture arm64
sudo apt-get -o Acquire::Retries=3 install -qy binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu qemu-user
rustup target add aarch64-unknown-linux-gnu
echo "STRIP_EXECUTABLE=aarch64-linux-gnu-strip" >> $GITHUB_ENV
- name: Install fpm
if: ${{ matrix.os == 'Linux' }}
run: sudo gem install --no-document fpm
- name: Configure Windows runner
if: ${{ matrix.os == 'windows' }}
run: |
# https://github.com/actions/runner-images/issues/9667
choco uninstall wixtoolset
choco install wixtoolset --version 3.14.0 --allow-downgrade --force
# Devolutions PEDM needs MakeAppx.exe
Write-Output "C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# WiX is installed on Windows runners but not in the PATH
Write-Output "C:\Program Files (x86)\WiX Toolset v3.14\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
# NASM is required by aws-lc-rs (used as rustls crypto backend)
choco install nasm
# We need to add the NASM binary folder to the PATH manually.
Write-Output "$Env:ProgramFiles\NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Configure Windows (arm) runner
if: ${{ runner.os == 'Windows' && matrix.arch == 'arm64' }}
run: |
rustup target add aarch64-pc-windows-msvc
shell: pwsh
- name: Add msbuild to PATH
if: ${{ matrix.os == 'windows' }}
uses: microsoft/setup-msbuild@v2
- name: Build
run: |
if ($Env:RUNNER_OS -eq "Windows") {
$Env:DAGENT_PEDM_SHELL_EXT_DLL = "${{ steps.load-variables.outputs.dagent-pedm-shell-ext-dll }}"
$Env:DAGENT_PEDM_SHELL_EXT_MSIX = "${{ steps.load-variables.outputs.dagent-pedm-shell-ext-msix }}"
$Env:DAGENT_SESSION_EXECUTABLE = "${{ steps.load-variables.outputs.dagent-session-executable }}"
$Env:DAGENT_TUN2SOCKS_EXE = "${{ steps.tun2socks.outputs.tun2socks-executable-path }}"
$Env:DAGENT_WINTUN_DLL = "${{ steps.tun2socks.outputs.wintun-library-path }}"
}
if ($Env:RUNNER_OS -eq "Linux") {
$LinuxArch = @{'x86_64'='amd64';'arm64'='arm64'}['${{ matrix.arch }}']
$RustArch = @{'x86_64'='x86_64';'arm64'='aarch64'}['${{ matrix.arch }}']
$RustTarget = "$RustArch-unknown-linux-gnu"
$Env:SYSROOT_NAME = "ubuntu-18.04-$LinuxArch"
. "$HOME/.cargo/cbake/${RustTarget}-enter.ps1"
$Env:AWS_LC_SYS_CMAKE_BUILDER="true"
}
./ci/tlk.ps1 build -Product agent -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
shell: pwsh
env:
CARGO_PACKAGE: devolutions-agent
DAGENT_EXECUTABLE: ${{ steps.load-variables.outputs.dagent-executable }}
TARGET_OUTPUT_PATH: ${{ steps.load-variables.outputs.target-output-path }}
- name: Package
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
run: |
if ($Env:RUNNER_OS -eq "Windows") {
$DesktopStagingPath = Join-Path (Get-Location) "devolutions-pedm-desktop"
Get-ChildItem -Path $DesktopStagingPath -Recurse | Where-Object { $_.Extension -notin '.exe', '.dll' } | Remove-Item -Recurse -Force
$Env:DAGENT_PACKAGE = "${{ steps.load-variables.outputs.dagent-package }}"
$Env:DAGENT_DESKTOP_AGENT_PATH = $DesktopStagingPath
$Env:DAGENT_PEDM_SHELL_EXT_DLL = "${{ steps.load-variables.outputs.dagent-pedm-shell-ext-dll }}"
$Env:DAGENT_PEDM_SHELL_EXT_MSIX = "${{ steps.load-variables.outputs.dagent-pedm-shell-ext-msix }}"
$Env:DAGENT_SESSION_EXECUTABLE = "${{ steps.load-variables.outputs.dagent-session-executable }}"
$Env:DAGENT_TUN2SOCKS_EXE = "${{ steps.tun2socks.outputs.tun2socks-executable-path }}"
$Env:DAGENT_WINTUN_DLL = "${{ steps.tun2socks.outputs.wintun-library-path }}"
}
./ci/tlk.ps1 package -Product agent -Platform ${{ matrix.os }} -Architecture ${{ matrix.arch }} -CargoProfile ${{ needs.preflight.outputs.rust-profile }}
shell: pwsh
env:
DAGENT_EXECUTABLE: ${{ steps.load-variables.outputs.dagent-executable }}
TARGET_OUTPUT_PATH: ${{ steps.load-variables.outputs.target-output-path }}
- name: Clean up architecture-agnostic files before upload
run: |
if ($Env:RUNNER_OS -eq "Windows") {
# Remove devolutions-pedm-desktop folder completely to avoid duplicates
# These will be available separately from the devolutions-pedm-desktop job
$DesktopStagingPath = Join-Path (Get-Location) "devolutions-pedm-desktop"
if (Test-Path $DesktopStagingPath) {
Write-Host "Removing devolutions-pedm-desktop folder: $DesktopStagingPath"
Remove-Item $DesktopStagingPath -Recurse -Force
}
}
shell: pwsh
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: devolutions-agent-${{ matrix.os }}-${{ matrix.arch }}
path: ${{ steps.load-variables.outputs.staging-path }}
devolutions-agent-merge:
name: devolutions agent merge artifacts
runs-on: ubuntu-latest
needs: [preflight, devolutions-agent]
steps:
- name: Merge Artifacts
uses: actions/upload-artifact/merge@v4
with:
name: devolutions-agent
pattern: devolutions-agent-*
delete-merged: true
devolutions-pedm-client:
name: devolutions-pedm-client
runs-on: ubuntu-latest
needs: [preflight]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Build
run: ./crates/devolutions-pedm/openapi/dotnet-client/build.ps1
shell: pwsh
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: devolutions-pedm-client
path: ./crates/devolutions-pedm/openapi/dotnet-client/src/Devolutions.Pedm.Client/bin/Release/Devolutions.Pedm.Client.*
dotnet-utils-tests:
name: .NET utils tests
runs-on: windows-2022
needs: [preflight]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Tests
run: |
Set-PSDebug -Trace 1
dotnet test utils/dotnet/GatewayUtils.sln
shell: pwsh
winapi-sanitizer-tests:
name: Windows API sanitizer tests
runs-on: windows-2022
needs: [preflight]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Prepare runner
run: |
$VSInstallationPath = $(vswhere.exe -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath)
Write-Host "VCToolsInstallDir = $VSInstallationPath"
Get-ChildItem "$VSInstallationPath"
$toolsPath = "$VSInstallationPath\VC\Tools\MSVC"
Write-Host "toolsPath = $toolsPath"
Get-ChildItem "$toolsPath"
$firstItem = Get-ChildItem "$toolsPath" | Select-Object -Last 1
$binPath = "$toolsPath\$($firstItem.Name)\bin\Hostx64\x64"
Write-Host "binPath = $binPath"
Get-ChildItem "$binPath"
$asanDllPath = "$binPath\clang_rt.asan_dynamic-x86_64.dll"
Write-Host "asanDllPath = $asanDllPath"
New-Item -ItemType Directory ".\target\x86_64-pc-windows-msvc\debug\"
Copy-Item -Path "$asanDllPath" -Destination .\target\x86_64-pc-windows-msvc\debug\
rustup toolchain install nightly
shell: pwsh
- name: Run tests
run: |
$Env:RUSTFLAGS="-Zsanitizer=address"
cargo +nightly test --target x86_64-pc-windows-msvc -p win-api-wrappers -p devolutions-pedm
shell: pwsh
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
winapi-miri:
name: Windows API miri tests [${{ matrix.os }}][${{ matrix.mode }}]
needs: [preflight]
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
os:
- windows
- linux
mode:
- stacked-borrow
- tree-borrows
include:
- os: windows
runner: windows-latest
- os: linux
runner: ubuntu-latest
- mode: tree-borrows
miriflags: -Zmiri-tree-borrows
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Setup Rust cache
uses: ./.github/actions/setup-rust-cache
with:
sccache-enabled: ${{ needs.preflight.outputs.sccache }}
- name: Prepare runner
run: |
rustup toolchain install nightly --component miri
- name: Run tests
run: |
$Env:MIRIFLAGS = "${{ matrix.miriflags }}"
cargo +nightly miri test -p win-api-wrappers
shell: pwsh
- name: Show sccache stats
if: ${{ needs.preflight.outputs.sccache == 'true' && !cancelled() }}
shell: pwsh
run: sccache --show-stats
pedm-simulator:
name: PEDM simulator
runs-on: windows-2022
needs: [preflight]
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
- name: Prepare runner
run: |
rustup toolchain install nightly
choco install pstools --yes
- name: Prepare PEDM simulator build
run: ./crates/pedm-simulator/prepare.ps1
- name: Build PEDM simulator container
run: ./crates/pedm-simulator/build-container.ps1
- name: Run PEDM simulator (container with limited user)
run: ./crates/pedm-simulator/run-container.ps1
# It’s difficult to get realtime stdout/stderr when using psexec -s.
# Instead, the run-expect-elevation.ps1 script will redirect the output into a file that we can read afterwards.
- name: Run PEDM simulator (as LocalSystem)
run: |
$scriptPath = Resolve-Path -Path "./crates/pedm-simulator/run-expect-elevation.ps1"
psexec -accepteula -s pwsh.exe $scriptPath
Get-Content -Path ./crates/pedm-simulator/pedm-simulator_run-expect-elevation.out
success:
name: Success
if: ${{ always() }}
needs: [tests, lints, check-dependencies, jetsocat-lipo, devolutions-gateway-powershell, devolutions-gateway, devolutions-gateway-merge, devolutions-pedm-desktop, devolutions-agent, devolutions-agent-merge, devolutions-pedm-client, dotnet-utils-tests, winapi-sanitizer-tests, winapi-miri, pedm-simulator]
runs-on: ubuntu-latest
steps:
- name: Check success
run: |
$results = '${{ toJSON(needs.*.result) }}' | ConvertFrom-Json
$succeeded = $($results | Where { $_ -Ne "success" }).Count -Eq 0
exit $(if ($succeeded) { 0 } else { 1 })
shell: pwsh
upload-git-log:
name: Upload git-log output
if: ${{ github.ref == 'refs/heads/master' }}
needs: [preflight, success]
runs-on: ubuntu-latest
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
with:
ref: ${{ needs.preflight.outputs.ref }}
fetch-depth: 10
- name: Generate git-log.txt
run: git log --max-count=10 > ./git-log.txt
shell: pwsh
- name: Upload git-log.txt
uses: actions/upload-artifact@v4
with:
name: git-log
path: ./git-log.txt
onedrive:
name: OneDrive
environment: onedrive-upload
if: ${{ github.ref == 'refs/heads/master' }}
needs: [preflight, upload-git-log]
runs-on: ubuntu-latest
steps:
- name: Check out Devolutions/actions
uses: actions/checkout@v4
with:
repository: Devolutions/actions
ref: v1
token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }}
path: ./.github/workflows
- name: Get current timestamp
id: timestamp
run: echo "timestamp=$(date +'%Y%m%d%H%M')" >> $GITHUB_OUTPUT
- name: Install Devolutions Toolbox
uses: ./.github/workflows/toolbox-install
with:
github_token: ${{ secrets.DEVOLUTIONSBOT_TOKEN }}
- uses: actions/download-artifact@v4
with:
name: jetsocat
path: ${{ runner.temp }}/artifacts_raw
- uses: actions/download-artifact@v4
with:
name: devolutions-gateway
path: ${{ runner.temp }}/artifacts_raw
- uses: actions/download-artifact@v4
with:
name: devolutions-agent
path: ${{ runner.temp }}/artifacts_raw
- uses: actions/download-artifact@v4
with:
name: git-log
path: ${{ runner.temp }}/artifacts_raw
- name: Prepare upload
id: prepare
run: |
$version="${{ needs.preflight.outputs.version }}"
$ref="${{ needs.preflight.outputs.ref }}"
$shortRef=$ref.Substring(0, 8)
$sourceFolder = "${{ runner.temp }}/artifacts_raw"
$destinationFolder = "${{ runner.temp }}/artifacts"
Write-Host "version = $version"
Write-Host "ref = $ref"
echo "version=$version" >> $Env:GITHUB_OUTPUT
echo "short-ref=$shortRef" >> $Env:GITHUB_OUTPUT
echo "files-to-upload=$destinationFolder" >> $Env:GITHUB_OUTPUT
New-Item -Path "$destinationFolder" -ItemType "directory"
$allFiles = Get-ChildItem -Path "$sourceFolder" -Exclude PowerShell | Get-ChildItem -Recurse | Where { -Not $_.Mode.StartsWith('d') }
# Exclude some files that are already bundled in installers
$excludeFiles = @(
'DevolutionsPedmShellExt.dll',
'DevolutionsPedmShellExt.msix',
'DevolutionsSession.exe',
# NOTE: We may want to include that in the future, but needs to be renamed per platform.
# TODO(@awakecoding): We could create a zip with the same name as
# the package except ".symbols" at the end, so we'd end up with arch-specific zips
# containing the debug symbols. I've done this for MsRdpEx.
'DevolutionsPedmShellExt.pdb',
'DevolutionsSession.pdb'
)
Write-Host
foreach ($file in $allFiles) {
$dir = $file.Directory
$name = $file.Name
$source = "$dir/$name"
$destination = "$destinationFolder/$name"
# Skip architecture-specific files that are part of installers
if ($name -in $excludeFiles) {
Write-Host "Skipping $source"
continue
}
Write-Host "$source --> $destination"
Move-Item -Path "$source" -Destination "$destination"
}
shell: pwsh
- name: Upload to OneDrive
uses: ./.github/workflows/onedrive-upload
with:
azure_client_id: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_ID }}
azure_client_secret: ${{ secrets.ONEDRIVE_AUTOMATION_CLIENT_SECRET }}
conflict_behavior: replace
destination_path: /Gateway/${{ steps.prepare.outputs.version }}-${{ steps.timestamp.outputs.timestamp }}-${{ steps.prepare.outputs.short-ref }}
remote: prereleases
source_path: ${{ steps.prepare.outputs.files-to-upload }}