kubero-dev / kubero-dev/kubero
Bug: Editing an app resets branch to default
- Dominant language
- TypeScript
- Stars
- 4.4k
- Forks
- 213
- PR merge metrics
- No merged PRs in 30d
Description
### Which component(s) is affected?
Kubero UI
### Describe the bug
When editing an existing app that is configured to use a non-default branch (e.g. `develop`), the branch input field shows the repository's default branch (e.g. `main`) instead of the previously configured branch. If the user clicks "Save" without noticing, the app's branch is silently changed to the default — causing it to deploy from the wrong branch.
### Steps to reproduce
1. Create a pipeline connected to a git repository with multiple branches (e.g. `main`, `develop`)
2. Create an app and set the branch to a non-default branch (e.g. `develop`)
3. Save the app
4. Navigate back to edit the same app
5. **Observe**: The branch field shows `main` (the default branch) instead of `develop`
6. Click "Save" without changing anything
7. **Result**: The app's branch is now changed to `main`
### Expected behavior
When editing an existing app, the branch field should show the branch that was previously configured and saved.
### Screenshots
_No response_
### Additional information
## Root Cause
The bug is a **race condition** in `client/src/components/apps/form.vue` between two unawaited async calls in `loadPipelineAndApp()` (line 1928):
1. **Line 1936**: `this.loadBranches()` fires an async HTTP request to `/api/repo/.../branches` (NOT awaited)
2. **Line 2004**: `this.loadApp()` fires an async HTTP request to `/api/apps/...` (NOT awaited)
Both `.then()` callbacks assign `this.branch`:
- `loadApp()` (line 2141) correctly sets `this.branch = response.data.spec.branch` (the saved value, e.g. `"develop"`)
- `loadBranches()` (lines 2037–2042) **unconditionally overwrites** `this.branch` with `pipelineData.git.repository.default_branch` (e.g. `"main"`)
Since `loadBranches()` calls an external git provider API (GitHub/GitLab/etc.), it is typically **slower** than `loadApp()` (which hits the local Kubernetes API). So the usual execution order is:
1. `loadApp()` resolves first → sets `this.branch = "develop"` ✅
2. `loadBranches()` resolves second → **overwrites** `this.branch = "main"` ❌
## Suggested Fix
Guard the branch assignment in `loadBranches()` so it only pre-selects a default branch when creating a **new** app:
```javascript
// In loadBranches(), lines 2036-2042:
if (this.app == "new") {
let defaultBranch = this.pipelineData.git.repository.default_branch;
if (this.branchesList.includes(defaultBranch)) {
this.branch = defaultBranch;
} else {
this.branch = this.branchesList[0];
}
}
```
This ensures `loadBranches()` still populates the `branchesList` dropdown (needed for both create and edit), but only pre-selects a branch value during app creation. During edit, `loadApp()` retains the final say on `this.branch`.
## Additional Context
- The server side correctly stores and returns `spec.branch` from the KuberoApp CRD — no issue there
- The kubero-operator (Helm-based) passes `spec.branch` through to deployment templates without modification — no issue there
- The bug is purely a frontend race condition
### Debug information
_No response_
Contributor guide
Research direction
Read client/src/components/apps/form.vue, starting with loadPipelineAndApp() and the async loadBranches() and loadApp() calls around the referenced lines. Confirm that branch loading still populates branchesList, while editing preserves the saved branch and creating a new app selects the repository default; verify the create and edit flows in the Kubero UI.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100