From bfa35ac64721e6e2a23dd7f7560a0160b5befe9a Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Wed, 22 Apr 2026 15:00:00 +0200 Subject: [PATCH] via workflow dispatch --- .github/workflows/after_release.yml | 126 ++---------------- .github/workflows/deploy_docs.yml | 26 +++- .../src/tasks/workflows/after_release.rs | 68 ++++++++-- .../xtask/src/tasks/workflows/deploy_docs.rs | 67 +++++++--- 4 files changed, 136 insertions(+), 151 deletions(-) diff --git a/.github/workflows/after_release.yml b/.github/workflows/after_release.yml index c28763cfb7fd58c78b4bfb56904bbc8d4c3c880d..269b7465f617bc8ec4dceaeb11c987bfaaf93cbf 100644 --- a/.github/workflows/after_release.yml +++ b/.github/workflows/after_release.yml @@ -11,10 +11,6 @@ on: description: tag_name required: true type: string - prerelease: - description: prerelease - required: true - type: boolean body: description: body type: string @@ -36,114 +32,16 @@ jobs: VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} deploy_docs: if: github.repository_owner == 'zed-industries' - name: Build and Deploy Docs - runs-on: namespace-profile-16x32-ubuntu-2204 - env: + permissions: + contents: read + uses: zed-industries/zed/.github/workflows/deploy_docs.yml@main + secrets: DOCS_AMPLITUDE_API_KEY: ${{ secrets.DOCS_AMPLITUDE_API_KEY }} - MDBOOK_BOOK__SITE_URL: ${{ steps.resolve-channel.outputs.site_url }} - DOCS_CHANNEL: ${{ steps.resolve-channel.outputs.channel }} - steps: - - id: resolve-channel - name: deploy_docs::resolve_channel_step - run: | - if [ -z "$CHANNEL" ]; then - if [ "$GITHUB_REF" = "refs/heads/main" ]; then - CHANNEL="nightly" - else - echo "::error::channel input is required when ref is not main." - exit 1 - fi - fi - - case "$CHANNEL" in - "nightly") - SITE_URL="/docs/nightly/" - PROJECT_NAME="docs-nightly" - ;; - "preview") - SITE_URL="/docs/preview/" - PROJECT_NAME="docs-preview" - ;; - "stable") - SITE_URL="/docs/" - PROJECT_NAME="docs" - ;; - *) - echo "::error::Invalid docs channel '$CHANNEL'. Expected one of: nightly, preview, stable." - exit 1 - ;; - esac - - echo "channel=$CHANNEL" >> "$GITHUB_OUTPUT" - echo "site_url=$SITE_URL" >> "$GITHUB_OUTPUT" - echo "project_name=$PROJECT_NAME" >> "$GITHUB_OUTPUT" - env: - CHANNEL: ${{ (github.event.release.prerelease || inputs.prerelease) && 'preview' || 'stable' }} - - name: steps::checkout_repo - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd - with: - clean: false - ref: ${{ github.event.release.tag_name || inputs.tag_name }} - - name: steps::setup_cargo_config - run: | - mkdir -p ./../.cargo - cp ./.cargo/ci-config.toml ./../.cargo/config.toml - - name: steps::cache_rust_dependencies_namespace - uses: namespacelabs/nscloud-cache-action@a90bb5d4b27522ce881c6e98eebd7d7e6d1653f9 - with: - cache: rust - path: ~/.rustup - - name: steps::setup_linux - run: ./script/linux - - name: steps::download_wasi_sdk - run: ./script/download-wasi-sdk - - name: ./script/generate-action-metadata - run: ./script/generate-action-metadata - - name: deploy_docs::lychee_link_check - uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 - with: - args: --no-progress --exclude '^http' './docs/src/**/*' - fail: true - jobSummary: false - - name: deploy_docs::install_mdbook - uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 - with: - mdbook-version: 0.4.37 - - name: deploy_docs::build_docs_book - run: | - mkdir -p target/deploy - mdbook build ./docs --dest-dir=../target/deploy/docs/ - - name: deploy_docs::lychee_link_check - uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 - with: - args: --no-progress --exclude '^http' 'target/deploy/docs' - fail: true - jobSummary: false - - name: deploy_docs::docs_deploy_steps::deploy_to_cf_pages - uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: pages deploy target/deploy --project-name=${{ steps.resolve-channel.outputs.project_name }} - - name: deploy_docs::docs_deploy_steps::upload_install_script - uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: r2 object put -f script/install.sh zed-open-source-website-assets/install.sh - - name: deploy_docs::docs_deploy_steps::deploy_docs_worker - uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 - with: - apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} - accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - command: deploy .cloudflare/docs-proxy/src/worker.js - - name: deploy_docs::docs_deploy_steps::upload_wrangler_logs - if: always() - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 - with: - name: wrangler_logs - path: /home/runner/.config/.wrangler/logs/ - timeout-minutes: 60 + CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + with: + channel: ${{ endsWith(github.event.release.tag_name || inputs.tag_name, '-pre') && 'preview' || 'stable' }} + checkout_ref: ${{ github.event.release.tag_name || inputs.tag_name }} post_to_discord: needs: - rebuild_releases_page @@ -153,7 +51,7 @@ jobs: - id: get-release-url name: after_release::post_to_discord::get_release_url run: | - if [ "${{ github.event.release.prerelease || inputs.prerelease }}" == "true" ]; then + if [ "${{ endsWith(github.event.release.tag_name || inputs.tag_name, '-pre') }}" == "true" ]; then URL="https://zed.dev/releases/preview" else URL="https://zed.dev/releases/stable" @@ -200,7 +98,7 @@ jobs: - id: set-package-name name: after_release::publish_winget::set_package_name run: | - if ("${{ github.event.release.prerelease || inputs.prerelease }}" -eq "true") { + if ("${{ endsWith(github.event.release.tag_name || inputs.tag_name, '-pre') }}" -eq "true") { $PACKAGE_NAME = "ZedIndustries.Zed.Preview" } else { $PACKAGE_NAME = "ZedIndustries.Zed" @@ -234,10 +132,10 @@ jobs: notify_on_failure: needs: - rebuild_releases_page - - deploy_docs - post_to_discord - publish_winget - create_sentry_release + - deploy_docs if: failure() runs-on: namespace-profile-2x4-ubuntu-2404 steps: diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index d665506b52e3496250ecad5c8ce383949161b73c..a61237127391a812adee81c7218724d483a993c2 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -2,14 +2,34 @@ # Rebuild with `cargo xtask workflows`. name: deploy_docs on: + workflow_call: + inputs: + channel: + description: channel + type: string + default: '' + checkout_ref: + description: checkout_ref + type: string + default: '' + secrets: + DOCS_AMPLITUDE_API_KEY: + description: DOCS_AMPLITUDE_API_KEY + required: true + CLOUDFLARE_API_TOKEN: + description: CLOUDFLARE_API_TOKEN + required: true + CLOUDFLARE_ACCOUNT_ID: + description: CLOUDFLARE_ACCOUNT_ID + required: true workflow_dispatch: inputs: channel: description: 'Docs channel to deploy: nightly, preview, or stable' type: string default: '' - commit_sha: - description: Exact commit SHA to checkout and deploy. Defaults to event SHA when omitted. + checkout_ref: + description: Git ref to checkout and deploy. Defaults to event SHA when omitted. type: string default: '' jobs: @@ -62,7 +82,7 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd with: clean: false - ref: ${{ inputs.commit_sha != '' && inputs.commit_sha || github.sha }} + ref: ${{ inputs.checkout_ref != '' && inputs.checkout_ref || github.sha }} - name: steps::setup_cargo_config run: | mkdir -p ./../.cargo diff --git a/tooling/xtask/src/tasks/workflows/after_release.rs b/tooling/xtask/src/tasks/workflows/after_release.rs index 785a9286c2cd005274d71e327fc300d1570da64a..766618e23b48890bb18d54b0bd93d1f4c5d2ad7c 100644 --- a/tooling/xtask/src/tasks/workflows/after_release.rs +++ b/tooling/xtask/src/tasks/workflows/after_release.rs @@ -1,7 +1,6 @@ use gh_workflow::*; use crate::tasks::workflows::{ - deploy_docs, release::{self, notify_on_failure}, runners, steps::{CommonJobConditions, NamedJob, checkout_repo, dependant_job, named}, @@ -9,28 +8,32 @@ use crate::tasks::workflows::{ }; const TAG_NAME: &str = "${{ github.event.release.tag_name || inputs.tag_name }}"; -const IS_PRERELEASE: &str = "${{ github.event.release.prerelease || inputs.prerelease }}"; +const IS_PRERELEASE: &str = + "${{ endsWith(github.event.release.tag_name || inputs.tag_name, '-pre') }}"; const RELEASE_BODY: &str = "${{ github.event.release.body || inputs.body }}"; -const DOCS_CHANNEL: &str = - "${{ (github.event.release.prerelease || inputs.prerelease) && 'preview' || 'stable' }}"; +const DOCS_CHANNEL: &str = "${{ endsWith(github.event.release.tag_name || inputs.tag_name, '-pre') && 'preview' || 'stable' }}"; 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 deploy_docs = deploy_docs::release_docs_job(DOCS_CHANNEL, TAG_NAME); + let deploy_docs = deploy_docs(); let post_to_discord = post_to_discord(&[&refresh_zed_dev]); let publish_winget = publish_winget(); let create_sentry_release = create_sentry_release(); - let notify_on_failure = notify_on_failure(&[ - &refresh_zed_dev, - &deploy_docs, - &post_to_discord, - &publish_winget, - &create_sentry_release, - ]); + let notify_on_failure = { + let notify_on_failure = notify_on_failure(&[ + &refresh_zed_dev, + &post_to_discord, + &publish_winget, + &create_sentry_release, + ]); + NamedJob { + name: notify_on_failure.name, + job: notify_on_failure.job.add_need(deploy_docs.name.clone()), + } + }; named::workflow() .on(Event::default() @@ -38,7 +41,6 @@ pub fn after_release() -> Workflow { .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) @@ -49,6 +51,44 @@ pub fn after_release() -> Workflow { .add_job(notify_on_failure.name, notify_on_failure.job) } +fn deploy_docs() -> NamedJob { + let job = Job::default() + .cond(Expression::new( + "github.repository_owner == 'zed-industries'", + )) + .permissions(Permissions::default().contents(Level::Read)) + .uses( + "zed-industries", + "zed", + ".github/workflows/deploy_docs.yml", + "main", + ) + .with( + Input::default() + .add("channel", DOCS_CHANNEL) + .add("checkout_ref", TAG_NAME), + ) + .secrets(indexmap::IndexMap::from([ + ( + "DOCS_AMPLITUDE_API_KEY".to_owned(), + vars::DOCS_AMPLITUDE_API_KEY.to_owned(), + ), + ( + "CLOUDFLARE_API_TOKEN".to_owned(), + vars::CLOUDFLARE_API_TOKEN.to_owned(), + ), + ( + "CLOUDFLARE_ACCOUNT_ID".to_owned(), + vars::CLOUDFLARE_ACCOUNT_ID.to_owned(), + ), + ])); + + NamedJob { + name: "deploy_docs".to_owned(), + job, + } +} + fn rebuild_releases_page() -> NamedJob { fn refresh_cloud_releases() -> Step { named::bash(format!( diff --git a/tooling/xtask/src/tasks/workflows/deploy_docs.rs b/tooling/xtask/src/tasks/workflows/deploy_docs.rs index 7f90c64f2dc9bcb740c9f3aa164d41dfda09c390..2aa6de87654fe7919c8c1b3cdb5d67e2c0ab3e35 100644 --- a/tooling/xtask/src/tasks/workflows/deploy_docs.rs +++ b/tooling/xtask/src/tasks/workflows/deploy_docs.rs @@ -1,4 +1,7 @@ -use gh_workflow::{Event, Expression, Job, Run, Step, Use, Workflow, WorkflowDispatch}; +use gh_workflow::{ + Event, Expression, Job, Run, Step, Use, Workflow, WorkflowCall, WorkflowCallSecret, + WorkflowDispatch, +}; use crate::tasks::workflows::{ runners, @@ -239,23 +242,16 @@ fn docs_job(channel_expr: impl Into, checkout_ref: Option) -> Na } } -pub(crate) fn release_docs_job( - channel_expr: impl Into, - checkout_ref: impl Into, -) -> NamedJob { - docs_job(channel_expr, Some(checkout_ref.into())) -} - pub(crate) fn deploy_docs_job( channel_input: &WorkflowInput, - commit_sha_input: &WorkflowInput, + checkout_ref_input: &WorkflowInput, ) -> NamedJob { docs_job( channel_input.expr(), Some(format!( "${{{{ {} != '' && {} || github.sha }}}}", - commit_sha_input.expr(), - commit_sha_input.expr() + checkout_ref_input.expr(), + checkout_ref_input.expr() )), ) } @@ -263,16 +259,47 @@ pub(crate) fn deploy_docs_job( pub(crate) fn deploy_docs() -> Workflow { let channel = WorkflowInput::string("channel", Some(String::new())) .description("Docs channel to deploy: nightly, preview, or stable"); - let commit_sha = WorkflowInput::string("commit_sha", Some(String::new())).description( - "Exact commit SHA to checkout and deploy. Defaults to event SHA when omitted.", - ); - let deploy_docs = deploy_docs_job(&channel, &commit_sha); + let checkout_ref = WorkflowInput::string("checkout_ref", Some(String::new())) + .description("Git ref to checkout and deploy. Defaults to event SHA when omitted."); + let deploy_docs = deploy_docs_job(&channel, &checkout_ref); named::workflow() - .on(Event::default().workflow_dispatch( - WorkflowDispatch::default() - .add_input(channel.name, channel.input()) - .add_input(commit_sha.name, commit_sha.input()), - )) + .add_event( + Event::default().workflow_dispatch( + WorkflowDispatch::default() + .add_input(channel.name, channel.input()) + .add_input(checkout_ref.name, checkout_ref.input()), + ), + ) + .add_event( + Event::default().workflow_call( + WorkflowCall::default() + .add_input(channel.name, channel.call_input()) + .add_input(checkout_ref.name, checkout_ref.call_input()) + .secrets([ + ( + "DOCS_AMPLITUDE_API_KEY".to_owned(), + WorkflowCallSecret { + description: "DOCS_AMPLITUDE_API_KEY".to_owned(), + required: true, + }, + ), + ( + "CLOUDFLARE_API_TOKEN".to_owned(), + WorkflowCallSecret { + description: "CLOUDFLARE_API_TOKEN".to_owned(), + required: true, + }, + ), + ( + "CLOUDFLARE_ACCOUNT_ID".to_owned(), + WorkflowCallSecret { + description: "CLOUDFLARE_ACCOUNT_ID".to_owned(), + required: true, + }, + ), + ]), + ), + ) .add_job(deploy_docs.name, deploy_docs.job) }