kubeflow / kubeflow/notebooks

[TASK] Improve development workflow for PRs containing both backend API and frontend changes

Open
#856 2 comments 0 reactions 0 assignees View on GitHub
area/ci area/frontend area/v2 kind/plan-task
Dominant language
No language data
Stars
84
Forks
149
Avg merge
5d 15h
Merged PRs (30d)
29

Description

### Certification

- [x] I certify I am an Epic Owner for Kubeflow Notebooks 2.0 and expected to create planning-related issues.

### Description

When a PR delivers changes across both the **backend API** (new/modified endpoints) and the **frontend** (TypeScript code consuming those endpoints), the current `swagger.version`-based workflow creates friction during development.

### Current Architecture

The frontend generates its TypeScript API client from the backend's OpenAPI spec using the following mechanism:

1. **Backend**: `make swag` generates `workspaces/backend/openapi/swagger.json` from Go handler annotations
2. **Frontend**: `npm run generate:api` runs `scripts/generate-api.sh` which:
- Reads a git commit hash from `scripts/swagger.version`
- Uses `git show :../backend/openapi/swagger.json` to fetch that specific version
- Generates TypeScript types and API client code into `src/generated/`

### Why This Works for Releases

For release workflows, this design is elegant:
- Frontend can target a specific, stable backend API version
- Temporal decoupling allows independent component releases
- Historical API versions remain accessible via git history

### The Development Problem

For **active development** where a single PR contains both backend and frontend changes, this workflow breaks down:

| Step | Issue |
|------|-------|
| 1. Developer modifies backend API handlers | swagger.json is regenerated locally |
| 2. Developer writes frontend code using new API | Needs TypeScript types from the new swagger.json |
| 3. Developer runs `npm run generate:api` | **Fails** - `swagger.version` points to a commit that doesn't have the new swagger.json |
| 4. Developer cannot update `swagger.version` | The commit hash for the new swagger.json **doesn't exist yet** |

The fundamental issue: **`swagger.version` references a git commit hash, but during development, uncommitted changes have no hash.**

### Current Workarounds (All Problematic)

1. **Two-PR approach**: Merge backend first, then frontend → Delays development, creates coordination overhead
2. **Manual local swagger.json copy**: Skip the generate script and manually copy files → Breaks CI, risky
3. **Temporary dummy hash**: Use a local commit hash → Must remember to update before PR, error-prone

### Key Files Involved

| File | Role |
|------|------|
| `workspaces/frontend/scripts/swagger.version` | Stores backend commit hash to generate from |
| `workspaces/frontend/scripts/generate-api.sh` | Fetches swagger.json from git history, runs generator |
| `workspaces/backend/openapi/swagger.json` | Generated OpenAPI spec (source of truth for types) |
| `workspaces/frontend/src/generated/*` | Generated TypeScript client (must match swagger.json) |

### CI Behavior

Both frontend and backend CI workflows include "porcelain checks" that fail if generated files are uncommitted:
- Backend CI: Runs `make build` (triggers swag), checks for uncommitted swagger.json changes
- Frontend CI: Runs `npm run generate:api`, checks for uncommitted changes in `src/generated/`

This means **both the swagger.version file AND the generated TypeScript files must be committed together** and must be consistent.

### Concepts a Solution Should Consider

1. **Local development experience**: How can a developer iterate on both backend and frontend in a single working session?
2. **CI compatibility**: Any solution must pass the existing porcelain checks or propose changes to them
3. **Release workflow preservation**: The current git-hash-based approach works well for releases; don't break it
4. **Single-PR capability**: Ideally, one PR can deliver coordinated backend + frontend changes
5. **Discoverability**: New contributors should understand the workflow without deep archaeology

### Acceptance Criteria

- [ ] A developer can create a single PR containing both backend API changes and frontend code that consumes those changes
- [ ] The npm run generate:api command works during local development with uncommitted backend changes
- [ ] CI pipelines continue to pass porcelain checks (generated files are committed and consistent)
- [ ] The existing release workflow (git-hash-based versioning for stable API targeting) remains functional
- [ ] Documentation is updated to reflect the new development workflow

Contributor guide

Open the contributing guide

Research direction

Start with workspaces/frontend/scripts/generate-api.sh and scripts/swagger.version, then inspect workspaces/backend/openapi/swagger.json and src/generated/. Run make swag and npm run generate:api to reproduce the uncommitted-change failure. Done means a single backend/frontend PR can generate consistent committed files, pass both porcelain checks, preserve release versioning, and document the workflow.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, go, openapi, typescript
Domain
api, backend-api-design, build-system, developer-experience, documentation, frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.