-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathaction.yml
More file actions
358 lines (319 loc) · 15.5 KB
/
action.yml
File metadata and controls
358 lines (319 loc) · 15.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
name: Publish to NuGet
description: Publishes the project or solution in the current directory to a NuGet source.
inputs:
source:
required: false
default: https://api.nuget.org/v3/index.json
description: The NuGet server URL used by the `dotnet nuget push` command's `--source` argument.
verbosity:
required: false
default: minimal
description: The logging verbosity type used by the `dotnet` command.
enable-corepack:
type: string
default: 'false'
description: Indicates whether to enable Node.js corepack before the build.
dotnet-pack-ignore-warning:
required: false
default: ''
description: >
Additional warning codes for the `-p:NoWarn=` argument of `dotnet pack`. The items can be separated by any
whitespace, including newlines.
dotnet-pack-include-symbols:
required: false
default: 'true'
description: If set to "true", a symbol package will be created together with the NuGet package.
publish-version:
required: false
default: USE_GITHUB_REF_NAME
description: >
The desired NuGet package version used for publishing. If not specified, the GITHUB_REF_NAME environment variable
is used which is suitable if the version is derived from a git tag. If "USE_GITHUB_RUN_NUMBER" is used, then the
version is derived from the latest non-prerelease version tag and the current run number to create a preview
version (e.g. "1.0.1-preview-1" if the current version is 1.0.0). With "USE_NEXT_PATCH_VERSION" the version is
derived from the latest non-prerelease version tag to create the next patch version (e.g. "1.0.1" if the current
version is 1.0.0). If a literal version is provided, an optional leading `v` is ignored.
require-major-version-for-compatibility-suppressions:
required: false
default: 'true'
description: >
If set to "true", publishing fails when any CompatibilitySuppressions.xml file exists in the repository and the
publish version's major version is not greater than the latest stable tag's major version. Versions in the format
`vM.N.O-[alpha|beta|preview|rc]` with an optional `".X.<issue-code>`" suffix are exempt. Set to "false" for
intentional compatibility suppressions that don't require a SemVer major release.
nuget-artifact-retention-days:
required: false
default: '14'
description: >
Duration in days after which the artifact of the NuGet package publishing (if any) will expire. See
https://github.com/actions/upload-artifact#retention-period for more details. Note that this only affects the
retention of the workflow run's artifact, not the artifacts attached to the release created on GitHub; those will
remain indefinitely.
add-source-link-package:
required: false
default: 'true'
description: If set to "true", the Microsoft.SourceLink.GitHub NuGet package is added to the projects.
dry-run:
required: false
default: 'false'
description: |
If set to "true", the action will perform all package creation and validation steps without actually publishing
the NuGet package or creating a GitHub release.
mark-breaking-changes:
type: string
default: 'false'
description: |
When set to 'true', failed package validation against the baseline will mark the pull request with a title suffix,
a breaking-changes label, and a guidance comment.
runs:
using: composite
steps:
- name: Setup Scripts
shell: pwsh
run: |
'${{ github.action_path }}' >> $Env:GITHUB_PATH
(Resolve-Path '${{ github.action_path }}/../../../Scripts').Path >> $Env:GITHUB_PATH
- name: Setup NuGet Version
id: setup
shell: pwsh
run: |
$source = @'
${{ inputs.source }}
'@.Trim()
Write-Output "NuGet Source: $source"
Set-GitHubOutput "source-url" $source
$version = @'
${{ inputs.publish-version }}
'@.Trim()
if ($version -notin @('USE_GITHUB_REF_NAME', 'USE_GITHUB_RUN_NUMBER', 'USE_NEXT_PATCH_VERSION'))
{
$version = $version.TrimStart('v')
}
if ($version -eq 'USE_GITHUB_REF_NAME')
{
$version = $Env:GITHUB_REF_NAME.Trim().TrimStart("v")
if (!($version -match '^\d+\.\d+\.\d+(-(alpha|beta|preview|rc)(\.\d+(\.[a-zA-Z]{2,}(-\d+)?)?)?)?$'))
{
Write-Output ("::error::`"v$version`" is invalid. The correct format is " +
"`"vM.N.O`" or `"vM.N.O-[alpha|beta|preview|rc]`" with an optional `".X.<issue-code>`" suffix.")
exit 1
}
}
# We have to use the CLI to query the remote repository for tags, because `gh tag` only returns the current
# tag in the runner, which will never match in this scenario.
$tags = gh api "/repos/$Env:GITHUB_REPOSITORY/git/refs/tags" |
ConvertFrom-Json |
ForEach-Object { $PSItem.ref -replace '^refs/tags/v', '' } |
Where-Object { $PSItem -match '^\d+\.\d+\.\d+$' } |
ForEach-Object { [version]$PSItem } |
Sort-Object -Descending
$current = if ($tags.Count -gt 0) { $tags[0] } else { [version]"0.0.0" }
if ($version -eq 'USE_GITHUB_RUN_NUMBER' -or $version -eq 'USE_NEXT_PATCH_VERSION')
{
$next = New-Object "System.Version" $current.Major, $current.Minor, ($current.Build + 1)
$version = "$next$($version -eq 'USE_GITHUB_RUN_NUMBER' ? "-preview-$Env:GITHUB_RUN_NUMBER" : '')"
}
if ($tags.Count -gt 1)
{
if ($version -eq $current)
{
# In this case the new release is not a prelease so the previous tag should be used as baseline version.
$baselineVersion = $tags[1]
}
else
{
$baselineVersion = $current
}
}
else
{
# In this case validation to baseline version is not possible due to being this the first release.
$baselineVersion = ''
}
$isPreReleaseVersion = $version -match '^\d+\.\d+\.\d+-(alpha|beta|preview|rc)(\.\d+(\.[a-zA-Z]{2,}(-\d+)?)?)?$'
if ('${{ inputs.require-major-version-for-compatibility-suppressions }}' -eq 'true' -and -not $isPreReleaseVersion)
{
$compatibilitySuppressionsFiles = @(Get-ChildItem -Path . -Recurse -File -Filter CompatibilitySuppressions.xml -ErrorAction SilentlyContinue)
if ($compatibilitySuppressionsFiles.Count -gt 0)
{
Write-Output 'CompatibilitySuppressions.xml file(s) found:'
$compatibilitySuppressionsFiles | ForEach-Object { Write-Output "- $($PSItem.FullName)" }
$versionMatch = [regex]::Match($version, '^(?<major>\d+)\.\d+\.\d+($|-)')
if (-not $versionMatch.Success)
{
Write-Output ("::error::CompatibilitySuppressions.xml files indicate breaking changes, but " +
"`"$version`" doesn't use an x.y.z version format. Following Semantic Versioning, publish a " +
'new major version.')
exit 1
}
$publishMajorVersion = [int]$versionMatch.Groups['major'].Value
if ($publishMajorVersion -le $current.Major)
{
Write-Output ("::error::CompatibilitySuppressions.xml files indicate breaking changes. Following " +
"Semantic Versioning, publish a new major version. The current version is $current, so the " +
"publish version's major version must be greater than $($current.Major), but it is " +
"$publishMajorVersion in `"$version`".")
exit 1
}
}
}
Write-Output "Baseline version: $baselineVersion"
Write-Output "Publish version: $version"
Set-GitHubOutput "baseline-version" $baselineVersion
Set-GitHubOutput "publish-version" $version
# This also implicitly restores NuGet dependencies.
- name: Add Source Link package
shell: pwsh
run: |
if ('${{ inputs.add-source-link-package }}' -eq 'true')
{
Add-SourceLinkPackage
}
else
{
dotnet restore -p:NuGetBuild=true
}
- name: Update package manifest version
shell: pwsh
run: Update-ManifestVersion './' '${{ steps.setup.outputs.publish-version }}'
- name: Enable Node corepack
if: inputs.enable-corepack == 'true'
uses: Lombiq/GitHub-Actions/.github/actions/enable-corepack@dev
- name: Generate nuspec file if needed
if: hashFiles('ConvertTo-Nuspec.ps1')
shell: pwsh
run: ./ConvertTo-Nuspec.ps1 '${{ steps.setup.outputs.publish-version }}'
- name: Build
uses: Lombiq/GitHub-Actions/.github/actions/build-dotnet@dev
# Notes on the configuration:
# * -p:NuGetBuild=true is our property to load Lombiq dependencies from NuGet by switching project references
# to package references.
# * -p:GenerateDocumentationFile=True is for generating XML doc files. Needed both for build and pack. It'd
# cause CS* warnings but we handle that centrally from .NET Analyzers so disabling them here.
# * VSTHRD* rules come from somewhere unknown, disabling them.
# * -p:EnableNETAnalyzers=false is to disable further .NET analyzer we don't need here.
# * -p:ContinuousIntegrationBuild=true is needed for Deterministic Builds:
# https://github.com/clairernovotny/DeterministicBuilds.
# * -p:DebugSymbols=true and -p:DebugType=portable are needed to generate PDB files.
with:
verbosity: ${{ inputs.verbosity }}
enable-code-analysis: false
publish-version: ${{ steps.setup.outputs.publish-version }}
# Intentionally an empty string to use the default dotnet build behavior of "build the only project or only
# solution, or fail if there are multiple projects".
solution-or-project-path: ''
dotnet-build-switches: |
-p:NuGetBuild=true
-p:LangVersion=Latest
-p:GenerateDocumentationFile=True
-p:NoWarn=CS1573%3BCS1591%3BVSTHRD002%3BVSTHRD200
-p:EnableNETAnalyzers=false
-p:ContinuousIntegrationBuild=true
-p:DebugSymbols=true
-p:DebugType=portable
- name: Actions prior to dotnet pack
if: hashFiles('Invoke-BeforePack.ps1')
shell: pwsh
run: ./Invoke-BeforePack.ps1
- name: Pack
id: pack
shell: pwsh
# Notes on the configuration apart from what's also for dotnet build:
# * -p:WarnOnPackingNonPackableProject=True will cause a build warning (converted to error) if we try to pack a
# non-packable project.
# * -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg are needed to generate symbol packages:
# https://docs.microsoft.com/en-us/nuget/create-packages/symbol-packages-snupkg.
# * p:EnablePackageValidation=true is for package validation, see:
# https://docs.microsoft.com/en-us/dotnet/fundamentals/package-validation/overview.
run: |
$noWarn = @('CS1573%3BCS1591%3BVSTHRD002%3BVSTHRD200') + @'
${{ inputs.dotnet-pack-ignore-warning }}
'@.Split() | ? { $_ }
$version = '${{ steps.setup.outputs.publish-version }}'
# Disabling package validation for alphas and issue-specific pre-releases like v4.3.1-alpha.osoe-86. This is
# necessary because you need to add a CompatibilitySuppressions.xml file for breaking changes (and this is also
# checked by Validate NuGet Publish if used) but having such suppressions are actively disallowed for
# pre-releases, causing "Unnecessary suppressions found." errors.
$enablePackageValidation = !($version -like '*-*')
$parameters = @{
EnablePackageValidation=$enablePackageValidation
PackageValidationBaselineVersion='${{ steps.setup.outputs.baseline-version }}'
Version=$version
BaseBranch='${{ github.base_ref }}'
CompatibilitySuppressionsDirectoryPath=(Join-Path $PWD CompatibilitySuppressions)
PackParameters = @(
"--configuration:Release",
"--warnaserror",
"--no-restore",
"--output:" + (Join-Path $PWD artifacts),
"--verbosity:${{ inputs.verbosity }}",
"-p:NuGetBuild=true",
"-p:LangVersion=Latest",
"-p:Version=$version",
"-p:NuspecProperties=version=$version",
"-p:GenerateDocumentationFile=True",
"-p:NoWarn=$($noWarn -join '%3B')",
"-p:TreatWarningsAsErrors=true",
"-p:WarnOnPackingNonPackableProject=True",
"-p:IncludeSymbols=${{ inputs.dotnet-pack-include-symbols }}",
"-p:SymbolPackageFormat=snupkg",
"-p:NoDefaultExcludes=true"
)}
New-NuGetPackage @parameters
if ('${{ inputs.dry-run }}' -eq 'true')
{
Write-Output "::notice::Dry run mode: Package created successfully but will not be published."
}
- name: Show Breaking Status
if: ${{ (failure() || success()) && steps.pack.outputs.is-breaking == 'true' }}
shell: pwsh
run: |
Write-Output "::notice::Package validation detected breaking changes compared to the baseline version."
- name: Push with dotnet
if: inputs.dry-run != 'true'
shell: pwsh
run: |
if ([string]::IsNullOrWhiteSpace($Env:API_KEY))
{
Write-Output "::error::API_KEY is missing or empty."
exit 1
}
dotnet nuget push artifacts/*.nupkg --api-key $Env:API_KEY --source '${{ steps.setup.outputs.source-url }}' --skip-duplicate
- name: Check for ignore-breaking-changes Label
id: check-ignore-breaking
if: ${{ (failure() || success()) && inputs.mark-breaking-changes == 'true' && github.event_name == 'pull_request' }}
uses: Lombiq/GitHub-Actions/.github/actions/check-pull-request-labels@dev
with:
label1: ignore-breaking-changes
- name: Mark Breaking Changes on Pull Request
if: ${{ (failure() || success()) &&
inputs.mark-breaking-changes == 'true' &&
github.event_name == 'pull_request' }}
uses: Lombiq/GitHub-Actions/.github/actions/mark-breaking-changes@dev
with:
is-breaking: ${{ steps.check-ignore-breaking.outputs.contains-label == 'true' && 'false' || steps.pack.outputs.is-breaking == 'true' }}
env:
GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }}
- name: Upload NuGet Package Artifact
uses: Lombiq/GitHub-Actions/.github/actions/upload-artifact@dev
with:
name: NuGet-Package
path: artifacts
retention-days: ${{ inputs.nuget-artifact-retention-days }}
- name: Upload CompatibilitySuppressions File Artifact
if: success() || failure()
uses: Lombiq/GitHub-Actions/.github/actions/upload-artifact@dev
with:
name: CompatibilitySuppressions
path: CompatibilitySuppressions
retention-days: 1
if-no-files-found: ignore
- name: Create Release
uses: Lombiq/GitHub-Actions/.github/actions/release-action@dev
# Also preventing creating releases when pushing tags for issue-specific pre-releases like v4.3.1-alpha.osoe-86.
if: inputs.dry-run != 'true' && !contains(steps.setup.outputs.publish-version, '-')
with:
allowUpdates: true
generateReleaseNotes: true
tag: v${{ steps.setup.outputs.publish-version }}
artifacts: artifacts/*.nupkg, artifacts/*.snupkg