Add CI workflow to repo
Tags: opensource, beginners, typescript
Published: 2023-11-15 00:46:37

**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

```typescript
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
```

_**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.

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

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.

```python
    @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."
        )
```

**Outcome**
![outcome](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9dj1zh4j3zw2lyzqxe9o.png)

More details in GitHub: [pr](https://github.com/mingming-ma/txt2html/pull/16)

**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](https://github.com/avelynhc/til_tracker/pull/27)