Skip to content

Repository files navigation

install-sql-server

This action installs and runs SQL Server for a GitHub Actions workflow. Also adds support for sqlcmd.

  1. Runs SQL Server in a Linux Docker container on every platform.
  • On Linux, the container runs directly via Docker using the mcr.microsoft.com/mssql/server:2022-latest image.
  • On Windows, the Linux container runs inside WSL2 provisioned by setup-wsl-action — run it first, see Prerequisites.
  • Sets collation to case sensitive SQL_Latin1_General_CP1_CS_AS note SQL Azure is insensitive CI_AS
  1. Creates environment variables for a connection string and for sqlcmd.
  2. Waits for the SQL instance to be accessible.
  3. Creates a default database catalog.
  4. Tears the container down in a post step (see Cleanup).

Prerequisites

This action does not provision WSL or Docker itself. On Windows runners it requires setup-wsl-action to run first in the same job — that action provisions WSL2 + Docker, keeps the instance alive, and exports the WSL_DISTRIBUTION, WSL_IP, and WSL_TOOLS_MODULE_PATH environment variables this action relies on. On Linux runners setup-wsl-action is a no-op but should still be included so the workflow is uniform.

If setup-wsl-action has not run, the action fails fast with a clear error.

Usage

Install SQL Server 2022 with a default database of nservicebus and put the connection string in the environment variable SQL_SERVER_CONNECTION_STRING:

steps:
  - name: Setup WSL
    uses: Particular/setup-wsl-action@v1
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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

Every example below assumes a Setup WSL step runs first (as shown in the first example); it is omitted for brevity.

It is also possible to specify the SQl server major version to be installed

steps:
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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
      sqlserver-version: 2019
      catalog: nservicebus

To add additional parameters to the end of the connection string, such as Max Pool Size. The connection string generated by the action already ends with a semicolon, and the extra-params are appended at the end.

steps:
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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
      extra-params: "Max Pool Size=100;"

To enable SQL Server Full-Text Search:

steps:
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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"

To enable distributed transactions (MSDTC) in the container:

steps:
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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-distributed-transactions: "true"

Parameters

Parameter Required Default Description
connection-string-env-var Yes - Environment variable name that will be filled with the SQL connection string, which can then be used in successive steps.
catalog No nservicebus The default catalog, which will be created by the action.
collation No SQL_Latin1_General_CP1_CS_AS The collation to use for the SQL Server database. Override to any available SQL collation.
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.
enable-distributed-transactions No "false" When set to "true", configures the container for the Microsoft Distributed Transaction Coordinator (MSDTC) so SQL Server can participate in distributed transactions.

When enable-full-text-search is enabled, setup time may increase because extra SQL components/packages are installed. On both Linux and Windows the SQL Server container is the same Linux image, so Full-Text Search is added by installing the matching mssql-server-fts apt package for the requested SQL Server major version. Current Full-Text Search setup support includes SQL Server major versions 2019, 2022, and 2025.

When enable-distributed-transactions is enabled, the action sets the MSSQL_RPC_PORT and MSSQL_DTC_TCP_PORT environment variables and publishes the corresponding ports (135 and 51000) on the container, following the SQL Server Linux container distributed transactions guidance. SQL Server 2019 and later containers run as a non-root user and cannot bind to the privileged RPC port 135, so the RPC endpoint mapper listens on 13500 and the action maps host port 135 to it. On Windows the ports are published inside the WSL2 VM and are reachable from the host via the WSL IP (the same address used in the connection string).

Because the previous Windows path ran a native SQL Server Express instance on the same host, distributed transactions were coordinated by the local DTC and worked without any configuration. Running SQL Server in a WSL2 container turns those into network transactions, so on Windows the action additionally configures the host's Local DTC when this input is set: it enables Network DTC Access (inbound and outbound), sets the authentication level to No Authentication Required (the Linux container's MSDTC does not authenticate RPC), allows the Distributed Transaction Coordinator through Windows Firewall, sets the container's hostname to sqlserver, and adds a Windows hosts file entry mapping that name to the WSL2 IP. The hostname mapping is necessary because the container's DTC advertises its hostname in its transaction "whereabouts" — without a resolvable name the host DTC cannot push the transaction (see mssql-docker#492). This restores the previous "it just works" behavior for consumers' distributed-transaction tests.

Note

.NET 7+ opt-in: Since .NET 7, TransactionManager.ImplicitDistributedTransactions defaults to false, meaning TransactionScope escalation to MSDTC throws NotSupportedException unless the application explicitly sets TransactionManager.ImplicitDistributedTransactions = true at startup. This is a per-process setting the action cannot set for consumers. If your tests use distributed transactions, add this one line to your test setup:

TransactionManager.ImplicitDistributedTransactions = true;

Cleanup

The action runs a JavaScript-based entry point (dist/index.mjs) for both main and post. The post step invokes cleanup.ps1, which removes the SQL Server container (sqlserver) it started in the main step. On Windows it also restores the DTC/RPC firewall rule profiles to Domain,Private if they were widened for the duration of the job. The container name is persisted via the action state so the post step can target the right container, and external tooling (CI verification scripts, docker exec sqlserver …) can address it without resolving state.

On hosted runners this cleanup is harmless — the runner VM is destroyed at the end of the job — but it keeps long-lived self-hosted runners from accumulating orphaned containers.

Connection string

The generated connection string uses SQL authentication (User Id=sa;Password=...;Encrypt=false;):

  • On Linux the data source is localhost (Server=localhost;...).
  • On Windows the data source is the WSL2 VM IP address (Server=<wsl-ip>;...) so that the host can reach the container. The address comes from the WSL_IP environment variable set by setup-wsl-action.

Using sqlcmd

The action also makes it possible to run sqlcmd. How it does this is different based on platform:

  • Windows: The runner's native sqlcmd (installed via the SQL Server Command Line Utilities) is wrapped in a small sqlcmd.cmd shim that injects -C so the container's self-signed certificate is trusted. The action sets the SQLCMDSERVER, SQLCMDUSER, and SQLCMDPASSWORD environment variables (pointing at the WSL container), so sqlcmd can be used without any additional login parameters. For larger scripts, prefer sqlcmd -i <file> over passing multi-line arguments inline.
  • Linux: A bash script named sqlcmd is created and added to the PATH. All commands to it are forwarded to the Docker container via docker exec. The Docker container is initialized with environment variables so that login parameters are not necessary.

For example:

steps:
  - name: Install SQL Server
    uses: Particular/install-sql-server-action@v1.5.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
  - name: Create schemas
    shell: pwsh
    run: |
        echo "Create additional schemas"
        sqlcmd -Q "CREATE SCHEMA receiver AUTHORIZATION db_owner" -d "nservicebus"
        sqlcmd -Q "CREATE SCHEMA sender AUTHORIZATION db_owner" -d "nservicebus"
        sqlcmd -Q "CREATE SCHEMA db@ AUTHORIZATION db_owner" -d "nservicebus"

Local development

The action uses @vercel/ncc to bundle index.mjs and its dependencies into a single dist/index.mjs that the runner executes directly. After editing index.mjs, rebuild the bundle with:

npm install
npm run prepare

(npm install triggers the prepare script, which runs ncc build.)

The Full-Text Search installer lives in scripts/install-fts.sh and is docker cp'd into the SQL Server container at runtime, so it stays a real, editable shell script (no base64 dance) and the same file is used on both Linux and Windows.

To test the cleanup action, create a .env.cleanup file in the repository root with:

INPUT_CONNECTION-STRING-ENV-VAR=SQL_SERVER_CONNECTION_STRING
STATE_IsPost=true
STATE_ContainerName=sqlserver
STATE_EnableDistributedTransactions=false

…and then run:

node -r dotenv/config dist/index.mjs dotenv_config_path=.env.cleanup

To run setup.ps1 / cleanup.ps1 directly during local debugging, set the same INPUT_* and STATE_* variables they expect on the command line:

pwsh -File setup.ps1 -ContainerName sqlserver -ConnectionStringName SQL_SERVER_CONNECTION_STRING -Catalog nservicebus
pwsh -File cleanup.ps1 -ContainerName sqlserver

Running setup.ps1/cleanup.ps1 directly on Windows requires WSL_TOOLS_MODULE_PATH to point at setup-wsl-action's WslTools module (set it by running setup-wsl-action first).

About

Runs SQL Server for a GitHub Actions workflow

Resources

Contributing

Stars

11 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages