mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-06-17 14:18:10 +00:00
Compare commits
1 Commits
luzk/docs-
...
flow-scrip
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
386a1650da |
114
.github/workflows/docs-snapshots.yml
vendored
114
.github/workflows/docs-snapshots.yml
vendored
@@ -1,114 +0,0 @@
|
||||
name: Docs Snapshots Guard
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "docs/**"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
|
||||
jobs:
|
||||
guard:
|
||||
name: Protect frozen snapshots and append-only assets
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Determine merge base
|
||||
id: base
|
||||
run: |
|
||||
base_sha="$(git merge-base "origin/${{ github.event.pull_request.base.ref }}" HEAD)"
|
||||
echo "sha=$base_sha" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Detect escape-hatch label
|
||||
id: escape
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
run: |
|
||||
# The [docs-freeze] marker (in the PR title) is the only way to
|
||||
# legitimately modify frozen snapshots or remove published assets.
|
||||
# Detect it from the title since the workflow runs on
|
||||
# pull_request (not pull_request_target) and can't always read
|
||||
# labels reliably.
|
||||
if [[ "$PR_TITLE" == *"[docs-freeze]"* ]]; then
|
||||
echo "allowed=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "allowed=false" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
- name: Guard frozen snapshots
|
||||
env:
|
||||
ALLOWED: ${{ steps.escape.outputs.allowed }}
|
||||
BASE_SHA: ${{ steps.base.outputs.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Anything under docs/v<X.Y.Z>/ is a frozen release snapshot and
|
||||
# must not change after the release-cut PR that introduced it.
|
||||
# The release-cut PR uses the [docs-freeze] title prefix to opt
|
||||
# out of this guard. ``docs/v[0-9]*/**`` is the defensive form so
|
||||
# we never catch a hypothetical ``docs/vendor/`` etc.
|
||||
violations="$(git diff --name-only --diff-filter=AMDRT \
|
||||
"$BASE_SHA"..HEAD -- 'docs/v[0-9]*/**' || true)"
|
||||
|
||||
if [[ -z "$violations" ]]; then
|
||||
echo "OK: no changes under docs/v*/"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$ALLOWED" == "true" ]]; then
|
||||
echo "OK: [docs-freeze] PR is allowed to touch docs/v*/:"
|
||||
echo "$violations"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "::error::This PR modifies frozen release snapshots under docs/v*/."
|
||||
echo "Frozen snapshots are immutable. To intentionally edit a snapshot"
|
||||
echo "(e.g. a release-cut PR generated by 'devtools release' or the"
|
||||
echo "manual 'scripts/docs/freeze_current_edge.py' wrapper), prefix"
|
||||
echo "the PR title with [docs-freeze]."
|
||||
echo
|
||||
echo "Offending files:"
|
||||
echo "$violations"
|
||||
exit 1
|
||||
|
||||
- name: Guard append-only images
|
||||
env:
|
||||
ALLOWED: ${{ steps.escape.outputs.allowed }}
|
||||
BASE_SHA: ${{ steps.base.outputs.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Deleting or renaming an image breaks every frozen snapshot that
|
||||
# still references it (snapshots reuse docs/images/ at the docs
|
||||
# root). Only [docs-freeze] PRs are allowed to do that.
|
||||
deletions="$(git diff --name-only --diff-filter=DR \
|
||||
"$BASE_SHA"..HEAD -- 'docs/images/**' || true)"
|
||||
|
||||
if [[ -z "$deletions" ]]; then
|
||||
echo "OK: no images deleted or renamed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$ALLOWED" == "true" ]]; then
|
||||
echo "OK: [docs-freeze] PR is allowed to delete/rename images:"
|
||||
echo "$deletions"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "::error::This PR deletes or renames files under docs/images/."
|
||||
echo "Images are append-only because frozen snapshots in docs/v*/"
|
||||
echo "share a single docs/images/ directory and would break if an"
|
||||
echo "asset they reference disappears or moves."
|
||||
echo
|
||||
echo "If the asset is wrong, add a new file with a new name and"
|
||||
echo "reference the new name in Edge (docs/edge/<lang>/...). Leave"
|
||||
echo "the old file in place so historical snapshots keep rendering."
|
||||
echo
|
||||
echo "Offending files:"
|
||||
echo "$deletions"
|
||||
exit 1
|
||||
142
AGENTS.md
142
AGENTS.md
@@ -1,142 +0,0 @@
|
||||
# Docs contributor guide
|
||||
|
||||
The `docs/` directory is published at [docs.crewai.com](https://docs.crewai.com)
|
||||
by [Mintlify](https://www.mintlify.com/). Mintlify watches `docs/docs.json`
|
||||
and the MDX files referenced from it.
|
||||
|
||||
## TL;DR for editing docs
|
||||
|
||||
- Edit MDX under `docs/edge/<lang>/...` (e.g. `docs/edge/en/concepts/agents.mdx`).
|
||||
- Your change ships under the **Edge** version selector the moment it merges
|
||||
to `main`. Edge follows `main` and is the channel for unreleased work.
|
||||
- On release cut, the current Edge state is frozen into `docs/v<X.Y.Z>/` and
|
||||
that snapshot becomes the new default version in the selector (tag:
|
||||
`Latest`). Canonical URLs (`/<lang>/...`) auto-redirect to the new default.
|
||||
- Never modify files under `docs/v*/`. Those are frozen release snapshots
|
||||
and the `docs-snapshots` CI guard rejects writes. The only exception is a
|
||||
release-cut PR (auto-generated by `devtools release` or the manual
|
||||
`scripts/docs/freeze_current_edge.py` wrapper), which uses a
|
||||
`[docs-freeze]` title prefix to opt out.
|
||||
- Never delete or rename files under `docs/images/`. Images are append-only.
|
||||
See [Images](#images) below.
|
||||
|
||||
## The version model
|
||||
|
||||
The site has one rolling channel (Edge) plus one frozen snapshot per
|
||||
release.
|
||||
|
||||
```
|
||||
docs/
|
||||
edge/ <-- Edge sources (you edit here)
|
||||
en/...
|
||||
pt-BR/ ko/ ar/
|
||||
enterprise-api.*.yaml
|
||||
|
||||
v1.14.7/ <-- frozen snapshot of v1.14.7
|
||||
en/...
|
||||
pt-BR/ ko/ ar/
|
||||
enterprise-api.*.yaml
|
||||
v1.14.6/...
|
||||
...
|
||||
|
||||
images/ <-- shared, append-only
|
||||
docs.json <-- Mintlify config: navigation + redirects
|
||||
```
|
||||
|
||||
`docs/docs.json` lists one navigation block per version per language. Edge
|
||||
points at `docs/edge/<lang>/...`; every other version points at its own
|
||||
`docs/v<X.Y.Z>/<lang>/...` subtree. Mintlify scopes both the sidebar and the
|
||||
in-site search to whichever version the reader selects, so picking
|
||||
`v1.10.0` genuinely shows the v1.10.0 docs (and only those).
|
||||
|
||||
### URLs and canonical redirects
|
||||
|
||||
Each Mintlify version corresponds to its own URL prefix:
|
||||
|
||||
- Edge: `/edge/<lang>/<page>` (e.g. `/edge/en/concepts/agents`)
|
||||
- Frozen: `/v<X.Y.Z>/<lang>/<page>` (e.g. `/v1.14.7/en/concepts/agents`)
|
||||
|
||||
External links to the old, unversioned `/<lang>/<page>` URLs would 404 under
|
||||
this layout. To keep them working, `docs.json` ships wildcard redirects:
|
||||
|
||||
```jsonc
|
||||
{ "source": "/en/:slug*", "destination": "/v1.14.7/en/:slug*", "permanent": false }
|
||||
```
|
||||
|
||||
The release-cut step rewrites the destination on every release so canonical
|
||||
`/<lang>/...` URLs always resolve to the latest stable docs.
|
||||
|
||||
## Lifecycle
|
||||
|
||||
1. **During development.** You add or edit pages under
|
||||
`docs/edge/<lang>/...` in normal PRs. They land in Edge as soon as the PR
|
||||
merges. Both `/edge/<lang>/<page>` and the version selector's `Edge` entry
|
||||
reflect the change immediately.
|
||||
2. **Release cut.** The release engineer runs `devtools release X.Y.Z`. As
|
||||
part of that flow the CLI opens a `[docs-freeze]` PR that copies Edge into
|
||||
`docs/v<X.Y.Z>/`, rewrites internal OpenAPI references, updates
|
||||
`docs/docs.json` to make `v<X.Y.Z>` the new default + `Latest`, and rewires
|
||||
the canonical-URL redirects to the new default. The PR must merge before
|
||||
the tag and PyPI publish run.
|
||||
3. **After release.** Edge keeps rolling. Patch fixes to the just-released
|
||||
docs go into Edge and ship with the next release. We do not back-edit
|
||||
frozen snapshots.
|
||||
|
||||
See [`RELEASING.md`](RELEASING.md) for the full release runbook.
|
||||
|
||||
## Images
|
||||
|
||||
Snapshots share a single `docs/images/` directory. If an image is deleted
|
||||
or renamed, every frozen snapshot that referenced it breaks. So the rule
|
||||
is:
|
||||
|
||||
- Adding new images is always fine.
|
||||
- Deleting or renaming an existing image fails CI unless the PR is a
|
||||
`[docs-freeze]` release-cut PR.
|
||||
- If an asset is wrong, add a new file with a new name and reference the
|
||||
new name in the Edge MDX (`docs/edge/<lang>/...`). Leave the old file
|
||||
alone.
|
||||
|
||||
## Local preview
|
||||
|
||||
Install the Mintlify CLI and run from `docs/`:
|
||||
|
||||
```bash
|
||||
npm i -g mintlify
|
||||
mintlify dev
|
||||
```
|
||||
|
||||
Use the version selector at the top of the rendered page to switch between
|
||||
Edge and frozen versions.
|
||||
|
||||
To check links across every version:
|
||||
|
||||
```bash
|
||||
mintlify broken-links
|
||||
```
|
||||
|
||||
CI runs the broken-links check on every PR that touches `docs/**` via
|
||||
[`.github/workflows/docs-broken-links.yml`](.github/workflows/docs-broken-links.yml).
|
||||
|
||||
## Scripts
|
||||
|
||||
- `scripts/docs/freeze_historical_versions.py` — one-time migration that
|
||||
reconstructed `docs/v1.10.0/` through `docs/v1.14.7/` from git tags. You
|
||||
should not need to run this again.
|
||||
- `scripts/docs/prefix_version_paths.py` — one-time migration that switched
|
||||
`docs/docs.json` to directory-based versioning, inserted Edge, and added
|
||||
the canonical-URL redirects. You should not need to run this again.
|
||||
- `scripts/docs/freeze_current_edge.py` — thin CLI wrapper around
|
||||
`crewai_devtools.docs_versioning.freeze`. `devtools release` calls the
|
||||
same module during its docs PR step; this script is the manual escape
|
||||
hatch (e.g. retroactively freezing a forgotten release).
|
||||
|
||||
## CI guards
|
||||
|
||||
- [`.github/workflows/docs-snapshots.yml`](.github/workflows/docs-snapshots.yml)
|
||||
enforces the two rules above (frozen snapshots immutable, images
|
||||
append-only). Both checks accept the `[docs-freeze]` PR-title escape
|
||||
hatch.
|
||||
- [`.github/workflows/docs-broken-links.yml`](.github/workflows/docs-broken-links.yml)
|
||||
runs `mintlify broken-links` against the whole site, so adding a new
|
||||
page or moving a snapshot file that breaks a link will fail CI.
|
||||
13
README.md
13
README.md
@@ -601,19 +601,6 @@ CrewAI is open-source and we welcome contributions. If you're looking to contrib
|
||||
- Send a pull request.
|
||||
- We appreciate your input!
|
||||
|
||||
### Contributing to the docs
|
||||
|
||||
The site at [docs.crewai.com](https://docs.crewai.com) is published from
|
||||
`docs/` by [Mintlify](https://www.mintlify.com/). The docs use directory-based
|
||||
versioning: edits to `docs/edge/<lang>/...` (e.g.
|
||||
`docs/edge/en/concepts/agents.mdx`) land under the **Edge** version selector
|
||||
immediately and are frozen into a new versioned snapshot under
|
||||
`docs/v<X.Y.Z>/` at the next release cut. Frozen snapshots are immutable — CI
|
||||
rejects PRs that modify them without a `[docs-freeze]` title prefix. The
|
||||
release CLI (`devtools release`) handles the freeze automatically; see
|
||||
[`AGENTS.md`](AGENTS.md) for the full contributor guide and
|
||||
[`RELEASING.md`](RELEASING.md) for the release-cut runbook.
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
```bash
|
||||
|
||||
104
RELEASING.md
104
RELEASING.md
@@ -1,104 +0,0 @@
|
||||
# Releasing crewai
|
||||
|
||||
The release CLI (`devtools release`) drives the full end-to-end flow,
|
||||
including the docs-versioning step that has to happen at every release cut.
|
||||
This runbook is the human-facing summary; the canonical implementation lives
|
||||
in [`lib/devtools/src/crewai_devtools/cli.py`](lib/devtools/src/crewai_devtools/cli.py).
|
||||
|
||||
## Why a docs-versioning step exists
|
||||
|
||||
Until the v1.15 series, `docs/docs.json` had 16 "versions" in its selector
|
||||
but every one of them rendered the same single-source MDX files. Picking
|
||||
v1.10.0 in the dropdown silently served the latest docs from `main`. We
|
||||
fixed that by adopting Mintlify's directory-based versioning: each release
|
||||
gets its own frozen snapshot under `docs/v<X.Y.Z>/`, an `Edge` selector
|
||||
renders the rolling `main` state (`docs/edge/...`) for unreleased work,
|
||||
and the canonical `/<lang>/...` URLs redirect to whichever version is
|
||||
currently `default` + `Latest`.
|
||||
|
||||
The release-cut step keeps this model honest. Skip it and the new release
|
||||
will not appear in the selector and the canonical URLs will keep pointing
|
||||
at the previous default — i.e. users following a stale link land on docs
|
||||
that don't describe the version they just installed.
|
||||
|
||||
## Happy path: `devtools release`
|
||||
|
||||
For a normal release:
|
||||
|
||||
```bash
|
||||
devtools release 1.15.0
|
||||
```
|
||||
|
||||
This runs the full pipeline:
|
||||
|
||||
1. Phase 1 — version bump PR, polls until merged.
|
||||
2. Phase 2 — generates AI release notes, then opens the docs PR titled
|
||||
`[docs-freeze] docs: snapshot and changelog for v1.15.0`. That PR:
|
||||
- prepends a release entry to `docs/edge/<lang>/changelog.mdx` for every
|
||||
supported locale,
|
||||
- copies `docs/edge/` into `docs/v1.15.0/`,
|
||||
- rewrites `openapi:` MDX refs inside the snapshot so each frozen page
|
||||
reads its own OpenAPI YAML instead of the live one,
|
||||
- inserts a `v1.15.0` entry into every language block in
|
||||
`docs/docs.json`, marks it `default: true` with tag `"Latest"`, and
|
||||
demotes the previous default,
|
||||
- rewires the wildcard redirects so `/<lang>/:slug*` lands on
|
||||
`/v1.15.0/<lang>/:slug*`.
|
||||
|
||||
The CLI polls until you (or another reviewer) merge the docs PR.
|
||||
3. Phase 2 (cont.) — tags `main`, creates the GitHub release, triggers
|
||||
`publish.yml`, and bumps the deployment_test repo.
|
||||
4. Phase 3 — clones the enterprise repo, bumps versions, opens its bump
|
||||
PR, polls, then tags + releases enterprise.
|
||||
|
||||
The `[docs-freeze]` PR title prefix is what the
|
||||
[`docs-snapshots.yml`](.github/workflows/docs-snapshots.yml) CI guard reads
|
||||
to allow the snapshot directory and any image deletions to land. The CLI
|
||||
sets it automatically.
|
||||
|
||||
Pre-releases (e.g. `1.15.0a1`) skip the snapshot step — they ride Edge —
|
||||
and the docs PR title omits the `[docs-freeze]` prefix.
|
||||
|
||||
## Manual escape hatch: freeze script
|
||||
|
||||
If you ever need to freeze without going through the full release flow (e.g.
|
||||
retroactively snapshotting a release that shipped without docs versioning,
|
||||
or testing the freeze locally):
|
||||
|
||||
```bash
|
||||
python scripts/docs/freeze_current_edge.py 1.15.0
|
||||
```
|
||||
|
||||
This is a thin wrapper around the same `crewai_devtools.docs_versioning.freeze`
|
||||
function used by `devtools release`. It updates the snapshot + `docs.json`
|
||||
+ redirects but does not touch changelogs, open a PR, or coordinate with the
|
||||
rest of the release flow. Pair it with a manual PR titled
|
||||
`[docs-freeze] snapshot docs for v1.15.0`.
|
||||
|
||||
## Lifecycle reminders
|
||||
|
||||
- Edge (`docs/edge/...`) always reflects `main`. After a release cut, fixes
|
||||
to the just-released docs go into Edge as normal PRs and ship with the
|
||||
next release.
|
||||
- We do not back-port docs fixes into older frozen snapshots. If a fix
|
||||
matters enough to publish on an older version, it is a deliberate
|
||||
`[docs-freeze]` PR — treat that as an exception.
|
||||
- The freeze function is idempotent. If you have to re-run it (e.g. you
|
||||
pushed a docs fix between snapshotting and merging the PR), delete the
|
||||
partially-built `docs/v<X.Y.Z>/` directory first and run again.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **The freeze step warned that the snapshot was already current.** Either
|
||||
someone else already cut this version, or a previous run left a stale
|
||||
`docs/v<X.Y.Z>/` directory. Inspect it, then either keep going or delete
|
||||
the directory and re-run.
|
||||
- **CI fails on a non-`[docs-freeze]` PR claiming you modified frozen
|
||||
snapshots.** Check the diff — almost always this is an accidental edit
|
||||
under `docs/v*/`. Move the change to the matching path under
|
||||
`docs/edge/<lang>/...` instead. If you truly need to edit a frozen
|
||||
snapshot, re-title the PR with the `[docs-freeze]` prefix and document
|
||||
the reason in the PR description.
|
||||
- **CI fails on a non-`[docs-freeze]` PR claiming you deleted an image.**
|
||||
Add a new image under a new filename and reference that from Edge. Leave
|
||||
the old file in place so older snapshots keep rendering.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user