Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
matrix:
os: [windows-latest, ubuntu-latest]
sqlserver:
- label: 'SQL Server 2025'
version: '2025'
- label: 'SQL Server 2022'
version: '2022'
- label: 'SQL Server 2019'
Expand All @@ -42,3 +44,44 @@ jobs:

$result = sqlcmd -Q "SELECT DB_NAME() as CatalogName" -d "my-test-catalog"
echo $result
ci-full-text-search:
runs-on: ${{ matrix.os }}
name: ${{ matrix.name }}-${{ matrix.sqlserver.label }}-FTS
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest]
sqlserver:
- label: 'SQL Server 2025'
version: '2025'
- label: 'SQL Server 2022'
version: '2022'
- label: 'SQL Server 2019'
version: '2019'
include:
- os: windows-latest
name: Windows
- os: ubuntu-latest
name: Linux
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Run with FTS
uses: ./
with:
connection-string-env-var: SQL_CONN_STR
catalog: my-test-catalog
sqlserver-version: ${{ matrix.sqlserver.version }}
enable-full-text-search: "true"
- name: Check FTS result
shell: pwsh
run: |
$connstr = $Env:SQL_CONN_STR
Write-Host "Connection String: $connstr"

sqlcmd -b -Q "IF FULLTEXTSERVICEPROPERTY('IsFullTextInstalled') <> 1 THROW 50001, 'Full-Text Search is not installed.', 1;"
sqlcmd -b -Q "USE [my-test-catalog];
CREATE TABLE dbo.FullTextSmoke (Id INT NOT NULL, Content NVARCHAR(200) NOT NULL);
CREATE UNIQUE INDEX UX_FullTextSmoke_Id ON dbo.FullTextSmoke(Id);
CREATE FULLTEXT CATALOG SmokeCatalog AS DEFAULT;
CREATE FULLTEXT INDEX ON dbo.FullTextSmoke(Content LANGUAGE 1033) KEY INDEX UX_FullTextSmoke_Id;"
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@ steps:
extra-params: "Max Pool Size=100;"
```

To enable SQL Server Full-Text Search:

```yaml
steps:
- name: Install SQL Server
uses: Particular/install-sql-server-action@v1.4.0 # Check if this is the latest version at https://github.com/Particular/install-sql-server-action/tags
with:
connection-string-env-var: SQL_SERVER_CONNECTION_STRING
catalog: nservicebus
enable-full-text-search: "true"
```

## Parameters

| Parameter | Required | Default | Description |
Expand All @@ -56,6 +68,12 @@ steps:
| `collation` | No | `SQL_Latin1_General_CP1_CS_AS` | The collation to use for the SQL Server database. Override to any available [SQL collation](https://learn.microsoft.com/en-us/sql/relational-databases/collations/collation-and-unicode-support). |
| `sqlserver-version` | No | `2022` | The SQL server major version to use. |
| `extra-params` | No | - | Extra parameters to be appended to the end of the connection string. |
| `enable-full-text-search` | No | `"false"` | When set to `"true"`, the action installs/enables and verifies SQL Server Full-Text Search before completion. |

When `enable-full-text-search` is enabled, setup time may increase because extra SQL components/packages are installed.
On Windows, this switches installation to Chocolatey's `sql-server-express-adv` package so Full-Text Search is available.
On Linux, the action adds the matching Microsoft SQL Server apt feed and installs `mssql-server-fts` for the requested SQL Server major version.
Current Full-Text Search setup support includes SQL Server major versions `2019`, `2022`, and `2025`.

## Using `sqlcmd`

Expand Down
118 changes: 94 additions & 24 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ inputs:
extra-params:
description: Extra parameters to add to the connection string
required: false
enable-full-text-search:
description: Enable SQL Server Full-Text Search installation
required: false
default: "false"
runs:
using: "composite"
steps:
Expand All @@ -27,26 +31,27 @@ runs:
shell: pwsh
run: |
# Windows SQL install via Chocolatey
$template = @'
{[string]Package*:sql-server-express}|{[int]Major:2022}.{[int]Minor:16}.{[int]Patch:0}.{[int]Build:1000}
{[string]Package*:sql-server-express}|{[int]Major:2022}.{[int]Minor:16}.{[int]Patch:0}.{[int]Build:0}
{[string]Package*:sql-server-express}|{[int]Major:14}.{[int]Minor:1801}.{[int]Patch:3958}.{[int]Build:1}
'@

# Limited output should be sql-server-express|versionstring
$availableVersions = choco search sql-server-express --exact --all-versions --limit-output | Where-Object { $_ -like "*${{ inputs.sqlserver-version }}**" }
# IncludeExtent will feed the input into an ExtendText property. Using the template examples helps to order by Major which is all we are interested in
$sortedVersions = $availableVersions | ConvertFrom-String -TemplateContent $template -IncludeExtent | Sort-Object -Property Major -Descending
$newestVersion = $sortedVersions[0].ExtentText.Split("|")[1]
$enableFts = '${{ inputs.enable-full-text-search }}' -eq 'true'
$packageName = if ($enableFts) { 'sql-server-express-adv' } else { 'sql-server-express' }

# Limited output is package|version
$newestVersion = choco search $packageName --exact --all-versions --limit-output `
| ForEach-Object { ($_ -split '\|')[1] } `
| Where-Object { $_ -like "${{ inputs.sqlserver-version }}*" } `
| Sort-Object { [version](($_ -split '-')[0]) } -Descending `
| Select-Object -First 1

$installArgs = @('install', $packageName, '-y', '--no-progress')

if ($newestVersion) {
Write-Output "Installing SQL Server Express version $newestVersion with Chocolatey..."
choco install sql-server-express --version $newestVersion -y --no-progress
$installArgs += @('--version', $newestVersion)
Write-Output "Installing $packageName version $newestVersion with Chocolatey..."
} else {
Write-Output "No versions found matching the prefix '${{ inputs.sqlserver-version }}'. Installing latest with Chocolatey..."
choco install sql-server-express --no-progress
Write-Output "No versions found matching the prefix '${{ inputs.sqlserver-version }}'. Installing latest $packageName with Chocolatey..."
}

choco @installArgs

Write-Output "Setting environment variables for sqlcmd..."
Write-Output "SQLCMDSERVER=.\SQLEXPRESS" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf-8 -Append

Expand All @@ -62,15 +67,71 @@ runs:
sa_pw=$(uuidgen)
echo "::add-mask::$sa_pw"

echo "Starting SQL Server in a Docker container..."
docker run -e "ACCEPT_EULA=Y" \
-e "SA_PASSWORD=$sa_pw" \
-e "MSSQL_PID=Developer" \
-e "MSSQL_COLLATION=${{ inputs.collation }}" \
-e "SQLCMDSERVER=localhost" \
-e "SQLCMDUSER=sa" \
-e "SQLCMDPASSWORD=$sa_pw" \
-p 1433:1433 --name sqlserver -d mcr.microsoft.com/mssql/server:${{ inputs.sqlserver-version }}-latest
image="mcr.microsoft.com/mssql/server:${{ inputs.sqlserver-version }}-latest"
base_run_args=(
-e "ACCEPT_EULA=Y"
-e "SA_PASSWORD=$sa_pw"
-e "MSSQL_PID=Developer"
-e "MSSQL_COLLATION=${{ inputs.collation }}"
-e "SQLCMDSERVER=localhost"
-e "SQLCMDUSER=sa"
-e "SQLCMDPASSWORD=$sa_pw"
-p 1433:1433
--name sqlserver
-d
)

if [ "${{ inputs.enable-full-text-search }}" = "true" ]; then
echo "Starting SQL Server container in setup mode for Full-Text Search installation..."
docker run "${base_run_args[@]}" --entrypoint /bin/bash "$image" -lc "sleep infinity"
else
echo "Starting SQL Server in a Docker container..."
docker run "${base_run_args[@]}" "$image"
fi

if [ "${{ inputs.enable-full-text-search }}" = "true" ]; then
case "${{ inputs.sqlserver-version }}" in
2025*) sql_engine_major=17; repo_channel=2025 ;;
2022*) sql_engine_major=16; repo_channel=2022 ;;
2019*) sql_engine_major=15; repo_channel=2019 ;;
*)
echo "Unsupported sqlserver-version for FTS: '${{ inputs.sqlserver-version }}'. Supported values: 2019, 2022, 2025." >&2
exit 1
;;
esac

echo "Installing Full-Text Search support in the SQL Server container..."
docker exec -u 0 sqlserver bash -lc "
set -euo pipefail
apt-get update
ACCEPT_EULA=Y apt-get install -y --no-install-recommends curl gnupg

. /etc/os-release
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
| gpg --dearmor > /usr/share/keyrings/microsoft-prod.gpg
echo \"deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/\${VERSION_ID}/mssql-server-${repo_channel} \${VERSION_CODENAME} main\" \
> /etc/apt/sources.list.d/mssql-server.list

apt-get update

fts_version=\$(apt-cache madison mssql-server-fts \
| awk '{print \$3}' \
| grep -E '^${sql_engine_major}\.' \
| head -n 1)

if [ -z \"\${fts_version}\" ]; then
echo \"No mssql-server-fts package found for SQL Server engine major ${sql_engine_major}.\" >&2
exit 1
fi

ACCEPT_EULA=Y apt-get install -y --no-install-recommends \"mssql-server-fts=\${fts_version}\"
apt-get clean
rm -rf /var/lib/apt/lists/*
"

echo "Starting SQL Server process..."
docker exec -d sqlserver /opt/mssql/bin/sqlservr
fi

echo "Creating `sqlcmd` bash script to forward commands via docker exec"
mkdir -p ~/bin
Expand All @@ -91,6 +152,7 @@ runs:
shell: pwsh
run: |
# Wait for availability then create initial catalog
$enableFts = '${{ inputs.enable-full-text-search }}' -eq 'true'

for ($i = 1; $i -le 30; $i++) {
Write-Output "Attempt $i/30 to connect to SQL Server..."
Expand All @@ -104,5 +166,13 @@ runs:
}
}

if ($enableFts) {
Write-Output "Verifying Full-Text Search availability..."
$ftsInstalled = (sqlcmd -h -1 -W -Q "SET NOCOUNT ON; SELECT FULLTEXTSERVICEPROPERTY('IsFullTextInstalled');").Trim()
if ($LASTEXITCODE -ne 0 -or $ftsInstalled -ne '1') {
throw "Full-Text Search was requested but is not available."
}
}

Write-Output "Creating initial catalog '${{ inputs.catalog }}'"
sqlcmd -Q "CREATE DATABASE [${{ inputs.catalog }}]"