Release 20 #20
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 | |
| run-name: 'Release ${{ github.run_number }}' | |
| 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-vs2026 | |
| timeout-minutes: 10 | |
| outputs: | |
| nuget-artifact-id: ${{ steps.upload-nuget.outputs.artifact-id }} | |
| chocolatey-artifact-id: ${{ steps.upload-chocolatey.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@v6 | |
| - 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@v5 | |
| with: | |
| # Platform-specific IJW hosts from previous .NET SDKs are used when building C++/CLI projects. | |
| dotnet-version: | | |
| 8.0.x | |
| 9.0.x | |
| 10.0.x | |
| cache: true | |
| cache-dependency-path: 'Src/*/packages.lock.json' | |
| - name: Cache DotNet Global Tools | |
| id: cache-dotnet-globaltools | |
| uses: actions/cache@v5 | |
| 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 DSInternals.SkipTests.slnf -target:Restore -property:RestorePackagesConfig=true -property:Configuration=Release -property:Platform=x64 | |
| - name: Build x86 | |
| working-directory: Src | |
| run: msbuild.exe DSInternals.ArchitectureSpecific.slnf -target:Build -property:Configuration=Release -property:Platform=Win32 -property:RestorePackages=false | |
| - name: Build ARM64 | |
| working-directory: Src | |
| run: msbuild.exe DSInternals.ArchitectureSpecific.slnf -target:Build -property:Configuration=Release -property:Platform=ARM64 -property:RestorePackages=false | |
| - name: Build AMD64 | |
| working-directory: Src | |
| run: msbuild.exe DSInternals.SkipTests.slnf -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.ADSI/release_*/DSInternals.ADSI.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.psd1" | |
| "DSInternals.PowerShell/Release/DSInternals/Test-ModuleCompatibility.ps1" | |
| "DSInternals.PowerShell/Release/DSInternals/Integrity.Tests.ps1" | |
| "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.ADSI\release_net48\DSInternals.ADSI.dll" "DSInternals.PowerShell\Release\DSInternals\net48\" | |
| copy /Y "DSInternals.ADSI\release_net8.0-windows\DSInternals.ADSI.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_net48\Win32\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\x86\" | |
| copy /Y "DSInternals.Replication.Interop\release_net48\x64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\amd64\" | |
| copy /Y "DSInternals.Replication.Interop\release_net48\ARM64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net48\arm64\" | |
| copy /Y "DSInternals.Replication.Interop\release_net8.0-windows\Win32\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\x86\" | |
| copy /Y "DSInternals.Replication.Interop\release_net8.0-windows\x64\DSInternals.Replication.Interop.dll" "DSInternals.PowerShell\Release\DSInternals\net8.0-windows\amd64\" | |
| copy /Y "DSInternals.Replication.Interop\release_net8.0-windows\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.DotNetSdk.slnf --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: | | |
| [System.Management.Automation.PSModuleInfo] $manifest = Test-ModuleManifest -Path ./Src/DSInternals.PowerShell/DSInternals.psd1 -ErrorAction SilentlyContinue | |
| [string] $version = $manifest.Version | |
| [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: Create Chocolatey Package | |
| shell: pwsh | |
| run: | | |
| choco pack Src/DSInternals.PowerShell/Chocolatey/dsinternals-psmodule.nuspec --version=${{ steps.get-module-info.outputs.version }} --output-directory=Build/package/Chocolatey --execution-timeout=60 --confirm configuration=Release | |
| - name: Sign Chocolatey Package | |
| shell: cmd | |
| if: ${{ inputs.certificate_sign }} | |
| run: > | |
| sign code azure-key-vault | |
| *.nupkg | |
| --base-directory "${{ github.workspace }}/Build/package/Chocolatey" | |
| --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: Upload PowerShell Module as Artifact | |
| uses: actions/upload-artifact@v6 | |
| 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@v6 | |
| id: upload-nuget | |
| with: | |
| name: NuGet_v${{ steps.get-module-info.outputs.version }} | |
| path: Build/package/release/*nupkg | |
| - name: Upload Chocolatey Package as Artifact | |
| uses: actions/upload-artifact@v6 | |
| id: upload-chocolatey | |
| with: | |
| name: Chocolatey_v${{ steps.get-module-info.outputs.version }} | |
| path: Build/package/Chocolatey/*.nupkg | |
| - name: Run PowerShell Desktop Tests | |
| working-directory: Scripts | |
| shell: powershell | |
| run: ./Invoke-SmokeTests.ps1 -Configuration 'Release' | |
| - name: Run PowerShell Core Tests | |
| working-directory: Scripts | |
| shell: pwsh | |
| run: ./Invoke-SmokeTests.ps1 -Configuration 'Release' | |
| - name: Test Module Digital Signatures | |
| if: ${{ inputs.certificate_sign }} | |
| shell: powershell | |
| run: ./Build/bin/DSInternals.PowerShell/Release/DSInternals/Integrity.Tests.ps1 | |
| 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@v7 | |
| with: | |
| artifact-ids: ${{ needs.build.outputs.nuget-artifact-id }} | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v5 | |
| - 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@v7 | |
| 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 }} | |
| PROCESSOR_ARCHITECTURE: amd64 # Fallback for Linux | |
| 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@v6 | |
| - name: Download PowerShell Module | |
| uses: actions/download-artifact@v7 | |
| 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). | |
| - The module is also available as a [Chocolatey package](https://community.chocolatey.org/packages/dsinternals-psmodule). | |
| ### 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 | |
| chocolatey: | |
| name: 'Publish to Chocolatey Gallery' | |
| if: ${{ inputs.publish_chocolatey }} | |
| runs-on: windows-2025 | |
| needs: build | |
| steps: | |
| - name: Download Chocolatey Package | |
| uses: actions/download-artifact@v7 | |
| with: | |
| artifact-ids: ${{ needs.build.outputs.chocolatey-artifact-id }} | |
| - name: Publish Chocolatey Package | |
| shell: pwsh | |
| env: | |
| CHOCOLATEY_APIKEY: ${{ secrets.CHOCOLATEY_APIKEY }} | |
| run: | | |
| choco push --source='https://push.chocolatey.org/' --api-key=$env:CHOCOLATEY_APIKEY |