Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5e9c891
Refactor code structure for improved readability and maintainability
PierreAntoineAP Mar 13, 2026
ab0a443
Enhance release workflow: add artifact verification, improve error ha…
PierreAntoineAP Mar 13, 2026
ae18d00
Fix release workflow: update DACPAC path, adjust output directory, an…
PierreAntoineAP Mar 13, 2026
b4ac62d
Refactor logging messages in release workflow for consistency
PierreAntoineAP Mar 13, 2026
4980769
Target SQL Server 2016 for maximum compatibility
PierreAntoineAP Mar 13, 2026
0277a00
Fix BAK compression and SQL script generation
PierreAntoineAP Mar 13, 2026
2c03c55
Update assembly version to 0.3.8.0
PierreAntoineAP Mar 13, 2026
79c2ed3
Add certificate-based security - eliminate TRUSTWORTHY requirement
PierreAntoineAP Mar 13, 2026
af98fc1
Revert certificate approach - use TRUSTWORTHY ON
PierreAntoineAP Mar 13, 2026
4d8b404
Target .NET Framework 4.0 for SQL Server 2016 compatibility
PierreAntoineAP Mar 13, 2026
8785df3
Use .NET Framework 4.6.2 (available on GitHub Actions)
PierreAntoineAP Mar 13, 2026
0fbe474
Remove assembly signing to fix 0x80FC80F1 error
PierreAntoineAP Mar 13, 2026
9d0f22c
v0.5.0 - Retour à la configuration d'origine (.NET 4.8.1, SQL Server …
PierreAntoineAP Mar 13, 2026
a4f19ef
Remove backup of assembly signing key
PierreAntoineAP Mar 13, 2026
2fe3c40
v0.5.1 - Cibler SQL Server 2016 pour compatibilité LocalDB 2019
PierreAntoineAP Mar 13, 2026
33b94cb
v0.5.2 - Ajout support trusted assembly pour SQL Server 2017+ (clr st…
PierreAntoineAP Mar 13, 2026
8a93756
Retrait des modifications trusted assembly - retour à v0.5.1
PierreAntoineAP Mar 13, 2026
2f7ef68
v0.5.3 - Fix: Ajout sp_changedbowner 'sa' pour résoudre erreur 0x80FC…
PierreAntoineAP Mar 13, 2026
f18e894
v0.5.4 - Fix: Retour SQL Server 2016 pour compatibilité LocalDB 2019
PierreAntoineAP Mar 13, 2026
aba6c9c
v0.5.5 - Fix: Activation CLR avant test et correction génération scri…
PierreAntoineAP Mar 13, 2026
b13dae5
v0.6.0 - Ajout des paramètres FastTransfer v0.15: useWorkTables, data…
PierreAntoineAP Mar 16, 2026
50147be
Fix: correction erreur syntaxe accolade manquante ligne 611
PierreAntoineAP Mar 16, 2026
a822379
Fix: ajout déclaration args4Log manquante
PierreAntoineAP Mar 16, 2026
5c6cf9d
Fix: mise à jour signature SQL avec nouveaux paramètres v0.6.0
PierreAntoineAP Mar 16, 2026
43d8c5b
v0.7.0 - Ajout paramètres FastBCP: applicationintent, parquetcompress…
PierreAntoineAP Mar 16, 2026
3fe2292
docs: ajout instructions configuration post-installation (TRUSTWORTHY…
PierreAntoineAP Mar 16, 2026
df5b0e4
docs: suppression section Creating a New Release
PierreAntoineAP Mar 16, 2026
e8627e1
docs: ajout option sp_add_trusted_assembly (sécurisée) pour configura…
PierreAntoineAP Mar 16, 2026
c4ab02b
docs: ajout section 'Available Stored Procedures' décrivant le conten…
PierreAntoineAP Mar 16, 2026
b79b595
docs: ajout section 'Logging and Output' pour FastTransfer avec descr…
PierreAntoineAP Mar 16, 2026
9297b78
docs: ajout section 'Security Roles' détaillant FastTransfer_Executor…
PierreAntoineAP Mar 16, 2026
f4db21d
Potential fix for pull request finding
rferraton Mar 17, 2026
367de35
feat: script SQL avec assembly injecté + extraction binaire dans GitH…
PierreAntoineAP Mar 18, 2026
9001ccc
Merge branch 'master' of https://github.com/PierreAntoineAP/FastWrapp…
PierreAntoineAP Mar 18, 2026
8e2846d
fix: correction signature xp_RunFastBCP_secure pour correspondre au c…
PierreAntoineAP Mar 18, 2026
e4c60b2
docs: update installation instructions and add additional options for…
PierreAntoineAP Mar 18, 2026
3c6de7c
Remove DACPAC and BACPAC from release artifacts
PierreAntoineAP Apr 2, 2026
2e8e87a
Fix: Restore build steps to generate assembly for .sql artifact
PierreAntoineAP Apr 2, 2026
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
89 changes: 89 additions & 0 deletions .github/workflows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Release Workflow

This GitHub Actions workflow automates the creation of releases for the FastWrappers-TSQL project.

## Trigger

The workflow is automatically triggered when creating a new tag starting with `v` (e.g., `vx.y.z`).

## Generated Artifacts

The workflow generates 4 types of artifacts for different installation methods:

1. **FastWrappers-TSQL.dacpac** - Data-tier Application Package
- Recommended for Visual Studio / SQL Server Data Tools
- Enables controlled deployment with drift detection

2. **FastWrappers-TSQL.bacpac** - Binary Application Package
- For import/export between servers
- Contains the schema + compiled assembly

3. **FastWrappers-TSQL.bak** - SQL Server Backup
- Compatible with SQL Server 2016+ (Compatibility Level 130)
- Direct restore via SSMS or T-SQL

4. **FastWrappers-TSQL.sql** - Pure SQL Script
- Executable via sqlcmd or SSMS
- **Automatically generated from DACPAC with up-to-date binary**
- Contains the compiled assembly in inline hexadecimal format

## Build Process

1. **Checkout** source code
2. **Setup** MSBuild and NuGet
3. **Build** SQL project in Release mode
4. **Deploy** temporarily to SQL LocalDB
5. **Generate** artifacts:
- BACPAC via SqlPackage export
- BAK via BACKUP DATABASE (with compression)
- DACPAC copied from bin/Release
- **SQL script generated from DACPAC (contains up-to-date compiled binary)**
6. **Create** GitHub release with all artifacts

## How to Create a New Release

### 1. Update the Version

Edit [Properties/AssemblyInfo.cs](../Properties/AssemblyInfo.cs):
```csharp
[assembly: AssemblyVersion("x.y.z.0")]
[assembly: AssemblyFileVersion("x.y.z.0")]
```

Optional: Update [FastWrappers_TSQL.sqlproj](../FastWrappers_TSQL.sqlproj):
```xml
<DacVersion>x.y.z.0</DacVersion>
```

### 2. Commit and Tag

```bash
git add Properties/AssemblyInfo.cs
git commit -m "Bump version to x.y.z"
git tag vx.y.z
git push origin main
git push origin vx.y.z
```

### 3. Verify the Release

1. Go to https://github.com/aetperf/FastWrappers-TSQL/actions
2. Check that the "Create Release Artifacts" workflow is running
3. Once completed, verify the release at https://github.com/aetperf/FastWrappers-TSQL/releases

## Troubleshooting

### Workflow fails during build

- Verify that the project compiles locally in Release mode
- Check NuGet dependencies

### SqlPackage cannot find the assembly

- Verify that the DACPAC is correctly generated in `bin/Release/`
- Verify that the file is signed (AetPCLRSign.pfx.snk)

### Backup fails

- SQL LocalDB may need more time to start
- Increase the `Start-Sleep` after LocalDB startup
251 changes: 251 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
name: Create Release Artifacts

on:
push:
tags:
- 'v*.*.*'

jobs:
build-and-release:
runs-on: windows-latest

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v2

- name: Setup NuGet
uses: nuget/setup-nuget@v2

- name: Restore NuGet packages
run: nuget restore FastWrappers-TSQL.sln

- name: Build SQL Project
run: msbuild FastWrappers_TSQL.sqlproj /p:Configuration=Release /p:Platform="Any CPU" /t:Build

- name: Verify Build Artifacts
shell: powershell
run: |
Write-Host "Checking for build output..."
if (Test-Path "bin") {
Get-ChildItem -Path "bin" -Recurse -File | Format-Table FullName, Length
} else {
Write-Host "bin folder does not exist!"
}

# Check for DACPAC in bin\Output (SQL Projects output here)
$dacpacPath = "bin\Output\FastWrappers_TSQL.dacpac"
if (Test-Path $dacpacPath) {
Write-Host "DACPAC found at: $dacpacPath"
} else {
Write-Host "DACPAC not found at: $dacpacPath"
Write-Host "Looking for .dacpac files..."
Get-ChildItem -Path . -Filter "*.dacpac" -Recurse -ErrorAction SilentlyContinue | Format-Table FullName
exit 1
}

- name: Setup SQL Server (LocalDB)
shell: powershell
run: |
# Start SQL LocalDB
sqllocaldb create MSSQLLocalDB
sqllocaldb start MSSQLLocalDB

# Wait for SQL Server to be ready
Start-Sleep -Seconds 10

- name: Deploy Database and Create Artifacts
shell: powershell
run: |
# Variables
$serverInstance = "(localdb)\MSSQLLocalDB"
$dbName = "FastWrappers-TSQL"
$dacpacPath = "bin\Output\FastWrappers_TSQL.dacpac"
$outputDir = "bin\Release"
$bakPath = "$outputDir\FastWrappers-TSQL.bak"
$generatedSqlPath = "$outputDir\FastWrappers-TSQL.sql"
$templateSqlPath = "FastWrappers-TSQL.sql"

# Ensure output directory exists
if (!(Test-Path $outputDir)) {
Write-Host "Creating $outputDir directory..."
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
}

# Verify DACPAC exists
if (!(Test-Path $dacpacPath)) {
Write-Error "DACPAC not found at: $dacpacPath"
exit 1
}

# Download SqlPackage if needed
if (!(Test-Path "SqlPackage\SqlPackage.exe")) {
Write-Host "Downloading SqlPackage..."
Invoke-WebRequest -Uri "https://aka.ms/sqlpackage-windows" -OutFile "SqlPackage.zip"
Expand-Archive -Path "SqlPackage.zip" -DestinationPath "SqlPackage" -Force
Remove-Item "SqlPackage.zip"
}

$sqlPackage = "SqlPackage\SqlPackage.exe"

# Deploy the DACPAC to create the database
Write-Host "Deploying DACPAC to create database..."
& $sqlPackage /Action:Publish /SourceFile:$dacpacPath /TargetServerName:$serverInstance /TargetDatabaseName:$dbName /p:IncludeCompositeObjects=True

if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to deploy DACPAC"
exit 1
}

# Wait for deployment to complete
Start-Sleep -Seconds 5

# Test the assembly
Write-Host "Testing assembly..."
$testResult = sqlcmd -S $serverInstance -d $dbName -Q "SELECT dbo.EncryptString('test') AS Result" 2>&1

if ($LASTEXITCODE -eq 0) {
Write-Host "Assembly test successful!"
Write-Host $testResult
} else {
Write-Warning "Assembly test failed: $testResult"
Write-Warning "Continuing with artifact creation..."
}

# Create backup file
Write-Host "Creating SQL Server backup..."
$bakFullPath = Join-Path $PWD $bakPath
sqlcmd -S $serverInstance -Q "BACKUP DATABASE [$dbName] TO DISK = N'$bakFullPath' WITH STATS = 10"

if ($LASTEXITCODE -ne 0) {
Write-Warning "Failed to create BAK file, continuing..."
}

# Generate SQL script with current assembly binary
Write-Host "Generating SQL script with assembly binary..."

# Extract assembly binary from deployed database using SqlClient (no size limitations)
$connectionString = "Server=$serverInstance;Database=$dbName;Integrated Security=True;TrustServerCertificate=True;"
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$connection.Open()

$command = $connection.CreateCommand()
$command.CommandText = "SELECT content FROM sys.assembly_files WHERE assembly_id = (SELECT assembly_id FROM sys.assemblies WHERE name = 'FastWrappers_TSQL')"

$reader = $command.ExecuteReader()
$assemblyHex = $null

if ($reader.Read()) {
$bytes = $reader.GetSqlBytes(0).Value
$hexString = [System.BitConverter]::ToString($bytes) -replace '-',''
$assemblyHex = "0x$hexString"
Write-Host "Assembly binary extracted (length: $($assemblyHex.Length) chars, $($bytes.Length) bytes)"
}

$reader.Close()
$connection.Close()

if ($assemblyHex) {
# Read template and inject assembly binary
$sqlTemplate = Get-Content $templateSqlPath -Raw
$finalSql = $sqlTemplate -replace '__ASSEMBLY_FROM_0X__', $assemblyHex
$finalSql | Out-File -FilePath $generatedSqlPath -Encoding UTF8
Write-Host "SQL script generated successfully"
} else {
Write-Warning "Failed to extract assembly binary"
}

# List all created artifacts
Write-Host "`nCreated artifacts:"
Get-ChildItem -Path $outputDir -File | Format-Table Name, Length

Write-Host "All artifacts processing completed!"

- name: Get version from tag
id: get_version
shell: bash
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

- name: Prepare Release Files
shell: powershell
run: |
# Create a release directory with all available artifacts
New-Item -Path "release" -ItemType Directory -Force | Out-Null

# Copy available files
$files = @(
@{Source="bin\Release\FastWrappers-TSQL.bak"; Name="FastWrappers-TSQL.bak"},
@{Source="bin\Release\FastWrappers-TSQL.sql"; Name="FastWrappers-TSQL.sql"}
)

foreach ($file in $files) {
if (Test-Path $file.Source) {
Copy-Item $file.Source "release\$($file.Name)" -Force
Write-Host "Copied $($file.Name)"
} else {
Write-Warning "$($file.Name) not found, skipping"
}
}

Write-Host "`nRelease files:"
Get-ChildItem -Path "release" | Format-Table Name, Length

- name: Create Release
id: create_release
uses: softprops/action-gh-release@v1
with:
name: Release v${{ steps.get_version.outputs.VERSION }}
body: |
## FastWrappers-TSQL v${{ steps.get_version.outputs.VERSION }}

### Installation Files

- **FastWrappers-TSQL.bak** - SQL Server Backup (restore using SSMS)
- **FastWrappers-TSQL.sql** - SQL Script (execute using sqlcmd or SSMS)

### Installation

**Option 1: Restore from backup (.bak file)**
```sql
-- Restore database
RESTORE DATABASE [FastWrappers-TSQL] FROM DISK = 'FastWrappers-TSQL.bak';
GO

-- Enable TRUSTWORTHY and CLR
ALTER DATABASE [FastWrappers-TSQL] SET TRUSTWORTHY ON;
GO

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO

-- IMPORTANT: Change database owner to 'sa'
-- Required for signed UNSAFE assemblies to load properly
USE [FastWrappers-TSQL];
GO
EXEC sp_changedbowner 'sa';
GO

-- Test
SELECT dbo.EncryptString('test');
```

**Option 2: Execute SQL Script (.sql file)**
```sql
-- Simply execute the script in SSMS or using sqlcmd
sqlcmd -S YourServer -i FastWrappers-TSQL.sql
```

### Usage

See [README.md](https://github.com/${{ github.repository }}/blob/main/README.md) for examples.
files: |
release/*
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading
Loading