End-to-End MLOps with DagsHub and GitHub Actions | Automate DVC Data, Models & Experiments
Most ML projects fail not because of weak models, but because data, code, and experiments aren’t managed properly. In this article, I’ll…
End-to-End MLOps with DagsHub and GitHub Actions | Automate DVC Data, Models & Experiments
Most ML projects fail not because of weak models, but because data, code, and experiments aren’t managed properly. In this article, I’ll show you how to build end-to-end MLOps with DagsHub, GitHub Actions, and DVC — where a single git push automatically syncs your code, datasets, and models. Say goodbye to manual dvc push and hello to reproducible, automated MLOps.
End-to-End Project Implementation with DagsHub and GitBot
Machine Learning isn’t just about building models — it’s about keeping track of every dataset, model version, and experiment so the whole project stays reproducible. This is where MLOps meets data versioning and experiment tracking, and tools like DagsHub + GitBot come in.
In this article, we’ll build a complete end-to-end MLOps workflow that focuses on reproducibility and automation. You’ll learn how to:
✅ Version datasets and models with DVC
✅ Store and sync data automatically with DagsHub
✅ Automate dvc push using GitHub Actions as a GitBot
✅ Track experiments and metrics in DagsHub’s dashboard
By the end, you’ll have a pipeline where a single git push updates your code, datasets, and models automatically — no more manual steps. And the best part? It’s entirely open-source and free to get started.
From Code to Data: Building an MLOps Library with DagsHub
Think of an MLOps workflow like running a modern library. Instead of managing books, we’re managing datasets, models, and experiments that need to be properly cataloged, stored, and tracked.

📚 Card Catalog → GitHub Every library starts with a catalog. For us, that’s GitHub: it lists all the datasets and models we have, but doesn’t store the heavy files themselves.
📖 Library Shelves → DagsHub (DVC) The actual books — our datasets and models — are stored neatly on DagsHub’s shelves, linked to the catalog for easy retrieval.
👩🏫 Librarian → GitBot Instead of you shelving every new book manually, the librarian (GitHub Actions) automatically files them in the right place when you update the catalog.
📓 Reading Logs → Experiments Every time someone studies a book (trains a model), the reading log records which edition was used and what insights (metrics) were gained.
By the end of this journey, we’ll have built a smart library for ML projects — one where every dataset, model, and experiment is cataloged, stored, and tracked automatically.
📌 Prerequisites → Library Membership Card
Before entering the library, you need a membership card. For our MLOps library, that means having a few essentials ready:
- Git + GitHub account → the catalog system.
- DagsHub account → the library shelves.
- Python 3.9+ installed → the language to organize our books.
- Git installed locally → to interact with the catalog.
- GitHub Actions enabled → to hire your librarian.
With this card in hand, you’re ready to walk into the library and start cataloging.
📖 Step 1: Cataloging the Books → GitHub + DVC Setup
Since you already created the GitHub repo (catalog) and cloned it locally, we’ll just organize it and add the shelving system (DVC).
🏗️ Organize the Library Sections
mkdir data src models # Create sections for books, notes, and editions
data/→ the actual books (datasets).src/→ the methods (training code).models/→ new editions (trained models).
📦 Add the Shelving System (Initialize DVC)
pip install dvc # Install DVC → the library’s shelf manager
dvc init # Initialize DVC → activates the shelving system
git add .dvc .dvcignore # Add DVC config files & ignore rules to catalog
git commit -m "Initialize DVC" # Save this setup in GitHub catalog

📊 Add the First Book (Dataset)
Here, we’ll use the Wine Quality dataset 🍷 as our first book.
curl -o data/winequality-red.csv https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv
# Download the dataset (the first book to put on our shelves)
dvc add data/winequality-red.csv
# Create a catalog card for this dataset (Git will track only this .dvc file)
git add data/winequality-red.csv.dvc .gitignore
# Add the dataset’s catalog card + updated ignore rules to Git
git commit -m "Add wine quality dataset with DVC"
# Save this new book entry in the catalog (GitHub)

🔗 Connect DagsHub to Your GitHub Repo
Before hiring the librarian, we need to connect our library catalog (GitHub repo) with our library shelves (DagsHub repo).
- Go to **DagsHub and create a new repository**.
- When creating it, choose Import from GitHub.
- Select the GitHub repo you already created for this project (ex:
dagshub_gitbot). - DagsHub will now mirror your GitHub repo and add extra features:
- Data tab → stores datasets, models, and metrics versioned with DVC.
- Experiments tab → logs all MLflow runs (parameters, metrics, artifacts).
From now on:
- Every
git push→ updates code in GitHub and reflects in DagsHub. - Every
dvc push(or GitBot auto push) → syncs datasets/models to DagsHub’s storage.





🔗 Connect to the Big Library (DagsHub Remote)
Now let’s connect our shelves to DagsHub. Copy the DVC remote URL from your DagsHub repo (looks like: https://dagshub.com/<user>/<repo>.dvc).
dvc remote add origin https://dagshub.com/<user>/<repo>.dvc
# Add DagsHub as the official shelf for storing books
dvc remote default origin
#
dvc remote modify origin --local auth basic
# Tell DVC to use basic authentication (username + token) for access
dvc remote modify origin --local user <your-dagshub-username>
# Provide your DagsHub username (like the librarian's ID card)
dvc remote modify origin --local password <your-dagshub-token>
# Provide your DagsHub personal access token (the librarian's key)
dvc push
git add data/winequality-red.csv.dvc data/.gitignore .dvc/config
# Add catalog cards (winequality-red.csv.dvc) + rules (data/.gitignore) + fixed shelf address (.dvc/config) to Git
git commit -m "Track wine quality dataset with DVC and fix remote config"
# Save these updates into the catalog history with a clear note:
# - New book card for winequality-red.csv
# - Rules to ignore raw books in Git
# - Correct shelf (remote) settings for DagsHub
git push origin main
# Publish the catalog updates to GitHub/DagsHub so everyone sees:
# - The new book card
# - The updated rules
# - The fixed shelf connection

Github

Dagshub
📖 Step 2: Hiring the Librarian → GitBot Automation
So far, we’ve built the catalog (GitHub) and placed your first book on the shelves (DagsHub). But right now, you have to shelve books manually by running dvc push. That’s like being your own librarian — tiring and error-prone.
Let’s hire a librarian (GitBot) using GitHub Actions. From now on, whenever you update the catalog (git push), the librarian will automatically put the books on the shelves (dvc push).
📝 Create a Workflow File
Inside your repo, create a workflow folder and file:
mkdir .github\workflows # Create workflows folder (if not already)
type nul > .github\workflows\ci-cd.yaml # Create workflow file
DVC Auto Push to DagsHub (CI)
name: DVC Auto Push to DagsHub
on:
push:
branches: [ "main" ] # Trigger on pushes to main
pull_request:
branches: [ "main" ]
permissions:
contents: write
jobs:
dvc-sync:
runs-on: ubuntu-latest
steps:
# Step 1: Checkout repository (your GitHub repo contents)
- name: Checkout repository
uses: actions/checkout@v3
# Step 2: Set up Python (needed for DVC)
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
# Step 3: Install DVC
- name: Install DVC
run: pip install dvc[all]
# Step 4: Configure DVC remote (connect shelves in DagsHub)
- name: Configure DVC remote
run: |
dvc remote add origin https://dagshub.com/${{ secrets.DAGSHUB_USER }}/dagshub_gitbot.dvc
dvc remote modify origin --local auth basic
dvc remote modify origin --local user ${{ secrets.DAGSHUB_USER }}
dvc remote modify origin --local password ${{ secrets.DAGSHUB_TOKEN }}
# Step 5: Auto push data/models/metrics to DagsHub
- name: DVC Push
run: dvc push🔑 Add Librarian’s Keys (Secrets)
- Go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret.
. Add DAGSHUB_USER → your DagsHub username (ex:santosh.flyingmachine).
.Add DAGSHUB_TOKEN → your DagsHub personal access token (from DagsHub → Settings → Developer → Personal Access Tokens)

📖 Reading Logs → Experiments with MLflow
In a library, every reader leaves behind a reading log:
- Which edition of the book they used (parameters)
- How good the study session was (metrics)
- Sometimes, they even leave notes or summaries (artifacts/models)
In MLOps, this is called experiment tracking. We’ll use MLflow with DagsHub to track parameters, metrics, and models.
📝 Install required packages
pip install dagshub mlflow scikit-learn pandas
dagshub→ connects MLflow directly with your repo.mlflow→ experiment tracking system.scikit-learn+pandas→ model training & dataset handling.
📝 Training script (src/train.py)
type NUL > src\train.py
import dagshub
import mlflow
import pandas as pd
import joblib
import json
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# 📖 Connect MLflow tracking to your DagsHub repo
dagshub.init(
repo_owner='santosh.flyingmachine',
repo_name='dagshub_gitbot',
mlflow=True
)
# 📚 Load dataset (semicolon-separated CSV from UCI Wine Quality dataset)
data = pd.read_csv("data/winequality-red.csv", sep=";")
# Features (X) and target (y)
X = data.drop("quality", axis=1)
y = (data["quality"] >= 6).astype(int) # Good wine (>=6) vs Bad wine (<6)
# Split into train/test sets
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 📖 Start a new MLflow run (experiment log)
with mlflow.start_run():
# Parameters (edition of the book studied)
C = 0.1
max_iter = 1000 # avoid convergence warnings
# Train model
model = LogisticRegression(C=C, max_iter=max_iter)
model.fit(X_train, y_train)
# Predictions + accuracy
preds = model.predict(X_test)
acc = accuracy_score(y_test, preds)
# Log parameters & metrics
mlflow.log_param("C", C)
mlflow.log_param("max_iter", max_iter)
mlflow.log_metric("accuracy", acc)
# Save model locally
model_path = "models/model.pkl"
joblib.dump(model, model_path)
# Log model file as an artifact (supported in DagsHub MLflow)
mlflow.log_artifact(model_path)
# Save metrics for DVC tracking
with open("metrics.json", "w") as f:
json.dump({"accuracy": acc}, f)
print(f"✅ Run logged to MLflow with accuracy: {acc:.4f}")
print(f"📦 Model saved at: {model_path}")
📝 Create a DVC Pipeline (dvc.yaml)
Now we define a training stage that depends on both the dataset and the training code.
stages:
train:
cmd: python src/train.py
deps: # Dependencies
- data/winequality-red.csv
- src/train.py
outs: # Outputs (tracked by DVC)
- models/model.pkl
metrics: # Metrics (tracked by DVC, special handling)
- metrics.json
📝 Run the pipeline
dvc repro # dvc repro automatically re-runs the pipeline stages in dvc.yaml when dependencies change, regenerating outputs and updating dvc.lock for reproducibility.

📝 Track Everything with Git + DVC
Once the pipeline runs successfully, we need to register the outputs in our catalog (GitHub) and store the actual artifacts in our shelves (DagsHub).
git add dvc.yaml dvc.lock metrics.json
git commit -m "Add training pipeline with DVC and MLflow tracking"
git push origin main
dvc push
📖 Step 3: Automating New Editions → CI/CD with GitBot
Right now, retraining and pushing the new model still requires manual steps (dvc repro, dvc push). That’s like you being the librarian who still has to shelve every new book and edition yourself.
Let’s fix that by teaching our librarian (GitHub Actions) how to not only catalog new data but also update models automatically whenever something changes.
📝 Extend Workflow (.github/workflows/ci-cd.yaml) DVC Auto Push to DagsHub (CI)
CI/CD Pipeline (CI + CD)
name: CI/CD Pipeline
on:
push:
branches: [ "main" ]
jobs:
dvc-sync:
runs-on: ubuntu-latest
steps:
# Step 1: Checkout code (the catalog)
- name: Checkout repository
uses: actions/checkout@v3
# Step 2: Setup Python
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.9"
# Step 3: Install dependencies
- name: Install dependencies
run: |
pip install dvc[all]
pip install dagshub mlflow scikit-learn pandas joblib
# Step 4: Configure shelves (DagsHub remote)
- name: Configure DVC remote
run: |
dvc remote modify origin --local auth basic
dvc remote modify origin --local user ${{ secrets.DAGSHUB_USER }}
dvc remote modify origin --local password ${{ secrets.DAGSHUB_TOKEN }}
# Step 5: Reproduce pipeline (retrain model if data/code changed)
- name: Reproduce Pipeline
run: dvc repro
# Step 6: Push new data & models to DagsHub
- name: Push Data & Models to DagsHub
run: dvc push
📝 Explaining the Workflow → Librarian’s Daily Routine
Our librarian (GitHub Actions) doesn’t just randomly shelve books. They follow a clear routine:
- Checkout Repository → The librarian first opens the catalog to see what’s new.
- Set up Python → Gets the right tools to handle shelves and records.
- Install Dependencies → Equips themselves with everything needed (DVC, MLflow, etc.).
- Configure DVC Remote → Connects to the correct shelves in the library.
- Reproduce Pipeline → Runs through the training plan if any new books or methods arrived.
- Push Data & Models → Finally, places the new books/editions neatly on the shelves.
This routine ensures nothing gets misplaced, and the library stays in perfect order.
📝 Commit and Push the Workflow
Once the workflow file is ready, we need to add it to our GitHub repo so GitBot (the librarian) officially comes on duty.
git add .github/workflows/ci-cd.yaml
git commit -m "Add CI/CD pipeline with DVC automation"
git push origin main
📖 Trigger the Librarian
Now that the librarian (GitBot) is officially hired and trained, it’s time for the first test run.
Simply make any small change in your repo (like updating README.md) and push it:
git add .
git commit -m "Test automation with new data"
git push origin main

🔍 Verify in DagsHub
Once the librarian (GitBot) has done its job, it’s time to walk into the library and check the shelves.
- Go to your DagsHub repo → Experiments to see runs and metrics.

🏁 Wrap-Up / Conclusion → A Modern Digital Library
We started with a single dusty book (raw dataset) and built a full modern library where:
- GitHub catalogs every entry.
- DagsHub neatly stores all books and editions.
- GitBot (GitHub Actions) automatically shelves new arrivals.
- MLflow keeps the reading logs for every study session.
Now, every push you make doesn’t just update code — it updates datasets, models, and metrics, all in sync.
Think of it as transforming a messy pile of books into a smart digital library for ML projects 📚 — one where reproducibility and automation are built in from day one.
메타데이터
- post_id
- 68b29deb491d
- slug
- end-to-end-mlops-with-dagshub-and-github-actions-automate-dvc-data-models-experiments-68b29deb491d
- url
- https://medium.com/@andrsantoshkumar/end-to-end-mlops-with-dagshub-and-github-actions-automate-dvc-data-models-experiments-68b29deb491d
- canonical_url
- https://medium.com/@andrsantoshkumar/end-to-end-mlops-with-dagshub-and-github-actions-automate-dvc-data-models-experiments-68b29deb491d
- author_url
- https://medium.com/@andrsantoshkumar
- status
- ok
- fetched_at
- 2026-08-27 15:43:20