From e6593f9a4bdad17e0e6ab11a4e2b92a526e03f96 Mon Sep 17 00:00:00 2001 From: Ben Kunkle Date: Wed, 25 Feb 2026 17:16:33 -0500 Subject: [PATCH] generate deploy docs --- .github/workflows/deploy_docs.yml | 85 +++++++++++ .github/workflows/run_tests.yml | 22 +-- tooling/xtask/src/tasks/workflows.rs | 2 + .../xtask/src/tasks/workflows/deploy_docs.rs | 133 ++++++++++++++++++ .../xtask/src/tasks/workflows/run_tests.rs | 51 +------ tooling/xtask/src/tasks/workflows/vars.rs | 3 + 6 files changed, 237 insertions(+), 59 deletions(-) create mode 100644 .github/workflows/deploy_docs.yml create mode 100644 tooling/xtask/src/tasks/workflows/deploy_docs.rs diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml new file mode 100644 index 0000000000000000000000000000000000000000..0920fe4da5c3d06a03f9d32889f3f68c3095c058 --- /dev/null +++ b/.github/workflows/deploy_docs.yml @@ -0,0 +1,85 @@ +# Generated from xtask::workflows::deploy_docs +# Rebuild with `cargo xtask workflows`. +name: deploy_docs +on: + push: + branches: + - main + - staged-docs-releases +jobs: + deploy_docs_job: + if: github.repository_owner == 'zed-industries' + name: Build and Deploy Docs + runs-on: namespace-profile-16x32-ubuntu-2204 + env: + DOCS_AMPLITUDE_API_KEY: ${{ secrets.DOCS_AMPLITUDE_API_KEY }} + steps: + - name: steps::checkout_repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + with: + clean: false + - 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@v1 + with: + cache: rust + path: ~/.rustup + - name: steps::setup_linux + run: ./script/linux + - name: steps::install_mold + run: ./script/install-mold + - 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::deploy_docs_to_pages + uses: cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: pages deploy target/deploy --project-name=docs + - name: deploy_docs::deploy_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::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::upload_wrangler_logs + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 + with: + name: wrangler_logs + path: /home/runner/.config/.wrangler/logs/ + timeout-minutes: 60 +defaults: + run: + shell: bash -euxo pipefail {0} diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 07caa6007e87fcd093b40bb9a15108e18b159068..af47904c7ade90aed2bc9ac1297363152aafed2b 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -502,7 +502,9 @@ jobs: needs: - orchestrate if: needs.orchestrate.outputs.run_docs == 'true' - runs-on: namespace-profile-8x16-ubuntu-2204 + runs-on: namespace-profile-16x32-ubuntu-2204 + env: + DOCS_AMPLITUDE_API_KEY: ${{ secrets.DOCS_AMPLITUDE_API_KEY }} steps: - name: steps::checkout_repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 @@ -517,12 +519,6 @@ jobs: with: cache: rust path: ~/.rustup - - name: run_tests::check_docs::lychee_link_check - uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 - with: - args: --no-progress --exclude '^http' './docs/src/**/*' - fail: true - jobSummary: false - name: steps::setup_linux run: ./script/linux - name: steps::install_mold @@ -531,15 +527,21 @@ jobs: run: ./script/download-wasi-sdk - name: ./script/generate-action-metadata run: ./script/generate-action-metadata - - name: run_tests::check_docs::install_mdbook + - 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: run_tests::check_docs::build_docs + - name: deploy_docs::build_docs_book run: | mkdir -p target/deploy mdbook build ./docs --dest-dir=../target/deploy/docs/ - - name: run_tests::check_docs::lychee_link_check + - name: deploy_docs::lychee_link_check uses: lycheeverse/lychee-action@82202e5e9c2f4ef1a55a3d02563e1cb6041e5332 with: args: --no-progress --exclude '^http' 'target/deploy/docs' diff --git a/tooling/xtask/src/tasks/workflows.rs b/tooling/xtask/src/tasks/workflows.rs index 5663ebec247c4025f7cfbae8e9467733e2c7be2d..f1493de77fb11bbe04c837db9c519c73c1d306dc 100644 --- a/tooling/xtask/src/tasks/workflows.rs +++ b/tooling/xtask/src/tasks/workflows.rs @@ -11,6 +11,7 @@ mod cherry_pick; mod compare_perf; mod danger; mod deploy_collab; +mod deploy_docs; mod extension_bump; mod extension_tests; mod extension_workflow_rollout; @@ -135,6 +136,7 @@ pub fn run_workflows(_: GenerateWorkflowArgs) -> Result<()> { WorkflowFile::zed(compare_perf::compare_perf), WorkflowFile::zed(danger::danger), WorkflowFile::zed(deploy_collab::deploy_collab), + WorkflowFile::zed(deploy_docs::deploy_docs), WorkflowFile::zed(extension_bump::extension_bump), WorkflowFile::zed(extension_tests::extension_tests), WorkflowFile::zed(extension_workflow_rollout::extension_workflow_rollout), diff --git a/tooling/xtask/src/tasks/workflows/deploy_docs.rs b/tooling/xtask/src/tasks/workflows/deploy_docs.rs new file mode 100644 index 0000000000000000000000000000000000000000..b215f59f64b8ee3461c83bb494afdbbfa788f767 --- /dev/null +++ b/tooling/xtask/src/tasks/workflows/deploy_docs.rs @@ -0,0 +1,133 @@ +use gh_workflow::{Event, Expression, Job, Push, Run, Step, Use, Workflow}; + +use crate::tasks::workflows::{ + runners::{self, Platform}, + steps::{self, FluentBuilder as _, NamedJob, named, release_job}, + vars, +}; + +pub(crate) fn lychee_link_check(dir: &str) -> Step { + named::uses( + "lycheeverse", + "lychee-action", + "82202e5e9c2f4ef1a55a3d02563e1cb6041e5332", + ) // v2.4.1 + .add_with(("args", format!("--no-progress --exclude '^http' '{dir}'"))) + .add_with(("fail", true)) + .add_with(("jobSummary", false)) +} + +pub(crate) fn install_mdbook() -> Step { + named::uses( + "peaceiris", + "actions-mdbook", + "ee69d230fe19748b7abf22df32acaa93833fad08", // v2 + ) + .with(("mdbook-version", "0.4.37")) +} + +pub(crate) fn build_docs_book() -> Step { + named::bash(indoc::indoc! {r#" + mkdir -p target/deploy + mdbook build ./docs --dest-dir=../target/deploy/docs/ + "#}) +} + +fn deploy_docs_to_pages() -> Step { + named::uses( + "cloudflare", + "wrangler-action", + "da0e0dfe58b7a431659754fdf3f186c529afbe65", + ) // v3 + .add_with(("apiToken", vars::CLOUDFLARE_API_TOKEN)) + .add_with(("accountId", vars::CLOUDFLARE_ACCOUNT_ID)) + .add_with(("command", "pages deploy target/deploy --project-name=docs")) +} + +fn deploy_install_script() -> Step { + named::uses( + "cloudflare", + "wrangler-action", + "da0e0dfe58b7a431659754fdf3f186c529afbe65", + ) // v3 + .add_with(("apiToken", vars::CLOUDFLARE_API_TOKEN)) + .add_with(("accountId", vars::CLOUDFLARE_ACCOUNT_ID)) + .add_with(( + "command", + "r2 object put -f script/install.sh zed-open-source-website-assets/install.sh", + )) +} + +fn deploy_docs_worker() -> Step { + named::uses( + "cloudflare", + "wrangler-action", + "da0e0dfe58b7a431659754fdf3f186c529afbe65", + ) // v3 + .add_with(("apiToken", vars::CLOUDFLARE_API_TOKEN)) + .add_with(("accountId", vars::CLOUDFLARE_ACCOUNT_ID)) + .add_with(("command", "deploy .cloudflare/docs-proxy/src/worker.js")) +} + +fn upload_wrangler_logs() -> Step { + named::uses( + "actions", + "upload-artifact", + "ea165f8d65b6e75b540449e92b4886f43607fa02", + ) // v4 + .if_condition(Expression::new("always()")) + .add_with(("name", "wrangler_logs")) + .add_with(("path", "/home/runner/.config/.wrangler/logs/")) +} + +fn docs_build_steps(job: Job) -> Job { + job.add_env(("DOCS_AMPLITUDE_API_KEY", vars::DOCS_AMPLITUDE_API_KEY)) + .runs_on(runners::LINUX_XL) + .add_step(steps::checkout_repo()) + .add_step(steps::setup_cargo_config(Platform::Linux)) + .add_step(steps::cache_rust_dependencies_namespace()) + .map(steps::install_linux_dependencies) + .add_step(steps::script("./script/generate-action-metadata")) + .add_step(lychee_link_check("./docs/src/**/*")) + .add_step(install_mdbook()) + .add_step(build_docs_book()) + .add_step(lychee_link_check("target/deploy/docs")) +} + +pub(crate) fn check_docs() -> NamedJob { + NamedJob { + name: "check_docs".to_owned(), + job: docs_build_steps(release_job(&[])), + } +} + +pub(crate) fn deploy_docs_job() -> NamedJob { + named::job( + docs_build_steps( + release_job(&[]) + .name("Build and Deploy Docs") + .cond(Expression::new( + "github.repository_owner == 'zed-industries'", + )), + ) + .add_step(deploy_docs_to_pages()) + .add_step(deploy_install_script()) + .add_step(deploy_docs_worker()) + .add_step(upload_wrangler_logs()), + ) +} + +pub(crate) fn deploy_docs() -> Workflow { + let deploy_docs = deploy_docs_job(); + + named::workflow() + .add_event( + Event::default().push( + Push::default() + .add_branch("main") + // todo! remove + .add_branch("staged-docs-releases"), + ), + ) + .add_job(deploy_docs.name, deploy_docs.job) +} diff --git a/tooling/xtask/src/tasks/workflows/run_tests.rs b/tooling/xtask/src/tasks/workflows/run_tests.rs index c234f46f3dd2edc4bd861d7df46f966a1e623708..8ec006a61b1785f28cf35e24a625bd055165b2df 100644 --- a/tooling/xtask/src/tasks/workflows/run_tests.rs +++ b/tooling/xtask/src/tasks/workflows/run_tests.rs @@ -10,6 +10,7 @@ use crate::tasks::workflows::{ }; use super::{ + deploy_docs, runners::{self, Platform}, steps::{self, FluentBuilder, NamedJob, named, release_job}, }; @@ -51,7 +52,7 @@ pub(crate) fn run_tests() -> Workflow { should_run_tests.guard(doctests()), should_run_tests.guard(check_workspace_binaries()), should_run_tests.guard(check_dependencies()), // could be more specific here? - should_check_docs.guard(check_docs()), + should_check_docs.guard(deploy_docs::check_docs()), should_check_licences.guard(check_licenses()), should_check_scripts.guard(check_scripts()), ]; @@ -511,54 +512,6 @@ fn check_licenses() -> NamedJob { ) } -fn check_docs() -> NamedJob { - fn lychee_link_check(dir: &str) -> Step { - named::uses( - "lycheeverse", - "lychee-action", - "82202e5e9c2f4ef1a55a3d02563e1cb6041e5332", - ) // v2.4.1 - .add_with(("args", format!("--no-progress --exclude '^http' '{dir}'"))) - .add_with(("fail", true)) - .add_with(("jobSummary", false)) - } - - fn install_mdbook() -> Step { - named::uses( - "peaceiris", - "actions-mdbook", - "ee69d230fe19748b7abf22df32acaa93833fad08", // v2 - ) - .with(("mdbook-version", "0.4.37")) - } - - fn build_docs() -> Step { - named::bash(indoc::indoc! {r#" - mkdir -p target/deploy - mdbook build ./docs --dest-dir=../target/deploy/docs/ - "#}) - } - - named::job( - release_job(&[]) - .runs_on(runners::LINUX_LARGE) - .add_step(steps::checkout_repo()) - .add_step(steps::setup_cargo_config(Platform::Linux)) - // todo(ci): un-inline build_docs/action.yml here - .add_step(steps::cache_rust_dependencies_namespace()) - .add_step( - lychee_link_check("./docs/src/**/*"), // check markdown links - ) - .map(steps::install_linux_dependencies) - .add_step(steps::script("./script/generate-action-metadata")) - .add_step(install_mdbook()) - .add_step(build_docs()) - .add_step( - lychee_link_check("target/deploy/docs"), // check links in generated html - ), - ) -} - pub(crate) fn check_scripts() -> NamedJob { fn download_actionlint() -> Step { named::bash( diff --git a/tooling/xtask/src/tasks/workflows/vars.rs b/tooling/xtask/src/tasks/workflows/vars.rs index aa8fb0a4056a53807cd4b2f12f331cb9d4d0a235..2d16348ee7c63dedc1ed7e54229fff4d38b97989 100644 --- a/tooling/xtask/src/tasks/workflows/vars.rs +++ b/tooling/xtask/src/tasks/workflows/vars.rs @@ -51,6 +51,9 @@ secret!(SLACK_WEBHOOK_WORKFLOW_FAILURES); secret!(R2_ACCOUNT_ID); secret!(R2_ACCESS_KEY_ID); secret!(R2_SECRET_ACCESS_KEY); +secret!(CLOUDFLARE_API_TOKEN); +secret!(CLOUDFLARE_ACCOUNT_ID); +secret!(DOCS_AMPLITUDE_API_KEY); // todo(ci) make these secrets too... var!(AZURE_SIGNING_ACCOUNT_NAME);