Release #6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| certificate_sign: | |
| description: 'Sign the binaries and packages using a certificate stored in Azure Key Vault?' | |
| required: true | |
| type: boolean | |
| default: false | |
| strong_name_sign: | |
| description: 'Sign the assemblies using a strong name key stored in GitHub Secrets?' | |
| required: true | |
| type: boolean | |
| default: false | |
| create_github_release: | |
| description: 'Create a GitHub Release?' | |
| required: true | |
| type: boolean | |
| default: false | |
| publish_nuget: | |
| description: 'Publish packages to NuGet Gallery?' | |
| required: true | |
| type: boolean | |
| default: false | |
| publish_powershell: | |
| description: 'Publish module to PowerShell Gallery?' | |
| required: true | |
| type: boolean | |
| default: false | |
| publish_chocolatey: | |
| description: 'Publish module to Chocolatey Community repository?' | |
| required: true | |
| type: boolean | |
| default: false | |
| permissions: | |
| id-token: write | |
| contents: write | |
| env: | |
| DOTNET_NOLOGO: true | |
| DOTNET_CLI_TELEMETRY_OPTOUT: true | |
| jobs: | |
| build: | |
| name: 'Build and Sign' | |
| runs-on: windows-2025 | |
| timeout-minutes: 10 | |
| outputs: | |
| nuget-artifact-id: ${{ steps.upload-nuget.outputs.artifact-id }} | |
| powershell-artifact-id: ${{ steps.upload-powershell.outputs.artifact-id }} | |
| powershell-module-version: ${{ steps.get-module-info.outputs.version }} | |
| powershell-module-release-notes: ${{ steps.get-module-info.outputs.release-notes }} | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: Restore Strong Name Key | |
| if: ${{ inputs.strong_name_sign }} | |
| working-directory: Keys | |
| shell: powershell | |
| env: | |
| STRONG_NAME_KEY: ${{ secrets.STRONG_NAME_KEY }} | |
| run: | | |
| if($null -ne $env:STRONG_NAME_KEY) | |
| { | |
| Write-Host 'Creating file Keys/DSInternals.Private.snk...' | |
| [byte[]] $privateKey = [System.Convert]::FromBase64String($env:STRONG_NAME_KEY) | |
| [System.IO.File]::WriteAllBytes('DSInternals.Private.snk', $privateKey) | |
| } | |
| else | |
| { | |
| Write-Warning 'The STRONG_NAME_KEY secret is not available. Skipping SNK file creation.' | |
| } | |
| - name: Setup MSBuild | |
| uses: microsoft/setup-msbuild@v2 | |
| with: | |
| msbuild-architecture: x64 # default is x86 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| cache: true | |
| cache-dependency-path: 'Src/*/packages.lock.json' | |
| - name: Cache DotNet Global Tools | |
| id: cache-dotnet-globaltools | |
| uses: actions/cache@v4 | |
| if: ${{ inputs.certificate_sign }} | |
| with: | |
| path: ~/.dotnet/tools | |
| # Heuristics: The current list of required global tools is defined in this workflow file. | |
| key: ${{ runner.os }}-DotNET-GlobalTools-Release-${{ hashFiles('.github/workflows/release.yml') }} | |
| - name: Install Code Signing Tools | |
| if: ${{ inputs.certificate_sign && steps.cache-dotnet-globaltools.outputs.cache-hit != 'true' }} | |
| run: | | |
| dotnet tool install --global --prerelease sign | |
| - name: Restore NuGet Packages | |
| working-directory: Src | |
| run: msbuild.exe -target:Restore -property:RestorePackagesConfig=true | |
| - name: Build x86 | |
| working-directory: Src | |
| run: msbuild.exe -target:Build -property:Configuration=Release -property:Platform=Win32 -property:RestorePackages=false | |
| #- name: Build ARM64 | |
| # working-directory: Src | |
| # run: msbuild.exe -target:Build -property:Configuration=Release -property:Platform=ARM64 -property:RestorePackages=false | |
| - name: Build AMD64 | |
| working-directory: Src | |
| run: msbuild.exe -target:Build -property:Configuration=Release -property:Platform=x64 -property:RestorePackages=false | |
| - name: Azure Login | |
| uses: azure/login@v2 | |
| if: ${{ inputs.certificate_sign }} | |
| with: | |
| client-id: ${{ secrets.SIGNING_CLIENT_ID }} | |
| tenant-id: ${{ secrets.SIGNING_TENANT_ID }} | |
| allow-no-subscriptions: true | |
| - name: Sign Binaries and Scripts | |
| shell: cmd | |
| if: ${{ inputs.certificate_sign }} | |
| run: > | |
| sign code azure-key-vault | |
| "DSInternals.Common/release_*/DSInternals.Common.dll" | |
| "DSInternals.DataStore/release_*/DSInternals.DataStore.dll" | |
| "DSInternals.Replication/release_*/DSInternals.Replication.dll" | |
| "DSInternals.Replication.Model/release_*/DSInternals.Replication.Model.dll" | |
| "DSInternals.Replication.Interop/Release_*/DSInternals.Replication.Interop.dll" | |
| "DSInternals.SAM/release_*/DSInternals.SAM.dll" | |
| "DSInternals.PowerShell/Release/DSInternals/*/DSInternals.PowerShell.dll" | |
| "DSInternals.PowerShell/Release/DSInternals/DSInternals.Bootstrap.psm1" | |
| "DSInternals.PowerShell/Release/DSInternals/DSInternals.psd1" | |
| "DSInternals.PowerShell/Release/DSInternals/DSInternals.types.ps1xml" | |
| "DSInternals.PowerShell/Release/DSInternals/Views/*.ps1xml" | |
| --base-directory "${{ github.workspace }}/Build/bin" | |
| --azure-key-vault-url "${{ secrets.SIGNING_KEY_VAULT_URL }}" | |
| --azure-key-vault-certificate "${{ secrets.SIGNING_KEY_VAULT_CERTIFICATE }}" | |
| --azure-credential-type azure-cli | |
| --file-digest SHA256 | |
| --timestamp-digest SHA256 | |
| --timestamp-url "http://timestamp.acs.microsoft.com" | |
| --verbosity Information | |
| - name: Copy Signed Binaries to PowerShell Module | |
| shell: cmd | |
| working-directory: Build/bin | |
| if: ${{ inputs.certificate_sign }} | |
| timeout-minutes: 1 | |
| run: | | |
| copy /Y "DSInternals.Common\release_net48\DSInternals.Common.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.Common\release_net8.0-windows\DSInternals.Common.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\" | |
| copy /Y "DSInternals.DataStore\release_net48\DSInternals.DataStore.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.DataStore\release_net8.0-windows\DSInternals.DataStore.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\" | |
| copy /Y "DSInternals.Replication\release_net48\DSInternals.Replication.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.Replication\release_net8.0-windows\DSInternals.Replication.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\" | |
| copy /Y "DSInternals.Replication.Model\release_net48\DSInternals.Replication.Model.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.Replication.Model\release_net8.0-windows\DSInternals.Replication.Model.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\" | |
| copy /Y "DSInternals.Replication.Interop\Release_net4.8-Win32\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\x86\" | |
| copy /Y "DSInternals.Replication.Interop\Release_net4.8-x64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\amd64\" | |
| REM copy /Y "DSInternals.Replication.Interop\Release_net4.8-ARM64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\arm64\" | |
| copy /Y "DSInternals.Replication.Interop\Release_net8.0-Win32\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\x86\" | |
| copy /Y "DSInternals.Replication.Interop\Release_net8.0-x64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\amd64\" | |
| REM copy /Y "DSInternals.Replication.Interop\Release_net8.0-ARM64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\arm64\" | |
| copy /Y "DSInternals.SAM\release_net48\DSInternals.SAM.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.SAM\release_net8.0-windows\DSInternals.SAM.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\" | |
| - name: Create Module Catalog | |
| shell: powershell | |
| working-directory: Build/bin/DSInternals.PowerShell/Release | |
| run: New-FileCatalog -CatalogVersion 2 -Path DSInternals -CatalogFilePath .\DSInternals\DSInternals.cat | |
| - name: Create Managed NuGet Packages | |
| working-directory: Src | |
| run: | | |
| dotnet pack DSInternals.Common --configuration Release --no-build | |
| dotnet pack DSInternals.DataStore --configuration Release --no-build | |
| dotnet pack DSInternals.SAM --configuration Release --no-build | |
| - name: Create Mixed NuGet Package | |
| working-directory: Src | |
| run: | | |
| msbuild.exe DSInternals.Replication -target:Pack -property:Configuration=Release -property:Platform=x64 -property:RestorePackages=false -property:NoBuild=true -property:BuildProjectReferences=false | |
| - name: Sign NuGet Packages and PowerShell Catalog | |
| shell: cmd | |
| if: ${{ inputs.certificate_sign }} | |
| run: > | |
| sign code azure-key-vault | |
| package/release/*.*nupkg | |
| bin/DSInternals.PowerShell/Release/DSInternals/DSInternals.cat | |
| --base-directory "${{ github.workspace }}/Build" | |
| --azure-key-vault-url "${{ secrets.SIGNING_KEY_VAULT_URL }}" | |
| --azure-key-vault-certificate "${{ secrets.SIGNING_KEY_VAULT_CERTIFICATE }}" | |
| --azure-credential-type azure-cli | |
| --file-digest SHA256 | |
| --timestamp-digest SHA256 | |
| --timestamp-url "http://timestamp.acs.microsoft.com" | |
| --verbosity Information | |
| - name: Get PowerShell Module Info | |
| shell: pwsh | |
| id: get-module-info | |
| run: | | |
| [hashtable] $manifest = Import-PowerShellDataFile -Path ./Src/DSInternals.PowerShell/DSInternals.psd1 | |
| [string] $version = $manifest.ModuleVersion | |
| [string] $releaseNotes = $manifest.PrivateData.PSData.ReleaseNotes | |
| echo "version=$version" >> $env:GITHUB_OUTPUT | |
| echo 'release-notes<<EOF' >> $env:GITHUB_OUTPUT | |
| echo $releaseNotes >> $env:GITHUB_OUTPUT | |
| echo 'EOF' >> $env:GITHUB_OUTPUT | |
| - name: Upload PowerShell Module as Artifact | |
| uses: actions/upload-artifact@v4 | |
| id: upload-powershell | |
| with: | |
| name: DSInternals_v${{ steps.get-module-info.outputs.version }} | |
| path: Build/bin/DSInternals.PowerShell/Release | |
| - name: Upload NuGet Packages as Artifacts | |
| uses: actions/upload-artifact@v4 | |
| id: upload-nuget | |
| with: | |
| name: NuGet_v${{ steps.get-module-info.outputs.version }} | |
| path: Build/package/release/*nupkg | |
| # TODO: Smoke Tests | |
| nuget: | |
| name: 'Publish to NuGet Gallery' | |
| if: ${{ inputs.publish_nuget }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Download NuGet Packages | |
| uses: actions/download-artifact@v5 | |
| with: | |
| artifact-ids: ${{ needs.build.outputs.nuget-artifact-id }} | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| - name: Publish NuGet Packages | |
| shell: pwsh | |
| env: | |
| NUGET_GALLERY_APIKEY: ${{ secrets.NUGET_GALLERY_APIKEY }} | |
| run: | | |
| dotnet nuget push *.nupkg --source 'https://api.nuget.org/v3/index.json' --api-key $env:NUGET_GALLERY_APIKEY --skip-duplicate | |
| psgallery: | |
| name: 'Publish to PowerShell Gallery' | |
| if: ${{ inputs.publish_powershell }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Download PowerShell Module | |
| uses: actions/download-artifact@v5 | |
| with: | |
| artifact-ids: ${{ needs.build.outputs.powershell-artifact-id }} | |
| path: Module | |
| - name: Publish PowerShell Module | |
| shell: pwsh | |
| env: | |
| POWERSHELL_GALLERY_APIKEY: ${{ secrets.POWERSHELL_GALLERY_APIKEY }} | |
| run: | | |
| Publish-Module -Path ./Module/DSInternals -NuGetApiKey $env:POWERSHELL_GALLERY_APIKEY -Repository PSGallery -Force | |
| release: | |
| name: 'Create GitHub Release Draft' | |
| if: ${{ inputs.create_github_release }} | |
| runs-on: ubuntu-latest | |
| needs: build | |
| steps: | |
| - name: Checkout Repository | |
| uses: actions/checkout@v4 | |
| - name: Download PowerShell Module | |
| uses: actions/download-artifact@v5 | |
| with: | |
| artifact-ids: ${{ needs.build.outputs.powershell-artifact-id }} | |
| path: GitHub/Module | |
| - name: Create Module ZIP for GitHub Release | |
| shell: pwsh | |
| working-directory: GitHub | |
| run: Compress-Archive -Path ./Module/* -DestinationPath ./DSInternals_v${{ needs.build.outputs.powershell-module-version }}.zip -CompressionLevel Optimal -Force | |
| - name: Create GitHub Release | |
| shell: pwsh | |
| working-directory: GitHub | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| @' | |
| ### Notable Changes | |
| ${{ needs.build.outputs.powershell-module-release-notes }} | |
| See the [Changelog](https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/CHANGELOG.md) for a more detailed list of new features. | |
| ### DSInternals PowerShell Module | |
| - The module is available in the [PowerShell Gallery](https://www.powershellgallery.com/packages/DSInternals). | |
| - As an alternative, the attached `DSInternals_v${{ needs.build.outputs.powershell-module-version }}.zip` file can be used for [offline module installation](https://github.com/MichaelGrafnetter/DSInternals#offline-module-distribution). | |
| ### NuGet Packages | |
| Official binary packages are available in the [NuGet Gallery](https://www.nuget.org/profiles/DSInternals). | |
| '@ > release-notes.md | |
| gh release create v${{ needs.build.outputs.powershell-module-version }} ./*.zip --draft --latest --title "DSInternals PowerShell Module ${{ needs.build.outputs.powershell-module-version }}" --notes-file release-notes.md | |
| # TODO: chocolatey |