Skip to content

Commit

Permalink
Introducing sql-action v2 (#122)
Browse files Browse the repository at this point in the history
* v2 - Use tedious mssql module instead of sqlcmd (#96)

* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* PR comments, fix error handling

* Update main.js

* Use try catch for error handling

* Fix typo

* v2 - Change script action from sqlcmd to mssql query (#99)

* Change script action from sqlcmd to mssql query

* Update action.yml

* Fully qualify Table1 in sql script

* Add more debug logging

* Clone config before changing db to master

* Cleanup

* Set TEST_DB name before cleanup

* Use runner.temp

* Always cleanup

* PR comments

* Fix database cleanup step in pr-check (#101)

* Debug script contents

* Fix sed command

* Remove debug

* v2 - Add support for AAD password, AAD default, and AAD service principal auth (#100)

* Use tedious mssql library instead of sqlcmd

* Fix mssql connection

* Fix SqlUtils tests

* Use config instead of connection string

* Replace conn string builder with mssql config

* Connect to master db

* Restore connection string validation regex

* AAD auth

* Add support for client and tenant IDs

* Add more debug messaging

* Fix connection string find array

* Make client-id and tenant-id action inputs

* Fix error handling

* More fixes

* Use try catch instead

* Add tests to pr-check.yml

* Change script action from sqlcmd to mssql query

* Update action.yml

* Fully qualify Table1 in sql script

* Add more debug logging

* Clone config before changing db to master

* Cleanup

* Set TEST_DB name before cleanup

* Use runner.temp

* Always cleanup

* Add tests for different auth types

* Mask tenant and client IDs

* Add AAD password test to pr-check.yml

* Fix yaml

* Limit max-parallel to 2

* Add test for service principal

* PR comments

* Fix typo

* Cleanup sqlcmd references (#102)

* Retry connection with user DB if master connection fails (#104)

* Retry with DB connection if master fails

* Add tests

* Add ConnectionResult interface

* Add missing doc comment

* PR comments

* PR Comments

* Download and extract go-sqlcmd before main action (#108)

* Add setup script to download go-sqlcmd

* Add sqlcmd call to pr-check.yml

* Add bz2 specific extract tar

* Move setup code to main

* Move setup code to main

* Fix casing of Setup.ts

* Use go-sqlcmd for script action (#113)

* call go-sqlcmd for script action

* Fix auth options not flowing through

* Add test cases

* Restore sqlcmd variable in cleanup script

* Fix pr-check cleanup

* Undo changes to pr-check.yml

* Undo pr-check.yml changes

* PR comments

* Change inputs (#105)

* Update SQL API version to 2021-11-01 (#117)

* Add support for Script, DeployReport, and DriftReport (#106)

* Change inputs

* Add other publish like actions

* Add tests

* Fix test

* PR comments

* Add mockReturnValue for auth type test

* Remove MacOS from ci.yml

* links to documentation on each argument type (#123)

* v2 - Remove client-id and tenant-id as inputs (#124)

* Set tenantId and clientId only when passed in

* Default to empty string

* Default to empty string

* Replace mssql call with go-sqlcmd query

* Capture sqlcmd error message

* Add more debug

* Capture stdout too

* Fix config passing

* Completely remove client-id and tenant-id

* cleanup

* Update sqlcmd query

* adding connection string format to docs (#138)

adding connection string format to docs

Co-authored-by: Drew Skwiers-Koballa <dzsquared@users.noreply.github.com>
  • Loading branch information
zijchen and dzsquared authored Sep 28, 2022
1 parent eed4942 commit b62786f
Show file tree
Hide file tree
Showing 26 changed files with 3,695 additions and 724 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, ubuntu-latest, macos-latest]
os: [windows-latest, ubuntu-latest]
steps:

- name: 'Checking out repo code'
Expand Down
42 changes: 31 additions & 11 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,18 @@ jobs:
strategy:
matrix:
os: [windows-latest, ubuntu-latest]
auth_type: [sql_login, aad_password, service_principal] # Unique for each parallel job run, part of TEST_DB name to ensure no collisions from parallel jobs
include:
# Includes the connection string Github secret name, effectively a switch statement on auth_type
- auth_type: sql_login
connection_string_secret: AZURE_SQL_CONNECTION_STRING_NO_DATABASE
- auth_type: aad_password
connection_string_secret: AAD_PASSWORD_CONNECTION_STRING_NO_DATABASE
- auth_type: service_principal
connection_string_secret: SERVICE_PRINCIPAL_CONNECTION_STRING_NO_DATABASE

env:
TEST_DB: 'SqlActionTest-${{ matrix.os }}'
TEST_DB: 'SqlActionTest-${{ matrix.os }}-${{ matrix.auth_type }}'

steps:
- name: Checkout from PR branch
Expand All @@ -42,26 +52,36 @@ jobs:
- name: Test DACPAC Action
uses: ./
with:
connection-string: '${{ secrets.AZURE_SQL_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
dacpac-package: ./__testdata__/sql-action.dacpac
connection-string: '${{ secrets[matrix.connection_string_secret] }}Initial Catalog=${{ env.TEST_DB }};'
path: ./__testdata__/sql-action.dacpac
action: 'publish'

# Build and publish sqlproj that should create a new view
- name: Test Build and Publish
uses: ./
with:
connection-string: '${{ secrets.AZURE_SQL_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
project-file: ./__testdata__/TestProject/sql-action.sqlproj
connection-string: '${{ secrets[matrix.connection_string_secret] }}Initial Catalog=${{ env.TEST_DB }};'
path: ./__testdata__/TestProject/sql-action.sqlproj
action: 'publish'

# Execute testsql.sql via SQLCMD on server
# Execute testsql.sql via script action on server
- name: Test SQL Action
uses: ./
with:
connection-string: '${{ secrets.AZURE_SQL_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=${{ env.TEST_DB }};'
sql-file: ./__testdata__/testsql.sql
connection-string: '${{ secrets[matrix.connection_string_secret] }}Initial Catalog=${{ env.TEST_DB }};'
path: ./__testdata__/testsql.sql

# Test that go-sqlcmd has been added to runner, this step will be removed in future PR when go-sqlcmd is hooked up
- name: Test go-sqlcmd is setup
run: sqlcmd -?

- name: Set database name for cleanup
if: always()
run: sed 's/$(DbName)/${{ env.TEST_DB }}/' ./__testdata__/cleanup.sql > ${{ runner.temp }}/cleanup.sql

- name: Cleanup Test Database
if: always()
uses: ./
with:
connection-string: '${{ secrets.AZURE_SQL_CONNECTION_STRING_NO_DATABASE }}Initial Catalog=master;'
sql-file: ./__testdata__/cleanup.sql
arguments: '-v DbName="${{ env.TEST_DB }}"'
connection-string: '${{ secrets[matrix.connection_string_secret] }}Initial Catalog=master;'
path: ${{ runner.temp }}/cleanup.sql
77 changes: 48 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ Get started today with a [free Azure account](https://azure.com/free/open-source
The definition of this GitHub Action is in [action.yml](https://github.com/Azure/sql-action/blob/master/action.yml). Learn more in the [user guide](#📓-user-guide).

```yaml
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: # required, connection string incl the database and user authentication information
# required, connection string incl the database and user authentication information
connection-string:

# optional for SQL project deployment - project-file, build-arguments
project-file: # path to a .sqlproj file
build-arguments: # additional arguments applied to dotnet build when building the .sqlproj to .dacpac
# required, path to either a .sql, .dacpac, or .sqlproj file
path:

# optional for dacpac deployment - dacpac-package
dacpac-package: # path to a .dacpac file
# optional when using a .sql script, required otherwise
# sqlpackage action on the .dacpac or .sqlproj file, supported options are: Publish, Script, DeployReport, DriftReport
action:

# optional for SQL scripts deployment - sql-file
sql-file: # path to SQL scripts
# optional additional sqlpackage or go-sqlcmd arguments
arguments:


# optional for all deployments - arguments
arguments: # sqlpackage arguments for .sqlproj or .dacpac deployment or sqlcmd arguments for SQL script deployment
# optional additional dotnet build options when building a database project file
build-arguments:
```
## 🎨 Samples
Expand All @@ -45,12 +45,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
project-file: './Database.sqlproj'
build-arguments: '-c Release' # Optional arguments passed to dotnet build
arguments: '/p:DropObjectsNotInSource=true' # Optional parameters for SqlPackage Publish
path: './Database.sqlproj'
action: 'publish'
build-arguments: '-c Release' # Optional build options passed to dotnet build
arguments: '/p:DropObjectsNotInSource=true' # Optional properties and parameters for SqlPackage Publish
```
### Deploy SQL scripts to an Azure SQL Database with a temporary firewall rule
Expand All @@ -67,10 +68,10 @@ jobs:
- uses: azure/login@v1 # Azure login required to add a temporary firewall rule
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
sql-file: './sqlscripts/*.sql'
path: './sqlscripts/*.sql'
```
### Deploy a DACPAC to an Azure SQL database with Allow Azure Services access enabled
Expand All @@ -84,27 +85,43 @@ jobs:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
dacpac-package: './Database.dacpac'
arguments: '/p:DropObjectsNotInSource=true' # Optional parameters for SqlPackage Publish
path: './Database.dacpac'
action: 'publish'
arguments: '/p:DropObjectsNotInSource=true' # Optional properties parameters for SqlPackage Publish
```
## 📓 User Guide
### Authentication
### Authentication and Connection String
The v1.x version of sql-action supports SQL authentication only in the connection string. Starting in v2, AAD Password, AAD Service Principal, and AAD Default authentications are also supported.
The basic format of a connection string includes a series of keyword/value pairs separated by semicolons. The equal sign (=) connects each keyword and its value. (Ex: Key1=Val1;Key2=Val2) An example connection string template is: `Server=<servername>; User ID=<user_id>; Password=<password>; Initial Catalog=<database>`.

The following rules are to be followed while passing special characters in values:
1. To include values that contain a semicolon, single-quote character, or double-quote character, the value must be enclosed in double quotation marks.
2. If the value contains both a semicolon and a double-quote character, the value can be enclosed in single quotation marks.
3. The single quotation mark is also useful if the value starts with a double-quote character. Conversely, the double quotation mark can be used if the value starts with a single quotation mark.
4. If the value contains both single-quote and double-quote characters, the quotation mark character used to enclose the value must be doubled every time it occurs within the value.


For more information about connection strings, see https://aka.ms/sqlconnectionstring

The v1.x version of sql-action supports SQL authentication only in the connection string.
### Arguments

The `server-name` action YAML key is optional and is only available to provide backward compatibility. It is strongly recommended to put the server name in the connection string as displayed in the examples. The connection string uses this template: `Server=<servername>; User ID=<user_id>; Password=<password>; Initial Catalog=<database>`. In case the server name is put both in the `server-name` and in the `connection-string`, the server name used will be the one specified in the `server-name` YAML key.
sql-action supports passing arguments to SqlPackage, go-sqlcmd, and dotnet build.
- **SqlPackage**: SqlPackage publish properties are passed to the SqlPackage utility from the `arguments` property. More information on these properties is available in the [SqlPackage publish](https://docs.microsoft.com/sql/tools/sqlpackage/sqlpackage-publish#properties-specific-to-the-publish-action) documentation. SqlPackage [parameters](https://docs.microsoft.com/sql/tools/sqlpackage/sqlpackage-publish#parameters-for-the-publish-action) that do not impact the source or target setting are also valid, including `/Profile:` for a publish profile, `/DeployReportPath:` for a deployment report, and `/Variables:` to set SQLCMD variable values.
- **go-sqlcmd**: go-sqlcmd parameters are passed to the go-sqlcmd utility from the `arguments` property. This enables SQLCMD variables `-v` to be passed to scripts as seen in the [sqlcmd documentation](https://docs.microsoft.com/sql/tools/sqlcmd-utility#syntax).
- **dotnet build**: dotnet build options are passed to the SQL project build step from the `build-arguments` property. More information on options is available in the [dotnet build documentation](https://docs.microsoft.com/dotnet/core/tools/dotnet-build#options).

### Environments

sql-action is supported on both Windows and Linux environments. The [default images](https://github.com/actions/virtual-environments) include the prerequisites:

- sqlcmd
- sqlpackage (for sqlproj or dacpac deployment)
- dotnet (for sqlproj build)

Expand Down Expand Up @@ -166,10 +183,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
project-file: './Database.sqlproj'
path: './Database.sqlproj'
action: 'publish'
```
3. Place the connection string from the Azure Portal in GitHub secrets as `AZURE_SQL_CONNECTION_STRING`. Connection string format is: `Server=<server.database.windows.net>;User ID=<user>;Password=<password>;Initial Catalog=<database>`.
4. Copy the below SQL project template and paste the content in your project repository as `Database.sqlproj`.
Expand Down Expand Up @@ -218,10 +236,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: azure/sql-action@v1.3
- uses: azure/sql-action@v2
with:
connection-string: ${{ secrets.AZURE_SQL_CONNECTION_STRING }}
dacpac-package: './PreviousDatabase.dacpac'
path: './PreviousDatabase.dacpac'
action: 'publish'
```
4. Place the connection string from the Azure Portal in GitHub secrets as `AZURE_SQL_CONNECTION_STRING`. Connection string format is: `Server=<server.database.windows.net>;User ID=<user>;Password=<password>;Initial Catalog=<database>`.
5. Commit and push your project to GitHub repository, you should see a new GitHub Action initiated in **Actions** tab.
Expand Down
1 change: 1 addition & 0 deletions __testdata__/TestProject/sql-action.sqlproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<Name>sql-action</Name>
<DSP>Microsoft.Data.Tools.Schema.Sql.SqlAzureV12DatabaseSchemaProvider</DSP>
<ModelCollation>1033, CI</ModelCollation>
<ProjectGuid>{829ec500-6bb6-42c3-a1ab-ab621099d153}</ProjectGuid>
</PropertyGroup>
</Project>
6 changes: 3 additions & 3 deletions __testdata__/testsql.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
-- This script is used by pr-check.yml to test the SQLCMD action
-- This script is used by pr-check.yml to test the script action

-- This should successfully insert data into the table created in the DACPAC step
INSERT INTO [Table1] VALUES(1, 'test');
INSERT INTO [dbo].[Table1] VALUES(1, 'test');

-- This should successfully SELECT from the view created by the sqlproj
SELECT * FROM [View1];
SELECT * FROM [dbo].[View1];
Loading

0 comments on commit b62786f

Please sign in to comment.