diff --git a/.github/workflows/nuget-test-flow.yml b/.github/workflows/nuget-test-flow.yml index 888da1b3c3..4e3ec127de 100644 --- a/.github/workflows/nuget-test-flow.yml +++ b/.github/workflows/nuget-test-flow.yml @@ -22,9 +22,10 @@ jobs: # ================================ # .NET Tool # ================================ - dotnet-tool-payload-sign: - name: Build .NET tool and Sign Payload + create-dotnet-tool-artifacts: + name: Create .NET Tool Artifacts runs-on: windows-latest + environment: release needs: prereqs steps: - uses: actions/checkout@v4 @@ -35,10 +36,15 @@ jobs: dotnet-version: 7.0.x - name: Build .NET tool - shell: bash run: | - $GITHUB_WORKSPACE/src/shared/DotnetTool/layout.sh ` - --configuration=Release + & $env:GITHUB_WORKSPACE\src\shared\DotnetTool\layout.ps1 Release + # The AzureCodeSigning PowerShell module currently cannot handle files + # without extensions. This is a temporary workaround until the issue is + # fixed. + mkdir $env:GITHUB_WORKSPACE\incompatible-files + Get-ChildItem -Path $env:GITHUB_WORKSPACE\out\shared\DotnetTool\nupkg\Release\payload\* ` + -Include NOTICE | Move-Item -Destination ` + $env:GITHUB_WORKSPACE\incompatible-files - name: Log into Azure uses: azure/login@v1 @@ -53,40 +59,13 @@ jobs: endpoint: https://wus2.codesigning.azure.net/ code-signing-account-name: git-fundamentals-signing certificate-profile-name: git-fundamentals-windows-signing - files-folder: ${{ github.workspace }}\out\shared\DotnetTool\nupkg\Release + files-folder: ${{ github.workspace }}\out\shared\DotnetTool\nupkg\Release\payload files-folder-filter: exe,dll file-digest: SHA256 timestamp-rfc3161: http://timestamp.acs.microsoft.com - timestamp-digest: SHA256 - - - name: Lay out signed payload, images, and symbols - shell: bash - run: | - mkdir dotnet-tool-payload-sign - rm -rf payload - mv images payload.sym -t dotnet-tool-payload-sign - unzip signed/payload.zip -d dotnet-tool-payload-sign - - - name: Upload signed payload - uses: actions/upload-artifact@v3 - with: - name: dotnet-tool-payload-sign - path: | - dotnet-tool-payload-sign - - dotnet-tool-pack: - name: Package .NET tool - runs-on: ubuntu-latest - needs: [ prereqs, dotnet-tool-payload-sign ] - steps: - - uses: actions/checkout@v4 - - - name: Download signed payload - uses: actions/download-artifact@v3 - with: - name: dotnet-tool-payload-sign - path: signed + timestamp-digest: SHA256 + # The Azure Code Signing action overrides the .NET version, so we reset it. - name: Set up .NET uses: actions/setup-dotnet@v3.2.0 with: @@ -94,46 +73,17 @@ jobs: - name: Package tool run: | - src/shared/DotnetTool/pack.sh --configuration=Release \ - --version="${{ needs.prereqs.outputs.version }}" \ - --publish-dir=$(pwd)/signed - - - name: Upload unsigned package - uses: actions/upload-artifact@v3 - with: - name: tmp.dotnet-tool-package-unsigned - path: | - out/shared/DotnetTool/nupkg/Release/*.nupkg - - dotnet-tool-sign: - name: Sign .NET tool package - # ESRP service requires signing to run on Windows - runs-on: windows-latest - environment: release - needs: dotnet-tool-pack - steps: - - uses: actions/checkout@v4 - - - name: Download unsigned package - uses: actions/download-artifact@v3 - with: - name: tmp.dotnet-tool-package-unsigned - path: nupkg + & $env:GITHUB_WORKSPACE\src\shared\DotnetTool\pack.ps1 Release ` + ${{ needs.prereqs.outputs.version }} "$pwd.Path\signed" - name: Zip unsigned package shell: pwsh run: | - Compress-Archive -Path nupkg/*.nupkg nupkg/gcm-nupkg.zip + Compress-Archive -Path out/shared/DotnetTool/nupkg/Release/git-credential-manager.${{ needs.prereqs.outputs.version }}.nupkg ` + nupkg/gcm-nupkg.zip cd nupkg Get-ChildItem -Exclude gcm-nupkg.zip | Remove-Item -Recurse -Force - - name: Log into Azure - uses: azure/login@v1 - with: - client-id: ${{ secrets.AZURE_CLIENT_ID }} - tenant-id: ${{ secrets.AZURE_TENANT_ID }} - subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} - - name: Set up ESRP client shell: pwsh env: diff --git a/src/shared/DotnetTool/layout.ps1 b/src/shared/DotnetTool/layout.ps1 new file mode 100644 index 0000000000..07ad3b7641 --- /dev/null +++ b/src/shared/DotnetTool/layout.ps1 @@ -0,0 +1,56 @@ +# Inputs +param ([Parameter(Mandatory)] $CONFIGURATION) + +# Directories +$THISDIR = $MyInvocation.MyCommand.Path | Split-Path -Parent +$ROOT = (Get-Item $THISDIR).parent.parent.parent.FullName +$SRC = "$ROOT/src" +$OUT = "$ROOT/out" +$GCM_SRC = "$SRC/shared/Git-Credential-Manager" +$DOTNET_TOOL = "shared/DotnetTool" +$PROJ_OUT = "$OUT/$DOTNET_TOOL" +$FRAMEWORK = "net7.0" + +# Outputs +$OUTDIR = "$PROJ_OUT/nupkg/$CONFIGURATION" +$IMGOUT = "$OUTDIR/images" +$PAYLOAD = "$OUTDIR/payload" +$SYMBOLOUT = "$OUTDIR/payload.sym" + +# Clean up any old payload and symbols directories +if (Test-Path -Path $OUTDIR) +{ + Write-Output "Cleaning old payload directory '$OUTDIR'..." + Remove-Item -Recurse "$OUTDIR" -Force +} + +# Ensure payload and symbol directories exist +mkdir -p "$IMGOUT","$PAYLOAD","$SYMBOLOUT" + +# Set DOTNET_ROOT if needed +$DOTNET_SET = Get-Item "Env:DOTNET_ROOT" -ErrorAction SilentlyContinue +if (!$DOTNET_SET) { + $Env:DOTNET_ROOT = (Get-Command dotnet).Path | Split-Path -Parent +} + +# Publish core application executables +Write-Output "Publishing core application..." +& "$env:DOTNET_ROOT\dotnet.exe" publish "$GCM_SRC" ` + --configuration="$CONFIGURATION" ` + --framework="$FRAMEWORK" ` + --output="$PAYLOAD" ` + -p:UseAppHost=false + +# Collect symbols +Write-Output "Collecting managed symbols..." +Copy-Item -Path "$PAYLOAD/*.pdb" -Destination "$SYMBOLOUT" + +# Copy DotnetToolSettings.xml file +Write-Output "Copying out package configuration files..." +Copy-Item -Path "$SRC/$DOTNET_TOOL/DotnetToolSettings.xml" -Destination "$PAYLOAD/" + +# Copy package icon image +Write-Output "Copying images..." +Copy-Item -Path "$SRC/$DOTNET_TOOL/icon.png" -Destination "$IMGOUT" + +Write-Output "Layout complete." diff --git a/src/shared/DotnetTool/layout.sh b/src/shared/DotnetTool/layout.sh deleted file mode 100755 index 44c712650e..0000000000 --- a/src/shared/DotnetTool/layout.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -make_absolute () { - case "$1" in - /*) - echo "$1" - ;; - *) - echo "$PWD/$1" - ;; - esac -} - -##################################################################### -# Lay out -##################################################################### -# Parse script arguments -for i in "$@" -do -case "$i" in - --configuration=*) - CONFIGURATION="${i#*=}" - shift # past argument=value - ;; - *) - # unknown option - ;; -esac -done - -# Directories -THISDIR="$( cd "$(dirname "$0")" ; pwd -P )" -ROOT="$( cd "$THISDIR"/../../.. ; pwd -P )" -SRC="$ROOT/src" -OUT="$ROOT/out" -GCM_SRC="$SRC/shared/Git-Credential-Manager" -DOTNET_TOOL="shared/DotnetTool" -PROJ_OUT="$OUT/$DOTNET_TOOL" - -CONFIGURATION="${CONFIGURATION:=Debug}" - -# Build parameters -FRAMEWORK=net7.0 - -# Outputs -OUTDIR="$PROJ_OUT/nupkg/$CONFIGURATION" -IMGOUT="$OUTDIR/images" -PAYLOAD="$OUTDIR/payload" -SYMBOLOUT="$OUTDIR/payload.sym" - -# Cleanup output directory -if [ -d "$OUTDIR" ]; then - echo "Cleaning existing output directory '$OUTDIR'..." - rm -rf "$OUTDIR" -fi - -# Ensure output directories exist -mkdir -p "$PAYLOAD" "$SYMBOLOUT" "$IMGOUT" - -if [ -z "$DOTNET_ROOT" ]; then - DOTNET_ROOT="$(dirname $(which dotnet))" -fi - -# Publish core application executables -echo "Publishing core application..." -$DOTNET_ROOT/dotnet publish "$GCM_SRC" \ - --configuration="$CONFIGURATION" \ - --framework="$FRAMEWORK" \ - --output="$(make_absolute "$PAYLOAD")" \ - -p:UseAppHost=false || exit 1 - -# Collect symbols -echo "Collecting managed symbols..." -mv "$PAYLOAD"/*.pdb "$SYMBOLOUT" || exit 1 - -# Copy DotnetToolSettings.xml file -echo "Copying out package configuration files..." -cp "$SRC/$DOTNET_TOOL/DotnetToolSettings.xml" "$PAYLOAD/" - -# Copy package icon image -echo "Copying images..." -cp "$SRC/$DOTNET_TOOL/icon.png" "$IMGOUT" || exit 1 - -echo "Build complete." diff --git a/src/shared/DotnetTool/pack.ps1 b/src/shared/DotnetTool/pack.ps1 new file mode 100644 index 0000000000..b3256fe0d7 --- /dev/null +++ b/src/shared/DotnetTool/pack.ps1 @@ -0,0 +1,27 @@ +# Inputs +param ([Parameter(Mandatory)] $CONFIGURATION, [Parameter(Mandatory)] $VERSION, $PUBLISH_DIR) + +# Directories +$THISDIR = $MyInvocation.MyCommand.Path | Split-Path -Parent +$ROOT = (Get-Item $THISDIR).parent.parent.parent.FullName +$SRC = "$ROOT/src" +$OUT = "$ROOT/out" +$DOTNET_TOOL = "shared/DotnetTool" + +if ([string]::IsNullOrEmpty($PUBLISH_DIR)) { + $PUBLISH_DIR = "$OUT/$DOTNET_TOOL/nupkg/$CONFIGURATION" +} + +# Set DOTNET_ROOT if needed +$DOTNET_SET = Get-Item "Env:DOTNET_ROOT" -ErrorAction SilentlyContinue +if (!$DOTNET_SET) { + $Env:DOTNET_ROOT = (Get-Command dotnet).Path | Split-Path -Parent +} + +Write-Output "Creating dotnet tool package..." +& "$env:DOTNET_ROOT\dotnet.exe" pack "$SRC/$DOTNET_TOOL/DotnetTool.csproj" ` + /p:Configuration="$CONFIGURATION" ` + /p:PackageVersion="$VERSION" ` + /p:PublishDir="$PUBLISH_DIR/" + +Write-Output "Dotnet tool pack complete." diff --git a/src/shared/DotnetTool/pack.sh b/src/shared/DotnetTool/pack.sh deleted file mode 100755 index 5b2eaf8dc4..0000000000 --- a/src/shared/DotnetTool/pack.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -die () { - echo "$*" >&2 - exit 1 -} - -# Parse script arguments -for i in "$@" -do -case "$i" in - --configuration=*) - CONFIGURATION="${i#*=}" - shift # past argument=value - ;; - --version=*) - VERSION="${i#*=}" - shift # past argument=value - ;; - --publish-dir=*) - PUBLISH_DIR="${i#*=}" - shift # past argument=value - ;; - *) - # unknown option - ;; -esac -done - -CONFIGURATION="${CONFIGURATION:=Debug}" -if [ -z "$VERSION" ]; then - die "--version was not set" -fi - -# Directories -THISDIR="$( cd "$(dirname "$0")" ; pwd -P )" -ROOT="$( cd "$THISDIR"/../../.. ; pwd -P )" -SRC="$ROOT/src" -OUT="$ROOT/out" -DOTNET_TOOL="shared/DotnetTool" - -if [ -z "$PUBLISH_DIR" ]; then - PUBLISH_DIR="$OUT/$DOTNET_TOOL/nupkg/$CONFIGURATION" -fi - -echo "Creating dotnet tool package..." - -dotnet pack "$SRC/$DOTNET_TOOL/DotnetTool.csproj" \ - /p:Configuration="$CONFIGURATION" \ - /p:PackageVersion="$VERSION" \ - /p:PublishDir="$PUBLISH_DIR/" - -echo "Dotnet tool pack complete."