Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .claude/commands/pr-description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Generate a pull request description for the current branch based on the commit history and the project's PR template.

Steps:

1. Run `git log origin/master..HEAD --oneline` to list commits in this branch.
2. Run `git diff origin/master..HEAD --stat` to see which files changed.
3. Run `git diff origin/master..HEAD` to read the full diff for context on what changed.
4. Read `.github/PULL_REQUEST_TEMPLATE.md` to get the PR template structure.

Then produce a filled-in PR description using the template:

- Write a clear, concise summary of what changed and why, based on the commits and diff. Include links to relevant files or sections if helpful.
- Leave `### Date Needed` blank (the user will fill it in if needed).
- Leave the `### Reviewers` checklist items blank for the user to fill in names.
- Check the `Ran ./run_tests.sh without warnings or errors` box only if the conversation history shows tests were run and passed cleanly.
- Leave `### HTML Version` and `### Sandbox` unchecked.
- Leave `### Post-review` unchecked.

Output the result as a plain markdown code block (wrapped in triple backticks) so the user can easily copy and paste it into a GitHub PR.
40 changes: 40 additions & 0 deletions .claude/commands/pr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Generate and create a pull request for the current branch against the repo's default upstream (derived from the current git remote).

Steps:

1. Run `git log origin/master..HEAD --oneline` to list commits in this branch.
2. Run `git diff origin/master..HEAD --stat` to see which files changed.
3. Run `git diff origin/master..HEAD` to read the full diff for context on what changed.
4. Read `.github/PULL_REQUEST_TEMPLATE.md` to get the PR template structure.

Generate a PR title and description:

- **Title**: A short, descriptive title (under 70 characters) based on the commits.
- **Description**: Fill in the PR template:
- Write a clear summary of what changed and why, based on the commits and diff.
- Leave `### Date Needed` blank.
- Leave `### Reviewers` checklist items blank for the user to fill in.
- Check the `Ran ./run_tests.sh without warnings or errors` box only if the conversation history shows tests passed cleanly.
- Leave `### HTML Version`, `### Sandbox`, and `### Post-review` unchecked.

Then:

5. **Security scan**: Search the diff for potential secrets or sensitive material. Look for patterns such as:
- API keys, tokens, or passwords (e.g. strings matching `sk-`, `ghp_`, `xox`, `Bearer`, `token`, `secret`, `password`, `api_key` — case-insensitive)
- Private keys or certificates (e.g. `-----BEGIN`)
- Hardcoded credentials or connection strings
- AWS/GCP/Azure key patterns

If anything suspicious is found, **stop and report it to the user** before proceeding. Do not create the PR.

6. Show the user the generated title and description and ask for confirmation before proceeding.
7. If confirmed, push the current branch to `origin` if it hasn't been pushed yet (run `git push -u origin HEAD`).
8. Determine the target repo by running `gh repo view --json nameWithOwner -q .nameWithOwner` to derive it from the current git remote. Write the PR body to a temp file and create the PR using:
```
cat > /tmp/pr-body.md << 'EOF'
<description>
EOF
gh pr create --repo <nameWithOwner> --base master --title "<title>" --body-file /tmp/pr-body.md
Comment on lines +34 to +37
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The command gh pr create --repo <nameWithOwner> --base master --title "<title>" --body-file /tmp/pr-body.md interpolates the generated PR title directly into a double-quoted shell argument, which can lead to command injection if <title> ever contains shell metacharacters such as $(), backticks, or unbalanced quotes derived from commit messages or other untrusted text. An attacker who controls commit messages or branch metadata could craft content that, when used to build <title>, causes arbitrary commands to execute when this snippet is run in a shell. To avoid this, ensure the title is passed to gh without going through the shell for interpolation (for example by using a safe argument-passing mechanism or robust escaping/quoting rather than embedding it directly in a double-quoted shell string).

Suggested change
cat > /tmp/pr-body.md << 'EOF'
<description>
EOF
gh pr create --repo <nameWithOwner> --base master --title "<title>" --body-file /tmp/pr-body.md
python - << 'PY'
import subprocess
import textwrap
name_with_owner = "<nameWithOwner>"
title = "<title>"
body = textwrap.dedent("""<description>
""").lstrip()
with open("/tmp/pr-body.md", "w", encoding="utf-8") as f:
f.write(body)
subprocess.run(
[
"gh",
"pr",
"create",
"--repo",
name_with_owner,
"--base",
"master",
"--title",
title,
"--body-file",
"/tmp/pr-body.md",
],
check=True,
)
PY

Copilot uses AI. Check for mistakes.
rm /tmp/pr-body.md
Comment on lines +31 to +38
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 8 derives <nameWithOwner> from the current repo, but step 1–3 still assume origin/master and step 37 hard-codes --base master. If the base branch differs or the repo is a fork, this can create PRs against the wrong base. Consider deriving the base branch name from the target repo (and/or local default branch ref) and using it for both the diff range and the gh pr create --base argument.

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +38
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing the PR body to a fixed path (/tmp/pr-body.md) risks clobbering an existing file and can be unsafe on multi-user systems (symlink/hardlink attacks). Prefer creating a unique temp file (e.g., via mktemp) and cleaning it up reliably (e.g., with a shell trap) after gh pr create runs.

Suggested change
8. Determine the target repo by running `gh repo view --json nameWithOwner -q .nameWithOwner` to derive it from the current git remote. Write the PR body to a temp file and create the PR using:
```
cat > /tmp/pr-body.md << 'EOF'
<description>
EOF
gh pr create --repo <nameWithOwner> --base master --title "<title>" --body-file /tmp/pr-body.md
rm /tmp/pr-body.md
8. Determine the target repo by running `gh repo view --json nameWithOwner -q .nameWithOwner` to derive it from the current git remote. Write the PR body to a securely created temp file and create the PR using:

pr_body_file="$(mktemp)"
trap 'rm -f "$pr_body_file"' EXIT
cat > "$pr_body_file" << 'EOF'

EOF
gh pr create --repo --base master --title "<title>" --body-file "$pr_body_file"

Copilot uses AI. Check for mistakes.
```
9. Output the PR URL so the user can open it.
15 changes: 15 additions & 0 deletions .claude/commands/test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Run the full Sphinx documentation build and test suite using `./run_tests.sh` (or a specific project if one is provided as an argument, e.g. `/test en_us/course_authors/`).

Identify an appropriate virtualenv and source it before running. If an appropriate virtualenv is not found, be sure to prompt the user to either select / enter an appropriate virtualenv, create a new virtualenv, or have you install the requirements globally (not advised) before running.

After the build completes:

1. Report the total Sphinx error and warning counts clearly to the user.
2. Read the `test_root/<project>/err.log` files for any project that failed to get the full warning/error detail.
3. If there are **no errors or warnings**, confirm the build is clean and ready to push.
4. If there **are** errors or warnings:
- List each one with its file path and line number.
- For each issue, either:
- **Fix it automatically** if it is straightforward (e.g. title overline too short, trailing whitespace, malformed RST directives), then re-run the tests to confirm the fix works.
- **Explain how to fix it manually** if it requires editorial judgment (e.g. broken cross-references pointing to missing content, ambiguous section structure).
- After attempting all auto-fixes, re-run the tests and report the final result.
61 changes: 61 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Repository Status

This is an organizational fork of the upstream edx-documentation repository. While the upstream is deprecated, this fork is actively maintained to keep documentation up to date for our organization.

## Common Commands

```bash
# Install Python dependencies
make requirements

# Build all documentation projects (runs tests)
./run_tests.sh

# Build a single documentation project
./run_tests.sh en_us/developers/

# Start live-reload development server for a project
pip install -r shared/tools.txt
./develop.sh en_us/developers/ [port] # Default port: 9090

# Update/recompile Python requirements
make upgrade

# Clean build artifacts
make clean

# Create translation files for Transifex
make i18n
```

## Architecture

This is a **Sphinx-based static documentation site** using reStructuredText (RST) source files. There is no application code — only documentation content and build configuration.

**Technology stack:**
- Markup: reStructuredText (RST)
- Build: Sphinx with `sphinx-book-theme`
- Hosting: Read the Docs (docs.edx.org)
- Translations: Transifex (only 3 projects: edx_students, open_edx_course_authors, open_edx_release_notes)
- CI: GitHub Actions (`.github/workflows/build.yml`) — builds on push to `master` and PRs

**Project layout:**

Each of the 13 documentation projects lives under `en_us/<project_name>/` with standard Sphinx structure:
```
en_us/<project>/
├── Makefile
└── source/
├── conf.py
└── index.rst + content .rst files
```

**Shared configuration** in `shared/conf.py` and `shared/edxconf.py` is imported by individual project `conf.py` files.

**Build behavior:** `run_tests.sh` builds all projects in nit-picky Sphinx mode (`-n`) with 4 parallel workers. Warnings and errors are written to log files in `test_root/` via `-w`, then parsed — a build with any Sphinx warnings or errors is considered a failure.

**PR requirements:** Run `./run_tests.sh` without warnings or errors before submitting. PRs require SME, product, and partner support sign-off per `.github/PULL_REQUEST_TEMPLATE.md`.