Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 28 additions & 4 deletions .azure-pipelines/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,24 @@ parameters:
- name: windows_matrix
type: object
default:
- id: windows_x64
- id: windows_x86
jobName: 'Windows (x86)'
runtime: win-x86
pool: GitClientPME-1ESHostedPool-intel-pc
image: win-x86_64-ado1es
os: windows
- id: windows_x64
jobName: 'Windows (x64)'
runtime: win-x64
pool: GitClientPME-1ESHostedPool-intel-pc
image: win-x86_64-ado1es
os: windows
- id: windows_arm64
jobName: 'Windows (ARM64)'
runtime: win-arm64
pool: GitClientPME-1ESHostedPool-intel-pc
image: win-x86_64-ado1es
os: windows

- name: macos_matrix
type: object
Expand Down Expand Up @@ -130,14 +142,15 @@ extends:
arguments: |
-Configuration Release `
-Output $(Build.ArtifactStagingDirectory)\payload `
-SymbolOutput $(Build.ArtifactStagingDirectory)\symbols_raw
-SymbolOutput $(Build.ArtifactStagingDirectory)\symbols_raw `
-RuntimeIdentifier ${{ dim.runtime }}
- task: ArchiveFiles@2
displayName: 'Archive symbols'
inputs:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)\symbols_raw'
includeRootFolder: false
archiveType: zip
archiveFile: '$(Build.ArtifactStagingDirectory)\symbols\gcm-win-x86-$(version)-symbols.zip'
archiveFile: '$(Build.ArtifactStagingDirectory)\symbols\gcm-${{ dim.runtime }}-$(version)-symbols.zip'
- task: EsrpCodeSigning@5
condition: and(succeeded(), eq('${{ parameters.esrp }}', true))
displayName: 'Sign payload'
Expand Down Expand Up @@ -189,6 +202,7 @@ extends:
-p:NoLayout=true `
-p:PayloadPath="$(Build.ArtifactStagingDirectory)\payload" `
-p:OutputPath="$(Build.ArtifactStagingDirectory)\installers"
-p:RuntimeIdentifier="${{ dim.runtime }}"
- task: EsrpCodeSigning@5
condition: and(succeeded(), eq('${{ parameters.esrp }}', true))
displayName: 'Sign installers'
Expand Down Expand Up @@ -233,7 +247,7 @@ extends:
rootFolderOrFile: '$(Build.ArtifactStagingDirectory)\payload'
includeRootFolder: false
archiveType: zip
archiveFile: '$(Build.ArtifactStagingDirectory)\installers\gcm-win-x86-$(version).zip'
archiveFile: '$(Build.ArtifactStagingDirectory)\installers\gcm-${{ dim.runtime }}-$(version).zip'
- task: PowerShell@2
displayName: 'Collect artifacts for publishing'
inputs:
Expand Down Expand Up @@ -768,6 +782,12 @@ extends:
- input: pipelineArtifact
artifactName: 'win-x86'
targetPath: $(Pipeline.Workspace)/assets/win-x86
- input: pipelineArtifact
artifactName: 'win-x64'
targetPath: $(Pipeline.Workspace)/assets/win-x64
- input: pipelineArtifact
artifactName: 'win-arm64'
targetPath: $(Pipeline.Workspace)/assets/win-arm64
- input: pipelineArtifact
artifactName: 'osx-x64'
targetPath: $(Pipeline.Workspace)/assets/osx-x64
Expand Down Expand Up @@ -796,6 +816,10 @@ extends:
assets: |
$(Pipeline.Workspace)/assets/win-x86/*.exe
$(Pipeline.Workspace)/assets/win-x86/*.zip
$(Pipeline.Workspace)/assets/win-x64/*.exe
$(Pipeline.Workspace)/assets/win-x64/*.zip
$(Pipeline.Workspace)/assets/win-arm64/*.exe
$(Pipeline.Workspace)/assets/win-arm64/*.zip
$(Pipeline.Workspace)/assets/osx-x64/*.pkg
$(Pipeline.Workspace)/assets/osx-x64/*.tar.gz
$(Pipeline.Workspace)/assets/osx-arm64/*.pkg
Expand Down
22 changes: 16 additions & 6 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ jobs:
windows:
name: Windows
runs-on: windows-latest
strategy:
matrix:
runtime: [win-x86, win-x64, win-arm64]

steps:
- uses: actions/checkout@v6
Expand All @@ -27,24 +30,31 @@ jobs:
run: dotnet restore

- name: Build
run: dotnet build --configuration WindowsRelease
run: |
dotnet build src/windows/Installer.Windows/Installer.Windows.csproj `
--configuration=Release `
--runtime=${{ matrix.runtime }}

- name: Test
# GitHub's hosted runners are x64 so can test x64 and x86, but not arm64
if: matrix.runtime != 'win-arm64'
run: |
dotnet test --verbosity normal --configuration=WindowsRelease
dotnet test --verbosity normal `
--configuration=WindowsRelease `
--runtime=${{ matrix.runtime }}

- name: Prepare artifacts
shell: bash
run: |
mkdir -p artifacts/bin
mv out/windows/Installer.Windows/bin/Release/net472/win-x86 artifacts/bin/
cp out/windows/Installer.Windows/bin/Release/net472/win-x86.sym/* artifacts/bin/win-x86/
mv out/windows/Installer.Windows/bin/Release/net472/gcm*.exe artifacts/
mv out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }}/gcm*.exe artifacts/
mv out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }} artifacts/bin/
cp out/windows/Installer.Windows/bin/Release/net472/${{ matrix.runtime }}.sym/* artifacts/bin/${{ matrix.runtime }}/

- name: Upload artifacts
uses: actions/upload-artifact@v6
with:
name: win-x86
name: ${{ matrix.runtime }}
path: |
artifacts

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OSPlatform)'=='windows'">net472;net8.0</TargetFrameworks>
<RuntimeIdentifiers>win-x86;osx-x64;linux-x64;osx-arm64;linux-arm64;linux-arm</RuntimeIdentifiers>
<PlatformTarget Condition="'$(OSPlatform)'=='windows'">x86</PlatformTarget>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64;osx-x64;linux-x64;osx-arm64;linux-arm64;linux-arm</RuntimeIdentifiers>
<AssemblyName>git-credential-manager</AssemblyName>
<RootNamespace>GitCredentialManager</RootNamespace>
<ApplicationIcon>$(RepoAssetsPath)gcmicon.ico</ApplicationIcon>
Expand Down
18 changes: 13 additions & 5 deletions src/windows/Installer.Windows/Installer.Windows.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<Project>
<Project>
<!-- Implicit SDK props import -->
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />

<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultItems>false</EnableDefaultItems>
<PayloadPath>$(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\win-x86</PayloadPath>
<PayloadPath>$(PlatformOutPath)Installer.Windows\bin\$(Configuration)\net472\$(RuntimeIdentifier)</PayloadPath>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RuntimeIdentifier is not set when building without a specific RID/Architecture parameter, such as when building the solution from inside of an IDE, or with dotnet build -c WindowsDebug.

Installer.Windows net472 failed with 1 error(s) (1.4s)

D:\src\gcm\src\windows\Installer.Windows\Installer.Windows.csproj(43,5): error Layout script failed with exit code 1 and message Output: D:\src\gcm\out\windows\Installer.Windows\bin\Debug\net472;Unsupported RuntimeIdentifier:

The other 'Installer/Packacing' projects for macOS/Linux don't do much except shell out to a shell script that dynamically computes the current host's RID when it's not specified.

We can probably do some MSBuild fun with properties and discovering the current host's arch if RID has not been explicitly specified.

OR.. mimic the macOS/Linux implementations and create some layout.ps1 and pack.ps1 scripts; not relying on project-project dependencies to build the PayloadPath contents.

<InnoSetupVersion>6.3.1</InnoSetupVersion>
</PropertyGroup>

Expand All @@ -27,12 +27,20 @@

<Target Name="CoreCompile" Condition="'$(OSPlatform)'=='windows'">
<PropertyGroup>
<InnoSetupCommandSystem>"$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)"</InnoSetupCommandSystem>
<InnoSetupCommandUser>"$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)"</InnoSetupCommandUser>
<InnoSetupCommandSystem>"$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=system /DGcmRuntimeIdentifier="$(RuntimeIdentifier)" "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)"</InnoSetupCommandSystem>
<InnoSetupCommandUser>"$(NuGetPackageRoot)Tools.InnoSetup\$(InnoSetupVersion)\tools\ISCC.exe" /DPayloadDir="$(PayloadPath)" /DInstallTarget=user /DGcmRuntimeIdentifier="$(RuntimeIdentifier)" "$(RepoSrcPath)\windows\Installer.Windows\Setup.iss" /O"$(OutputPath)"</InnoSetupCommandUser>
</PropertyGroup>

<Message Text="Lay Out" Importance="High" />
<Exec Condition="'$(NoLayout)'!='true'" Command="powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -Command &quot;&amp; {&amp;'$(MSBuildProjectDirectory)\layout.ps1' -Configuration '$(Configuration)' -Output '$(PayloadPath)'}&quot;" />
<Exec Condition="'$(NoLayout)'!='true'"
ConsoleToMSBuild="true"
Command="powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -Command &quot;&amp; {&amp;'$(MSBuildProjectDirectory)\layout.ps1' -Configuration '$(Configuration)' -Output '$(PayloadPath)' -RuntimeIdentifier '$(RuntimeIdentifier)'; if ($?) { exit 0 } else { exit 1 }}&quot;"
IgnoreExitCode="true">
<!-- If we want to display the console output if the exit code is not 0, we need to capture it and then output it using the <Error /> below -->
<Output TaskParameter="ExitCode" PropertyName="ExitCodeOfExec" />
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
</Exec>
<Error Condition="'$(NoLayout)'!='true' AND '$(ExitCodeOfExec)' != '0'" Text="Layout script failed with exit code $(ExitCodeOfExec) and message $(OutputOfExec)" />
<Message Text="$(InnoSetupCommandSystem)" Importance="High" />
<Exec Command="$(InnoSetupCommandSystem)" />
<Message Text="$(InnoSetupCommandUser)" Importance="High" />
Expand Down
15 changes: 13 additions & 2 deletions src/windows/Installer.Windows/Setup.iss
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#error Installer target property 'InstallTarget' must be specifed
#endif

#ifndef GcmRuntimeIdentifier
#error GCM Runtime Identifier 'GcmRuntimeIdentifier' must be specifed (e.g. win-x64)
#endif

#if InstallTarget == "user"
#define GcmAppId "{{aa76d31d-432c-42ee-844c-bc0bc801cef3}}"
#define GcmLongName "Git Credential Manager (User)"
Expand All @@ -40,7 +44,6 @@
#define GcmRepoRoot "..\..\.."
#define GcmAssets GcmRepoRoot + "\assets"
#define GcmExe "git-credential-manager.exe"
#define GcmArch "x86"

#ifnexist PayloadDir + "\" + GcmExe
#error Payload files are missing
Expand All @@ -67,9 +70,17 @@ AppUpdatesURL={#GcmUrl}
AppContact={#GcmUrl}
AppCopyright={#GcmCopyright}
AppReadmeFile={#GcmReadme}
; Windows ARM64 supports installing and running x64 binaries, but not vice versa.
#if GcmRuntimeIdentifier=="win-x64"
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
#elif GcmRuntimeIdentifier=="win-arm64"
ArchitecturesAllowed=arm64
ArchitecturesInstallIn64BitMode=arm64
#endif
VersionInfoVersion={#GcmVersion}
LicenseFile={#GcmRepoRoot}\LICENSE
OutputBaseFilename={#GcmSetupExe}-win-{#GcmArch}-{#GcmVersionSimple}
OutputBaseFilename={#GcmSetupExe}-{#GcmRuntimeIdentifier}-{#GcmVersionSimple}
DefaultDirName={autopf}\{#GcmShortName}
Compression=lzma2
SolidCompression=yes
Expand Down
12 changes: 8 additions & 4 deletions src/windows/Installer.Windows/layout.ps1
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# Inputs
param ([Parameter(Mandatory)] $Configuration, [Parameter(Mandatory)] $Output, $SymbolOutput)
param ([Parameter(Mandatory)] $Configuration, [Parameter(Mandatory)] $Output, [Parameter(Mandatory)] $RuntimeIdentifier, $SymbolOutput)

Write-Output "Output: $Output"

if ($RuntimeIdentifier -ne 'win-x86' -and $RuntimeIdentifier -ne 'win-x64' -and $RuntimeIdentifier -ne 'win-arm64') {
Write-Host "Unsupported RuntimeIdentifier: $RuntimeIdentifier"
exit 1
}

# Directories
$THISDIR = $PSScriptRoot
$ROOT = (Get-Item $THISDIR).Parent.Parent.Parent.FullName
Expand Down Expand Up @@ -41,15 +46,14 @@ Write-Output "Publishing core application..."
dotnet publish "$GCM_SRC" `
--framework net472 `
--configuration "$Configuration" `
--runtime win-x86 `
--runtime $RuntimeIdentifier `
--output "$PAYLOAD"

# Delete libraries that are not needed for Windows but find their way
# into the publish output.
Remove-Item -Path "$PAYLOAD/*.dylib" -Force -ErrorAction Ignore

# Delete extraneous files that get included for other architectures
# We only care about x86 as the core GCM executable is only targeting x86
# Delete extraneous files that get included for other runtimes
Remove-Item -Path "$PAYLOAD/arm/" -Recurse -Force -ErrorAction Ignore
Remove-Item -Path "$PAYLOAD/arm64/" -Recurse -Force -ErrorAction Ignore
Remove-Item -Path "$PAYLOAD/x64/" -Recurse -Force -ErrorAction Ignore
Expand Down