Quality‐Driven Development & Contribution - CApy-RPI/app GitHub Wiki

Quality-Driven Development

This development approach emphasizes meeting strict quality gates before considering any task or feature "done." It integrates principles from several established methodologies, ensuring robust, maintainable, and error-free code.

1. Key Principles

  1. Test-Driven Development (TDD):

    • Writing automated tests before implementing the code.
    • Ensures functionality meets requirements from the start.
    • Emphasizes "all tests must pass" as a non-negotiable requirement.
  2. Continuous Integration/Continuous Deployment (CI/CD):

    • Every change to the codebase passes through automated pipelines for testing, linting, and type checks.
    • Ensures consistent code quality and reduces integration issues.
  3. Static Typing and Code Quality Enforcement:

    • Tools like mypy (type checking), flake8 or pylint (linting), and black (code formatting) are enforced.
    • Guarantees code is type-safe, well-formatted, and adheres to coding standards.
  4. Definition of Done (DoD):

    • Establishes a clear checklist to define when a task or feature is complete.
    • Tasks must:
      • Pass all automated tests.
      • Validate linting rules.
      • Enforce typing with no errors.
    • Prevents incomplete or low-quality code from being merged or deployed.

2. Quality-Driven Development Practices

  • Prioritizing Quality Gates: Quality gates (tests, linting, typing) are prerequisites for task completion.
  • Clean Code Development: Clean, maintainable, and validated code is enforced in every step of the workflow.
  • Best Practices-Driven Development: Industry standards like TDD, CI/CD, and static typing are integrated to ensure robustness.

3. Benefits of This Approach

  • Error Prevention: Automated gates catch issues early in the development process.
  • Consistency: Linting and typing ensure code adheres to a uniform style and standard.
  • Robustness: Passing tests and type checks reduces bugs and increases confidence in the code.
  • Maintainability: Clean, well-tested code is easier to understand and extend in the future.

4. AI in Quality-Driven Development

The use of AI is not only allowed but also encouraged. AI tools can assist in:

  • Debugging: Identifying and resolving issues quickly.
  • Code Suggestions: Accelerating development by generating code snippets and tests.
  • Research Assistance: Streamlining research into best practices and tools.

However, we maintain high standards for students' ability to debug and research issues independently. All development practices must be met before marking a task as done. If any criteria are unmet, we will work with the developer to review and improve the work.

5. Pre-Push Checklist

Before pushing your code to the repository, ensure the following steps are completed:

5.1. Code Formatting with Black

  • Use black to automatically format your code files:
# Install black if not already installed
pip install black

# Format your code files
black path/to/your/code/file.py

5.2. Linting with Flake8

  • Use flake8 to check for style guide enforcement and code quality issues in your code files:
# Install flake8 if not already installed
pip install flake8

# Run flake8 on your code files
flake8 path/to/your/code/file.py

5.3. Type Checking with Mypy

  • Use mypy for static type checking in your code files:
# Install mypy if not already installed
pip install mypy

# Run mypy on your code files
mypy path/to/your/code/file.py

5.4. Running Tests with Pytest

  • Use pytest for running unit tests:
# Install pytest if not already installed
pip install pytest

# Run all tests
pytest

5.5. Using Branches in GitHub

🌿 What is a Branch?

A branch is a copy of your codebase where you can make changes without affecting the main code.

Branches allow you to:

  • Work on new features, bug fixes, or experiments
  • Collaborate safely without breaking the main app
  • Submit changes through pull requests (PRs)

If you look at the CAPY-RPI GitHub (https://github.com/CApy-RPI), there are 5 main repositories titled app, graphics, webui, onboarding, and app-deprecated.

We will primarily be looking at the app repository. If you look at the different branches of app, you will see the following branches:

Branch Description
main The production-ready branch. This is the most stable version of the app, and code is only merged in after testing and code review.
develop The development branch. This is where all feature branches are merged first. Used for integration testing and reviewing multiple features together. Once stable, it gets merged into main.
feature\cap... These are custom branches created by developers to work on specific tasks. Allows devs to work independently without affecting main codebase. When ready, they are merged into develop.

🧠 Key Terms

  • Switch: Switching to a different branch
  • Merge: Bringing changes from one branch into another
  • Pull request (PR): A request to merge your branch into the main one

🔧 Creating a Branch

Anytime you are assigned a task in Linear, you must create a branch to work on it. This ensures that your changes are isolated, easy to review, and can be merged later.

  1. Copy the branch name from your task in linear.

    • Right click the task in Linear → CopyCopy git branch name
    • This copies something like: feature/cap-...
  2. Update your local develop branch.

    • Open your terminal in VS Code and run:
      git switch develop           # Switch to the develop branch
      git pull origin develop      # Pull the latest changes from GitHub
  3. Create and switch to your feature branch

    • Paste the copied branch name to create your branch:

      git branch [paste]-[description]           # Create a new branch with the name from Linear, write a short description for your task
      git switch [paste]                         # Switch to that branch
    • Make sure you write a description for your branch when you create it.

      Examples of this:

      feature/cap-123-add-user-auth
      feat/cap-234-search-api
      fix/cap-301-fix-login-redirect
      hotfix/cap-999-prod-crash
      refactor/cap-444-clean-auth-flow
      test/cap-555-add-unit-tests
      docs/cap-777-update-readme
      release/1.2.0
      

5.6 Merging

It is important to keep your feature branch updated. Sometimes develop is updated while you are still working on your feature. To avoid conflicts later, make sure to merge often!

⚠️ Important: Do NOT merge your changes directly into the overall develop branch.

You should be merging your changes into the branch that you created in the develop branch. If you do not know how to create a branch, refer back to section 5.5: Using Branches in GitHub.

Follow these directions exactly and input your feature branch.

git switch develop                   # Switches to develop
git pull origin develop              # Pulls the latest updates
git switch [your-feature-branch]     # Switch to your feature branch
git merge develop                    # Merge develop into your feature branch

If you do not merge frequently, you risk code drift and face the following errors and problems:

  1. Merge Conflicts

    In this case, Git cannot automatically combine your changes with the latest code. This happens because someone else might have edited the same file, line, or function you are working on, or you made changes on outdated code.

  2. Outdated Dependencies or Imports

    If you are getting this error, your branch may be missing files, functions, or modules added by others. You may see a message like cannot find module 'xyz' or undefined is not a function if you have this problem.

  3. Failing Pull Request Checks

    When you make a Pull Request (without merging) and GitHub checks fail, your branch may be out-of-sync with latest test configurations or main logic.

  4. Painful Last-Minute Conflicts

    The longer you wait to merge, the messier it gets. If you merge after many changes were made, Git will try to merge a large set of chances all at once. This may introduce new bugs, accidentally overwrite other people's work, or manually resolve dozens of conflicts.

5.7. Pushing to the Repository

When pushing to the repository, you should ensure the following:

  • Code is properly formatted and linted (Sections 5.1, 5.2, & 5.3)
  • Feature is operational & meets all expectations
    • All tests pass (Section 5.4)
  • You have merged the latest develop branch into it (Section 5.6)

If and ONLY IF you have completed the above, you may then push your code to the repository.

Put the following into your terminal.

# Add changes to the staging area
git add .

# Commit changes with a descriptive message
git commit -m "[Description of changes]"      # See below for examples of descriptions

# Push changes to the repository
git push origin [branch-name]

Use descriptive commit messages:

[Feature] Add user profile creation functionality
[Update] Updated README with setup instructions
[Edit] Adjust spacing in landing page layout
[Refactor] Moving utility method to module
[Fix] Resolve MongoDB connection issue

Once you have successfully pushed and committed your changes, you may move on to creating a Pull Request. Refer to Section 6 below for instructions.

6. Pull Request Guidelines

Pull Requests (PRs) are basically how you say: "Here's my work — can someone review and approve it before it becomes part of the main codebase?"

As discussed in Section 5.6, we merge develop into our feature branches while working on smaller tasks to keep our branch up to date with the latest project changes. This helps prevent conflicts and ensures compatbility.

On the other hand, pull requests are used to merge our completed work from those feature branches into develop, after extensive review and approval by the team lead(s).

Pull requests help with:

  1. Code Review

    • Lets teammates & leads review your changes before they go into the shared codebase
    • Reviewers check for:
      • Bugs
      • Code quality
      • Styling and formatting
      • Logic correctness
      • Possible improvements
  2. Collaboration

    • Devs can comment, ask questions, or suggest edits
    • Prevents misunderstandings and encourages teamwork
  3. Automated Checks

    • We have tools that run tests, lint code, and check build success of pull requests to help catch issues before merging.
  4. Safe Integration

    • Instead of merging code blindly, PRs act like a checkpoint
    • You only merge once everything looks good and has been tested or approved.

If you have already pushed and committed your changes, you may create a pull request.

Instructions:

  1. Go to the CAPY-RPI GitHub and select the correct repository app (https://github.com/CApy-RPI/app).

  2. Click the Compare & Pull Request button, which should appear right after pushing.

    • If it does not appear, go to the Pull requests tab, click New pull request, and select the branches manually.
  3. When chosing branches, ensure your base (target) branch is develop and your compare (source) branch is your feature branch that contains the new code.

  4. Add a title.

    Use a descriptive title such as:

     [Feature] Add login page UI
     [Fix] Adjust temperature reading conversion
     [Refactor] Simplify state management in dashboard
  5. Assign yourself and your team lead to the PR.

After competing all these steps, your task should automatically be marked as completed on Linear.

📝Note:

You will also use these pull requests to prove that you have made progress and/or contributed towards towards the CAPY project.

  • Every pull request serves as documented proof of your work on a specific task.
  • It helps project leads track individual contributions and ensure accountability.

After PR Submission

  • Wait for review and feedback

  • Make any requested changes and push more commits (they will auto-update the pull request)

  • Once your PR is approved, someone (most likely your team lead) will merge it into develop.

    • You are under no condition allowed to merge any changes into the overarching branches like main or develop. You may only merge changes from develop into your branch for your task, like a feature.
⚠️ **GitHub.com Fallback** ⚠️