GitHub Actions can orchestrate your entire machine learning model development lifecycle, from code commit to deployed artifact.

Let’s see it in action. Imagine a simple Python script that trains a scikit-learn model and saves it.

# train_model.py
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
import joblib

# Load data
X, y = load_iris(return_X_y=True)

# Train model
model = LogisticRegression(max_iter=200)
model.fit(X, y)

# Save model
joblib.dump(model, 'model.joblib')
print("Model trained and saved to model.joblib")

Now, let’s set up a GitHub Actions workflow to automatically run this script whenever we push changes.

Create a file named .github/workflows/mlops.yml in your repository:

name: MLOps CI/CD

on:
  push:
    branches:
      - main

jobs:
  build_and_test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install scikit-learn joblib

      - name: Train model
        run: python train_model.py

      - name: Upload model artifact
        uses: actions/upload-artifact@v3
        with:
          name: trained-model
          path: model.joblib

When you push this workflow and the train_model.py script to your main branch on GitHub, a new workflow run will start. The build_and_test job will execute. It checks out your code, sets up a Python environment, installs scikit-learn and joblib, runs your train_model.py script, and then uses actions/upload-artifact to save the generated model.joblib file as a downloadable artifact from the workflow run.

The core problem this solves is the manual, error-prone process of versioning, training, and packaging machine learning models. By integrating this into CI/CD, you ensure that every change to your model code is automatically validated and the resulting model is versioned. The on: push trigger means this process starts automatically on code commits, and the jobs and steps define the sequence of operations. actions/checkout fetches your repository’s code, actions/setup-python provides a consistent Python environment, and actions/upload-artifact is crucial for capturing the output of your training script, making the trained model available for subsequent steps like deployment or evaluation.

You control this by defining the triggers (on:), the operating system (runs-on:), and the specific commands or actions (steps:) to be executed. Each uses: line points to a pre-built GitHub Action that performs common tasks.

What most people don’t realize is that the artifact itself isn’t just a file dump; it’s tied to the specific commit and workflow run that generated it. This provides an immutable record of your model’s lineage. If you later need to reproduce a specific model version, you can go back to the exact workflow run, download the artifact, and know it corresponds precisely to the code and environment at that point in time. This is fundamental for auditability and debugging.

The next logical step is to automate the deployment of this artifact to a model registry or a serving endpoint.

Want structured learning?

Take the full MLOps & AI DevOps course →