← Back to list

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…

Andra santosh kumar · 2025-09-03 19:53 · 4 claps · 10.2 min read
#mlops #dagshub #mlflow #github-actions #machine-learning
Open on Medium ↗
Wiki topics: OPS · LLMOps & Inference ML · Machine Learning STP · Startups & Venture EDU · Education & Learning ☁️ · DevOps & Cloud 🔓 · Open Source 🔬 · Science · General

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).

  1. Go to **DagsHub and create a new repository**.
  2. When creating it, choose Import from GitHub.
  3. Select the GitHub repo you already created for this project (ex: dagshub_gitbot).
  4. 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

Github

Dagshub

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)
  1. 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