Case Study: Automating Major Library Updates with Breaking Changes

Updating dependencies to their latest major versions can be tricky due to breaking changes. Let's look at a real-world example where GitAuto helped upgrade PyQt5 to PyQt6 in an open-source Tetris game, handling multiple breaking changes along the way.

Starting the Process

The process began with a simple issue creation - just a title without any detailed requirements: "Update pyqt5 to the latest version pyqt6". This minimal approach was chosen to simulate how users might interact with GitAuto in real-world scenarios. While providing more detailed requirements typically leads to better-targeted results, it's interesting to see how GitAuto handles such open-ended requests.

Initial Approach

When first tasked with the update, GitAuto made the most straightforward changes:

  1. Updated
    requirements.txt
    to replace PyQt5 with PyQt6
  2. Modified imports in the main file (
    game_manager.py
    ) from PyQt5 to PyQt6

This initial pull request was created without any knowledge of potential breaking changes - similar to how a developer might start by simply updating the version number to see what breaks.

Handling Breaking Changes

As the GitHub Actions workflow failed, GitAuto began addressing issues one by one:

1. System Dependencies

The first error revealed that PyQt6 requires

libegl1-mesa
, which wasn't installed in the GitHub Actions Ubuntu environment. GitAuto added the necessary installation command to the workflow:

.github/workflows/test-ubuntu.yaml
run: |
sudo apt-get update
sudo apt-get install -y libegl1-mesa
pip install -r requirements.txt

2. Deprecated APIs

Several PyQt6 API changes needed to be addressed:

  1. QDesktopWidget Removal: GitAuto updated the screen geometry access:

    game_manager/game_manager.py
    - screen = QDesktopWidget().screenGeometry()
    + screen = self.screen().availableGeometry()
  2. Focus Policy Changes: Updated to use the new enum format:

    game_manager/game_manager.py
    - self.setFocusPolicy(Qt.StrongFocus)
    + self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)

Manual Interventions Needed

While GitAuto successfully handled many changes, some issues required human intervention:

  1. Import Location Changes: GitAuto removed the unused

    QScreen
    import:

    game_manager/game_manager.py
    - from PyQt6.QtWidgets import QMainWindow, ..., QScreen
    + from PyQt6.QtWidgets import QMainWindow, ..., QLabel

    Improvement needed: Allow multiple retry attempts for different GitHub Actions Check Run errors, or even for the same error, to better mimic human behavior.

  2. Method Name Updates: Updated the exec method name:

    game_manager/game_manager.py
    - sys.exit(app.exec_())
    + sys.exit(app.exec())

    Improvement needed: Same as above.

  3. Enum Path Changes: Updated the key constant paths:

    game_manager/game_manager.py
    - Qt.Key_Left
    + Qt.Key.Key_Left

    Improvement needed: Implement a final code review step to catch patterns that might be missed by automated tests for all modified files by GitAuto.

Lessons Learned

This case study revealed several insights about automating major version updates:

  1. Iterative Problem Solving: GitAuto successfully handled multiple breaking changes by addressing each error as it appeared in the CI pipeline.

  2. Areas for Improvement:

    • Allow multiple retry attempts for different GitHub Actions Check Run errors
    • Implement a final code review step to catch patterns in changes for all modified files by GitAuto
  3. Human-AI Collaboration: While GitAuto automated much of the tedious work, human oversight was still valuable for:

    • Reviewing generated changes
    • Handling edge cases
    • Testing uncovered functionality

Conclusion

The final pull request successfully upgraded PyQt5 to PyQt6, demonstrating how automation can handle complex library updates. While some manual intervention was needed, GitAuto reduced the time and effort required for this major version upgrade.

And this real example itself is not that complex for experienced Python developers. But in real-world scenarios, organizations often face:

While each task might be straightforward for an experienced developer, the sheer volume of such "simple" tasks makes it impossible for any individual or team to handle them all manually. This is where automation becomes invaluable - not because the tasks are difficult, but because they are numerous and time-consuming in aggregate.

You can view the complete changes in the example pull request or see the merged pull request in the original project.

Want to ship 500x faster?

GitAuto is your AI coding agent that turns backlog tickets into pull requests in just 3 minutes for $10 - making it 500x faster and 99.5% cheaper.

It requires GitHub sign-in.