How to Automate Model Retraining and Deployment with GitHub Actions and MLflow: Step-by-Step Guide
Introduction
Two years ago, a mid-sized fintech company deployed a fraud detection model. It worked flawlessly for three months—then false positives skyrocketed. The team spent two weeks manually retraining, testing, and redeploying. By then, the damage was done: angry users, lost transactions, a bruised reputation.
This story repeats across industries. The gap between model development and production reality grows with every data drift, every new feature, every business rule change. The solution isn't more manual oversight—it's automation. Specifically, a CI/CD pipeline for machine learning that retrains models on fresh data and redeploys them without human intervention.
In this guide, you'll learn how to build exactly that using GitHub Actions (free tier) and MLflow (open source). By the end, you'll have a production-ready pipeline that automatically retrains your model on a schedule or trigger, logs all experiments, and deploys the best version to a staging environment. No expensive tools required.
If you want to go deeper—covering feature stores, A/B testing, Kubeflow, data drift monitoring, and cost optimization—check out the full Production ML (MLOps) course on asibiont.com, which covers everything from model serving to hyperparameter tuning in production settings.
Why Automate Model Retraining and Deployment?
Manual retraining and deployment create several pain points:
| Problem | Consequence |
|---|---|
| Stale models | Accuracy decays, predictions become unreliable |
| Human error | Deploying wrong version, misconfigured environment |
| Slow iteration | Days or weeks to push a fix |
| No reproducibility | Hard to debug or audit model history |
Automation with CI/CD for machine learning solves all of these. A GitHub Actions ML pipeline can:
- Retrain on a cron schedule (daily, weekly) or on demand (e.g., when new data arrives)
- Log every run with MLflow for full traceability
- Automatically deploy the best model to a staging server
- Roll back to a previous version if validation fails
This is MLOps automation at its core: reducing manual overhead while ensuring production models stay current.
Prerequisites
Before we dive into code, make sure you have:
- A GitHub repository with your ML code (Python, scikit-learn or TensorFlow)
- MLflow Tracking Server (can be local or on a cloud VM)
- A staging server (e.g., a small AWS EC2 instance or a Docker host)
- Basic familiarity with YAML and Python
If you're new to MLflow, think of it as an experiment tracker + model registry that also handles deployment. GitHub Actions is your orchestrator.
Step 1: Set Up MLflow Tracking and Model Registry
First, configure MLflow to log experiments and store models. In your training script (train.py), add:
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
mlflow.set_tracking_uri("http://your-mlflow-server:5000")
mlflow.set_experiment("fraud-detection")
with mlflow.start_run():
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
acc = accuracy_score(y_test, predictions)
mlflow.log_param("n_estimators", 100)
mlflow.log_metric("accuracy", acc)
mlflow.sklearn.log_model(model, "model")
# Register the model (creates a new version)
mlflow.register_model(
f"runs:/{mlflow.active_run().info.run_id}/model",
"fraud-detection-model"
)
This registers every trained model in MLflow's Model Registry. Each version gets a unique ID, metrics, and parameters.
Step 2: Create a GitHub Actions Workflow for Retraining
Now, let's automate retraining. Create .github/workflows/retrain.yml in your repo:
name: Retrain and Deploy ML Model
on:
schedule:
- cron: '0 6 * * 1' # Every Monday at 6 AM UTC
workflow_dispatch: # Allow manual trigger
jobs:
retrain:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install mlflow
- name: Retrain model
env:
MLFLOW_TRACKING_URI: ${{ secrets.MLFLOW_TRACKING_URI }}
run: |
python train.py
- name: Get best model version
id: best_model
run: |
BEST_VERSION=$(mlflow models list --model "fraud-detection-model" --latest 1 --format json | jq -r '.[0].version')
echo "best_version=$BEST_VERSION" >> $GITHUB_OUTPUT
- name: Deploy to staging
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: |
# Example: deploy via SSH to staging server
mlflow deployments create --flavor python_function \
--model-uri "models:/fraud-detection-model/${{ steps.best_model.outputs.best_version }}" \
--target $DEPLOY_HOST
Key points:
- The workflow runs on a cron schedule (
schedule) and can be triggered manually (workflow_dispatch) - Secrets like
MLFLOW_TRACKING_URIandDEPLOY_HOSTare stored in GitHub Secrets - The
mlflow deployments createcommand deploys the latest registered model to a remote server—this is the model retraining automation part
Step 3: Validate Before Deployment
Deploying a bad model is worse than deploying nothing. Add a validation step before deployment:
- name: Validate model
run: |
python validate.py # Script that runs on a holdout set
if [ $? -ne 0 ]; then
echo "Validation failed. Skipping deployment."
exit 1
fi
Your validate.py might check:
- Accuracy above a threshold (e.g., 0.85)
- No data drift detected (e.g., using Evidently or Great Expectations)
- Inference time under 100ms
If validation fails, the pipeline stops—no deployment. This is a core MLOps automation best practice.
Step 4: Automate Data Freshness Checks
Model retraining is useless if you retrain on stale data. Integrate a data freshness check into your pipeline. For example, use a Python script that checks the timestamp of your latest training data:
import pandas as pd
from datetime import datetime, timedelta
data = pd.read_parquet("s3://your-bucket/training_data.parquet")
latest_timestamp = data["event_date"].max()
if latest_timestamp < datetime.now() - timedelta(days=7):
print("Data is stale. Skipping retraining.")
exit(1)
else:
print("Data is fresh. Proceeding with retraining.")
Add this as a step before train.py. This ensures your model retraining automation only runs when it makes sense.
Step 5: Monitor and Rollback
Even with validation, things can go wrong in production. Set up a monitoring step that checks model performance after deployment. You can use MLflow's model registry to roll back:
# Rollback to previous version
mlflow deployments update --model-uri "models:/fraud-detection-model/3" --target $DEPLOY_HOST
This can be triggered manually or via a webhook if your monitoring system (e.g., Prometheus + Grafana) detects degradation.
Production Considerations
This pipeline works great for small to medium projects. For larger scale, consider:
- Parallel training: Use matrix strategies in GitHub Actions to train multiple models simultaneously
- GPU support: GitHub Actions doesn't offer GPUs for free. Use self-hosted runners or a separate CI service for GPU workloads
- Model registry cleanup: Automate deletion of old versions (MLflow supports lifecycle stages: Staging, Production, Archived)
- Security: Use GitHub Actions OIDC tokens to authenticate to cloud providers instead of long-lived secrets
If you're building a full production ML infrastructure—including feature stores, Kubeflow pipelines, A/B testing, and cost optimization—the Production ML (MLOps) course on asibiont.com covers all of this in depth.
Real-World Example: Fraud Detection at Scale
A real e-commerce company implemented this exact pipeline. Before automation, model retraining took two engineers three days. After:
- Retraining runs every Monday at 6 AM automatically
- Model quality is validated against a holdout set
- Best model is deployed to staging, then promoted to production after a 24-hour shadow test
- Rollback happens in under 5 minutes
They reduced time-to-deployment from days to minutes, and false positives dropped by 40% because models were always fresh.
Conclusion
Automating model retraining and deployment with GitHub Actions and MLflow isn't just a nice-to-have—it's a necessity for any ML team that wants to keep models accurate and responsive to change. The pipeline we built is free, open source, and production-ready with minimal overhead.
Start small: set up retraining on a weekly schedule, add validation, then expand to data freshness checks and rollback. Each step reduces manual work and increases reliability.
For a comprehensive deep dive—including Kubeflow, A/B testing, data drift monitoring, and hyperparameter tuning at scale—explore the Production ML (MLOps) course on asibiont.com. It's designed to take you from prototype to production ML infrastructure.
Your models deserve to be as automated as your code.
Ready to build? Fork the example repo, add your MLflow server URL, and trigger your first automated retrain. The future of MLOps is here—and it's free.
Comments