Repository: denoland/deno
Pull request: ci: fix 'promote_to_rc' workflow by adding codesigning

Just a simple typo :)

Changed files:
filename: .github/workflows/promote_to_rc.yml
patch: @@ -4,13 +4,13 @@ on:
   workflow_dispatch:
     inputs:
       commitHash:
-        description: 'Commit to promote to the Release Candidate'
+        description: Commit to promote to the Release Candidate
         required: true
 
 jobs:
   promote-to-rc:
     name: Promote to Release Candidate
-    runs-on: ubuntu-latest
+    runs-on: macOS-latest
     if: github.repository == 'denoland/deno'
     steps:
       - name: Clone repository
@@ -37,11 +37,19 @@ jobs:
         with:
           deno-version: v1.x
 
+      - name: Install rust-codesign
+        run: |-
+          ./tools/install_prebuilt.js rcodesign
+          echo $GITHUB_WORKSPACE/third_party/prebuilt/mac >> $GITHUB_PATH
+
       - name: Promote to RC
+        env:
+          APPLE_CODESIGN_KEY: '${{ secrets.APPLE_CODESIGN_KEY }}'
+          APPLE_CODESIGN_PASSWORD: '${{ secrets.APPLE_CODESIGN_PASSWORD }}'
         run: |
-          deno run -A ./tools/release/promote_to_rc.ts ${{github.event.inputs.releaseKind}}
+          deno run -A ./tools/release/promote_to_rc.ts ${{github.event.inputs.commitHash}}
 
       - name: Upload archives to dl.deno.land
         run: |
-          gsutil -h "Cache-Control: public, max-age=3600" cp ./*.zip gs://dl.deno.land/release/$(echo release-rc-latest.txt)/
+          gsutil -h "Cache-Control: public, max-age=3600" cp ./*.zip gs://dl.deno.land/release/$(cat release-rc-latest.txt)/
           gsutil -h "Cache-Control: no-cache" cp release-rc-latest.txt gs://dl.deno.land/release-rc-latest.txt

filename: tools/release/promote_to_rc.ts
patch: @@ -120,7 +120,42 @@ async function runPatchver(
   }
 }
 
-async function promoteBinaryToRc(binary: string, target: string) {
+async function runRcodesign(
+  target: string,
+  rcBinaryName: string,
+  commitHash: string,
+) {
+  if (!target.includes("apple") || rcBinaryName.includes("denort")) {
+    return;
+  }
+  $.logStep(`Codesign ${rcBinaryName}`);
+  const tempFile = $.path("temp.p12");
+  let output;
+  try {
+    await $`echo $APPLE_CODESIGN_KEY | base64 -d`.stdout(tempFile);
+    output =
+      await $`rcodesign sign ./${rcBinaryName} --binary-identifier=deno-${commitHash} --code-signature-flags=runtime --code-signature-flags=runtime --p12-password="$APPLE_CODESIGN_PASSWORD" --p12-file=${tempFile} --entitlements-xml-file=cli/entitlements.plist`;
+  } finally {
+    try {
+      tempFile.removeSync();
+    } catch {
+      // pass
+    }
+  }
+  if (output.code !== 0) {
+    $.logError(
+      `Failed to codesign ${rcBinaryName} (error code ${output.code})`,
+    );
+    Deno.exit(1);
+  }
+  await $`codesign -dv --verbose=4 ./deno`;
+}
+
+async function promoteBinaryToRc(
+  binary: string,
+  target: string,
+  commitHash: string,
+) {
   const unzippedName = getUnzippedFilename(binary, target);
   const rcBinaryName = getRcBinaryName(binary, target);
   const archiveName = getArchiveName(binary, target);
@@ -149,6 +184,7 @@ async function promoteBinaryToRc(binary: string, target: string) {
   // Remove the unpatched binary and rename patched one.
   await remove(unzippedName);
   await Deno.rename(rcBinaryName, unzippedName);
+  await runRcodesign(target, unzippedName, commitHash);
   // Set executable permission
   if (!target.includes("windows")) {
     Deno.chmod(unzippedName, 0o777);
@@ -158,7 +194,7 @@ async function promoteBinaryToRc(binary: string, target: string) {
   await remove(unzippedName);
 }
 
-async function promoteBinariesToRc() {
+async function promoteBinariesToRc(commitHash: string) {
   const totalCanaries = SUPPORTED_TARGETS.length * DENO_BINARIES.length;
 
   for (let targetIdx = 0; targetIdx < SUPPORTED_TARGETS.length; targetIdx++) {
@@ -173,7 +209,7 @@ async function promoteBinariesToRc() {
         target,
         "to RC...",
       );
-      await promoteBinaryToRc(binaryName, target);
+      await promoteBinaryToRc(binaryName, target, commitHash);
       $.logLight(
         `[${currentIdx}/${totalCanaries}]`,
         "Promoted",
@@ -191,7 +227,7 @@ async function dumpRcVersion() {
   const output = await $`./deno -V`.stdout("piped");
   const denoVersion = output.stdout.slice(5).split("+")[0];
   $.logStep("Computed version", denoVersion);
-  await Deno.writeTextFile("./release-rc-latest.txt", denoVersion);
+  await Deno.writeTextFile("./release-rc-latest.txt", `v${denoVersion}`);
 }
 
 async function main() {
@@ -203,7 +239,7 @@ async function main() {
   await fetchLatestCanaryBinaries(commitHash);
   console.log("All canary binaries ready");
   $.logStep("Promote canary binaries to RC...");
-  await promoteBinariesToRc();
+  await promoteBinariesToRc(commitHash);
 
   // Finally dump the version name to a `release.txt` file for uploading to GCP
   await dumpRcVersion();