Skip to content
Merged
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
26 changes: 11 additions & 15 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,12 @@ jobs:
python-version: "3.12"

- name: Install dependencies
run: pip install outerbounds ob-project-utils pyyaml
run: pip install outerbounds ob-project-utils

- name: Configure Outerbounds
run: |
PROJECT_NAME=$(yq .project obproject.toml)
PLATFORM=$(yq .platform obproject.toml)
CICD_USER="${PROJECT_NAME//_/-}-cicd"
outerbounds service-principal-configure \
--name $CICD_USER \
--deployment-domain $PLATFORM \
--perimeter default \
--from-obproject-toml \
--github-actions

- name: Deploy Project
Expand All @@ -67,23 +62,24 @@ jobs:
python-version: "3.12"

- name: Install dependencies
run: pip install outerbounds ob-project-utils pyyaml
run: pip install outerbounds ob-project-utils

- name: Configure Outerbounds
run: |
PROJECT_NAME=$(yq .project obproject.toml)
PLATFORM=$(yq .platform obproject.toml)
CICD_USER="${PROJECT_NAME//_/-}-cicd"
outerbounds service-principal-configure \
--name $CICD_USER \
--deployment-domain $PLATFORM \
--perimeter default \
--from-obproject-toml \
--github-actions

- name: Teardown branch resources
run: |
BRANCH=${{ github.head_ref || github.event.ref }}
PROJECT=$(yq .project obproject.toml)
PROJECT=$(python3 -c "
try:
import tomllib
except ImportError:
import toml as tomllib
print(tomllib.load(open('obproject.toml','rb'))['project'])
")
echo "Tearing down $PROJECT/$BRANCH"
outerbounds flowproject teardown-branch \
--id "$PROJECT/$BRANCH" --yes -o json
44 changes: 44 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Prod Event Example (prod_event_example)

Demonstrates branch-scoped event triggering where only the production
(main branch) deployment reacts to external signals. Shows the difference
between `@project_trigger`, `@trigger_on_finish`, `@schedule`, and `@trigger`.

## Platform Features Used

- **Events**: `@project_trigger(event="external_signal")` for branch-scoped external events; `prj.safe_publish_event("ingest_complete")` for internal events
- **Schedules**: `@schedule(cron="0 8 * * 1-5")` weekday morning ingest
- **Flow chaining**: `@trigger_on_finish(flow="EventProcessorFlow")` (auto branch-scoped)
- **Dev-assets**: `[dev-assets] branch = "main"` for cross-branch data reads

## Flows

| Flow | Trigger | Purpose |
|------|---------|---------|
| ScheduledIngestFlow | @schedule(cron) | Daily ingest, publishes `ingest_complete` event |
| EventProcessorFlow | @project_trigger(external_signal) | Processes external events, branch-isolated |
| ChainedReporterFlow | @trigger_on_finish(EventProcessor) | Reports after event processing |

## Event Scoping

`@project_trigger` creates sensors scoped to `prj.<project>.<branch>.<event>`:
- Main: `prj.prod_event_example.main.external_signal`
- Feature branch: `prj.prod_event_example.<branch>.external_signal`

External systems target prod by publishing to the `main` event name explicitly.

## Run Locally

```bash
cd prod-event-example
python flows/scheduled_ingest/flow.py run
python flows/event_processor/flow.py run
# chained_reporter requires an upstream run in Argo (uses current.trigger.run)
```

## Common Pitfalls

- `@trigger(event=...)` is NOT branch-scoped -- all branches react to the same event. Use `@project_trigger` instead.
- ChainedReporterFlow cannot run locally without a trigger context (`current.trigger.run` would be None)
- External event publishers must specify both project and branch to target the correct deployment
- See TESTING.md for the full verification plan including branch isolation tests
Loading