Skip to content

Commit 5f5dee5

Browse files
authored
Switch signing command to msbuild (#64555)
1 parent 64c5fa0 commit 5f5dee5

5 files changed

Lines changed: 111 additions & 73 deletions

File tree

‎Herebyfile.mjs‎

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1603,6 +1603,14 @@ function runCleanSignTempDirectory() {
16031603

16041604
let signCount = 0;
16051605

1606+
/**
1607+
* @param {string} value
1608+
*/
1609+
function assertMsbuildXmlValue(value) {
1610+
assert(value.length > 0 && !/[^\w./\\: -]/.test(value), `Unsupported MSBuild XML value: ${JSON.stringify(value)}`);
1611+
return value;
1612+
}
1613+
16061614
/**
16071615
* @typedef {{
16081616
* SignFileRecordList: {
@@ -1615,11 +1623,10 @@ let signCount = 0;
16151623
* @param {DDSignFileList} filelist
16161624
*/
16171625
async function sign(filelist, unchangedOutputOkay = false) {
1618-
let data = JSON.stringify(filelist, undefined, 4);
1619-
console.log("filelist:", data);
1626+
console.log("filelist:", JSON.stringify(filelist, undefined, 4));
16201627

1621-
if (!process.env.MBSIGN_APPFOLDER) {
1622-
console.log(styleText("yellow", "Faking signing because MBSIGN_APPFOLDER is not set."));
1628+
if (!process.env.MICROBUILD_PLUGIN_DIRECTORY) {
1629+
console.log(styleText("yellow", "Faking signing because MICROBUILD_PLUGIN_DIRECTORY is not set."));
16231630

16241631
// Fake signing for testing.
16251632

@@ -1659,6 +1666,7 @@ async function sign(filelist, unchangedOutputOkay = false) {
16591666
}
16601667

16611668
const signingWorkaround = true;
1669+
let signingFilelist = filelist;
16621670

16631671
/** @type {{ source: string; target: string }[]} */
16641672
const signingWorkaroundFiles = [];
@@ -1699,8 +1707,8 @@ async function sign(filelist, unchangedOutputOkay = false) {
16991707
}),
17001708
};
17011709

1702-
data = JSON.stringify(newFileList, undefined, 4);
1703-
console.log("new filelist:", data);
1710+
signingFilelist = newFileList;
1711+
console.log("new filelist:", JSON.stringify(signingFilelist, undefined, 4));
17041712
}
17051713

17061714
/** @type {Map<string, string>} */
@@ -1724,16 +1732,41 @@ async function sign(filelist, unchangedOutputOkay = false) {
17241732
}
17251733

17261734
const tmp = await getSignTempDir();
1727-
const filelistPath = path.resolve(tmp, `signing-filelist-${signCount++}.json`);
1728-
await fs.promises.writeFile(filelistPath, data);
1735+
const propsPath = path.resolve(tmp, `signing-items-${signCount++}.props`);
1736+
const signingItems = signingFilelist.SignFileRecordList.flatMap(record => record.SignFileList.map(file => ({ path: file.SrcPath, cert: record.Certs, macAppName: record.MacAppName })));
1737+
const items = signingItems.map(({ path: filePath, cert, macAppName }) =>
1738+
` <FilesToSign Include="${assertMsbuildXmlValue(filePath)}">
1739+
<Authenticode>${assertMsbuildXmlValue(cert)}</Authenticode>
1740+
<StrongName>None</StrongName>${
1741+
macAppName ? `
1742+
<MacAppName>${assertMsbuildXmlValue(macAppName)}</MacAppName>` : ""
1743+
}
1744+
</FilesToSign>`
1745+
).join("\n");
1746+
await fs.promises.writeFile(
1747+
propsPath,
1748+
`<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
1749+
<ItemGroup>
1750+
${items}
1751+
</ItemGroup>
1752+
</Project>
1753+
`,
1754+
);
17291755

17301756
try {
1731-
const dll = path.join(process.env.MBSIGN_APPFOLDER, "DDSignFiles.dll");
1732-
const filelistFlag = `/filelist:${filelistPath}`;
1733-
await run("dotnet", [dll, "--", filelistFlag]);
1757+
await run("dotnet", [
1758+
"build",
1759+
path.resolve("tools/signing/Sign.csproj"),
1760+
"--target:AfterBuild",
1761+
"--verbosity:normal",
1762+
"-p:SignType=real",
1763+
`-p:SignFilesDir=${path.resolve("built")}`,
1764+
`-p:FilesToSignPropsFile=${propsPath}`,
1765+
`-p:MicroBuildOverridePluginDirectory=${process.env.MICROBUILD_PLUGIN_DIRECTORY}`,
1766+
]);
17341767
}
17351768
finally {
1736-
await fs.promises.unlink(filelistPath);
1769+
await fs.promises.unlink(propsPath);
17371770
}
17381771

17391772
if (signingWorkaround) {
@@ -2798,7 +2831,7 @@ async function runSignVsixExtensions() {
27982831
],
27992832
});
28002833

2801-
if (!process.env.MBSIGN_APPFOLDER) {
2834+
if (!process.env.MICROBUILD_PLUGIN_DIRECTORY) {
28022835
console.log("Skipping VSIX signature verification because signing was faked.");
28032836
return;
28042837
}

‎tools/pipelines/typescript-build.yml‎

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,24 @@ extends:
5454
- job: Build
5555
displayName: Build and Sign
5656
timeoutInMinutes: 180
57+
pool:
58+
name: AzurePipelines-EO
59+
image: 1ESPT-Ubuntu22.04
60+
os: linux
5761

5862
templateContext:
63+
mb:
64+
signing:
65+
enabled: true
66+
signWithProd: true
67+
signType: real
68+
zipSources: false
69+
mbpresteps:
70+
# Needed for ESRP. https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/46279/Real-signing-with-PME-Enforcement
71+
- task: UseDotNet@2
72+
displayName: Use .NET Core sdk 8.0.x
73+
inputs:
74+
version: 8.0.x
5975
outputs:
6076
- output: pipelineArtifact
6177
targetPath: $(Build.ArtifactStagingDirectory)/npm
@@ -69,41 +85,6 @@ extends:
6985
displayName: 'Set build tag "Build.Reason.Schedule"'
7086
condition: eq(variables['Build.Reason'], 'Schedule')
7187

72-
# This is copied from https://dev.azure.com/devdiv/1ESPipelineTemplates/_git/MicroBuildTemplate?path=/azure-pipelines/Jobs/Job.yml
73-
# With the difference that we install .NET Core becuase DDSignFiles needs it.
74-
- task: NuGetAuthenticate@1
75-
displayName: '🔩 NuGet Authenticate'
76-
- task: UsePythonVersion@0
77-
displayName: 'Use Python 3.11'
78-
inputs:
79-
versionSpec: 3.11
80-
# This is old, but DDSignFiles is built with it.
81-
# Copying https://github.com/microsoft/vscode-gradle/blob/2f60b4483ef15aa9b196e008939610cdeab60029/.azure-pipelines/vscode-gradle-nightly.yml#L50
82-
- task: UseDotNet@2
83-
displayName: 'Use .NET Core 3.1.x'
84-
inputs:
85-
packageType: 'sdk'
86-
version: '3.1.x'
87-
# Needed for ESRP. https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/46279/Real-signing-with-PME-Enforcement
88-
- task: UseDotNet@2
89-
displayName: Use .NET Core sdk 8.0.x
90-
inputs:
91-
version: 8.0.x
92-
# https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/12267/ESRP-Signing-in-Mac-or-Linux-Pipelines
93-
# TODO: switch to the template's signing, now that DDSignFiles should work.
94-
- task: MicroBuildSigningPlugin@4
95-
displayName: '🔩 Install Signing Plugin'
96-
inputs:
97-
signType: real
98-
# azureSubscription AKA ConnectedServiceName
99-
azureSubscription: 'MicroBuild Signing Task (DevDiv)'
100-
# From "nonwindowspmeservicename" in https://dev.azure.com/devdiv/1ESPipelineTemplates/_git/MicroBuildTemplate?path=/azure-pipelines/Stages/Stage.yml
101-
ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39
102-
# We do this ourselves.
103-
zipSources: false
104-
env:
105-
MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)'
106-
10788
- checkout: self
10889
clean: true
10990
submodules: false
@@ -164,6 +145,7 @@ extends:
164145
- bash: npx hereby typescript:sign --forRelease --setPrerelease dev.$(initialBuildNumber)
165146
displayName: 'Sign packages'
166147
env:
148+
MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins
167149
# Needed for ESRP
168150
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
169151

@@ -176,6 +158,7 @@ extends:
176158
- bash: npx hereby vscode-typescript:sign --forRelease --setPrerelease dev.$(initialBuildNumber)
177159
displayName: 'Sign extensions'
178160
env:
161+
MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins
179162
# Needed for ESRP
180163
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
181164

‎tools/pipelines/vscode-typescript-build.yml‎

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,23 @@ extends:
4444
- job: Build
4545
displayName: Build and sign vscode-typescript
4646
timeoutInMinutes: 90
47+
pool:
48+
name: AzurePipelines-EO
49+
image: 1ESPT-Ubuntu22.04
50+
os: linux
4751

4852
templateContext:
53+
mb:
54+
signing:
55+
enabled: true
56+
signWithProd: true
57+
signType: real
58+
zipSources: false
59+
mbpresteps:
60+
- task: UseDotNet@2
61+
displayName: Use .NET Core SDK 8.0.x
62+
inputs:
63+
version: 8.0.x
4964
outputs:
5065
- output: pipelineArtifact
5166
targetPath: $(Build.ArtifactStagingDirectory)/vsix
@@ -95,31 +110,6 @@ extends:
95110
echo "##vso[build.updatebuildnumber]vscode-typescript-$packageVersion"
96111
displayName: Validate release tag
97112
98-
- task: NuGetAuthenticate@1
99-
displayName: '🔩 NuGet Authenticate'
100-
- task: UsePythonVersion@0
101-
displayName: Use Python 3.11
102-
inputs:
103-
versionSpec: 3.11
104-
- task: UseDotNet@2
105-
displayName: Use .NET Core 3.1.x
106-
inputs:
107-
packageType: sdk
108-
version: 3.1.x
109-
- task: UseDotNet@2
110-
displayName: Use .NET Core SDK 8.0.x
111-
inputs:
112-
version: 8.0.x
113-
- task: MicroBuildSigningPlugin@4
114-
displayName: '🔩 Install Signing Plugin'
115-
inputs:
116-
signType: real
117-
azureSubscription: MicroBuild Signing Task (DevDiv)
118-
ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39
119-
zipSources: false
120-
env:
121-
MicroBuildOutputFolderOverride: $(Agent.TempDirectory)
122-
123113
- template: /tools/pipelines/steps/setup-node-npm-ci.yml@self
124114

125115
- bash: npm test -w native-preview
@@ -128,6 +118,7 @@ extends:
128118
- bash: npx hereby vscode-typescript:release --forRelease --vscodeTypescriptRelease
129119
displayName: Build and sign extensions
130120
env:
121+
MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins
131122
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
132123
VSCODE_TYPESCRIPT_SIGN_TYPE: real
133124

‎tools/signing/NuGet.config‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<configuration>
3+
<packageSources>
4+
<clear />
5+
<add key="MicroBuildToolset" value="https://pkgs.dev.azure.com/devdiv/_packaging/MicroBuildToolset/nuget/v3/index.json" />
6+
</packageSources>
7+
</configuration>

‎tools/signing/Sign.csproj‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<IsPackable>false</IsPackable>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.VisualStudioEng.MicroBuild.Core" Version="1.0.0" />
9+
</ItemGroup>
10+
11+
<Import Project="$(FilesToSignPropsFile)" Condition="'$(FilesToSignPropsFile)' != ''" />
12+
13+
<Target Name="PrepSign" BeforeTargets="AfterBuild">
14+
<Error Condition="'$(FilesToSignPropsFile)' == '' or !Exists('$(FilesToSignPropsFile)')" Text="FilesToSignPropsFile is missing." />
15+
<Error Condition="'$(SignFilesDir)' == ''" Text="SignFilesDir is missing." />
16+
<PropertyGroup>
17+
<OutDir>$([MSBuild]::NormalizeDirectory('$(SignFilesDir)'))</OutDir>
18+
</PropertyGroup>
19+
</Target>
20+
21+
<Target Name="SignFiles" BeforeTargets="PrepSign">
22+
<Error Text="MicroBuild signing targets were not imported." />
23+
</Target>
24+
</Project>

0 commit comments

Comments
 (0)