DEV Community

Cover image for Setting up Continuous Integration (CI) for dev-mate-cli
Mayank Kumar
Mayank Kumar

Posted on

Setting up Continuous Integration (CI) for dev-mate-cli

In this blog, I will walk through my experience setting up a CI workflow for my project dev-mate-cli, including insights into collaborating on testing and CI with a peer's project. Along the way, I took on the optional challenge of integrating a linter and explored how this addition improves code quality and the CI experience. Here’s how it all came together:

Setting Up the GitHub Actions CI Workflow

To start, I set up a simple CI workflow using GitHub Actions, designed to run tests whenever I pushed new changes. I’ve worked with basic CI setups like this before so I knew what to do. I created a YAML file in the .github/workflows directory, with the following configuration:

name: CI
jobs:
  unit-test:
    name: Unit Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node
        uses: actions/setup-node@v4
        with:
          node-version: 'lts/*'
          cache: 'npm'
      - name: Install Dependencies and Run Tests
        run: npm install-ci-test
Enter fullscreen mode Exit fullscreen mode

This workflow checks out the repository, sets up Node.js, installs dependencies, and runs the tests. As soon as I pushed the changes, GitHub Actions triggered the workflow, running all my Jest test suites, which passed successfully. This was a great way to ensure that each update to my project wouldn’t inadvertently break any functionality. Checkout the action run here.

Collaboration for Testing

As part of the lab in my OSD600 course, I also needed to collaborate with a peer, Anh Chien Vu. We agreed to add tests to each other's projects. Since we had already worked together, we knew each other’s code style and project setups, which made this collaboration easier. Anh Chien’s PR included an additional test suite, which improved my test coverage. His code was well-structured, so after testing his changes locally, I was comfortable merging the PR.

Writing tests for Anh’s project, VShell, involved testing core CLI functions to verify program details and AI response generation. View the PR below:

Add tests for server.js #21

Description

This PR aims to add a new file with unit tests for server.js

Changes Made

Added server.test.js containing the following unit tests for server.js -

  • should set up CLI information i.e. name, version and description.
  • should use default values when no config file exists.
  • should exit when no files(for processing) are provided with debug enabled.
  • should process files and call promptAI

These tests have 100% code coverage for server.js file.


Testing Details

  • [x] Unit tests added
  • [x] Unit tests passed

Checklist

  • [x] Code compiles correctly
  • [x] Tests have been written and run
  • [x] Code adheres to the style guidelines
  • [x] Ready for review

Since both of our projects used Jest, I had a smooth start, but I ran into some challenges mocking modules due to dependencies. I had to use jest.resetModules() to clear the module cache after each test and directly import the required modules, which was a new but valuable lesson. This hands-on collaboration allowed me to experiment with test structures I can now apply in my own project.

Adding a Linter to the CI Workflow

To further enhance my CI pipeline, I took on the optional challenge of integrating a linter. The project initially used ESLint for linting, but I ran into multiple configuration complexities due to dependencies and plugins for Jest, Prettier, and TypeScript. To simplify things, I migrated to Biome, which combines both formatting and linting, reducing the need for multiple tools.

After updating the project to use Biome, I created a lint job in the CI configuration to automatically check for linting errors. Here’s what the addition looked like:

lint:
  name: Biome Lint
  runs-on: ubuntu-latest
  steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: Setup node
      uses: actions/setup-node@v4
      with:
        node-version: 'lts/*'
        cache: 'npm'
    - name: Install Dependencies
      run: npm ci
    - name: Run Biome Lint
      run: npm run lint
Enter fullscreen mode Exit fullscreen mode

Adding a linter to the CI helped enforce consistent coding practices, catching potential errors before merging.

Conclusion

Overall, I learned that even a basic CI setup can provide a strong foundation to the project. It helps by giving immediate feedback on the code's stability and catching issues before merging. Having CI with both tests and lint checks makes code review easier and encourages better code quality, and I plan to implement it in all future work.

Cover Image by freepik

Top comments (0)