Skip to content

Commit d436287

Browse files
committed
Refactoring pipeline for NuGet release (#12)
* Added MIT LICENSE.md * Updated solution properties - Updated TargetFrameworks to netstandard2.0;net6.0 - Enabled NuGet source link - Enabled nullable * Fix nullable warnings * Updated GH action, added AZ pipeline * Fix nullable warnings * Refactoring disposable and app+version args
1 parent 745cd13 commit d436287

32 files changed

+419
-265
lines changed

.azure/pipelines/ci.yml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
parameters:
2+
- name: verbosity
3+
displayName: Verbosity
4+
type: string
5+
default: minimal
6+
values:
7+
- minimal
8+
- normal
9+
- detailed
10+
- diagnostic
11+
12+
trigger: none
13+
14+
pool:
15+
vmImage: 'windows-latest'
16+
17+
variables:
18+
configuration: 'Release'
19+
assemblyVersion: '$(AppVersionMajor).0.0.0'
20+
semanticVersion: '$(AppVersionMajor).$(AppVersionMinor).$(AppVersionPatch)'
21+
22+
steps:
23+
- task: PowerShell@2
24+
displayName: 'Set variables'
25+
inputs:
26+
targetType: 'inline'
27+
script: |
28+
$versionSuffix = "$(AppVersionSuffix)"
29+
if ($versionSuffix -match "\S") { $versionSuffix = "-$versionSuffix" }
30+
Write-Host "##vso[task.setvariable variable=versionSuffix;]$versionSuffix"
31+
Write-Host "VersionSuffix $versionSuffix"
32+
$packageVersion = "$(semanticVersion)$versionSuffix"
33+
if ("$(isReleaseBuild)" -ne "true") { $packageVersion += "-CI-$(Build.BuildNumber)" }
34+
Write-Host "Set PackageVersion and BuildNumber to '$packageVersion'"
35+
Write-Host "##vso[task.setvariable variable=packageVersion;]$packageVersion"
36+
Write-Host "##vso[build.updatebuildnumber]$packageVersion"
37+
- task: DownloadSecureFile@1
38+
name: signKey
39+
displayName: 'Download sign key'
40+
inputs:
41+
secureFile: 'DaxFormatter.snk'
42+
- task: UseDotNet@2
43+
displayName: '.NET setup'
44+
inputs:
45+
packageType: sdk
46+
version: 6.0.x
47+
- task: DotNetCoreCLI@2
48+
displayName: '.NET restore'
49+
inputs:
50+
command: 'restore'
51+
projects: 'src/**/*.csproj'
52+
feedsToUse: 'select'
53+
verbosityRestore: '${{ parameters.verbosity }}'
54+
- task: DotNetCoreCLI@2
55+
displayName: '.NET build'
56+
inputs:
57+
command: 'build'
58+
projects: 'src/**/*.csproj'
59+
arguments: '--configuration "$(configuration)" --no-restore --verbosity ${{ parameters.verbosity }} /p:AssemblyVersion="$(assemblyVersion)" /p:FileVersion="$(semanticVersion)" /p:VersionPrefix="$(semanticVersion)" /p:VersionSuffix="$(versionSuffix)" /p:ContinuousIntegrationBuild="true" /p:AdditionalConstants="SIGNED" /p:SignAssembly="true" /p:AssemblyOriginatorKeyFile="$(signKey.secureFilePath)" /m'
60+
- task: DotNetCoreCLI@2
61+
displayName: '.NET test'
62+
inputs:
63+
command: 'test'
64+
projects: 'src/*Tests/*.csproj'
65+
arguments: '--no-restore --no-build --verbosity ${{ parameters.verbosity }} --logger "trx;LogFilePrefix=testResults" --collect "Code coverage"'
66+
- task: DotNetCoreCLI@2
67+
displayName: '.NET pack'
68+
inputs:
69+
command: 'pack'
70+
packagesToPack: 'src/Dax.Formatter/Dax.Formatter.csproj'
71+
nobuild: true
72+
versioningScheme: 'byEnvVar'
73+
versionEnvVar: 'packageVersion'
74+
verbosityPack: '${{ parameters.verbosity }}'
75+
- task: PublishPipelineArtifact@1
76+
displayName: 'Publish artifacts'
77+
inputs:
78+
targetPath: '$(Build.ArtifactStagingDirectory)'
79+
artifact: 'drop'
80+
publishLocation: 'pipeline'

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: CI
2+
on:
3+
push:
4+
branches:
5+
- master
6+
pull_request:
7+
branches:
8+
- master
9+
workflow_dispatch:
10+
env:
11+
CONFIGURATION: 'Release'
12+
jobs:
13+
build-and-test:
14+
name: build-and-test--${{ matrix.os-version }}
15+
runs-on: ${{ matrix.os-version }}
16+
strategy:
17+
matrix:
18+
os-version: [windows-latest] #, ubuntu-latest, macos-latest]
19+
steps:
20+
- uses: actions/checkout@v2
21+
- name: .NET setup
22+
uses: actions/setup-dotnet@v1
23+
with:
24+
dotnet-version: 6.0.x
25+
- name: .NET info
26+
run: dotnet --info
27+
- name: .NET restore
28+
run: dotnet restore ./src
29+
- name: .NET build
30+
run: dotnet build ./src/Dax.Formatter.sln --configuration ${{ env.CONFIGURATION }} --no-restore
31+
- name: .NET test
32+
run: dotnet test ./src/Dax.Formatter.Tests/Dax.Formatter.Tests.csproj --configuration ${{ env.CONFIGURATION }} --no-build --verbosity normal
33+
- name: .NET pack
34+
run: dotnet pack ./src/Dax.Formatter/Dax.Formatter.csproj --configuration ${{ env.CONFIGURATION }} --no-build --no-restore --verbosity normal

.github/workflows/dotnet.yml

Lines changed: 0 additions & 29 deletions
This file was deleted.

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) SQLBI Corporation
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
# Dax Formatter [![NuGet](https://github.com/sql-bi/DaxFormatter/actions/workflows/dotnet.yml/badge.svg)](https://github.com/sql-bi/DaxFormatter/actions/workflows/dotnet.yml)
2+
# Dax Formatter [![CI](https://github.com/sql-bi/DaxFormatter/actions/workflows/ci.yml/badge.svg)](https://github.com/sql-bi/DaxFormatter/actions/workflows/ci.yml)
33

44
DAX Formatter is a service available at https://www.daxformatter.com.
55
The service receives DAX expressions and format them according to rules for [DAX code formatting](https://www.sqlbi.com/articles/rules-for-dax-code-formatting/).

global.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"sdk": {
3+
"version": "6.0.100",
4+
"allowPrerelease": false,
5+
"rollForward": "latestFeature"
6+
}
7+
}

nuget.config

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<clear />
5+
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
6+
</packageSources>
7+
</configuration>
File renamed without changes.

src/Dax.Formatter.Tests/Dax.Formatter.Tests.csproj

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,23 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0</TargetFramework>
5-
4+
<TargetFrameworks>net461;net6.0</TargetFrameworks>
5+
<LangVersion>latest</LangVersion>
6+
<Nullable>enable</Nullable>
67
<IsPackable>false</IsPackable>
78
</PropertyGroup>
89

910
<ItemGroup>
10-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
11-
<PackageReference Include="xunit" Version="2.4.0" />
12-
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
13-
<PackageReference Include="coverlet.collector" Version="1.2.0" />
11+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0-preview-20220401-08" />
12+
<PackageReference Include="xunit" Version="2.4.2-pre.12" />
13+
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
14+
<PrivateAssets>all</PrivateAssets>
15+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
16+
</PackageReference>
17+
<PackageReference Include="coverlet.collector" Version="3.1.2">
18+
<PrivateAssets>all</PrivateAssets>
19+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
20+
</PackageReference>
1421
</ItemGroup>
1522

1623
<ItemGroup>

src/Dax.Formatter.Tests/DaxFormatterClientTests.cs

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class DaxFormatterClientFixture
1010
{
1111
public DaxFormatterClient Client { get; private set; }
1212

13-
public DaxFormatterClientFixture() => Client = new DaxFormatterClient();
13+
public DaxFormatterClientFixture() => Client = new DaxFormatterClient(application: "Dax.Formatter.Tests", version: "develop");
1414
}
1515

1616
public class DaxFormatterClientTests : IClassFixture<DaxFormatterClientFixture>
@@ -27,11 +27,8 @@ public DaxFormatterClientTests(DaxFormatterClientFixture formatter)
2727
[InlineData(DaxFormatterSpacingStyle.NoSpaceAfterFunction, "[X]=IF(1=1,TRUE(),FALSE())", "[X] =\r\nIF( 1 = 1, TRUE(), FALSE() )\r\n")]
2828
public async Task DaxFormatterClient_FormatAsync_SpacingStyleIsHonored(DaxFormatterSpacingStyle spacingStyle, string expression, string expectedExpression)
2929
{
30-
var request = new DaxFormatterSingleRequest
31-
{
32-
Dax = expression,
33-
SkipSpaceAfterFunctionName = spacingStyle
34-
};
30+
var request = DaxFormatterSingleRequest.CreateFrom(expression);
31+
request.SkipSpaceAfterFunctionName = spacingStyle;
3532

3633
var response = await _fixture.Client.FormatAsync(request);
3734
Assert.NotNull(response);
@@ -45,11 +42,8 @@ public async Task DaxFormatterClient_FormatAsync_SpacingStyleIsHonored(DaxFormat
4542
[InlineData(DaxFormatterLineStyle.ShortLine, "[X]:=IF(1=1,1,0)", "[X] :=\r\nIF (\r\n 1 = 1,\r\n 1,\r\n 0\r\n)\r\n")]
4643
public async Task DaxFormatterClient_FormatAsync_LineStyleIsHonored(DaxFormatterLineStyle lineStyle, string expression, string expectedExpression)
4744
{
48-
var request = new DaxFormatterSingleRequest
49-
{
50-
Dax = expression,
51-
MaxLineLength = lineStyle
52-
};
45+
var request = DaxFormatterSingleRequest.CreateFrom(expression);
46+
request.MaxLineLength = lineStyle;
5347

5448
var response = await _fixture.Client.FormatAsync(request);
5549
Assert.NotNull(response);
@@ -85,9 +79,7 @@ public async Task DaxFormatterClient_FormatAsync_SingleExpressionFails(string ex
8579
[InlineData("[X] := CALCULATE(SUM(Sales[Sales Amount]), USERELATIONSHIP(Sales[DueDateKey],'Date'[DateKey]))", "[X] :=\r\nCALCULATE (\r\n SUM ( Sales[Sales Amount] ),\r\n USERELATIONSHIP ( Sales[DueDateKey], 'Date'[DateKey] )\r\n)\r\n")]
8680
public async Task DaxFormatterClient_FormatAsync_SingleRequestSucceded(string expression, string expectedExpression)
8781
{
88-
var request = new DaxFormatterSingleRequest();
89-
request.Dax = expression;
90-
82+
var request = DaxFormatterSingleRequest.CreateFrom(expression);
9183
var response = await _fixture.Client.FormatAsync(request);
9284

9385
AssertSingleSucceded(response, expectedExpression);
@@ -98,9 +90,7 @@ public async Task DaxFormatterClient_FormatAsync_SingleRequestSucceded(string ex
9890
[InlineData("EVALUATE( Table ) ORDER Table[Column]", 0, 24)]
9991
public async Task DaxFormatterClient_FormatAsync_SingleRequestFails(string expression, int expectedErrorLine, int expectedErrorColumn)
10092
{
101-
var request = new DaxFormatterSingleRequest();
102-
request.Dax = expression;
103-
93+
var request = DaxFormatterSingleRequest.CreateFrom(expression);
10494
var response = await _fixture.Client.FormatAsync(request);
10595

10696
AssertSingleFails(response, expectedErrorLine, expectedErrorColumn);
@@ -113,9 +103,7 @@ public async Task DaxFormatterClient_FormatAsync_SingleRequestFails(string expre
113103
public async Task DaxFormatterClient_FormatAsync_MultipleRequestSucceded(string expression, string expectedExpression, int repeat)
114104
{
115105
var expressions = Enumerable.Repeat(expression, repeat);
116-
var request = new DaxFormatterMultipleRequest();
117-
request.Dax.AddRange(expressions);
118-
106+
var request = DaxFormatterMultipleRequest.CreateFrom(expressions);
119107
var response = await _fixture.Client.FormatAsync(request);
120108

121109
AssertMultipleSucceded(response, expectedExpression, repeat);
@@ -127,9 +115,7 @@ public async Task DaxFormatterClient_FormatAsync_MultipleRequestSucceded(string
127115
public async Task DaxFormatterClient_FormatAsync_MultipleRequestFails(string expression, int repeat, int expectedErrorLine, int expectedErrorColumn)
128116
{
129117
var expressions = Enumerable.Repeat(expression, repeat);
130-
var request = new DaxFormatterMultipleRequest();
131-
request.Dax.AddRange(expressions);
132-
118+
var request = DaxFormatterMultipleRequest.CreateFrom(expressions);
133119
var response = await _fixture.Client.FormatAsync(request);
134120

135121
AssertMultipleFails(response, repeat, expectedErrorLine, expectedErrorColumn);
@@ -149,30 +135,30 @@ public async Task DaxFormatterClient_FormatAsync_ParallelSingleExpressionSuccede
149135
[InlineData("evaluate('Table')", "EVALUATE\r\n( 'Table' )\r\n", 10)]
150136
public async Task DaxFormatterClient_FormatAsync_ParallelSingleRequestSucceded(string expression, string expectedExpression, int repeat)
151137
{
152-
var request = new DaxFormatterSingleRequest();
153-
request.Dax = expression;
154-
138+
var request = DaxFormatterSingleRequest.CreateFrom(expression);
155139
var tasks = Enumerable.Repeat(request, repeat).AsParallel().Select((r) => _fixture.Client.FormatAsync(r));
156140
var responses = await Task.WhenAll(tasks);
157141

158142
AssertParallelSingleSucceded(responses, expectedExpression, repeat);
159143
}
160144

161-
private static void AssertSingleSucceded(DaxFormatterResponse response, string expectedExpression)
145+
private static void AssertSingleSucceded(DaxFormatterResponse? response, string expectedExpression)
162146
{
163147
Assert.NotNull(response);
164-
148+
Assert.NotNull(response.Formatted);
149+
Assert.NotNull(response.Errors);
165150
Assert.NotEmpty(response.Formatted);
166151
Assert.Empty(response.Errors);
167152

168153
var actualExpression = response.Formatted;
169154
Assert.Equal(expectedExpression, actualExpression);
170155
}
171156

172-
private static void AssertSingleFails(DaxFormatterResponse response, int expectedErrorLine, int expectedErrorColumn)
157+
private static void AssertSingleFails(DaxFormatterResponse? response, int expectedErrorLine, int expectedErrorColumn)
173158
{
174159
Assert.NotNull(response);
175-
160+
Assert.NotNull(response.Formatted);
161+
Assert.NotNull(response.Errors);
176162
Assert.Empty(response.Formatted);
177163
Assert.Single(response.Errors);
178164

@@ -183,10 +169,11 @@ private static void AssertSingleFails(DaxFormatterResponse response, int expecte
183169

184170
private static void AssertMultipleSucceded(IReadOnlyList<DaxFormatterResponse> responses, string expectedExpression, int repeat)
185171
{
186-
Assert.NotNull(responses);
172+
Assert.NotNull(responses);
187173
Assert.Equal(repeat, responses.Count);
174+
Assert.DoesNotContain(responses, (r) => r.Errors is null);
188175

189-
var errors = responses.SelectMany((r) => r.Errors);
176+
var errors = responses.SelectMany((r) => r.Errors!);
190177
Assert.Empty(errors);
191178

192179
var formattedExpressions = responses.Select((r) => r.Formatted).Distinct();
@@ -200,8 +187,9 @@ private static void AssertMultipleFails(IReadOnlyList<DaxFormatterResponse> resp
200187
{
201188
Assert.NotNull(responses);
202189
Assert.Equal(repeat, responses.Count);
190+
Assert.DoesNotContain(responses, (r) => r.Errors is null);
203191

204-
var errors = responses.SelectMany((r) => r.Errors).ToList();
192+
var errors = responses.SelectMany((r) => r.Errors!).ToList();
205193
Assert.Equal(repeat, errors.Count);
206194

207195
var errorLines = errors.Select((e) => e.Line).Distinct();
@@ -223,11 +211,10 @@ private static void AssertMultipleFails(IReadOnlyList<DaxFormatterResponse> resp
223211
Assert.Equal(string.Empty, actualExpression);
224212
}
225213

226-
private static void AssertParallelSingleSucceded(DaxFormatterResponse[] responses, string expectedExpression, int repeat)
214+
private static void AssertParallelSingleSucceded(DaxFormatterResponse?[] responses, string expectedExpression, int repeat)
227215
{
216+
Assert.NotNull(responses);
228217
Assert.Equal(repeat, responses.Length);
229-
Assert.Empty(responses.SelectMany((r) => r.Errors));
230-
Assert.Single(responses.Select((r) => r.Formatted).Distinct());
231218

232219
foreach (var response in responses)
233220
AssertSingleSucceded(response, expectedExpression);

0 commit comments

Comments
 (0)