This week's lab focused on managing project complexity using Continuous Integration (CI), automated testing, reproducible environments, and code quality tools. I applied these concepts to my own project, share-my-repo, and also collaborated on a partner's C++ project, Repository-Context-manager. Through the process, I learned not just how CI works, but also how it improves collaboration, reliability, and development workflow.
Setting Up GitHub Actions CI in My Python Project
To ensure my project always stays in a working state, I added a GitHub Actions CI workflow. The goal was simple: whenever someone pushes or opens a pull request, the code should automatically:
- Install the environment
- Run linting
- Run all tests
- Show test coverage
I created a .github/workflows/ci.yml file that:
- Triggers on every push or PR to main
- Sets up Python 3.11
- Installs pytest, pytest-cov, flake8, and black
- Runs linters before tests
- Generates a coverage report on the terminal
This gave me a fully automated pipeline. I could visibly see CI results on every pull request, which made the entire development process more professional and error-free. Watching GitHub Actions run the workflow and report results felt like working on a real production project.
Testing CI Using My Own Pull Request
To verify that CI was truly working, I followed the workflow:
- Created a new branch —
add-more-tests. - Wrote additional unit tests for modules that had low coverage.
- Pushed the branch and opened a pull request against main.
- Observed GitHub Actions immediately fire up and begin running all steps.
I intentionally broke one of my functions to see how CI would behave. As expected, the tests failed and the pull request turned red. This highlighted how powerful CI is: no broken code can ever reach the main branch.
After fixing the bug, pushing again, and seeing CI pass, I gained confidence in using automated testing as a safeguard. This cycle of fail → inspect → fix → pass felt very satisfying and realistic.
Collaborating and Adding Tests to a Partner's C++ Project
My partner's project was completely different from mine — a C++ repository using Catch2 for testing. At first, I struggled to understand the README, so I reached out to the maintainer on Teams. After they clarified the instructions, I was able to set everything up and start working on the test.
Their workflow felt more complex than my Python setup because it required:
- Compiling test files manually
- Understanding multi-file C++ structures
- Running tests with Catch2
- Using a CI pipeline built around
g++
Even though it was challenging, contributing to a project in a different language taught me a lot. I learned to slow down, carefully read unfamiliar code, and adapt to a new build system. Once I wrote my test case and opened the pull request, their CI passed successfully. PR
Overall, it felt like collaborating on a real open-source project, and it helped me understand how cross-language teamwork works in practice.
Adding Linting + Formatting: flake8 and black
As an optional enhancement, I integrated flake8 and black into my project. These tools help maintain code quality by:
- flake8 → catching unused variables, undefined names, and style problems
- black → automatically formatting the code to a consistent style
I added both tools to the dev dependencies in setup.py and updated my CI workflow to run them before tests. This created a nice structure:
- flake8 checks for actual errors
- black --check ensures formatting consistency
- pytest runs only if both linters pass
This improved the readability of my project and prevented small bugs that often go unnoticed. It also taught me that CI is not just about testing — it's about enforcing standards across the whole team.
What I Learned About Continuous Integration
After setting up everything, working with two repositories, and experimenting with failures, I now have a solid understanding of CI's importance:
- CI acts like a 24/7 automated reviewer, catching issues instantly.
- It removes the risk of forgetting to run tests locally.
- It provides detailed logs that make debugging very transparent.
- It enforces consistency in both functionality and style.
- It helps maintain a healthy main branch that always works.
Overall, CI transformed my project into something more professional and maintainable. It made the testing workflow feel more natural, especially when working with branches and pull requests.
Final Reflection
This lab tied together all the concepts from earlier weeks: testing, automation, collaboration, and reproducibility. By setting up CI, adding new tests, linting my code, and contributing to a partner's project, I gained hands-on experience with real software engineering workflows.
CI is no longer just a concept; I've now seen how developers rely on it every day to protect their projects from mistakes. It made me more confident in working with branching strategies, GitHub Actions, and cross-language testing environments.
Top comments (0)