Detailed changes
@@ -34,6 +34,116 @@ jobs:
run: ./script/redeploy-vercel
env:
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:
+ 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
post_to_discord:
needs:
- rebuild_releases_page
@@ -124,6 +234,7 @@ jobs:
notify_on_failure:
needs:
- rebuild_releases_page
+ - deploy_docs
- post_to_discord
- publish_winget
- create_sentry_release
@@ -2,29 +2,6 @@
# Rebuild with `cargo xtask workflows`.
name: deploy_docs
on:
- push:
- branches:
- - main
- workflow_call:
- inputs:
- channel:
- description: channel
- type: string
- default: ''
- commit_sha:
- description: commit_sha
- 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:
@@ -46,7 +23,7 @@ jobs:
DOCS_CHANNEL: ${{ steps.resolve-channel.outputs.channel }}
steps:
- id: resolve-channel
- name: deploy_docs::deploy_docs_job::resolve_channel_step
+ name: deploy_docs::resolve_channel_step
run: |
if [ -z "$CHANNEL" ]; then
if [ "$GITHUB_REF" = "refs/heads/main" ]; then
@@ -80,7 +57,7 @@ jobs:
echo "site_url=$SITE_URL" >> "$GITHUB_OUTPUT"
echo "project_name=$PROJECT_NAME" >> "$GITHUB_OUTPUT"
env:
- CHANNEL: ${ inputs.channel }
+ CHANNEL: inputs.channel
- name: steps::checkout_repo
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd
with:
@@ -725,20 +725,6 @@ jobs:
run: gh release edit "$GITHUB_REF_NAME" --repo=zed-industries/zed --draft=false
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
- deploy_docs:
- needs:
- - validate_release_assets
- - create_draft_release
- permissions:
- contents: read
- uses: zed-industries/zed/.github/workflows/deploy_docs.yml@main
- secrets:
- DOCS_AMPLITUDE_API_KEY: ${{ secrets.DOCS_AMPLITUDE_API_KEY }}
- CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
- CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
- with:
- channel: ${{ endsWith(github.ref_name, '-pre') && 'preview' || 'stable' }}
- commit_sha: ${{ github.sha }}
push_release_update_notification:
needs:
- create_draft_release
@@ -1,219 +0,0 @@
-# Staged Docs Releases Plan
-
-## Background & Current State
-
-| Component | Status | Location |
-|---|---|---|
-| Docs build (CI check) | **xtask-generated** (in `run_tests.rs`) | `check_docs()` at L514–560 |
-| Docs deploy workflow | **Hand-written YAML** | `.github/workflows/deploy_cloudflare.yml` |
-| Composite build action | **Hand-written YAML** | `.github/actions/build_docs/action.yml` |
-| Docs-proxy worker | **Runtime JS** | `.cloudflare/docs-proxy/src/worker.js` |
-| book.toml | **Config** | `docs/book.toml` (site-url = `/docs/`) |
-
-There's already a TODO in the codebase acknowledging the duplication:
-
-```
-// todo(ci): un-inline build_docs/action.yml here
-```
-(`tooling/xtask/src/tasks/workflows/run_tests.rs` L549)
-
----
-
-## Step 1: Move Docs Build & Deploy into xtask Workflow Generation
-
-### 1.1 Create `deploy_docs.rs` with shared build helpers and deploy workflow
-
-Create `tooling/xtask/src/tasks/workflows/deploy_docs.rs`. This module owns all docs build and deploy logic and exports shared helpers used by both the new deploy workflow and `check_docs()` in `run_tests.rs`.
-
-**Shared helpers** — export as `pub(crate)`:
-
-```rust
-pub(crate) fn lychee_link_check(dir: &str) -> Step<Use> { ... }
-pub(crate) fn install_mdbook() -> Step<Use> { ... }
-pub(crate) fn build_docs_book() -> Step<Run> { ... }
-```
-
-Copy each implementation verbatim from the inline private functions currently inside `check_docs()` in `run_tests.rs`.
-
-**Build job** — mirror `.github/actions/build_docs/action.yml` step-for-step, using the patterns from `check_docs()` in `run_tests.rs` as the reference for how shared steps are expressed in xtask. Steps in order:
-
-1. `steps::checkout_repo()`
-2. A step that runs `cp ./.cargo/collab-config.toml ./.cargo/config.toml` — the deploy workflow uses `collab-config.toml` (not `ci-config.toml`), so this is distinct from `steps::setup_cargo_config`
-3. `steps::cache_rust_dependencies_namespace()`
-4. `steps::install_linux_dependencies` (covers `./script/linux`, `./script/install-mold`, `./script/download-wasi-sdk`)
-5. `steps::script("./script/generate-action-metadata")`
-6. `lychee_link_check("./docs/src/**/*")` — check Markdown links
-7. `install_mdbook()`
-8. `build_docs_book()`
-9. `lychee_link_check("target/deploy/docs")` — check links in generated HTML
-
-Set `DOCS_AMPLITUDE_API_KEY` on the build job (currently passed via `env:` to the composite action in `deploy_cloudflare.yml`).
-
-### 1.1.1
-**Deploy job** — copy each step verbatim from the `deploy-docs` job in `deploy_cloudflare.yml`. Steps in order:
-
-1. Wrangler: `pages deploy target/deploy --project-name=docs`
-2. Wrangler: `r2 object put -f script/install.sh zed-open-source-website-assets/install.sh`
-3. Wrangler: `deploy .cloudflare/docs-proxy/src/worker.js`
-4. Upload Wrangler logs artifact (`always()`, path `~/.config/.wrangler/logs/`, name `wrangler_logs`)
-
-Note: steps "Deploy Docs Workers" and "Deploy Install Workers" in `deploy_cloudflare.yml` run the identical `wrangler deploy .cloudflare/docs-proxy/src/worker.js` command — this is a copy-paste bug. Include it only once (step 3 above).
-
-Each Wrangler step uses `cloudflare/wrangler-action@da0e0dfe58b7a431659754fdf3f186c529afbe65` with `apiToken` and `accountId` from `vars::CLOUDFLARE_API_TOKEN` and `vars::CLOUDFLARE_ACCOUNT_ID`.
-
-**Update `check_docs()`** — once the module exists, replace the inline private `lychee_link_check`, `install_mdbook`, and `build_docs` functions in `run_tests.rs` with calls to `deploy_docs::lychee_link_check`, `deploy_docs::install_mdbook`, and `deploy_docs::build_docs_book`. This resolves the TODO at L549.
-
-### 1.2 Register the new workflow
-
-In `tooling/xtask/src/tasks/workflows.rs`:
-- Add `mod deploy_docs;`
-- Add `WorkflowFile::zed(deploy_docs::deploy_docs)` to the workflows array
-
-### 1.3 Add Cloudflare secrets to `vars.rs`
-
-Add typed secret references:
-
-```rust
-secret!(CLOUDFLARE_API_TOKEN);
-secret!(CLOUDFLARE_ACCOUNT_ID);
-secret!(DOCS_AMPLITUDE_API_KEY);
-```
-
-### 1.4 Verify generated output matches the hand-written workflow
-
-- Run `cargo xtask workflows` to generate `.github/workflows/deploy_docs.yml`
-- Diff the generated file against `.github/workflows/deploy_cloudflare.yml` and `.github/actions/build_docs/action.yml` to confirm all steps, env vars, secrets, triggers, and job dependencies are equivalent
-- Pay attention to: step ordering, `if:` conditions, artifact names, the Wrangler action hash, and that the duplicate worker deploy step is now deduplicated
-
-### 1.5 Ask the user to approve the generated files
-
-**Stop and show the generated `.github/workflows/deploy_docs.yml` to the user.** Ask them to confirm the output looks correct before proceeding to delete the hand-written files. Do not continue to step 1.6 without explicit approval.
-
-### 1.6 Delete hand-written files
-
-- Delete `.github/workflows/deploy_cloudflare.yml` (replaced by the generated workflow)
-- Delete `.github/actions/build_docs/action.yml` (steps are now inlined in xtask)
-
-### 1.7 Final check
-
-The CI self-check (`check_xtask_workflows`) will enforce that the generated file stays in sync going forward.
-
----
-
-## Step 2: Split Deployments into Nightly, Preview, and Stable
-
-### 2.1 Introduce `DocsChannel` and parameterize the build
-
-Add a `DocsChannel` enum to `deploy_docs.rs`:
-
-```rust
-pub(crate) enum DocsChannel {
- Nightly, // site-url = "/docs/nightly/", project = "docs-nightly"
- Preview, // site-url = "/docs/preview/", project = "docs-preview"
- Stable, // site-url = "/docs/", project = "docs"
-}
-```
-
-mdBook supports overriding `book.toml` values at build time via `MDBOOK_`-prefixed environment variables, using `__` for TOML key nesting. The `site-url` field lives under `[book]`, so setting `MDBOOK_BOOK__SITE_URL=/docs/nightly/` before `mdbook build` overrides it without touching the file. The `book.toml` in the repository remains unchanged at `site-url = "/docs/"`.
-
-The `build_docs_book()` step stays as-is; the channel env var is applied to the build job:
-
-```rust
-fn build_job(channel: DocsChannel, deps: &[&NamedJob]) -> NamedJob {
- // ...
- .add_env(("MDBOOK_BOOK__SITE_URL", channel.site_url()))
-}
-```
-
-The deploy step uses `--project-name` matching the channel:
-
-```rust
-fn pages_deploy_step(channel: &DocsChannel) -> Step<Use> {
- // wrangler: pages deploy target/deploy --project-name=<channel.project_name()>
-}
-```
-
-Export `pub(crate) fn deploy_docs_job(channel: DocsChannel, deps: &[&NamedJob]) -> NamedJob` for use in `release.rs`.
-
-### 2.2 Create `deploy_docs_nightly.rs`
-
-Create `tooling/xtask/src/tasks/workflows/deploy_docs_nightly.rs`. This is the standalone workflow for nightly docs, triggered on push to `main`. It calls `deploy_docs::deploy_docs_job(DocsChannel::Nightly, &[])`. The deploy job includes the `install.sh` R2 upload and docs-proxy worker deploy (these are `main`-push operations, currently bundled in `deploy_cloudflare.yml`).
-
-Register it in `workflows.rs`: `WorkflowFile::zed(deploy_docs_nightly::deploy_docs_nightly)`.
-
-### 2.3 Add preview and stable deploy jobs to `release.rs`
-
-In `release.rs`, call `deploy_docs::deploy_docs_job` twice after `validate_release_assets` completes:
-
-```rust
-let deploy_docs_preview = deploy_docs::deploy_docs_job(
- DocsChannel::Preview,
- &[&validate_release_assets],
-);
-let deploy_docs_stable = deploy_docs::deploy_docs_job(
- DocsChannel::Stable,
- &[&validate_release_assets],
-);
-```
-
-Apply an `if:` condition to each job:
-- Preview: `startsWith(github.ref, 'refs/tags/v') && contains(github.ref, '-pre')`
-- Stable: `startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-pre')`
-
-Add both jobs to the release workflow with `.add_job(...)`.
-
-### 2.4 Update the docs-proxy worker
-
-Modify `.cloudflare/docs-proxy/src/worker.js` to route all three channels:
-
-```javascript
-export default {
- async fetch(request, _env, _ctx) {
- const url = new URL(request.url);
-
- let hostname;
- if (url.pathname.startsWith("/docs/nightly")) {
- hostname = "docs-nightly.pages.dev";
- } else if (url.pathname.startsWith("/docs/preview")) {
- hostname = "docs-preview.pages.dev";
- } else {
- hostname = "docs-anw.pages.dev";
- }
-
- url.hostname = hostname;
- let res = await fetch(url, request);
-
- if (res.status === 404) {
- res = await fetch("https://zed.dev/404");
- }
-
- return res;
- },
-};
-```
-
-The `docs-nightly` and `docs-preview` Pages project hostnames will be auto-assigned by Cloudflare on first deploy — verify the actual `*.pages.dev` hostnames and update accordingly.
-
-**Important:** Confirm no existing stable docs pages have a path starting with `nightly` or `preview` — grep `docs/src/SUMMARY.md` to verify.
-
-### 2.5 Wire install.sh and worker deploys
-
-- **install.sh R2 upload** → stays in the nightly workflow (runs on push to `main`, matching current behavior)
-- **docs-proxy worker deploy** → stays in the nightly workflow (worker routes all three channels, deploying once on `main` push is sufficient)
-
----
-
-### 2.6 Add `noindex` meta tag for nightly and preview
-
-Also set a `DOCS_CHANNEL` env var (`nightly`, `preview`, or `stable`) on the build job alongside `MDBOOK_BOOK__SITE_URL` in step 2.1. Add a `channel_name() -> &'static str` method to `DocsChannel` returning the appropriate string.
-
-In `docs/theme/index.hbs`, add a `#noindex#` placeholder in `<head>` directly after the existing `{{#if is_print}}` noindex block:
-
-```html
-#noindex#
-```
-
-In `crates/docs_preprocessor/src/main.rs`'s `handle_postprocessing()`, read `DOCS_CHANNEL` and replace the placeholder — following the same pattern as the existing `#amplitude_key#` and `#description#` replacements:
-
-- `nightly` or `preview`: replace `#noindex#` with `<meta name="robots" content="noindex, nofollow">`
-- anything else: replace `#noindex#` with an empty string
@@ -1,6 +1,7 @@
use gh_workflow::*;
use crate::tasks::workflows::{
+ deploy_docs,
release::{self, notify_on_failure},
runners,
steps::{CommonJobConditions, NamedJob, checkout_repo, dependant_job, named},
@@ -10,6 +11,8 @@ 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 RELEASE_BODY: &str = "${{ github.event.release.body || inputs.body }}";
+const DOCS_CHANNEL: &str =
+ "${{ (github.event.release.prerelease || inputs.prerelease) && 'preview' || 'stable' }}";
pub fn after_release() -> Workflow {
let tag_name = WorkflowInput::string("tag_name", None);
@@ -17,11 +20,13 @@ pub fn after_release() -> Workflow {
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 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,
@@ -37,6 +42,7 @@ pub fn after_release() -> Workflow {
.add_input(body.name, body.input()),
))
.add_job(refresh_zed_dev.name, refresh_zed_dev.job)
+ .add_job(deploy_docs.name, deploy_docs.job)
.add_job(post_to_discord.name, post_to_discord.job)
.add_job(publish_winget.name, publish_winget.job)
.add_job(create_sentry_release.name, create_sentry_release.job)
@@ -1,7 +1,4 @@
-use gh_workflow::{
- Event, Expression, Job, Push, Run, Step, Use, Workflow, WorkflowCall, WorkflowCallSecret,
- WorkflowDispatch,
-};
+use gh_workflow::{Event, Expression, Job, Run, Step, Use, Workflow, WorkflowDispatch};
use crate::tasks::workflows::{
runners,
@@ -167,64 +164,61 @@ pub(crate) fn check_docs() -> NamedJob {
}
}
-pub(crate) fn deploy_docs_job(
- channel_input: &WorkflowInput,
- commit_sha_input: &WorkflowInput,
-) -> NamedJob {
- fn resolve_channel_step(
- channel_input: &WorkflowInput,
- ) -> (Step<Run>, StepOutput, StepOutput, StepOutput) {
- let step = named::bash(format!(
- indoc::indoc! {r#"
- 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
+fn resolve_channel_step(
+ channel_expr: impl Into<String>,
+) -> (Step<Run>, StepOutput, StepOutput, StepOutput) {
+ let step = Step::new("deploy_docs::resolve_channel_step").run(format!(
+ indoc::indoc! {r#"
+ 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="{nightly_site_url}"
- PROJECT_NAME="{nightly_project_name}"
- ;;
- "preview")
- SITE_URL="{preview_site_url}"
- PROJECT_NAME="{preview_project_name}"
- ;;
- "stable")
- SITE_URL="{stable_site_url}"
- PROJECT_NAME="{stable_project_name}"
- ;;
- *)
- echo "::error::Invalid docs channel '$CHANNEL'. Expected one of: nightly, preview, stable."
- exit 1
- ;;
- esac
+ case "$CHANNEL" in
+ "nightly")
+ SITE_URL="{nightly_site_url}"
+ PROJECT_NAME="{nightly_project_name}"
+ ;;
+ "preview")
+ SITE_URL="{preview_site_url}"
+ PROJECT_NAME="{preview_project_name}"
+ ;;
+ "stable")
+ SITE_URL="{stable_site_url}"
+ PROJECT_NAME="{stable_project_name}"
+ ;;
+ *)
+ 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"
- "#},
- nightly_site_url = DocsChannel::Nightly.site_url(),
- preview_site_url = DocsChannel::Preview.site_url(),
- stable_site_url = DocsChannel::Stable.site_url(),
- nightly_project_name = DocsChannel::Nightly.project_name(),
- preview_project_name = DocsChannel::Preview.project_name(),
- stable_project_name = DocsChannel::Stable.project_name(),
- ))
- .id("resolve-channel")
- .add_env(("CHANNEL", channel_input.expr()))
- ;
+ echo "channel=$CHANNEL" >> "$GITHUB_OUTPUT"
+ echo "site_url=$SITE_URL" >> "$GITHUB_OUTPUT"
+ echo "project_name=$PROJECT_NAME" >> "$GITHUB_OUTPUT"
+ "#},
+ nightly_site_url = DocsChannel::Nightly.site_url(),
+ preview_site_url = DocsChannel::Preview.site_url(),
+ stable_site_url = DocsChannel::Stable.site_url(),
+ nightly_project_name = DocsChannel::Nightly.project_name(),
+ preview_project_name = DocsChannel::Preview.project_name(),
+ stable_project_name = DocsChannel::Stable.project_name(),
+ ))
+ .id("resolve-channel")
+ .add_env(("CHANNEL", channel_expr.into()));
- let channel = StepOutput::new(&step, "channel");
- let site_url = StepOutput::new(&step, "site_url");
- let project_name = StepOutput::new(&step, "project_name");
- (step, channel, site_url, project_name)
- }
- let (resolve_step, channel, site_url, project_name) = resolve_channel_step(channel_input);
+ let channel = StepOutput::new(&step, "channel");
+ let site_url = StepOutput::new(&step, "site_url");
+ let project_name = StepOutput::new(&step, "project_name");
+ (step, channel, site_url, project_name)
+}
+
+fn docs_job(channel_expr: impl Into<String>, checkout_ref: Option<String>) -> NamedJob {
+ let (resolve_step, channel, site_url, project_name) = resolve_channel_step(channel_expr);
NamedJob {
name: "deploy_docs".to_owned(),
@@ -236,11 +230,7 @@ pub(crate) fn deploy_docs_job(
"github.repository_owner == 'zed-industries'",
))
.add_step(resolve_step),
- Some(format!(
- "${{{{ {} != '' && {} || github.sha }}}}",
- commit_sha_input.expr(),
- commit_sha_input.expr()
- )),
+ checkout_ref,
channel.to_string(),
site_url.to_string(),
),
@@ -249,6 +239,27 @@ pub(crate) fn deploy_docs_job(
}
}
+pub(crate) fn release_docs_job(
+ channel_expr: impl Into<String>,
+ checkout_ref: impl Into<String>,
+) -> NamedJob {
+ docs_job(channel_expr, Some(checkout_ref.into()))
+}
+
+pub(crate) fn deploy_docs_job(
+ channel_input: &WorkflowInput,
+ commit_sha_input: &WorkflowInput,
+) -> NamedJob {
+ docs_job(
+ channel_input.expr(),
+ Some(format!(
+ "${{{{ {} != '' && {} || github.sha }}}}",
+ commit_sha_input.expr(),
+ commit_sha_input.expr()
+ )),
+ )
+}
+
pub(crate) fn deploy_docs() -> Workflow {
let channel = WorkflowInput::string("channel", Some(String::new()))
.description("Docs channel to deploy: nightly, preview, or stable");
@@ -258,44 +269,10 @@ pub(crate) fn deploy_docs() -> Workflow {
let deploy_docs = deploy_docs_job(&channel, &commit_sha);
named::workflow()
- .add_event(
- Event::default()
- .push(Push::default().add_branch("main"))
- .workflow_dispatch(
- WorkflowDispatch::default()
- .add_input(channel.name, channel.input())
- .add_input(commit_sha.name, commit_sha.input()),
- ),
- )
- .add_event(
- Event::default().workflow_call(
- WorkflowCall::default()
- .add_input(channel.name, channel.call_input())
- .add_input(commit_sha.name, commit_sha.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,
- },
- ),
- ]),
- ),
- )
+ .on(Event::default().workflow_dispatch(
+ WorkflowDispatch::default()
+ .add_input(channel.name, channel.input())
+ .add_input(commit_sha.name, commit_sha.input()),
+ ))
.add_job(deploy_docs.name, deploy_docs.job)
}
@@ -1,7 +1,4 @@
-use gh_workflow::{
- Event, Expression, Input, Job, Level, Permissions, Push, Run, Step, Use, UsesJob, Workflow,
- ctx::Context,
-};
+use gh_workflow::{Event, Expression, Push, Run, Step, Use, Workflow, ctx::Context};
use indoc::formatdoc;
use crate::tasks::workflows::{
@@ -67,7 +64,6 @@ pub(crate) fn release() -> Workflow {
);
let auto_release_preview = auto_release_preview(&[&validate_release_assets]);
- let deploy_docs = deploy_docs(&[&validate_release_assets], &create_draft_release);
let test_jobs = [
&macos_tests,
@@ -113,7 +109,6 @@ pub(crate) fn release() -> Workflow {
.add_job(upload_release_assets.name, upload_release_assets.job)
.add_job(validate_release_assets.name, validate_release_assets.job)
.add_job(auto_release_preview.name, auto_release_preview.job)
- .add_job(deploy_docs.name, deploy_docs.job)
.add_job(push_slack_notification.name, push_slack_notification.job)
}
@@ -375,50 +370,6 @@ fn auto_release_preview(deps: &[&NamedJob]) -> NamedJob {
)
}
-fn deploy_docs(deps: &[&NamedJob], create_draft_release: &NamedJob) -> NamedJob<UsesJob> {
- let job = Job::default()
- .needs(
- deps.iter()
- .map(|job| job.name.clone())
- .chain(std::iter::once(create_draft_release.name.clone()))
- .collect::<Vec<_>>(),
- )
- .permissions(Permissions::default().contents(Level::Read))
- .uses(
- "zed-industries",
- "zed",
- ".github/workflows/deploy_docs.yml",
- "main",
- )
- .with(
- Input::default()
- .add(
- "channel",
- "${{ endsWith(github.ref_name, '-pre') && 'preview' || 'stable' }}",
- )
- .add("commit_sha", "${{ github.sha }}"),
- )
- .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,
- }
-}
-
pub(crate) fn download_workflow_artifacts() -> Step<Use> {
named::uses(
"actions",