Skip to content

Commit 91619f6

Browse files
committed
Adding release pipeline.
1 parent 8808801 commit 91619f6

12 files changed

+660
-6
lines changed

.github/workflows/release.yml

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
name: Version release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
env:
8+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
9+
DOTNET_CLI_TELEMETRY_OPTOUT: true
10+
mysqlCurrentSqlMode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
11+
mysqlLegacySqlMode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
12+
# Currently no ONLY_FULL_GROUP_BY, see #1167:
13+
mariadbSqlMode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
14+
maxConnections: 512
15+
skipAllTests: false
16+
skipWindowsTests: false
17+
jobs:
18+
BuildAndTest:
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
dbVersion:
23+
- 8.4.3-mysql
24+
- 8.0.40-mysql
25+
- 11.6.2-mariadb
26+
- 11.5.2-mariadb
27+
- 11.4.4-mariadb
28+
- 11.3.2-mariadb
29+
- 10.11.10-mariadb
30+
- 10.6.20-mariadb
31+
- 10.5.27-mariadb
32+
os:
33+
- ubuntu-latest
34+
- windows-latest
35+
runs-on: ${{ matrix.os }}
36+
steps:
37+
- name: Checkout
38+
uses: actions/checkout@v4
39+
- name: Set additional variables
40+
shell: pwsh
41+
run: |
42+
$os = '${{ matrix.os }}'.Split('-')[0] -eq 'windows' ? 'windows' : 'linux'
43+
echo "os=$os" >> $env:GITHUB_ENV
44+
45+
$dbVersionParts = '${{ matrix.dbVersion }}'.Split('-')
46+
47+
$databaseServerType = $dbVersionParts[1]
48+
echo "databaseServerType=$databaseServerType" >> $env:GITHUB_ENV
49+
50+
$databaseServerVersion = $dbVersionParts[0]
51+
echo "databaseServerVersion=$databaseServerVersion" >> $env:GITHUB_ENV
52+
53+
# The parenthesis around the right OR argument are mandatory for the expression to work correctly, because in PowerShell, AND and OR
54+
# operators have the SAME precedence.
55+
$skipTests = '${{ env.skipAllTests }}' -eq 'true' -or ($os -eq 'windows' -and '${{ env.skipWindowsTests }}' -eq 'true')
56+
echo "skipTests=$skipTests" >> $env:GITHUB_ENV
57+
58+
$sqlMode = $databaseServerType -eq 'mariadb' ? '${{ env.mariadbSqlMode }}' : $databaseServerType -eq 'mysql' -and $databaseServerVersion.Split('.')[0] -lt 8 ? '${{ env.mysqlLegacySqlMode }}' : '${{ env.mysqlCurrentSqlMode }}'
59+
echo "sqlMode=$sqlMode" >> $env:GITHUB_ENV
60+
61+
$serverExecutable = $databaseServerType -eq 'mariadb' -and $databaseServerVersion.Split('.')[0] -ge 11 ? 'mariadbd' : 'mysqld'
62+
echo "serverExecutable=$serverExecutable" >> $env:GITHUB_ENV
63+
64+
$clientExecutable = $databaseServerType -eq 'mariadb' -and $databaseServerVersion.Split('.')[0] -ge 11 ? 'mariadb' : 'mysql'
65+
echo "clientExecutable=$clientExecutable" >> $env:GITHUB_ENV
66+
67+
$clientCommandPrefix = $os -eq 'windows' ? $clientExecutable : "docker exec '$databaseServerType' $clientExecutable"
68+
echo "clientCommandPrefix=$clientCommandPrefix" >> $env:GITHUB_ENV
69+
70+
$windowsUserTempLocation = $os -eq 'windows' ? (Get-Item $env:Temp).FullName : ''
71+
echo "windowsUserTempLocation=$windowsUserTempLocation" >> $env:GITHUB_ENV
72+
- name: Output Variables
73+
shell: pwsh
74+
run: |
75+
echo "os: ${{ env.os }}"
76+
echo "databaseServerType: ${{ env.databaseServerType }}"
77+
echo "databaseServerVersion: ${{ env.databaseServerVersion }}"
78+
echo "sqlMode: ${{ env.sqlMode }}"
79+
echo "skipTests: ${{ env.skipTests }}"
80+
echo "skipAllTests: ${{ env.skipAllTests }}"
81+
echo "skipWindowsTests: ${{ env.skipWindowsTests }}"
82+
echo "serverExecutable: ${{ env.serverExecutable }}"
83+
echo "clientExecutable: ${{ env.clientExecutable }}"
84+
echo "clientCommandPrefix: ${{ env.clientCommandPrefix }}"
85+
echo "windowsUserTempLocation: ${{ env.windowsUserTempLocation }}"
86+
87+
echo "github.event_name: ${{ github.event_name }}"
88+
echo "github.repository: ${{ github.repository }}"
89+
- name: Install Database Server - Linux
90+
if: ${{ env.os == 'linux' }}
91+
shell: pwsh
92+
run: |
93+
sudo systemctl stop mysql
94+
95+
$waitMinutes = 5
96+
$pollingIntervalSeconds = 1
97+
$started = $false
98+
99+
dir './cache/database' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
100+
101+
if (Test-Path -PathType Leaf './cache/database/${{ env.databaseServerType }}_${{ env.databaseServerVersion }}.tar')
102+
{
103+
docker load --input './cache/database/${{ env.databaseServerType }}_${{ env.databaseServerVersion }}.tar'
104+
}
105+
else
106+
{
107+
if (-not (Test-Path -PathType Container './cache/database'))
108+
{
109+
New-Item -ItemType Directory './cache/database'
110+
}
111+
112+
docker pull '${{ env.databaseServerType }}:${{ env.databaseServerVersion }}'
113+
docker save -o './cache/database/${{ env.databaseServerType }}_${{ env.databaseServerVersion }}.tar' '${{ env.databaseServerType }}:${{ env.databaseServerVersion }}'
114+
115+
dir './cache/database' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
116+
}
117+
118+
docker run --name '${{ env.databaseServerType }}' -e MYSQL_ROOT_PASSWORD=Password12! -p 127.0.0.1:3306:3306 -d '${{ env.databaseServerType }}:${{ env.databaseServerVersion }}'
119+
$startTime = Get-Date
120+
121+
while (!($started = ${{ env.clientCommandPrefix }} --protocol=tcp -h localhost -P 3306 -u root -pPassword12! -e 'select 1;') -and ((Get-Date) - $startTime).TotalMinutes -lt $waitMinutes)
122+
{
123+
Start-Sleep -Seconds $pollingIntervalSeconds
124+
}
125+
126+
if (!$started)
127+
{
128+
throw "${{ env.databaseServerType }}:${{ env.databaseServerVersion }} docker container failed to start in ${waitMinutes} minutes"
129+
exit 1
130+
}
131+
- name: Install Database Server - Windows
132+
if: ${{ env.os == 'windows' }}
133+
shell: pwsh
134+
run: |
135+
$mySqlServiceName = '${{ env.databaseServerType }}_${{ env.databaseServerVersion }}'
136+
$lowerCaseTableNames = 2
137+
$packageName = 'Pomelo.Chocolatey.${{ env.databaseServerType }}.Server'
138+
$mySqlBinPath = "C:\tools\${packageName}\current\bin"
139+
$mySqlIniPath = "C:\tools\${packageName}\current\my.ini"
140+
$mySqlDataPath = 'C:\ProgramData\${{ env.databaseServerType }}\data'
141+
142+
dir "$env:Temp\${{ env.databaseServerType }}\${{ env.databaseServerVersion }}" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
143+
144+
$service = Get-Service '*${{ env.databaseServerType }}*' -ErrorAction SilentlyContinue
145+
if ($service -ne $null)
146+
{
147+
throw "A service for ${{ env.databaseServerType }} appears to already exist."
148+
exit 1
149+
}
150+
151+
# choco config set cacheLocation '$(Pipeline.Workspace)/cache/database'
152+
choco install $packageName '--version=${{ env.databaseServerVersion }}' --ignore-dependencies --source 'https://www.myget.org/F/pomelo/api/v2;https://community.chocolatey.org/api/v2' --params "/serviceName:$mySqlServiceName"
153+
154+
Get-Service '*${{ env.databaseServerType }}*' -ErrorAction SilentlyContinue
155+
Stop-Service $mySqlServiceName -Verbose
156+
157+
echo "Update PATH environment variable"
158+
$env:PATH = "$mySqlBinPath;$env:PATH"
159+
echo "PATH=$env:PATH" >> $env:GITHUB_ENV
160+
161+
echo "Update configuration file"
162+
"lower_case_table_names=$lowerCaseTableNames" >> $mySqlIniPath
163+
164+
Remove-Item $mySqlDataPath/* -Recurse -Force -Verbose
165+
166+
echo "Reinitialize database server"
167+
168+
if ('${{ env.databaseServerType }}' -eq 'mysql')
169+
{
170+
${{ env.serverExecutable }} --defaults-file="$mySqlIniPath" --initialize-insecure
171+
}
172+
else
173+
{
174+
mysql_install_db --datadir="$mySqlDataPath"
175+
}
176+
177+
Start-Service $mySqlServiceName -Verbose
178+
179+
echo "Setup credentials"
180+
${{ env.clientCommandPrefix }} -h localhost -u root -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Password12!';"
181+
${{ env.clientCommandPrefix }} -h localhost -u root -pPassword12! -e "SELECT @@version;"
182+
183+
dir "$env:Temp\${packageName}\${{ env.databaseServerVersion }}" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
184+
- name: Setup Database
185+
shell: pwsh
186+
run: ${{ env.clientCommandPrefix }} -u root -pPassword12! -e "SET GLOBAL sql_mode = '${{ env.sqlMode }}'; SET GLOBAL max_connections = ${{ env.maxConnections }};"
187+
- name: Database Information
188+
shell: pwsh
189+
run: ${{ env.clientCommandPrefix }} -u root -pPassword12! -e 'SHOW VARIABLES;'
190+
- name: Setup .NET SDK
191+
uses: actions/setup-dotnet@v4
192+
with:
193+
global-json-file: global.json
194+
- name: .NET Information
195+
shell: pwsh
196+
run: |
197+
dotnet --info
198+
- name: Install EF Core Tools
199+
shell: pwsh
200+
run: |
201+
dotnet tool restore
202+
dotnet ef --version
203+
- name: Restore dependencies
204+
shell: pwsh
205+
run: dotnet restore
206+
- name: Setup Solution
207+
shell: pwsh
208+
run: |
209+
Copy-Item test/EFCore.MySql.FunctionalTests/config.json.example test/EFCore.MySql.FunctionalTests/config.json
210+
Copy-Item test/EFCore.MySql.IntegrationTests/appsettings.ci.json test/EFCore.MySql.IntegrationTests/appsettings.json
211+
Copy-Item test/EFCore.MySql.IntegrationTests/config.json.example test/EFCore.MySql.IntegrationTests/config.json
212+
- name: Setup Integration Tests
213+
shell: pwsh
214+
run: |
215+
./test/EFCore.MySql.IntegrationTests/scripts/rebuild.ps1
216+
- name: Build Solution
217+
shell: pwsh
218+
run: |
219+
dotnet build -c Debug
220+
dotnet build -c Release
221+
- name: Functional Tests
222+
if: ${{ env.skipTests != 'true' }}
223+
shell: pwsh
224+
run: dotnet test test/EFCore.MySql.FunctionalTests -c Debug --no-build --logger "GitHubActions;report-warnings=false" --verbosity detailed
225+
- name: Tests
226+
if: ${{ env.skipTests != 'true' }}
227+
shell: pwsh
228+
run: dotnet test --logger "GitHubActions;report-warnings=false" test/EFCore.MySql.Tests
229+
- name: Integration Tests - Applying migrations
230+
if: ${{ env.skipTests != 'true' }}
231+
shell: pwsh
232+
run: dotnet run --project test/EFCore.MySql.IntegrationTests -c Release testMigrate
233+
- name: Integration Tests - Scaffolding
234+
if: ${{ env.skipTests != 'true' }}
235+
shell: pwsh
236+
run: ./test/EFCore.MySql.IntegrationTests/scripts/scaffold.ps1
237+
- name: Integration Tests - With EF_BATCH_SIZE = 1
238+
if: ${{ env.skipTests != 'true' }}
239+
shell: pwsh
240+
run: |
241+
$env:EF_BATCH_SIZE = "1"
242+
dotnet test -c Release --no-build --logger "GitHubActions;report-warnings=false" test/EFCore.MySql.IntegrationTests
243+
- name: Integration Tests - With EF_BATCH_SIZE = 10
244+
if: ${{ env.skipTests != 'true' }}
245+
shell: pwsh
246+
run: |
247+
$env:EF_BATCH_SIZE = "10"
248+
dotnet test -c Release --no-build --logger "GitHubActions;report-warnings=false" test/EFCore.MySql.IntegrationTests
249+
- name: Integration Tests - With EF_BATCH_SIZE = 1
250+
if: ${{ env.skipTests != 'true' }}
251+
shell: pwsh
252+
run: |
253+
$env:EF_RETRY_ON_FAILURE = "3"
254+
dotnet test -c Release --no-build --logger "GitHubActions;report-warnings=false" test/EFCore.MySql.IntegrationTests
255+
- name: Integration Tests - Legacy migrations
256+
if: ${{ env.skipTests != 'true' }}
257+
shell: pwsh
258+
run: ./test/EFCore.MySql.IntegrationTests/scripts/legacy.ps1
259+
- name: Integration Tests - Building migrations with EF_DATABASE = pomelo_test2
260+
if: ${{ env.skipTests != 'true' }}
261+
shell: pwsh
262+
run: |
263+
$env:EF_DATABASE = "pomelo_test2"
264+
dotnet build ./test/EFCore.MySql.IntegrationTests -c Release
265+
- name: Integration Tests - Setup migrations with EF_DATABASE = pomelo_test2
266+
if: ${{ env.skipTests != 'true' }}
267+
shell: pwsh
268+
run: |
269+
$env:EF_DATABASE = "pomelo_test2"
270+
./test/EFCore.MySql.IntegrationTests/scripts/rebuild.ps1
271+
- name: Integration Tests - With EF_DATABASE = pomelo_test2
272+
if: ${{ env.skipTests != 'true' }}
273+
shell: pwsh
274+
run: |
275+
$env:EF_DATABASE = "pomelo_test2"
276+
dotnet test -c Release --no-build --logger "GitHubActions;report-warnings=false" test/EFCore.MySql.IntegrationTests
277+
NuGet:
278+
needs: BuildAndTest
279+
if: github.repository == 'Microting/Pomelo.EntityFrameworkCore.MySql'
280+
runs-on: ubuntu-latest
281+
steps:
282+
- name: Checkout
283+
uses: actions/checkout@v4
284+
- name: Setup .NET SDK
285+
uses: actions/setup-dotnet@v4
286+
with:
287+
global-json-file: global.json
288+
- name: .NET Information
289+
shell: pwsh
290+
run: |
291+
dotnet --info
292+
- name: Get the version
293+
id: get_version
294+
run: echo "VERSION=$(echo $GITHUB_REF | cut -d / -f 3 | cut -d 'v' -f 2)" >> $GITHUB_OUTPUT
295+
- name: NuGet Pack
296+
shell: pwsh
297+
run: |
298+
$officialVersion = '${{ steps.get_version.outputs.VERSION }}'
299+
$continuousIntegrationTimestamp = Get-Date -Format yyyyMMddHHmmss
300+
$buildSha = '${{ github.sha }}'.SubString(0, 7);
301+
302+
echo "officialVersion: $officialVersion"
303+
echo "continuousIntegrationTimestamp: $continuousIntegrationTimestamp"
304+
echo "buildSha: $buildSha"
305+
306+
$projectFiles = Get-ChildItem src/*/*.csproj -Recurse | % { $_.FullName }
307+
308+
$combinations = @('default', @('Release')), @('withPdbs', @('Release')) #, @('embeddedPdbs', @('Release'))
309+
foreach ($combination in $combinations)
310+
{
311+
$type = $combination[0]
312+
$configurations = $combination[1]
313+
foreach ($configuration in $configurations)
314+
{
315+
$arguments = 'pack', '-c', $configuration, '-o', "nupkgs/$configuration/$type", '-p:ContinuousIntegrationBuild=true', '-p:OutputVersionProperties=true'
316+
317+
$finalOfficialVersion = $configuration -eq 'Debug' `
318+
? $officialVersion.Contains('-') `
319+
? $officialVersion + '.debug' `
320+
: $officialVersion + '-debug' `
321+
: $officialVersion
322+
323+
$arguments += "-p:OfficialVersion=$officialVersion"
324+
325+
switch ($type)
326+
{
327+
'withPdbs' { $arguments += '-p:PackPdb=true', '-p:IncludeSymbols=false' }
328+
'embeddedPdbs' { $arguments += '-p:DebugType=embedded', '-p:IncludeSymbols=false' }
329+
}
330+
331+
foreach ($projectFile in $projectFiles)
332+
{
333+
echo "Type: $type, Configuration: $configuration, Project: $projectFile"
334+
echo "Pack command: dotnet $(($arguments + $projectFile) -join ' ')"
335+
& dotnet ($arguments + $projectFile)
336+
}
337+
}
338+
}
339+
- name: Upload Artifacts
340+
uses: actions/upload-artifact@v4
341+
with:
342+
name: nupkgs
343+
path: nupkgs
344+
- name: "NuGet Push - nuget.org - Release"
345+
working-directory: nupkgs
346+
shell: pwsh
347+
run: dotnet nuget push './Release/default/**/*.nupkg' -k '${{ secrets.NUGET_SECRET_KEY }}' -s 'https://api.nuget.org/v3/index.json'

Directory.Build.props

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
<Import Project="Development.props" Condition="Exists('Development.props')" />
44

55
<PropertyGroup>
6+
<RootNamespace>Pomelo</RootNamespace>
7+
<AssemblyName>Pomelo</AssemblyName>
8+
<Product>Pomelo</Product>
69
<StrongNameKeyId>Pomelo.EntityFrameworkCore.MySql</StrongNameKeyId>
710
<PackageTags>pomelo;mysql;mariadb;Entity Framework Core;entity-framework-core;ef;efcore;ef core;orm;sql</PackageTags>
811
<Product>Pomelo.EntityFrameworkCore.MySql</Product>
@@ -16,22 +19,22 @@
1619
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
1720
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
1821
<PackageLicenseExpression>MIT</PackageLicenseExpression>
19-
<PackageProjectUrl>https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql</PackageProjectUrl>
22+
<PackageProjectUrl>https://github.com/microting/Pomelo.EntityFrameworkCore.MySql</PackageProjectUrl>
2023
<RepositoryType>git</RepositoryType>
21-
<RepositoryUrl>https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql</RepositoryUrl>
24+
<RepositoryUrl>https://github.com/microting/Pomelo.EntityFrameworkCore.MySql</RepositoryUrl>
2225
</PropertyGroup>
2326

2427
<PropertyGroup>
2528
<DebugType Condition="'$(DebugType)' == ''">portable</DebugType>
2629
</PropertyGroup>
2730

2831
<PropertyGroup>
29-
<PomeloTargetFramework>net8.0</PomeloTargetFramework>
32+
<PomeloTargetFramework>net9.0</PomeloTargetFramework>
3033
<PomeloTestTargetFramework>net9.0</PomeloTestTargetFramework>
31-
<EfCoreTargetFramework>net8.0</EfCoreTargetFramework>
34+
<EfCoreTargetFramework>net9.0</EfCoreTargetFramework>
3235
<EfCoreTestTargetFramework>net9.0</EfCoreTestTargetFramework>
33-
<MySqlConnectorTargetFramework>net8.0</MySqlConnectorTargetFramework>
34-
<MySqlConnectorDependencyInjectionTargetFramework>net8.0</MySqlConnectorDependencyInjectionTargetFramework>
36+
<MySqlConnectorTargetFramework>net9.0</MySqlConnectorTargetFramework>
37+
<MySqlConnectorDependencyInjectionTargetFramework>net9.0</MySqlConnectorDependencyInjectionTargetFramework>
3538
</PropertyGroup>
3639

3740
<PropertyGroup>

0 commit comments

Comments
 (0)