Allow triggering after release workflow manually (#44671)

Conrad Irwin created

Release Notes:

- N/A

Change summary

.github/workflows/after_release.yml                | 25 ++++-
tooling/xtask/src/tasks/workflows/after_release.rs | 74 +++++++++------
2 files changed, 65 insertions(+), 34 deletions(-)

Detailed changes

.github/workflows/after_release.yml 🔗

@@ -5,13 +5,27 @@ on:
   release:
     types:
     - published
+  workflow_dispatch:
+    inputs:
+      tag_name:
+        description: tag_name
+        required: true
+        type: string
+      prerelease:
+        description: prerelease
+        required: true
+        type: boolean
+      body:
+        description: body
+        type: string
+        default: ''
 jobs:
   rebuild_releases_page:
     if: (github.repository_owner == 'zed-industries' || github.repository_owner == 'zed-extensions')
     runs-on: namespace-profile-2x4-ubuntu-2404
     steps:
     - name: after_release::rebuild_releases_page::refresh_cloud_releases
-      run: curl -fX POST https://cloud.zed.dev/releases/refresh?expect_tag=${{ github.event.release.tag_name }}
+      run: curl -fX POST https://cloud.zed.dev/releases/refresh?expect_tag=${{ github.event.release.tag_name || inputs.tag_name }}
       shell: bash -euxo pipefail {0}
     - name: after_release::rebuild_releases_page::redeploy_zed_dev
       run: npm exec --yes -- vercel@37 --token="$VERCEL_TOKEN" --scope zed-industries redeploy https://zed.dev
@@ -27,7 +41,7 @@ jobs:
     - id: get-release-url
       name: after_release::post_to_discord::get_release_url
       run: |
-        if [ "${{ github.event.release.prerelease }}" == "true" ]; then
+        if [ "${{ github.event.release.prerelease || inputs.prerelease }}" == "true" ]; then
             URL="https://zed.dev/releases/preview"
         else
             URL="https://zed.dev/releases/stable"
@@ -40,9 +54,9 @@ jobs:
       uses: 2428392/gh-truncate-string-action@b3ff790d21cf42af3ca7579146eedb93c8fb0757
       with:
         stringToTruncate: |
-          📣 Zed [${{ github.event.release.tag_name }}](<${{ steps.get-release-url.outputs.URL }}>) was just released!
+          📣 Zed [${{ github.event.release.tag_name || inputs.tag_name }}](<${{ steps.get-release-url.outputs.URL }}>)  was just released!
 
-          ${{ github.event.release.body }}
+          ${{ github.event.release.body || inputs.body }}
         maxLength: 2000
         truncationSymbol: '...'
     - name: after_release::post_to_discord::discord_webhook_action
@@ -56,7 +70,7 @@ jobs:
     - id: set-package-name
       name: after_release::publish_winget::set_package_name
       run: |
-        if ("${{ github.event.release.prerelease }}" -eq "true") {
+        if ("${{ github.event.release.prerelease || inputs.prerelease }}" -eq "true") {
             $PACKAGE_NAME = "ZedIndustries.Zed.Preview"
         } else {
             $PACKAGE_NAME = "ZedIndustries.Zed"
@@ -68,6 +82,7 @@ jobs:
       uses: vedantmgoyal9/winget-releaser@19e706d4c9121098010096f9c495a70a7518b30f
       with:
         identifier: ${{ steps.set-package-name.outputs.PACKAGE_NAME }}
+        release-tag: ${{ github.event.release.tag_name || inputs.tag_name }}
         max-versions-to-keep: 5
         token: ${{ secrets.WINGET_TOKEN }}
   create_sentry_release:

tooling/xtask/src/tasks/workflows/after_release.rs 🔗

@@ -4,10 +4,18 @@ use crate::tasks::workflows::{
     release::{self, notify_on_failure},
     runners,
     steps::{CommonJobConditions, NamedJob, checkout_repo, dependant_job, named},
-    vars::{self, StepOutput},
+    vars::{self, StepOutput, WorkflowInput},
 };
 
+const TAG_NAME: &str = "${{ github.event.release.tag_name || inputs.tag_name }}";
+const IS_PRERELEASE: &str = "${{ github.event.release.prerelease || inputs.prerelease }}";
+const RELEASE_BODY: &str = "${{ github.event.release.body || inputs.body }}";
+
 pub fn after_release() -> Workflow {
+    let tag_name = WorkflowInput::string("tag_name", None);
+    let prerelease = WorkflowInput::bool("prerelease", None);
+    let body = WorkflowInput::string("body", Some(String::new()));
+
     let refresh_zed_dev = rebuild_releases_page();
     let post_to_discord = post_to_discord(&[&refresh_zed_dev]);
     let publish_winget = publish_winget();
@@ -20,7 +28,14 @@ pub fn after_release() -> Workflow {
     ]);
 
     named::workflow()
-        .on(Event::default().release(Release::default().types(vec![ReleaseType::Published])))
+        .on(Event::default()
+            .release(Release::default().types(vec![ReleaseType::Published]))
+            .workflow_dispatch(
+                WorkflowDispatch::default()
+                    .add_input(tag_name.name, tag_name.input())
+                    .add_input(prerelease.name, prerelease.input())
+                    .add_input(body.name, body.input()),
+            ))
         .add_job(refresh_zed_dev.name, refresh_zed_dev.job)
         .add_job(post_to_discord.name, post_to_discord.job)
         .add_job(publish_winget.name, publish_winget.job)
@@ -30,9 +45,9 @@ pub fn after_release() -> Workflow {
 
 fn rebuild_releases_page() -> NamedJob {
     fn refresh_cloud_releases() -> Step<Run> {
-        named::bash(
-            "curl -fX POST https://cloud.zed.dev/releases/refresh?expect_tag=${{ github.event.release.tag_name }}",
-        )
+        named::bash(format!(
+            "curl -fX POST https://cloud.zed.dev/releases/refresh?expect_tag={TAG_NAME}"
+        ))
     }
 
     fn redeploy_zed_dev() -> Step<Run> {
@@ -51,15 +66,16 @@ fn rebuild_releases_page() -> NamedJob {
 
 fn post_to_discord(deps: &[&NamedJob]) -> NamedJob {
     fn get_release_url() -> Step<Run> {
-        named::bash(indoc::indoc! {r#"
-            if [ "${{ github.event.release.prerelease }}" == "true" ]; then
-                URL="https://zed.dev/releases/preview"
-            else
-                URL="https://zed.dev/releases/stable"
-            fi
-
-            echo "URL=$URL" >> "$GITHUB_OUTPUT"
-        "#})
+        named::bash(format!(
+            r#"if [ "{IS_PRERELEASE}" == "true" ]; then
+    URL="https://zed.dev/releases/preview"
+else
+    URL="https://zed.dev/releases/stable"
+fi
+
+echo "URL=$URL" >> "$GITHUB_OUTPUT"
+"#
+        ))
         .id("get-release-url")
     }
 
@@ -72,11 +88,9 @@ fn post_to_discord(deps: &[&NamedJob]) -> NamedJob {
         .id("get-content")
         .add_with((
             "stringToTruncate",
-            indoc::indoc! {r#"
-                📣 Zed [${{ github.event.release.tag_name }}](<${{ steps.get-release-url.outputs.URL }}>) was just released!
-
-                ${{ github.event.release.body }}
-            "#},
+            format!(
+                "📣 Zed [{TAG_NAME}](<${{{{ steps.get-release-url.outputs.URL }}}}>)  was just released!\n\n{RELEASE_BODY}\n"
+            ),
         ))
         .add_with(("maxLength", 2000))
         .add_with(("truncationSymbol", "..."))
@@ -102,16 +116,17 @@ fn post_to_discord(deps: &[&NamedJob]) -> NamedJob {
 
 fn publish_winget() -> NamedJob {
     fn set_package_name() -> (Step<Run>, StepOutput) {
-        let step = named::pwsh(indoc::indoc! {r#"
-            if ("${{ github.event.release.prerelease }}" -eq "true") {
-                $PACKAGE_NAME = "ZedIndustries.Zed.Preview"
-            } else {
-                $PACKAGE_NAME = "ZedIndustries.Zed"
-            }
-
-            echo "PACKAGE_NAME=$PACKAGE_NAME" >> $env:GITHUB_OUTPUT
-        "#})
-        .id("set-package-name");
+        let script = format!(
+            r#"if ("{IS_PRERELEASE}" -eq "true") {{
+    $PACKAGE_NAME = "ZedIndustries.Zed.Preview"
+}} else {{
+    $PACKAGE_NAME = "ZedIndustries.Zed"
+}}
+
+echo "PACKAGE_NAME=$PACKAGE_NAME" >> $env:GITHUB_OUTPUT
+"#
+        );
+        let step = named::pwsh(&script).id("set-package-name");
 
         let output = StepOutput::new(&step, "PACKAGE_NAME");
         (step, output)
@@ -124,6 +139,7 @@ fn publish_winget() -> NamedJob {
             "19e706d4c9121098010096f9c495a70a7518b30f", // v2
         )
         .add_with(("identifier", package_name.to_string()))
+        .add_with(("release-tag", TAG_NAME))
         .add_with(("max-versions-to-keep", 5))
         .add_with(("token", vars::WINGET_TOKEN))
     }