DEV Community

Avelyn Hyunjeong Choi
Avelyn Hyunjeong Choi

Posted on

Add CI workflow to repo

Set up your GitHub Actions CI Workflow

  1. Create a .github/workflows folders in the root of repo
  2. Create a workflow YAML file, ci.yml, for the CI job as below
name: ci

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  lint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install node dependencies
        run: npm ci

      - name: Run ESLint
        run: npm run lint

  unit-tests:
    name: Unit Tests
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v3

      - name: Setup node
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install node dependencies and run Tests
        run: npm install-ci-test
Enter fullscreen mode Exit fullscreen mode

NOTE: This workflow runs linters followed by automated unit tests. It will be triggered whenever a pull request is made or someone pushes commits to the main branch.

How did your partner's repo and testing setup differ from yours?
First of all, my partner uses pytest for Python, so the testing setup was completely different from mine. One thing I noticed was the absence of a config file for the tests. I had to update my .eslintrc.cjs to inform ESLint that my repo uses Jest. Additionally, there was no setup to add npm scripts to package.json to run the tests, as long as pytest is installed. Without adding anything, a simple pytest does the same trick as npm run test. I find the testing setup for Python much simpler and easier than for TypeScript.

What was it like writing tests for a project you didn't create?
While writing unit tests, there were certain points where I needed to revisit the target code that I wanted to test and make changes to the original code. However, I was unsure if I was allowed to do so, considering the original code was not written by me. For instance, exit() was used when a FileNotFoundError occurred in the original code.

    try:
        with open(input_file, "r") as file:
            text_lines = file.readlines()
    except FileNotFoundError:
        print(f"Error: {input_file} not found.")
        exit()
Enter fullscreen mode Exit fullscreen mode

The issue was that the program did not exit immediately when I attempted to test this code. After some research, I discovered that using raise instead would achieve the desired immediate program exit. This way, I can test the code to ensure that the program raises an exception, as shown below.

    @patch("builtins.print")
    def test_process_non_exist_text_file(self, mock_print):
        with self.assertRaises(FileNotFoundError):
            process_text_file(
                "examples/test-folder/invalid.txt", "examples/test-folder-output"
            )

        mock_print.assert_called_once_with(
            "Error: examples/test-folder/invalid.txt not found."
        )
Enter fullscreen mode Exit fullscreen mode

Outcome
outcome

More details in GitHub: pr

What do you think of CI now that you've set it up for yourself?
There were many times when I pushed commits to the main branch before checking for linter errors, which may break the program. I realized that setting up the CI workflow makes a developer's life so much easier, as it reduces the number of things to worry about by preventing minor linter bugs and saving a significant amount of time.

More details in GitHub: pr

Top comments (0)