CI/CD with GitHub Actions

June 13, 2026

Before working with CI/CD on GitHub, I have added my own private runner to run my private CI/CD pipelines.

Adding a self-hosted runner to GitHub is pretty straightforward.

Create a new user on your Virtual Machine

sudo adduser github-runner

Then, go to your GitHub repository, click on "Settings" > "Actions" > "Runners" > "New self-hosted runner".

Switch to the github-runner user on your VM and follow the instructions provided by GitHub to download and configure the runner on your VM. This typically involves running a few commands in the terminal to set up the runner and connect it to your GitHub repository.

To run the job I use Docker runners. This has few benefits

  • Isolation: Each job runs in its own container. No dependency on host Python
  • Consistency: The same Docker image can be used across different environments
  • Maintainability: Easier upgrades and easier to manage dependencies

Install Docker from the Official Docker documentation: https://docs.docker.com/engine/install/ubuntu/

Give the github-runner user permission to run Docker commands:

sudo usermod -aG docker github-runner 

Now add a Lint and Test workflow to your GitHub repository. Create a new file in your repository at .github/workflows/lint.yml with the following content. This workflow will run on every push, and pull request to the repository, and it will use your self-hosted runner to execute the jobs using the specified Docker image python:3.12.

name: CI
on: [ push, pull_request ]
jobs:
  lint:
    runs-on: self-hosted
    strategy:
      matrix:
        python-version: [ "3.12" ]
    container:
      image: python@sha256:dbb1970cc04ce7d381c65efe8309c0c03d463e5b35c88f14d721796ad24cfbfd
    steps:
      - uses: actions/checkout@v7
      - name: Install dependencies
        run: |
          python -m venv venv
          source venv/bin/activate
          pip install --upgrade pip
          pip install ruff==0.15.0
      - name: Analysing the code with pylint
        run: |
          source venv/bin/activate
          ruff check .
  test:
    runs-on: self-hosted
    container:
      image: python@sha256:dbb1970cc04ce7d381c65efe8309c0c03d463e5b35c88f14d721796ad24cfbfd
    steps:
      - uses: actions/checkout@v7
      - name: install dependencies
        run: |
          python -m venv venv
          source venv/bin/activate
          pip install --upgrade pip
          pip install -r requirements.txt
      - name: Run tests
        run: |
          source venv/bin/activate
          python manage.py test --settings=portfolio.test_settings