Copy the branch list before prepending the last commit branch

What does this MR do and why?

Fixes an uncaught TypeError in the pipeline editor branch switcher after a commit to a new branch.

The branch selector app/assets/javascripts/ci/pipeline_editor/components/shared/branch_selector.vue loads availableBranches from the getAvailableBranches Apollo query. It also watches the client-side getLastCommitBranch query. After the user commits to a new branch, the commit form runs the updateLastCommitBranch client mutation, which writes the new branch name to the cache. The branch selector then added that branch to the top of the list with this.availableBranches.unshift(lastCommitBranch).

Apollo Client freezes query results in non-production builds. unshift on a frozen array of five branches throws TypeError: Cannot add property 5, object is not extensible. The throw happens inside an Apollo result handler, so the observable library rethrows it asynchronously and the console shows an Uncaught TypeError with a stack that points at vendor.dll.bundle.js. Production builds do not freeze results, so there the branch was added and no error appeared. The behaviour differed between environments.

In CI this logged the error in 2 examples in spec/features/projects/ci/editor_spec.rb: the branch switcher after committing on a new branch, and the editor navigation to the merge request page.

Changes made:

  • app/assets/javascripts/ci/pipeline_editor/components/shared/branch_selector.vue — keep lastCommitBranch as query data and prepend it in a computed, instead of mutating the query result in the result hook. The hook ran once, so the branch also disappeared after pagination or a search replaced availableBranches.
  • spec/frontend/ci/pipeline_editor/components/shared/branch_selector_spec.js — new block "when a commit is made on a branch that is not in the list". It runs the real updateLastCommitBranch client mutation through the mock Apollo client and asserts the new branch is first and the list has one more entry. The test fails on the old code, because the branch never appears, and passes with the fix. Three more tests cover a fetchMore after the commit, a search after the commit, and a commit on a branch that is already in the list. The setup also extracts a small writeLastCommitBranch helper.

How to set up and validate locally

  1. Open a project's Build > Pipeline editor.

  2. Change the file. In the commit form, pick "Commit to a new branch". Enter a branch name that does not exist and commit without creating a merge request.

  3. Open the DevTools console. Check there is no not extensible TypeError.

  4. Open the branch switcher. Check the new branch is listed first and selected.

    Branch switcher listing the new branch first and selected

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

References

🤖 Generated with Claude Code

Edited by Miguel Rincon

Merge request reports

Loading
Loading