|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +This repository contains Optimizely Labs - a collection of self-contained tutorials demonstrating how to work with Optimizely data and developer tools. Each lab is published to optimizely.com/labs via a Contentful CMS integration. |
| 8 | + |
| 9 | +## Repository Architecture |
| 10 | + |
| 11 | +### Content Structure |
| 12 | +- **`/labs/`**: Each subdirectory is a self-contained lab with its own README.md (tutorial content), metadata.md (Contentful metadata), and any supporting code/resources |
| 13 | +- **`/utils/`**: Python scripts for publishing and managing labs in Contentful CMS |
| 14 | +- **`/templates/`**: Templates for creating new labs (new-content and link-to-existing-content) |
| 15 | +- **`.github/workflows/`**: CI/CD pipelines for automatic publishing to Contentful |
| 16 | + |
| 17 | +### Lab Publication System |
| 18 | +The repository uses a Python-based publishing system that: |
| 19 | +1. Scans `/labs/` for all lab directories (slugs) |
| 20 | +2. Zips each lab's contents and uploads to S3 |
| 21 | +3. Parses `metadata.md` (YAML frontmatter) and README.md/index.md |
| 22 | +4. Upserts lab entries to Contentful CMS |
| 23 | +5. Labs appear at `optimizely.com/labs/{slug}` |
| 24 | + |
| 25 | +**Key files:** |
| 26 | +- `utils/publish.py`: Main publishing script - zips labs, uploads to S3, syncs to Contentful |
| 27 | +- `utils/delete.py`: Deletes a specific lab from Contentful |
| 28 | +- `utils/labs_constants.py`: Configuration constants (paths, Contentful settings, S3 credentials) |
| 29 | + |
| 30 | +### Lab Slug Requirements |
| 31 | +- Slugs must match `^[a-zA-Z0-9-.]{1,64}$` (alphanumeric, dashes, periods, underscores only) |
| 32 | +- Slugs serve as both directory names and Contentful entry IDs |
| 33 | +- Slugs become URL paths: `optimizely.com/labs/{slug}` |
| 34 | + |
| 35 | +## Common Development Tasks |
| 36 | + |
| 37 | +### Installing Dependencies |
| 38 | +```bash |
| 39 | +pip install -r requirements.txt |
| 40 | +``` |
| 41 | + |
| 42 | +### Publishing Labs to Contentful |
| 43 | +Publishing happens automatically on push to `master` branch via GitHub Actions, but can be run manually: |
| 44 | + |
| 45 | +```bash |
| 46 | +# Set required environment variables (see labs_constants.py for full list) |
| 47 | +export LABS_CONTENTFUL_ENVIRONMENT=master |
| 48 | +export LABS_CONTENTFUL_SPACE_ID=zw48pl1isxmc |
| 49 | +export LABS_CONTENTFUL_MANAGEMENT_API_TOKEN=<token> |
| 50 | +export LIBRARY_URL=https://library.optimizely.com/ |
| 51 | +export LIBRARY_S3_BUCKET=library-optimizely-com |
| 52 | +export LIBRARY_S3_ACCESS_KEY=<key> |
| 53 | +export LIBRARY_S3_SECRET_KEY=<secret> |
| 54 | + |
| 55 | +# Run publish script |
| 56 | +python utils/publish.py |
| 57 | +``` |
| 58 | + |
| 59 | +### Deleting a Lab |
| 60 | +```bash |
| 61 | +export SLUG_TO_DELETE=<lab-slug> |
| 62 | +export LABS_CONTENTFUL_ENVIRONMENT=master |
| 63 | +export LABS_CONTENTFUL_SPACE_ID=zw48pl1isxmc |
| 64 | +export LABS_CONTENTFUL_MANAGEMENT_API_TOKEN=<token> |
| 65 | + |
| 66 | +python utils/delete.py |
| 67 | +``` |
| 68 | + |
| 69 | +### Creating a New Lab |
| 70 | + |
| 71 | +1. Create directory under `/labs/` with a valid slug name |
| 72 | +2. Add `README.md` using template from `/templates/new-content/README.md` or `/templates/link-to-existing-content/README.md` |
| 73 | +3. Add `metadata.md` using template from `/templates/metadata.md` |
| 74 | +4. Set `excludeFromListing: true` in metadata.md initially |
| 75 | +5. Use absolute URLs for links/images (prefix with `https://raw.githubusercontent.com/optimizely/labs/master/` for images) |
| 76 | +6. Submit PR for review |
| 77 | +7. After merge, lab appears at `optimizely.com/labs/{slug}` |
| 78 | +8. When ready to feature, set `excludeFromListing: false` via separate PR |
| 79 | + |
| 80 | +### Lab Content Structure |
| 81 | + |
| 82 | +**README.md/index.md** (content priority: index.md > README.md): |
| 83 | +- Tutorial content in Markdown |
| 84 | +- Should include: summary, pre-requisites, numbered steps |
| 85 | +- Use absolute URLs for all links and images |
| 86 | + |
| 87 | +**metadata.md**: |
| 88 | +- YAML frontmatter with: title, summary, revisionDate, labels, author, seo, excludeFromListing |
| 89 | +- Controls how lab appears in Contentful and on optimizely.com/labs |
| 90 | + |
| 91 | +## Lab Types |
| 92 | + |
| 93 | +Labs cover various Optimizely integrations and use cases: |
| 94 | +- **Feature Flags**: Python Flask, Ruby Sinatra examples |
| 95 | +- **Data Analysis**: Spark/PySpark notebooks for Enriched Event data |
| 96 | +- **Integrations**: Third-party integrations (ContentSquare, Crazy Egg, Zuko, Segment) |
| 97 | +- **Browser Extensions**: Custom Optimizely editor extensions |
| 98 | +- **Event Targeting**: Sequential events, custom targeting examples |
| 99 | + |
| 100 | +### Data Analysis Labs |
| 101 | +Some labs (computing-experiment-metrics, query-enriched-event-data-with-spark) use: |
| 102 | +- Docker for containerized execution |
| 103 | +- PySpark for processing Optimizely Enriched Event data |
| 104 | +- Jupyter Lab for interactive notebooks |
| 105 | +- Python requirements.txt for lab-specific dependencies |
| 106 | + |
| 107 | +Run these labs using: |
| 108 | +```bash |
| 109 | +bash bin/run.sh # Uses Docker (primary method) |
| 110 | +bash bin/run-docker.sh # Direct Docker execution |
| 111 | +``` |
| 112 | + |
| 113 | +## Important Notes |
| 114 | + |
| 115 | +- Labs are self-contained - all resources should be within the lab directory |
| 116 | +- Publishing is automatic on master branch commits |
| 117 | +- Lab zips are uploaded to S3 and linked in Contentful as downloadable resources |
| 118 | +- Metadata field `excludeFromListing: true` hides labs from main listing page |
| 119 | +- Use GitHub Actions workflow "Contentful Delete" to manually delete labs |
0 commit comments