diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 3298ed9ec6d83..ca85ddf794695 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -1603,6 +1603,14 @@ function runCleanSignTempDirectory() { let signCount = 0; +/** + * @param {string} value + */ +function assertMsbuildXmlValue(value) { + assert(value.length > 0 && !/[^\w./\\: -]/.test(value), `Unsupported MSBuild XML value: ${JSON.stringify(value)}`); + return value; +} + /** * @typedef {{ * SignFileRecordList: { @@ -1615,11 +1623,10 @@ let signCount = 0; * @param {DDSignFileList} filelist */ async function sign(filelist, unchangedOutputOkay = false) { - let data = JSON.stringify(filelist, undefined, 4); - console.log("filelist:", data); + console.log("filelist:", JSON.stringify(filelist, undefined, 4)); - if (!process.env.MBSIGN_APPFOLDER) { - console.log(styleText("yellow", "Faking signing because MBSIGN_APPFOLDER is not set.")); + if (!process.env.MICROBUILD_PLUGIN_DIRECTORY) { + console.log(styleText("yellow", "Faking signing because MICROBUILD_PLUGIN_DIRECTORY is not set.")); // Fake signing for testing. @@ -1659,6 +1666,7 @@ async function sign(filelist, unchangedOutputOkay = false) { } const signingWorkaround = true; + let signingFilelist = filelist; /** @type {{ source: string; target: string }[]} */ const signingWorkaroundFiles = []; @@ -1699,8 +1707,8 @@ async function sign(filelist, unchangedOutputOkay = false) { }), }; - data = JSON.stringify(newFileList, undefined, 4); - console.log("new filelist:", data); + signingFilelist = newFileList; + console.log("new filelist:", JSON.stringify(signingFilelist, undefined, 4)); } /** @type {Map} */ @@ -1724,16 +1732,41 @@ async function sign(filelist, unchangedOutputOkay = false) { } const tmp = await getSignTempDir(); - const filelistPath = path.resolve(tmp, `signing-filelist-${signCount++}.json`); - await fs.promises.writeFile(filelistPath, data); + const propsPath = path.resolve(tmp, `signing-items-${signCount++}.props`); + const signingItems = signingFilelist.SignFileRecordList.flatMap(record => record.SignFileList.map(file => ({ path: file.SrcPath, cert: record.Certs, macAppName: record.MacAppName }))); + const items = signingItems.map(({ path: filePath, cert, macAppName }) => + ` + ${assertMsbuildXmlValue(cert)} + None${ + macAppName ? ` + ${assertMsbuildXmlValue(macAppName)}` : "" + } + ` + ).join("\n"); + await fs.promises.writeFile( + propsPath, + ` + +${items} + + +`, + ); try { - const dll = path.join(process.env.MBSIGN_APPFOLDER, "DDSignFiles.dll"); - const filelistFlag = `/filelist:${filelistPath}`; - await run("dotnet", [dll, "--", filelistFlag]); + await run("dotnet", [ + "build", + path.resolve("tools/signing/Sign.csproj"), + "--target:AfterBuild", + "--verbosity:normal", + "-p:SignType=real", + `-p:SignFilesDir=${path.resolve("built")}`, + `-p:FilesToSignPropsFile=${propsPath}`, + `-p:MicroBuildOverridePluginDirectory=${process.env.MICROBUILD_PLUGIN_DIRECTORY}`, + ]); } finally { - await fs.promises.unlink(filelistPath); + await fs.promises.unlink(propsPath); } if (signingWorkaround) { @@ -2798,7 +2831,7 @@ async function runSignVsixExtensions() { ], }); - if (!process.env.MBSIGN_APPFOLDER) { + if (!process.env.MICROBUILD_PLUGIN_DIRECTORY) { console.log("Skipping VSIX signature verification because signing was faked."); return; } diff --git a/tools/pipelines/typescript-build.yml b/tools/pipelines/typescript-build.yml index 84dc67d9af0ae..e46e306268e77 100755 --- a/tools/pipelines/typescript-build.yml +++ b/tools/pipelines/typescript-build.yml @@ -54,8 +54,24 @@ extends: - job: Build displayName: Build and Sign timeoutInMinutes: 180 + pool: + name: AzurePipelines-EO + image: 1ESPT-Ubuntu22.04 + os: linux templateContext: + mb: + signing: + enabled: true + signWithProd: true + signType: real + zipSources: false + mbpresteps: + # Needed for ESRP. https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/46279/Real-signing-with-PME-Enforcement + - task: UseDotNet@2 + displayName: Use .NET Core sdk 8.0.x + inputs: + version: 8.0.x outputs: - output: pipelineArtifact targetPath: $(Build.ArtifactStagingDirectory)/npm @@ -69,41 +85,6 @@ extends: displayName: 'Set build tag "Build.Reason.Schedule"' condition: eq(variables['Build.Reason'], 'Schedule') - # This is copied from https://dev.azure.com/devdiv/1ESPipelineTemplates/_git/MicroBuildTemplate?path=/azure-pipelines/Jobs/Job.yml - # With the difference that we install .NET Core becuase DDSignFiles needs it. - - task: NuGetAuthenticate@1 - displayName: '🔩 NuGet Authenticate' - - task: UsePythonVersion@0 - displayName: 'Use Python 3.11' - inputs: - versionSpec: 3.11 - # This is old, but DDSignFiles is built with it. - # Copying https://github.com/microsoft/vscode-gradle/blob/2f60b4483ef15aa9b196e008939610cdeab60029/.azure-pipelines/vscode-gradle-nightly.yml#L50 - - task: UseDotNet@2 - displayName: 'Use .NET Core 3.1.x' - inputs: - packageType: 'sdk' - version: '3.1.x' - # Needed for ESRP. https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/46279/Real-signing-with-PME-Enforcement - - task: UseDotNet@2 - displayName: Use .NET Core sdk 8.0.x - inputs: - version: 8.0.x - # https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/12267/ESRP-Signing-in-Mac-or-Linux-Pipelines - # TODO: switch to the template's signing, now that DDSignFiles should work. - - task: MicroBuildSigningPlugin@4 - displayName: '🔩 Install Signing Plugin' - inputs: - signType: real - # azureSubscription AKA ConnectedServiceName - azureSubscription: 'MicroBuild Signing Task (DevDiv)' - # From "nonwindowspmeservicename" in https://dev.azure.com/devdiv/1ESPipelineTemplates/_git/MicroBuildTemplate?path=/azure-pipelines/Stages/Stage.yml - ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39 - # We do this ourselves. - zipSources: false - env: - MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' - - checkout: self clean: true submodules: false @@ -164,6 +145,7 @@ extends: - bash: npx hereby typescript:sign --forRelease --setPrerelease dev.$(initialBuildNumber) displayName: 'Sign packages' env: + MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins # Needed for ESRP SYSTEM_ACCESSTOKEN: $(System.AccessToken) @@ -176,6 +158,7 @@ extends: - bash: npx hereby vscode-typescript:sign --forRelease --setPrerelease dev.$(initialBuildNumber) displayName: 'Sign extensions' env: + MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins # Needed for ESRP SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/tools/pipelines/vscode-typescript-build.yml b/tools/pipelines/vscode-typescript-build.yml index a8eb641f4f982..76d48508e4f68 100644 --- a/tools/pipelines/vscode-typescript-build.yml +++ b/tools/pipelines/vscode-typescript-build.yml @@ -44,8 +44,23 @@ extends: - job: Build displayName: Build and sign vscode-typescript timeoutInMinutes: 90 + pool: + name: AzurePipelines-EO + image: 1ESPT-Ubuntu22.04 + os: linux templateContext: + mb: + signing: + enabled: true + signWithProd: true + signType: real + zipSources: false + mbpresteps: + - task: UseDotNet@2 + displayName: Use .NET Core SDK 8.0.x + inputs: + version: 8.0.x outputs: - output: pipelineArtifact targetPath: $(Build.ArtifactStagingDirectory)/vsix @@ -95,31 +110,6 @@ extends: echo "##vso[build.updatebuildnumber]vscode-typescript-$packageVersion" displayName: Validate release tag - - task: NuGetAuthenticate@1 - displayName: '🔩 NuGet Authenticate' - - task: UsePythonVersion@0 - displayName: Use Python 3.11 - inputs: - versionSpec: 3.11 - - task: UseDotNet@2 - displayName: Use .NET Core 3.1.x - inputs: - packageType: sdk - version: 3.1.x - - task: UseDotNet@2 - displayName: Use .NET Core SDK 8.0.x - inputs: - version: 8.0.x - - task: MicroBuildSigningPlugin@4 - displayName: '🔩 Install Signing Plugin' - inputs: - signType: real - azureSubscription: MicroBuild Signing Task (DevDiv) - ConnectedPMEServiceName: beb8cb23-b303-4c95-ab26-9e44bc958d39 - zipSources: false - env: - MicroBuildOutputFolderOverride: $(Agent.TempDirectory) - - template: /tools/pipelines/steps/setup-node-npm-ci.yml@self - bash: npm test -w native-preview @@ -128,6 +118,7 @@ extends: - bash: npx hereby vscode-typescript:release --forRelease --vscodeTypescriptRelease displayName: Build and sign extensions env: + MICROBUILD_PLUGIN_DIRECTORY: $(Agent.TempDirectory)/MicroBuild/Plugins SYSTEM_ACCESSTOKEN: $(System.AccessToken) VSCODE_TYPESCRIPT_SIGN_TYPE: real diff --git a/tools/signing/NuGet.config b/tools/signing/NuGet.config new file mode 100644 index 0000000000000..fe93ac64ee1d6 --- /dev/null +++ b/tools/signing/NuGet.config @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tools/signing/Sign.csproj b/tools/signing/Sign.csproj new file mode 100644 index 0000000000000..741da3975efd9 --- /dev/null +++ b/tools/signing/Sign.csproj @@ -0,0 +1,24 @@ + + + net8.0 + false + + + + + + + + + + + + + $([MSBuild]::NormalizeDirectory('$(SignFilesDir)')) + + + + + + +