mirror of
https://github.com/zed-industries/zed.git
synced 2026-05-24 13:39:08 +00:00
## Summary
Fixes issues discovered while running the docs automation workflow for
the first time, plus improvements based on the v0.225 run where 44
suggestions overwhelmed a single Droid invocation.
### docs-suggest-publish
- Ignore untracked files when checking for clean working directory
- Add `--auto high` flag to droid exec for non-interactive use
- Add error handling to show droid output on failure
- Remove non-existent `documentation` label from PR creation
- Use `--write` flag for prettier to fix formatting
- **Batch suggestions** into groups of 10 (configurable with
`--batch-size`) to prevent Droid from dropping suggestions when context
is too large
- **Pre-PR docs build validation** — runs `generate-action-metadata` +
`mdbook build` before creating the PR to catch invalid `{#action}` and
`{#kb}` references locally instead of waiting for CI (skippable with
`--skip-validation`)
- **Prompt guardrail** — instructs Droid not to invent `{#kb}` or
`{#action}` references, only reusing action names already present in
docs files
- **Stable release detection** — at publish time, checks each queued
PR's merge commit against the latest stable release tag. PRs already in
stable get annotated "ALREADY IN STABLE" so Droid applies content
changes without adding incorrect Preview callouts
- **Feature flag detection** — parses
`crates/feature_flags/src/flags.rs` for all feature flag struct names,
then checks each PR's diff for references. PRs behind feature flags are
skipped entirely since those features aren't generally available yet
### docs-strip-preview-callouts
- Remove non-existent `documentation` label from PR creation
- Add `Release Notes: - N/A` to generated PR body (fixes Danger bot
check)
## Context
These scripts were run for the first time as part of the v0.225 release.
Issues found:
1. The `documentation` label doesn't exist in this repo
2. Droid exec needs `--auto high` for non-interactive execution
3. Prettier needs `--write` to actually fix files (was running in check
mode)
4. Untracked files should not block the workflow
5. Sending all 44 suggestions in one Droid invocation only applied 2 —
batching in groups of 10 fixed this
6. Droid hallucinated action names (`settings::OpenSettings`,
`gpui::Modifiers::secondary_key`) that broke the docs preprocessor build
7. PRs that shipped in stable v0.225 incorrectly got Preview callouts
because the queue doesn't distinguish preview-only from
already-in-stable
8. PRs behind feature flags (subagents, git graph) got documented
despite not being generally available
Release Notes:
- N/A
591 lines
19 KiB
Bash
Executable file
591 lines
19 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
#
|
|
# Create a draft documentation PR by auto-applying batched suggestions.
|
|
#
|
|
# Usage:
|
|
# script/docs-suggest-publish [--dry-run] [--model MODEL]
|
|
#
|
|
# This script:
|
|
# 1. Reads pending suggestions from the docs/suggestions-pending branch
|
|
# 2. Uses Droid to apply suggestions in batches (default 10 per batch)
|
|
# 3. Runs docs formatting
|
|
# 4. Validates docs build (action references, JSON schemas, links)
|
|
# 5. Creates a draft PR for human review/merge
|
|
# 6. Optionally resets the suggestions branch after successful PR creation
|
|
#
|
|
# Options:
|
|
# --dry-run Show what would be done without creating PR
|
|
# --keep-queue Don't reset the suggestions branch after PR creation
|
|
# --model MODEL Override Droid model used for auto-apply
|
|
# --batch-size N Suggestions per Droid invocation (default: 10)
|
|
# --skip-validation Skip the docs build validation step
|
|
# --verbose Show detailed progress
|
|
#
|
|
# Run this as part of the preview release workflow.
|
|
|
|
set -euo pipefail
|
|
|
|
DRY_RUN=false
|
|
KEEP_QUEUE=false
|
|
VERBOSE=false
|
|
SKIP_VALIDATION=false
|
|
BATCH_SIZE=10
|
|
MODEL="${DROID_MODEL:-claude-sonnet-4-5-latest}"
|
|
|
|
SUGGESTIONS_BRANCH="docs/suggestions-pending"
|
|
|
|
# Colors
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log() {
|
|
if [[ "$VERBOSE" == "true" ]]; then
|
|
echo -e "${BLUE}[docs-publish]${NC} $*" >&2
|
|
fi
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}Error:${NC} $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--dry-run)
|
|
DRY_RUN=true
|
|
shift
|
|
;;
|
|
--keep-queue)
|
|
KEEP_QUEUE=true
|
|
shift
|
|
;;
|
|
--verbose)
|
|
VERBOSE=true
|
|
shift
|
|
;;
|
|
--model)
|
|
MODEL="$2"
|
|
shift 2
|
|
;;
|
|
--batch-size)
|
|
BATCH_SIZE="$2"
|
|
shift 2
|
|
;;
|
|
--skip-validation)
|
|
SKIP_VALIDATION=true
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
head -30 "$0" | tail -28
|
|
exit 0
|
|
;;
|
|
*)
|
|
error "Unknown option: $1"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Get repo root
|
|
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
cd "$REPO_ROOT"
|
|
|
|
# Check if suggestions branch exists
|
|
log "Checking for suggestions branch..."
|
|
if ! git ls-remote --exit-code --heads origin "$SUGGESTIONS_BRANCH" > /dev/null 2>&1; then
|
|
echo "No pending suggestions found (branch $SUGGESTIONS_BRANCH doesn't exist)."
|
|
echo "Suggestions are queued automatically when PRs are merged to main."
|
|
exit 0
|
|
fi
|
|
|
|
# Fetch the suggestions branch
|
|
log "Fetching suggestions branch..."
|
|
git fetch origin "$SUGGESTIONS_BRANCH"
|
|
|
|
# Check for manifest
|
|
if ! git show "origin/$SUGGESTIONS_BRANCH:manifest.json" > /dev/null 2>&1; then
|
|
echo "No manifest found on suggestions branch."
|
|
exit 0
|
|
fi
|
|
|
|
# Read manifest
|
|
MANIFEST=$(git show "origin/$SUGGESTIONS_BRANCH:manifest.json")
|
|
SUGGESTION_COUNT=$(echo "$MANIFEST" | jq '.suggestions | length')
|
|
|
|
if [[ "$SUGGESTION_COUNT" -eq 0 ]]; then
|
|
echo "No pending suggestions in queue."
|
|
exit 0
|
|
fi
|
|
|
|
echo "Found $SUGGESTION_COUNT pending suggestion(s):"
|
|
echo ""
|
|
echo "$MANIFEST" | jq -r '.suggestions[] | " PR #\(.pr): \(.title)"'
|
|
echo ""
|
|
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
|
echo -e "${YELLOW}=== DRY RUN ===${NC}"
|
|
echo ""
|
|
echo "Would auto-apply suggestions to docs via Droid and create a draft PR."
|
|
echo "Model: $MODEL"
|
|
echo ""
|
|
|
|
# Show each suggestion file
|
|
for file in $(echo "$MANIFEST" | jq -r '.suggestions[].file'); do
|
|
echo "--- $file ---"
|
|
git show "origin/$SUGGESTIONS_BRANCH:$file" 2>/dev/null || echo "(file not found)"
|
|
echo ""
|
|
done
|
|
|
|
echo -e "${YELLOW}=== END DRY RUN ===${NC}"
|
|
echo ""
|
|
echo "Run without --dry-run to create the PR."
|
|
exit 0
|
|
fi
|
|
|
|
# Ensure clean working state (ignore untracked files with grep -v '??')
|
|
if [[ -n "$(git status --porcelain | grep -v '^??' || true)" ]]; then
|
|
error "Working directory has uncommitted changes. Please commit or stash first."
|
|
fi
|
|
|
|
REQUIRED_COMMANDS=(git gh jq droid)
|
|
if [[ "$SKIP_VALIDATION" != "true" ]]; then
|
|
REQUIRED_COMMANDS+=(mdbook)
|
|
fi
|
|
for command in "${REQUIRED_COMMANDS[@]}"; do
|
|
if ! command -v "$command" > /dev/null 2>&1; then
|
|
error "Required command not found: $command"
|
|
fi
|
|
done
|
|
|
|
# Remember current branch
|
|
ORIGINAL_BRANCH=$(git branch --show-current)
|
|
log "Current branch: $ORIGINAL_BRANCH"
|
|
|
|
# Create new branch for docs PR from latest main
|
|
git fetch origin main
|
|
DOCS_BRANCH="docs/preview-auto-$(date +%Y-%m-%d-%H%M%S)"
|
|
log "Creating docs branch: $DOCS_BRANCH"
|
|
|
|
git checkout -b "$DOCS_BRANCH" origin/main
|
|
|
|
TMPDIR=$(mktemp -d)
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
APPLY_SUMMARY_FILE="$TMPDIR/apply-summary.md"
|
|
touch "$APPLY_SUMMARY_FILE"
|
|
|
|
# Collect suggestion files into an array
|
|
SUGGESTION_FILES=()
|
|
while IFS= read -r file; do
|
|
SUGGESTION_FILES+=("$file")
|
|
done < <(echo "$MANIFEST" | jq -r '.suggestions[].file')
|
|
|
|
# Determine which PRs are already in the latest stable release.
|
|
# Suggestions queued with --preview may reference features that shipped in stable
|
|
# by the time this script runs, so their Preview callouts should be stripped.
|
|
STABLE_PRS=()
|
|
STABLE_TAG=$(git tag -l 'v*' --sort=-v:refname | grep -v 'pre' | head -1 || true)
|
|
if [[ -n "$STABLE_TAG" ]]; then
|
|
log "Latest stable release tag: $STABLE_TAG"
|
|
for file in "${SUGGESTION_FILES[@]}"; do
|
|
pr_num=$(echo "$MANIFEST" | jq -r --arg f "$file" '.suggestions[] | select(.file == $f) | .pr')
|
|
# Find the merge commit for this PR
|
|
merge_sha=$(gh pr view "$pr_num" --json mergeCommit --jq '.mergeCommit.oid' 2>/dev/null || true)
|
|
if [[ -n "$merge_sha" ]] && git merge-base --is-ancestor "$merge_sha" "$STABLE_TAG" 2>/dev/null; then
|
|
STABLE_PRS+=("$pr_num")
|
|
log "PR #$pr_num is in stable ($STABLE_TAG)"
|
|
fi
|
|
done
|
|
if [[ ${#STABLE_PRS[@]} -gt 0 ]]; then
|
|
echo -e "${YELLOW}Note:${NC} ${#STABLE_PRS[@]} suggestion(s) are for PRs already in stable ($STABLE_TAG)."
|
|
echo " Preview callouts will be stripped for: ${STABLE_PRS[*]}"
|
|
echo ""
|
|
fi
|
|
else
|
|
log "No stable release tag found, treating all suggestions as preview-only"
|
|
fi
|
|
|
|
# Determine which PRs touch code gated behind feature flags.
|
|
# Features behind flags aren't generally available and shouldn't be documented yet.
|
|
FLAGGED_PRS=()
|
|
FLAGS_FILE="$REPO_ROOT/crates/feature_flags/src/flags.rs"
|
|
if [[ -f "$FLAGS_FILE" ]]; then
|
|
# Extract feature flag struct names (e.g. SubagentsFeatureFlag, GitGraphFeatureFlag)
|
|
FLAG_NAMES=$(grep -oE 'pub struct \w+FeatureFlag' "$FLAGS_FILE" | awk '{print $3}')
|
|
if [[ -n "$FLAG_NAMES" ]]; then
|
|
FLAG_PATTERN=$(echo "$FLAG_NAMES" | tr '\n' '|' | sed 's/|$//')
|
|
log "Feature flags found: $(echo "$FLAG_NAMES" | tr '\n' ' ')"
|
|
for file in "${SUGGESTION_FILES[@]}"; do
|
|
pr_num=$(echo "$MANIFEST" | jq -r --arg f "$file" '.suggestions[] | select(.file == $f) | .pr')
|
|
# Skip PRs already marked as stable (no need to double-check)
|
|
is_already_stable=false
|
|
for stable_pr in "${STABLE_PRS[@]+"${STABLE_PRS[@]}"}"; do
|
|
if [[ "$stable_pr" == "$pr_num" ]]; then
|
|
is_already_stable=true
|
|
break
|
|
fi
|
|
done
|
|
if [[ "$is_already_stable" == "true" ]]; then
|
|
continue
|
|
fi
|
|
# Check if the PR diff references any feature flag
|
|
pr_diff=$(gh pr diff "$pr_num" 2>/dev/null || true)
|
|
if [[ -n "$pr_diff" ]] && echo "$pr_diff" | grep -qE "$FLAG_PATTERN"; then
|
|
matched_flags=$(echo "$pr_diff" | grep -oE "$FLAG_PATTERN" | sort -u | tr '\n' ', ' | sed 's/,$//')
|
|
FLAGGED_PRS+=("$pr_num")
|
|
log "PR #$pr_num is behind feature flag(s): $matched_flags"
|
|
fi
|
|
done
|
|
if [[ ${#FLAGGED_PRS[@]} -gt 0 ]]; then
|
|
echo -e "${YELLOW}Note:${NC} ${#FLAGGED_PRS[@]} suggestion(s) are for features behind feature flags."
|
|
echo " These will be skipped: ${FLAGGED_PRS[*]}"
|
|
echo ""
|
|
fi
|
|
fi
|
|
else
|
|
log "Feature flags file not found, skipping flag detection"
|
|
fi
|
|
|
|
# Split into batches
|
|
TOTAL=${#SUGGESTION_FILES[@]}
|
|
BATCH_COUNT=$(( (TOTAL + BATCH_SIZE - 1) / BATCH_SIZE ))
|
|
|
|
if [[ "$BATCH_COUNT" -gt 1 ]]; then
|
|
echo "Processing $TOTAL suggestions in $BATCH_COUNT batches of up to $BATCH_SIZE..."
|
|
else
|
|
echo "Processing $TOTAL suggestions..."
|
|
fi
|
|
echo ""
|
|
|
|
for (( batch=0; batch<BATCH_COUNT; batch++ )); do
|
|
START=$(( batch * BATCH_SIZE ))
|
|
END=$(( START + BATCH_SIZE ))
|
|
if [[ "$END" -gt "$TOTAL" ]]; then
|
|
END=$TOTAL
|
|
fi
|
|
|
|
BATCH_NUM=$(( batch + 1 ))
|
|
BATCH_SUGGESTIONS_FILE="$TMPDIR/batch-${BATCH_NUM}-suggestions.md"
|
|
BATCH_PROMPT_FILE="$TMPDIR/batch-${BATCH_NUM}-prompt.md"
|
|
BATCH_SUMMARY_FILE="$TMPDIR/batch-${BATCH_NUM}-summary.md"
|
|
|
|
echo -e "${BLUE}Batch $BATCH_NUM/$BATCH_COUNT${NC} (suggestions $(( START + 1 ))-$END of $TOTAL)"
|
|
|
|
# Combine suggestion files for this batch, skipping flagged PRs and annotating stable PRs
|
|
BATCH_HAS_SUGGESTIONS=false
|
|
for (( i=START; i<END; i++ )); do
|
|
file="${SUGGESTION_FILES[$i]}"
|
|
pr_num=$(echo "$MANIFEST" | jq -r --arg f "$file" '.suggestions[] | select(.file == $f) | .pr')
|
|
|
|
# Skip PRs behind feature flags entirely
|
|
is_flagged=false
|
|
for flagged_pr in "${FLAGGED_PRS[@]+"${FLAGGED_PRS[@]}"}"; do
|
|
if [[ "$flagged_pr" == "$pr_num" ]]; then
|
|
is_flagged=true
|
|
break
|
|
fi
|
|
done
|
|
if [[ "$is_flagged" == "true" ]]; then
|
|
log "Skipping PR #$pr_num (behind feature flag)"
|
|
{
|
|
echo "### Skipped: PR #$pr_num"
|
|
echo ""
|
|
echo "This PR is behind a feature flag and was not applied."
|
|
echo ""
|
|
} >> "$APPLY_SUMMARY_FILE"
|
|
continue
|
|
fi
|
|
|
|
BATCH_HAS_SUGGESTIONS=true
|
|
|
|
# Check if PR is already in stable
|
|
is_stable=false
|
|
for stable_pr in "${STABLE_PRS[@]+"${STABLE_PRS[@]}"}"; do
|
|
if [[ "$stable_pr" == "$pr_num" ]]; then
|
|
is_stable=true
|
|
break
|
|
fi
|
|
done
|
|
{
|
|
echo "## Source: $file"
|
|
if [[ "$is_stable" == "true" ]]; then
|
|
echo ""
|
|
echo "> **ALREADY IN STABLE**: PR #$pr_num shipped in $STABLE_TAG."
|
|
echo "> Do NOT add Preview or Changed-in-Preview callouts for this suggestion."
|
|
echo "> Apply the documentation content only, without any preview-related callouts."
|
|
fi
|
|
echo ""
|
|
git show "origin/$SUGGESTIONS_BRANCH:$file" 2>/dev/null || error "Suggestion file missing: $file"
|
|
echo ""
|
|
echo "---"
|
|
echo ""
|
|
} >> "$BATCH_SUGGESTIONS_FILE"
|
|
done
|
|
|
|
# Skip this batch if all its suggestions were flagged
|
|
if [[ "$BATCH_HAS_SUGGESTIONS" == "false" ]]; then
|
|
echo -e " ${YELLOW}Batch $BATCH_NUM skipped (all suggestions behind feature flags)${NC}"
|
|
continue
|
|
fi
|
|
|
|
# Build auto-apply prompt for this batch
|
|
cat > "$BATCH_PROMPT_FILE" << 'EOF'
|
|
# Documentation Auto-Apply Request (Preview Release)
|
|
|
|
Apply all queued documentation suggestions below directly to docs files in this repository.
|
|
|
|
Before making edits, read and follow these rule files:
|
|
- `.rules`
|
|
- `docs/.rules`
|
|
|
|
## Required behavior
|
|
|
|
1. Apply concrete documentation edits (not suggestion text) to the appropriate files.
|
|
2. Edit only docs content files under `docs/src/` unless a suggestion explicitly requires another docs path.
|
|
3. For every docs file you modify, run a full-file brand voice pass (entire file, not only edited sections).
|
|
4. Enforce the brand rubric exactly; final file content must score 4+ on every criterion:
|
|
- Technical Grounding
|
|
- Natural Syntax
|
|
- Quiet Confidence
|
|
- Developer Respect
|
|
- Information Priority
|
|
- Specificity
|
|
- Voice Consistency
|
|
- Earned Claims
|
|
5. Keep SEO/frontmatter/linking requirements from the suggestions where applicable.
|
|
6. Keep preview callout semantics correct:
|
|
- Additive features: `> **Preview:** ...`
|
|
- Behavior modifications: `> **Changed in Preview (vX.XXX).** ...`
|
|
- **Exception**: Suggestions marked "ALREADY IN STABLE" must NOT get any preview callouts.
|
|
These features already shipped in a stable release. Apply the content changes only.
|
|
- Suggestions for features behind feature flags have been pre-filtered and excluded.
|
|
If you encounter references to feature-flagged functionality, do not document it.
|
|
7. If a suggestion is too ambiguous to apply safely, skip it and explain why in the summary.
|
|
8. **Do not invent `{#kb}` or `{#action}` references.** Only use action names that already
|
|
appear in the existing docs files you are editing. If unsure whether an action name is
|
|
valid, use plain text instead. The docs build validates all action references against
|
|
the compiled binary and will reject unknown names.
|
|
|
|
## Output format (after making edits)
|
|
|
|
Return markdown with:
|
|
|
|
- `## Applied Suggestions`
|
|
- `## Skipped Suggestions`
|
|
- `## Files Updated`
|
|
- `## Brand Voice Verification` (one line per updated file confirming full-file pass)
|
|
|
|
Do not include a patch in the response; apply edits directly to files.
|
|
|
|
## Queued Suggestions
|
|
|
|
EOF
|
|
|
|
cat "$BATCH_SUGGESTIONS_FILE" >> "$BATCH_PROMPT_FILE"
|
|
|
|
log "Running Droid auto-apply (batch $BATCH_NUM) with model: $MODEL"
|
|
if ! droid exec -m "$MODEL" -f "$BATCH_PROMPT_FILE" --auto high > "$BATCH_SUMMARY_FILE" 2>&1; then
|
|
echo "Droid exec output (batch $BATCH_NUM):"
|
|
cat "$BATCH_SUMMARY_FILE"
|
|
error "Droid exec failed on batch $BATCH_NUM. See output above."
|
|
fi
|
|
|
|
# Append batch summary
|
|
{
|
|
echo "### Batch $BATCH_NUM"
|
|
echo ""
|
|
cat "$BATCH_SUMMARY_FILE"
|
|
echo ""
|
|
} >> "$APPLY_SUMMARY_FILE"
|
|
|
|
echo -e " ${GREEN}Batch $BATCH_NUM complete${NC}"
|
|
done
|
|
echo ""
|
|
|
|
log "All batches completed, checking results..."
|
|
|
|
if [[ -n "$(git status --porcelain | grep -v '^??' | grep -vE '^.. docs/' || true)" ]]; then
|
|
error "Auto-apply modified non-doc files. Revert and re-run."
|
|
fi
|
|
|
|
if [[ -z "$(git status --porcelain docs/ | grep '^.. docs/src/' || true)" ]]; then
|
|
error "Auto-apply produced no docs/src changes."
|
|
fi
|
|
|
|
log "Running docs formatter"
|
|
./script/prettier --write
|
|
|
|
if [[ -z "$(git status --porcelain docs/ | grep '^.. docs/src/' || true)" ]]; then
|
|
error "No docs/src changes remain after formatting; aborting PR creation."
|
|
fi
|
|
|
|
# Validate docs build before creating PR
|
|
if [[ "$SKIP_VALIDATION" != "true" ]]; then
|
|
echo "Validating docs build..."
|
|
log "Generating action metadata..."
|
|
if ! ./script/generate-action-metadata > /dev/null 2>&1; then
|
|
echo -e "${YELLOW}Warning:${NC} Could not generate action metadata (cargo build may have failed)."
|
|
echo "Skipping docs build validation. CI will still catch errors."
|
|
else
|
|
VALIDATION_DIR="$TMPDIR/docs-validation"
|
|
if ! mdbook build ./docs --dest-dir="$VALIDATION_DIR" 2>"$TMPDIR/validation-errors.txt"; then
|
|
echo ""
|
|
echo -e "${RED}Docs build validation failed:${NC}"
|
|
cat "$TMPDIR/validation-errors.txt"
|
|
echo ""
|
|
error "Fix the errors above and re-run, or use --skip-validation to bypass."
|
|
fi
|
|
echo -e "${GREEN}Docs build validation passed.${NC}"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Build PR body from suggestions
|
|
PR_BODY_FILE="$TMPDIR/pr-body.md"
|
|
cat > "$PR_BODY_FILE" << 'EOF'
|
|
# Documentation Updates for Preview Release
|
|
|
|
This draft PR auto-applies queued documentation suggestions collected from
|
|
recently merged PRs.
|
|
|
|
## How to Use This PR
|
|
|
|
1. Review the applied changes file-by-file.
|
|
2. Verify brand voice on each touched file as a full-file pass.
|
|
3. Ensure docs use the correct callout type:
|
|
- Additive features: Preview callout
|
|
- Behavior modifications: Changed in Preview callout
|
|
4. Merge when ready.
|
|
|
|
## Auto-Apply Summary
|
|
|
|
EOF
|
|
|
|
cat "$APPLY_SUMMARY_FILE" >> "$PR_BODY_FILE"
|
|
|
|
cat >> "$PR_BODY_FILE" << 'EOF'
|
|
|
|
## Preview Callouts
|
|
|
|
Use the Preview callout for new/additive features:
|
|
|
|
```markdown
|
|
> **Preview:** This feature is available in Zed Preview. It will be included in the next Stable release.
|
|
```
|
|
|
|
Use this callout for behavior modifications to existing functionality:
|
|
|
|
```markdown
|
|
> **Changed in Preview (v0.XXX).** See [release notes](/releases#0.XXX).
|
|
```
|
|
|
|
---
|
|
|
|
## Pending Suggestions
|
|
|
|
EOF
|
|
|
|
# Append each suggestion to PR body
|
|
for file in $(echo "$MANIFEST" | jq -r '.suggestions[].file'); do
|
|
log "Adding $file to PR body..."
|
|
echo "" >> "$PR_BODY_FILE"
|
|
git show "origin/$SUGGESTIONS_BRANCH:$file" >> "$PR_BODY_FILE" 2>/dev/null || true
|
|
echo "" >> "$PR_BODY_FILE"
|
|
echo "---" >> "$PR_BODY_FILE"
|
|
done
|
|
|
|
# Add tracking info
|
|
cat >> "$PR_BODY_FILE" << EOF
|
|
|
|
## PRs Included
|
|
|
|
EOF
|
|
|
|
echo "$MANIFEST" | jq -r '.suggestions[] | "- [PR #\(.pr)](\(.file)): \(.title)"' >> "$PR_BODY_FILE"
|
|
|
|
cat >> "$PR_BODY_FILE" << 'EOF'
|
|
|
|
Release Notes:
|
|
|
|
- N/A
|
|
EOF
|
|
|
|
git add docs/
|
|
git commit -m "docs: Auto-apply preview release suggestions
|
|
|
|
Auto-applied queued documentation suggestions from:
|
|
$(echo "$MANIFEST" | jq -r '.suggestions[] | "- PR #\(.pr)"')
|
|
|
|
Generated with script/docs-suggest-publish for human review in draft PR."
|
|
|
|
# Push and create PR
|
|
log "Pushing branch..."
|
|
git push -u origin "$DOCS_BRANCH"
|
|
|
|
log "Creating PR..."
|
|
PR_URL=$(gh pr create \
|
|
--draft \
|
|
--title "docs: Apply preview release suggestions" \
|
|
--body-file "$PR_BODY_FILE")
|
|
|
|
echo ""
|
|
echo -e "${GREEN}PR created:${NC} $PR_URL"
|
|
|
|
# Reset suggestions branch if not keeping
|
|
if [[ "$KEEP_QUEUE" != "true" ]]; then
|
|
echo ""
|
|
echo "Resetting suggestions queue..."
|
|
|
|
git checkout --orphan "${SUGGESTIONS_BRANCH}-reset"
|
|
git rm -rf . > /dev/null 2>&1 || true
|
|
|
|
cat > README.md << 'EOF'
|
|
# Documentation Suggestions Queue
|
|
|
|
This branch contains batched documentation suggestions for the next Preview release.
|
|
|
|
Each file represents suggestions from a merged PR. At preview branch cut time,
|
|
run `script/docs-suggest-publish` to create a documentation PR from these suggestions.
|
|
|
|
## Structure
|
|
|
|
- `suggestions/PR-XXXXX.md` - Suggestions for PR #XXXXX
|
|
- `manifest.json` - Index of all pending suggestions
|
|
|
|
## Workflow
|
|
|
|
1. PRs merged to main trigger documentation analysis
|
|
2. Suggestions are committed here as individual files
|
|
3. At preview release, suggestions are collected into a docs PR
|
|
4. After docs PR is created, this branch is reset
|
|
EOF
|
|
|
|
mkdir -p suggestions
|
|
echo '{"suggestions":[]}' > manifest.json
|
|
git add README.md suggestions manifest.json
|
|
git commit -m "Reset documentation suggestions queue
|
|
|
|
Previous suggestions published in: $PR_URL"
|
|
|
|
# Force push required: replacing the orphan suggestions branch with a clean slate
|
|
git push -f origin "${SUGGESTIONS_BRANCH}-reset:$SUGGESTIONS_BRANCH"
|
|
git checkout "$ORIGINAL_BRANCH"
|
|
git branch -D "${SUGGESTIONS_BRANCH}-reset"
|
|
|
|
echo "Suggestions queue reset."
|
|
else
|
|
git checkout "$ORIGINAL_BRANCH"
|
|
echo ""
|
|
echo "Suggestions queue kept (--keep-queue). Remember to reset manually after PR is merged."
|
|
fi
|
|
|
|
echo ""
|
|
echo -e "${GREEN}Done!${NC}"
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo "1. Review the draft PR and verify all auto-applied docs changes"
|
|
echo "2. Confirm full-file brand voice pass for each touched docs file"
|
|
echo "3. Mark ready for review and merge"
|