Skip to content

Commit 4607247

Browse files
committed
Add support for netstandard2.0
* Add `net472` target framework to Tests.csproj * Add Windows build * Cache installers on Windows * Fix Windows `rabbitmq.conf` for TLS * Disable AltCover on Windows * You cannot do EXTERNAL auth without the correct plugin enabled /facepalm * Use `LangVersion` 9 in library * Do not error when inet_error is seen in build-windows action
1 parent 53b8b1d commit 4607247

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+4351
-3420
lines changed

.ci/ubuntu/enabled_plugins

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[rabbitmq_auth_mechanism_ssl,rabbitmq_management].
1+
[rabbitmq_auth_mechanism_ssl,rabbitmq_management,rabbitmq_stream,rabbitmq_stream_management,rabbitmq_top].

.ci/ubuntu/rabbitmq.conf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
loopback_users = none
2+
loopback_users.guest = true
23

34
log.console = true
45
log.console.level = debug
@@ -16,9 +17,9 @@ ssl_options.cacertfile = /etc/rabbitmq/certs/ca_certificate.pem
1617
ssl_options.certfile = /etc/rabbitmq/certs/server_localhost_certificate.pem
1718
ssl_options.keyfile = /etc/rabbitmq/certs/server_localhost_key.pem
1819
ssl_options.verify = verify_peer
20+
ssl_options.password = grapefruit
21+
ssl_options.depth = 1
1922
ssl_options.fail_if_no_peer_cert = false
20-
ssl_options.password = grapefruit
21-
ssl_options.depth = 1
2223

2324
auth_mechanisms.1 = PLAIN
2425
auth_mechanisms.2 = EXTERNAL

.ci/windows/enabled_plugins

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[rabbitmq_auth_mechanism_ssl,rabbitmq_management,rabbitmq_stream,rabbitmq_stream_management,rabbitmq_top].

.ci/windows/gha-log-check.ps1

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
$ProgressPreference = 'Continue'
2+
$VerbosePreference = 'Continue'
3+
$ErrorActionPreference = 'Stop'
4+
Set-StrictMode -Version 2.0
5+
6+
$rabbitmq_log_dir = Join-Path -Path $env:AppData -ChildPath 'RabbitMQ' | Join-Path -ChildPath 'log'
7+
Write-Host "[INFO] looking for errors in '$rabbitmq_log_dir'"
8+
9+
If (Get-ChildItem $rabbitmq_log_dir\*.log | Select-String -Quiet -SimpleMatch -Pattern inet_error)
10+
{
11+
# Note: only issuing a warning since `inet_error,econnaborted` can be found
12+
# in Windows test runs
13+
Write-Host "[WARNING] found inet_error in '$rabbitmq_log_dir'"
14+
}

.ci/windows/gha-setup.ps1

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
$ProgressPreference = 'Continue'
2+
$VerbosePreference = 'Continue'
3+
$ErrorActionPreference = 'Stop'
4+
Set-StrictMode -Version 2.0
5+
6+
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor 'Tls12'
7+
8+
New-Variable -Name curdir -Option Constant -Value $PSScriptRoot
9+
Write-Host "[INFO] curdir: $curdir"
10+
11+
New-Variable -Name ci_dir -Option Constant -Value (Join-Path -Path $env:GITHUB_WORKSPACE -ChildPath '.ci')
12+
13+
New-Variable -Name certs_dir -Option Constant -Value (Join-Path -Path $ci_dir -ChildPath 'certs')
14+
15+
New-Variable -Name ci_windows_dir -Option Constant -Value (Join-Path -Path $ci_dir -ChildPath 'windows')
16+
17+
New-Variable -Name ca_certificate_file -Option Constant -Value `
18+
(Resolve-Path -LiteralPath (Join-Path -Path $certs_dir -ChildPath 'ca_certificate.pem'))
19+
20+
New-Variable -Name enabled_plugins_file -Option Constant -Value `
21+
(Resolve-Path -LiteralPath (Join-Path -Path $ci_windows_dir -ChildPath 'enabled_plugins'))
22+
23+
Write-Host "[INFO] importing CA cert from '$ca_certificate_file'"
24+
Import-Certificate -Verbose -CertStoreLocation Cert:\LocalMachine\Root -FilePath $ca_certificate_file
25+
26+
New-Variable -Name versions_path -Option Constant -Value `
27+
(Resolve-Path -LiteralPath (Join-Path -Path $ci_windows_dir -ChildPath 'versions.json'))
28+
$versions = Get-Content $versions_path | ConvertFrom-Json
29+
Write-Host "[INFO] versions: $versions"
30+
$erlang_ver = $versions.erlang
31+
$rabbitmq_ver = $versions.rabbitmq
32+
33+
$base_installers_dir = Join-Path -Path $HOME -ChildPath 'installers'
34+
if (-Not (Test-Path $base_installers_dir))
35+
{
36+
New-Item -Verbose -ItemType Directory $base_installers_dir
37+
}
38+
39+
$erlang_download_url = "https://github.com/erlang/otp/releases/download/OTP-$erlang_ver/otp_win64_$erlang_ver.exe"
40+
$erlang_installer_path = Join-Path -Path $base_installers_dir -ChildPath "otp_win64_$erlang_ver.exe"
41+
$erlang_install_dir = Join-Path -Path $HOME -ChildPath 'erlang'
42+
43+
Write-Host '[INFO] Downloading Erlang...'
44+
45+
if (-Not (Test-Path -LiteralPath $erlang_installer_path))
46+
{
47+
Invoke-WebRequest -UseBasicParsing -Uri $erlang_download_url -OutFile $erlang_installer_path
48+
}
49+
else
50+
{
51+
Write-Host "[INFO] Found '$erlang_installer_path' in cache!"
52+
}
53+
54+
Write-Host "[INFO] Installing Erlang to $erlang_install_dir..."
55+
& $erlang_installer_path '/S' "/D=$erlang_install_dir" | Out-Null
56+
57+
# https://github.com/rabbitmq/rabbitmq-server/releases/download/v4.0.0-beta.5/rabbitmq-server-windows-4.0.0-beta.5.zip
58+
$rabbitmq_installer_download_url = "https://github.com/rabbitmq/rabbitmq-server/releases/download/v$rabbitmq_ver/rabbitmq-server-$rabbitmq_ver.exe"
59+
$rabbitmq_installer_path = Join-Path -Path $base_installers_dir -ChildPath "rabbitmq-server-$rabbitmq_ver.exe"
60+
Write-Host "[INFO] rabbitmq installer path $rabbitmq_installer_path"
61+
62+
if (Test-Path -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\')
63+
{
64+
New-Variable -Name erlangRegKeyPath -Option Constant `
65+
-Value 'HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang'
66+
}
67+
else
68+
{
69+
New-Variable -Name erlangRegKeyPath -Option Constant `
70+
-Value 'HKLM:\SOFTWARE\Ericsson\Erlang'
71+
}
72+
73+
New-Variable -Name erlangRegKey -Option Constant `
74+
-Value (Get-ChildItem $erlangRegKeyPath)
75+
76+
if ($erlangRegKey -eq $null) {
77+
Write-Error "Could not find Erlang installation registry key at $erlangRegKeyPath"
78+
}
79+
80+
New-Variable -Name erlangErtsVersion -Option Constant `
81+
-Value (Select-Object -InputObject $erlangRegKey -Last 1).PSChildName
82+
Write-Verbose "erlangErtsVersion: $erlangErtsVersion"
83+
84+
New-Variable -Name erlangErtsRegKeyPath -Option Constant `
85+
-Value "HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang\$erlangErtsVersion"
86+
87+
New-Variable -Name erlangErtsRegKey -Option Constant `
88+
-Value (Get-ItemProperty -LiteralPath HKLM:\SOFTWARE\WOW6432Node\Ericsson\Erlang\$erlangErtsVersion)
89+
90+
if ($erlangErtsRegKey -eq $null) {
91+
Write-Error "Could not find Erlang erts registry key at $erlangErtsRegKeyPath"
92+
}
93+
94+
New-Variable -Name erlangProgramFilesPath -Option Constant `
95+
-Value ($erlangErtsRegKey.'(default)')
96+
97+
if (Test-Path -LiteralPath $erlangProgramFilesPath) {
98+
Write-Verbose "Erlang installation directory: '$erlangProgramFilesPath'"
99+
}
100+
else {
101+
Write-Error 'Could not find Erlang installation directory!'
102+
}
103+
104+
New-Variable -Name allowedExes -Option Constant -Value @('erl.exe', 'epmd.exe', 'werl.exe')
105+
106+
New-Variable -Name exes -Option Constant -Value `
107+
$(Get-ChildItem -Filter '*.exe' -Recurse -LiteralPath $erlangProgramFilesPath | Where-Object { $_.Name -in $allowedExes })
108+
109+
foreach ($exe in $exes) {
110+
$fwRuleName = "rabbitmq-allow-$($exe.Name)-$(Get-Random)"
111+
Write-Verbose "Updating or creating firewall rule for '$exe' - fwRuleName: $fwRuleName"
112+
if (!(Get-NetFirewallRule -ErrorAction 'SilentlyContinue' -Name $fwRuleName)) {
113+
New-NetFirewallRule -Enabled True -Name $fwRuleName -DisplayName $fwRuleName -Direction In -Program $exe -Profile Any -Action Allow
114+
}
115+
else {
116+
Set-NetFirewallRule -Enabled True -Name $fwRuleName -DisplayName $fwRuleName -Direction In -Program $exe -Profile Any -Action Allow
117+
}
118+
}
119+
120+
Write-Host "[INFO] Setting ERLANG_HOME to '$erlangProgramFilesPath'..."
121+
$env:ERLANG_HOME = $erlangProgramFilesPath
122+
[Environment]::SetEnvironmentVariable('ERLANG_HOME', $erlangProgramFilesPath, 'Machine')
123+
Add-Content -Verbose -LiteralPath $env:GITHUB_ENV -Value "ERLANG_HOME=$erlangProgramFilesPath"
124+
125+
Write-Host "[INFO] Setting RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS..."
126+
$env:RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS = '-rabbitmq_stream advertised_host localhost'
127+
[Environment]::SetEnvironmentVariable('RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS', '-rabbitmq_stream advertised_host localhost', 'Machine')
128+
129+
Write-Host '[INFO] Downloading RabbitMQ...'
130+
131+
if (-Not (Test-Path -LiteralPath $rabbitmq_installer_path))
132+
{
133+
Invoke-WebRequest -UseBasicParsing -Uri $rabbitmq_installer_download_url -OutFile $rabbitmq_installer_path
134+
}
135+
else
136+
{
137+
Write-Host "[INFO] Found '$rabbitmq_installer_path' in cache!"
138+
}
139+
140+
Write-Host "[INFO] Installer dir '$base_installers_dir' contents:"
141+
Get-ChildItem -Verbose -LiteralPath $base_installers_dir
142+
143+
$rabbitmq_conf_in_file = Join-Path -Path $ci_windows_dir -ChildPath 'rabbitmq.conf.in'
144+
$rabbitmq_appdata_dir = Join-Path -Path $env:AppData -ChildPath 'RabbitMQ'
145+
New-Item -Path $rabbitmq_appdata_dir -ItemType Directory
146+
$rabbitmq_conf_file = Join-Path -Path $rabbitmq_appdata_dir -ChildPath 'rabbitmq.conf'
147+
$rabbitmq_enabled_plugins_file = Join-Path -Path $rabbitmq_appdata_dir -ChildPath 'enabled_plugins'
148+
149+
Write-Host "[INFO] Creating RabbitMQ configuration file in '$rabbitmq_appdata_dir'"
150+
Get-Content $rabbitmq_conf_in_file | %{ $_ -replace '@@CERTS_DIR@@', $certs_dir } | %{ $_ -replace '\\', '/' } | Set-Content -LiteralPath $rabbitmq_conf_file
151+
Get-Content $rabbitmq_conf_file
152+
153+
Write-Host "[INFO] Copying '$enabled_plugins_file' to '$rabbitmq_enabled_plugins_file'"
154+
Copy-Item -Verbose -Force -LiteralPath $enabled_plugins_file -Destination $rabbitmq_enabled_plugins_file
155+
156+
Write-Host '[INFO] Creating Erlang cookie files...'
157+
158+
function Set-ErlangCookie
159+
{
160+
Param($Path, $Value = 'RABBITMQ-COOKIE')
161+
Remove-Item -Force $Path -ErrorAction SilentlyContinue
162+
[System.IO.File]::WriteAllText($Path, $Value, [System.Text.Encoding]::ASCII)
163+
}
164+
165+
$erlang_cookie_user = Join-Path -Path $HOME -ChildPath '.erlang.cookie'
166+
$erlang_cookie_system = Join-Path -Path $env:SystemRoot -ChildPath 'System32\config\systemprofile\.erlang.cookie'
167+
168+
Set-ErlangCookie -Path $erlang_cookie_user
169+
Set-ErlangCookie -Path $erlang_cookie_system
170+
171+
Write-Host '[INFO] Installing and starting RabbitMQ...'
172+
173+
& $rabbitmq_installer_path '/S' | Out-Null
174+
(Get-Service -Name RabbitMQ).Status
175+
176+
$rabbitmq_base_path = (Get-ItemProperty -Name Install_Dir -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\VMware, Inc.\RabbitMQ Server').Install_Dir
177+
$regPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ'
178+
if (Test-Path -LiteralPath 'HKLM:\SOFTWARE\WOW6432Node\')
179+
{
180+
$regPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\RabbitMQ'
181+
}
182+
$rabbitmq_version = (Get-ItemProperty $regPath 'DisplayVersion').DisplayVersion
183+
Write-Host "[INFO] RabbitMQ version path: $rabbitmq_base_path and version: $rabbitmq_version"
184+
185+
$rabbitmq_home = Join-Path -Path $rabbitmq_base_path -ChildPath "rabbitmq_server-$rabbitmq_version"
186+
Write-Host "[INFO] Setting RABBITMQ_HOME to '$rabbitmq_home'..."
187+
[Environment]::SetEnvironmentVariable('RABBITMQ_HOME', $rabbitmq_home, 'Machine')
188+
$env:RABBITMQ_HOME = $rabbitmq_home
189+
190+
$rabbitmqctl_path = Join-Path -Path $rabbitmq_base_path -ChildPath "rabbitmq_server-$rabbitmq_version" | Join-Path -ChildPath 'sbin' | Join-Path -ChildPath 'rabbitmqctl.bat'
191+
$rabbitmq_plugins_path = Join-Path -Path $rabbitmq_base_path -ChildPath "rabbitmq_server-$rabbitmq_version" | Join-Path -ChildPath 'sbin' | Join-Path -ChildPath 'rabbitmq-plugins.bat'
192+
193+
$epmd_running = $false
194+
[int]$count = 1
195+
196+
$epmd_exe = Join-Path -Path $erlangProgramFilesPath -ChildPath "erts-$erlangErtsVersion" | Join-Path -ChildPath 'bin' | Join-Path -ChildPath 'epmd.exe'
197+
198+
Write-Host "[INFO] Waiting for epmd ($epmd_exe) to report that RabbitMQ has started..."
199+
200+
Do {
201+
$epmd_running = & $epmd_exe -names | Select-String -CaseSensitive -SimpleMatch -Quiet -Pattern 'name rabbit at port'
202+
if ($epmd_running -eq $true) {
203+
Write-Host '[INFO] epmd reports that RabbitMQ is running!'
204+
break
205+
}
206+
207+
if ($count -gt 60) {
208+
throw '[ERROR] too many tries waiting for epmd to report RabbitMQ running!'
209+
}
210+
211+
Write-Host "[INFO] epmd NOT reporting yet that RabbitMQ is running, count: '$count'..."
212+
$count = $count + 1
213+
Start-Sleep -Seconds 5
214+
215+
} While ($true)
216+
217+
[int]$count = 1
218+
219+
Do {
220+
$proc_id = (Get-Process -Name erl).Id
221+
if (-Not ($proc_id -is [array])) {
222+
& $rabbitmqctl_path await_startup
223+
if ($LASTEXITCODE -ne 0) {
224+
throw "[ERROR] 'rabbitmqctl await_startup' returned error: $LASTEXITCODE"
225+
}
226+
break
227+
}
228+
229+
if ($count -gt 120) {
230+
throw '[ERROR] too many tries waiting for just one erl process to be running!'
231+
}
232+
233+
Write-Host '[INFO] multiple erl instances running still...'
234+
$count = $count + 1
235+
Start-Sleep -Seconds 5
236+
237+
} While ($true)
238+
239+
$ErrorActionPreference = 'Continue'
240+
Write-Host '[INFO] Getting RabbitMQ status...'
241+
& $rabbitmqctl_path status
242+
243+
echo Q | openssl s_client -connect localhost:5671 -CAfile "$certs_dir/ca_certificate.pem" -cert "$certs_dir/client_localhost_certificate.pem" -key "$certs_dir/client_localhost_key.pem" -pass pass:grapefruit
244+
if ($LASTEXITCODE -ne 0)
245+
{
246+
throw "[ERROR] 'openssl s_client' returned error: $LASTEXITCODE"
247+
}

.ci/windows/rabbitmq.conf.in

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
loopback_users = none
2+
loopback_users.guest = true
3+
4+
log.console = false
5+
log.file.level = debug
6+
log.exchange = false
7+
8+
listeners.tcp.default = 5672
9+
listeners.ssl.default = 5671
10+
reverse_dns_lookups = false
11+
12+
deprecated_features.permit.amqp_address_v1 = false
13+
14+
ssl_options.cacertfile = @@CERTS_DIR@@/ca_certificate.pem
15+
ssl_options.certfile = @@CERTS_DIR@@/server_localhost_certificate.pem
16+
ssl_options.keyfile = @@CERTS_DIR@@/server_localhost_key.pem
17+
ssl_options.verify = verify_peer
18+
ssl_options.password = grapefruit
19+
ssl_options.depth = 1
20+
ssl_options.fail_if_no_peer_cert = false
21+
22+
auth_mechanisms.1 = PLAIN
23+
auth_mechanisms.2 = EXTERNAL

.ci/windows/versions.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"erlang": "26.2.5.2",
3+
"rabbitmq": "4.0.0-beta.5"
4+
}

.github/workflows/build-test.yaml

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,46 @@ on:
55

66

77
jobs:
8-
build:
8+
build-win32:
9+
runs-on: windows-latest
10+
# https://github.com/NuGet/Home/issues/11548
11+
env:
12+
NUGET_CERT_REVOCATION_MODE: offline
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/cache@v4
16+
with:
17+
# Note: the cache path is relative to the workspace directory
18+
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#using-the-cache-action
19+
path: ~/installers
20+
key: ${{ runner.os }}-v0-${{ hashFiles('.ci/windows/versions.json') }}
21+
- uses: actions/cache@v4
22+
with:
23+
path: |
24+
~/.nuget/packages
25+
~/AppData/Local/NuGet/v3-cache
26+
key: ${{ runner.os }}-v0-nuget-${{ hashFiles('**/*.csproj') }}
27+
restore-keys: |
28+
${{ runner.os }}-v0-nuget-
29+
- name: Build (Debug)
30+
run: dotnet build ${{ github.workspace }}\Build.csproj
31+
- name: Verify
32+
run: dotnet format ${{ github.workspace }}\rabbitmq-amqp-dotnet-client.sln --no-restore --verify-no-changes
33+
- name: Install and Start RabbitMQ
34+
id: install-start-rabbitmq
35+
run: ${{ github.workspace }}\.ci\windows\gha-setup.ps1
36+
- name: Test
37+
timeout-minutes: 15
38+
run: dotnet test ${{ github.workspace }}\Build.csproj --no-restore --no-build --logger 'console;verbosity=detailed'
39+
- name: Check for errors in RabbitMQ logs
40+
run: ${{ github.workspace }}\.ci\windows\gha-log-check.ps1
41+
- name: Maybe upload RabbitMQ logs
42+
if: failure()
43+
uses: actions/upload-artifact@v4
44+
with:
45+
name: rabbitmq-logs-integration-win32
46+
path: ~/AppData/Roaming/RabbitMQ/log/
47+
build-ubuntu:
948
runs-on: ubuntu-latest
1049
steps:
1150
- uses: actions/checkout@v4
@@ -20,21 +59,15 @@ jobs:
2059
- name: Build (Debug)
2160
run: dotnet build ${{ github.workspace }}/Build.csproj
2261
- name: Verify
23-
run: dotnet format ${{ github.workspace }}/Build.csproj --no-restore --verify-no-changes
62+
run: dotnet format ${{ github.workspace }}/rabbitmq-amqp-dotnet-client.sln --no-restore --verify-no-changes
2463
- name: Start RabbitMQ
2564
id: start-rabbitmq
26-
# Note: not using toxiproxy yet
27-
# run: ${{ github.workspace }}/.ci/ubuntu/gha-setup.sh toxiproxy
2865
run: ${{ github.workspace }}/.ci/ubuntu/gha-setup.sh
2966
- name: Test
3067
timeout-minutes: 15
3168
run: dotnet test ${{ github.workspace }}/Build.csproj --no-restore --no-build --logger "console;verbosity=detailed" /p:AltCover=true /p:AltCoverStrongNameKey=${{github.workspace}}/rabbit.snk
3269
- name: Check for errors in RabbitMQ logs
3370
run: ${{ github.workspace}}/.ci/ubuntu/gha-log-check.sh
34-
# Note: not using toxiproxy yet
35-
# - name: Maybe collect toxiproxy logs
36-
# if: failure()
37-
# run: docker logs rabbitmq-amqp-dotnet-client-toxiproxy > ${{ github.workspace }}/.ci/ubuntu/log/toxiproxy.log
3871
- name: Maybe upload RabbitMQ logs
3972
if: failure()
4073
uses: actions/upload-artifact@v4

0 commit comments

Comments
 (0)