Skip to content

Commit 00b5547

Browse files
committed
refactoring
1 parent 00110e7 commit 00b5547

3 files changed

Lines changed: 158 additions & 124 deletions

File tree

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: 'Set up SQL Server on Linux'
2+
description: 'Starts a SQL Server 2022 Docker container with SA auth and exports BASE_CS.'
3+
4+
inputs:
5+
sa-password:
6+
description: 'SA password to use for the SQL Server instance.'
7+
required: true
8+
image:
9+
description: 'SQL Server Docker image to use.'
10+
required: false
11+
default: 'mcr.microsoft.com/mssql/server:2022-latest'
12+
13+
runs:
14+
using: composite
15+
steps:
16+
- name: Start SQL Server container
17+
shell: bash
18+
env:
19+
SA_PASSWORD: ${{ inputs.sa-password }}
20+
MSSQL_IMAGE: ${{ inputs.image }}
21+
run: |
22+
docker run -d --name sqlserver \
23+
-e "ACCEPT_EULA=Y" \
24+
-e "MSSQL_SA_PASSWORD=${SA_PASSWORD}" \
25+
-p 1433:1433 \
26+
"$MSSQL_IMAGE"
27+
28+
- name: Wait for SQL Server to be ready
29+
shell: bash
30+
env:
31+
SA_PASSWORD: ${{ inputs.sa-password }}
32+
run: |
33+
for i in $(seq 1 30); do
34+
if docker exec sqlserver /opt/mssql-tools18/bin/sqlcmd \
35+
-S localhost -U sa -P "${SA_PASSWORD}" -C -Q 'SELECT 1' >/dev/null 2>&1; then
36+
echo "SQL Server is ready"
37+
exit 0
38+
fi
39+
echo "Waiting for SQL Server... ($i/30)"
40+
sleep 5
41+
done
42+
echo "SQL Server did not become ready in time"
43+
docker logs sqlserver
44+
exit 1
45+
46+
- name: Set connection string
47+
shell: bash
48+
env:
49+
SA_PASSWORD: ${{ inputs.sa-password }}
50+
run: |
51+
echo "BASE_CS=Server=localhost;User ID=sa;Password=${SA_PASSWORD};TrustServerCertificate=True;" >> "$GITHUB_ENV"
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: 'Set up SQL Server on Windows'
2+
description: 'Installs SQL Server 2025 Express with SA auth and exports BASE_CS.'
3+
4+
inputs:
5+
sa-password:
6+
description: 'SA password to use for the SQL Server instance.'
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Download SQL Server 2025 Express installer
13+
shell: pwsh
14+
run: |
15+
$ssei = Join-Path $env:RUNNER_TEMP 'SQL2025-SSEI-Expr.exe'
16+
$media = Join-Path $env:RUNNER_TEMP 'sql-media'
17+
# Stable Microsoft fwlink redirecting to the SQL Server 2025 Express bootstrapper (SSEI)
18+
Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/?linkid=2216019' -OutFile $ssei
19+
Write-Host "Downloaded SSEI: $((Get-Item $ssei).Length) bytes"
20+
21+
# Run SSEI in download-only mode. Use Start-Process -Wait so we get a real exit code
22+
# (PowerShell's `&` returns asynchronously for installer-class executables).
23+
$p = Start-Process -FilePath $ssei -Wait -PassThru -ArgumentList @(
24+
'/Quiet',
25+
'/Action=Download',
26+
'/Language=en-US',
27+
"/MediaPath=$media",
28+
'/MediaType=Core',
29+
'/HideProgressBar'
30+
)
31+
if ($p.ExitCode -ne 0) { throw "SSEI download failed with exit code $($p.ExitCode)" }
32+
33+
Write-Host "=== Media directory contents ==="
34+
Get-ChildItem $media
35+
36+
- name: Install SQL Server Express with SA auth
37+
shell: pwsh
38+
env:
39+
SA_PASSWORD: ${{ inputs.sa-password }}
40+
run: |
41+
$media = Join-Path $env:RUNNER_TEMP 'sql-media'
42+
$selfExtract = Get-ChildItem $media -Filter 'SQLEXPR*.exe' | Select-Object -First 1
43+
if (-not $selfExtract) { throw "Installer EXE not found in $media" }
44+
45+
$extracted = Join-Path $env:RUNNER_TEMP 'sql-extracted'
46+
Write-Host "Extracting $($selfExtract.FullName) -> $extracted"
47+
$extract = Start-Process -FilePath $selfExtract.FullName -Wait -PassThru `
48+
-ArgumentList '/Q', "/X:$extracted"
49+
if ($extract.ExitCode -ne 0) { throw "Extraction failed with exit code $($extract.ExitCode)" }
50+
51+
$setup = Join-Path $extracted 'setup.exe'
52+
if (-not (Test-Path $setup)) { throw "setup.exe not found at $setup" }
53+
54+
Write-Host "Running $setup with SECURITYMODE=SQL"
55+
$install = Start-Process -FilePath $setup -Wait -PassThru -ArgumentList @(
56+
'/Q',
57+
'/ACTION=Install',
58+
'/FEATURES=SQLEngine',
59+
'/INSTANCENAME=MSSQLSERVER',
60+
'/SECURITYMODE=SQL',
61+
"/SAPWD=$env:SA_PASSWORD",
62+
'/TCPENABLED=1',
63+
'/IACCEPTSQLSERVERLICENSETERMS',
64+
'/UPDATEENABLED=False',
65+
'/SQLSYSADMINACCOUNTS=BUILTIN\Administrators'
66+
)
67+
68+
if ($install.ExitCode -ne 0) {
69+
Write-Host "Setup failed with exit code $($install.ExitCode)"
70+
$logRoot = 'C:\Program Files\Microsoft SQL Server'
71+
if (Test-Path $logRoot) {
72+
Get-ChildItem $logRoot -Recurse -Filter 'Summary*.txt' -ErrorAction SilentlyContinue |
73+
Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
74+
ForEach-Object { Write-Host "=== $($_.FullName) ==="; Get-Content $_.FullName }
75+
}
76+
throw "SQL Server install failed"
77+
}
78+
Get-Service | Where-Object { $_.Name -like 'MSSQL*' } | Format-Table
79+
80+
- name: Verify SQL auth
81+
shell: pwsh
82+
env:
83+
SA_PASSWORD: ${{ inputs.sa-password }}
84+
run: |
85+
$sqlcmd = (Get-ChildItem 'C:\Program Files\Microsoft SQL Server' -Recurse -Filter sqlcmd.exe -ErrorAction SilentlyContinue |
86+
Select-Object -First 1).FullName
87+
if (-not $sqlcmd) { throw "sqlcmd.exe not found after install" }
88+
& $sqlcmd -S 'localhost' -U sa -P $env:SA_PASSWORD -b -Q "SELECT @@VERSION"
89+
if ($LASTEXITCODE -ne 0) { throw "SQL auth verification failed" }
90+
91+
- name: Set connection string
92+
shell: bash
93+
env:
94+
SA_PASSWORD: ${{ inputs.sa-password }}
95+
run: |
96+
echo "BASE_CS=Server=localhost;User ID=sa;Password=${SA_PASSWORD};TrustServerCertificate=True;" >> "$GITHUB_ENV"

.github/workflows/pr-check.yml

Lines changed: 11 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ name: pr-check
55
# with no secrets and no elevated permissions.
66
#
77
# - Linux runners: spin up SQL Server 2022 in a Docker container with SA auth.
8-
# - Windows runners: use the pre-installed SQL Server Express with Integrated Security.
8+
# - Windows runners: install SQL Server 2025 Express directly from Microsoft with SA auth.
99

1010
on:
1111
pull_request:
@@ -25,7 +25,6 @@ jobs:
2525

2626
env:
2727
TEST_DB: SqlActionTest
28-
MSSQL_IMAGE: mcr.microsoft.com/mssql/server:2022-latest
2928

3029
defaults:
3130
run:
@@ -37,135 +36,23 @@ jobs:
3736
with:
3837
ref: ${{ github.event.pull_request.head.sha }}
3938

40-
# --- Linux setup: Docker container + SA auth with rotated password ---
41-
42-
- name: Start SQL Server container (Linux)
43-
if: runner.os == 'Linux'
44-
run: |
45-
docker run -d --name sqlserver \
46-
-e "ACCEPT_EULA=Y" \
47-
-e "MSSQL_SA_PASSWORD=Bootstrap1!" \
48-
-p 1433:1433 \
49-
"$MSSQL_IMAGE"
50-
51-
- name: Wait for SQL Server to be ready (Linux)
52-
if: runner.os == 'Linux'
53-
run: |
54-
for i in $(seq 1 30); do
55-
if docker exec sqlserver /opt/mssql-tools18/bin/sqlcmd \
56-
-S localhost -U sa -P 'Bootstrap1!' -C -Q 'SELECT 1' >/dev/null 2>&1; then
57-
echo "SQL Server is ready"
58-
exit 0
59-
fi
60-
echo "Waiting for SQL Server... ($i/30)"
61-
sleep 5
62-
done
63-
echo "SQL Server did not become ready in time"
64-
docker logs sqlserver
65-
exit 1
66-
67-
- name: Rotate SA password and set connection string (Linux)
68-
if: runner.os == 'Linux'
69-
run: |
70-
SA_PASSWORD="$(openssl rand -base64 18 | tr -d '/+=')Aa1!"
71-
docker exec sqlserver /opt/mssql-tools18/bin/sqlcmd \
72-
-S localhost -U sa -P 'Bootstrap1!' -C \
73-
-Q "ALTER LOGIN sa WITH PASSWORD='${SA_PASSWORD}'"
74-
echo "BASE_CS=Server=localhost;User ID=sa;Password=${SA_PASSWORD};TrustServerCertificate=True;" >> "$GITHUB_ENV"
75-
76-
# --- Windows setup: install SQL Server 2022 Express directly from Microsoft ---
77-
78-
- name: Generate SA password (Windows)
79-
if: runner.os == 'Windows'
39+
- name: Generate SA password
8040
run: |
8141
SA_PASSWORD="$(openssl rand -base64 18 | tr -d '/+=')Aa1!"
8242
echo "::add-mask::${SA_PASSWORD}"
8343
echo "SA_PASSWORD=${SA_PASSWORD}" >> "$GITHUB_ENV"
8444
85-
- name: Download SQL Server 2025 Express installer (Windows)
86-
if: runner.os == 'Windows'
87-
shell: pwsh
88-
run: |
89-
$ssei = Join-Path $env:RUNNER_TEMP 'SQL2025-SSEI-Expr.exe'
90-
$media = Join-Path $env:RUNNER_TEMP 'sql-media'
91-
# Stable Microsoft fwlink redirecting to the SQL Server 2025 Express bootstrapper (SSEI)
92-
Invoke-WebRequest -Uri 'https://go.microsoft.com/fwlink/?linkid=2216019' -OutFile $ssei
93-
Write-Host "Downloaded SSEI: $((Get-Item $ssei).Length) bytes"
94-
95-
# Run SSEI in download-only mode. Use Start-Process -Wait so we get a real exit code
96-
# (PowerShell's `&` returns asynchronously for installer-class executables).
97-
$p = Start-Process -FilePath $ssei -Wait -PassThru -ArgumentList @(
98-
'/Quiet',
99-
'/Action=Download',
100-
'/Language=en-US',
101-
"/MediaPath=$media",
102-
'/MediaType=Core',
103-
'/HideProgressBar'
104-
)
105-
if ($p.ExitCode -ne 0) { throw "SSEI download failed with exit code $($p.ExitCode)" }
106-
107-
Write-Host "=== Media directory contents ==="
108-
Get-ChildItem $media
109-
110-
- name: Install SQL Server Express with SA auth (Windows)
111-
if: runner.os == 'Windows'
112-
shell: pwsh
113-
run: |
114-
$media = Join-Path $env:RUNNER_TEMP 'sql-media'
115-
$selfExtract = Get-ChildItem $media -Filter 'SQLEXPR*.exe' | Select-Object -First 1
116-
if (-not $selfExtract) { throw "Installer EXE not found in $media" }
117-
118-
$extracted = Join-Path $env:RUNNER_TEMP 'sql-extracted'
119-
Write-Host "Extracting $($selfExtract.FullName) -> $extracted"
120-
$extract = Start-Process -FilePath $selfExtract.FullName -Wait -PassThru `
121-
-ArgumentList '/Q', "/X:$extracted"
122-
if ($extract.ExitCode -ne 0) { throw "Extraction failed with exit code $($extract.ExitCode)" }
123-
124-
$setup = Join-Path $extracted 'setup.exe'
125-
if (-not (Test-Path $setup)) { throw "setup.exe not found at $setup" }
126-
127-
Write-Host "Running $setup with SECURITYMODE=SQL"
128-
$install = Start-Process -FilePath $setup -Wait -PassThru -ArgumentList @(
129-
'/Q',
130-
'/ACTION=Install',
131-
'/FEATURES=SQLEngine',
132-
'/INSTANCENAME=MSSQLSERVER',
133-
'/SECURITYMODE=SQL',
134-
"/SAPWD=$env:SA_PASSWORD",
135-
'/TCPENABLED=1',
136-
'/IACCEPTSQLSERVERLICENSETERMS',
137-
'/UPDATEENABLED=False',
138-
'/SQLSYSADMINACCOUNTS=BUILTIN\Administrators'
139-
)
140-
141-
if ($install.ExitCode -ne 0) {
142-
Write-Host "Setup failed with exit code $($install.ExitCode)"
143-
$logRoot = 'C:\Program Files\Microsoft SQL Server'
144-
if (Test-Path $logRoot) {
145-
Get-ChildItem $logRoot -Recurse -Filter 'Summary*.txt' -ErrorAction SilentlyContinue |
146-
Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
147-
ForEach-Object { Write-Host "=== $($_.FullName) ==="; Get-Content $_.FullName }
148-
}
149-
throw "SQL Server install failed"
150-
}
151-
Get-Service | Where-Object { $_.Name -like 'MSSQL*' } | Format-Table
152-
153-
- name: Verify SQL auth (Windows)
154-
if: runner.os == 'Windows'
155-
shell: pwsh
156-
run: |
157-
$sqlcmd = (Get-ChildItem 'C:\Program Files\Microsoft SQL Server' -Recurse -Filter sqlcmd.exe -ErrorAction SilentlyContinue |
158-
Select-Object -First 1).FullName
159-
if (-not $sqlcmd) { throw "sqlcmd.exe not found after install" }
160-
& $sqlcmd -S 'localhost' -U sa -P $env:SA_PASSWORD -b -Q "SELECT @@VERSION"
161-
if ($LASTEXITCODE -ne 0) { throw "SQL auth verification failed" }
45+
- name: Set up SQL Server (Linux)
46+
if: runner.os == 'Linux'
47+
uses: ./.github/actions/setup-sql-linux
48+
with:
49+
sa-password: ${{ env.SA_PASSWORD }}
16250

163-
- name: Set connection string (Windows)
51+
- name: Set up SQL Server (Windows)
16452
if: runner.os == 'Windows'
165-
run: |
166-
echo "BASE_CS=Server=localhost;User ID=sa;Password=${SA_PASSWORD};TrustServerCertificate=True;" >> "$GITHUB_ENV"
167-
168-
# --- Common build and test steps ---
53+
uses: ./.github/actions/setup-sql-windows
54+
with:
55+
sa-password: ${{ env.SA_PASSWORD }}
16956

17057
- name: Build GitHub Action
17158
run: npm ci --ignore-scripts && npm run build

0 commit comments

Comments
 (0)