समझिए
1. GitHub Actions क्यों?
- मुफ़्त क्लाउड कंप्यूटर जो शेड्यूल पर आपकी स्क्रिप्ट चलाते हैं।
- आपका PC बंद रह सकता है।
- हर रन का लॉग रहता है, और फ़ेल होने पर आपको ईमेल आता है।
- pandas/openpyxl स्क्रिप्ट के लिए चलता है (Excel की ज़रूरत नहीं)। VBA या xlwings के लिए नहीं।
2. Repository की बनावट
monthly-report/ ← a GitHub repository (make it PRIVATE for business data)
.github/workflows/weekly-report.yml
sample-data/*.csv
monthly_report.py
send_mail.py
requirements.txt
requirements.txt:
pandas
openpyxl
सब चल जाए तो वर्ज़न पिन करें (जैसे pandas==2.2.3), ताकि भविष्य का लाइब्रेरी अपडेट रिपोर्ट न तोड़े।
3. Workflow फ़ाइल
.github/workflows/weekly-report.yml बनाएँ:
name: Weekly sales report
on:
schedule:
- cron: "30 3 * * 1" # every Monday 03:30 UTC = 09:00 IST
workflow_dispatch: # adds a "Run workflow" button for manual runs
permissions:
contents: read
jobs:
report:
runs-on: ubuntu-latest
env:
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
REPORT_TO: ${{ secrets.REPORT_TO }}
steps:
- name: Get the code and data
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install libraries
run: pip install -r requirements.txt
- name: Build the report
run: python monthly_report.py --input sample-data --output Sales_Report.xlsx
- name: Save report as a downloadable artifact
uses: actions/upload-artifact@v4
with:
name: sales-report
path: Sales_Report.xlsx
retention-days: 30
- name: Email the report
if: ${{ env.SMTP_USER != '' && env.SMTP_PASSWORD != '' && env.REPORT_TO != '' }}
env:
SMTP_HOST: smtp.gmail.com
SMTP_PORT: "587"
SMTP_USER: ${{ secrets.SMTP_USER }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
run: python send_mail.py Sales_Report.xlsx "$REPORT_TO"
Commit और push करें। तुरंत जाँचने के लिए Actions टैब → Weekly sales report → Run workflow खोलें।
4. Cron UTC में होता है
GitHub के शेड्यूल UTC में होते हैं। भारत UTC + 5:30 है, इसलिए 5 घंटे 30 मिनट घटाएँ:
| चाहिए (IST) | लिखें (UTC) |
|---|---|
| सोम 09:00 | 30 3 * * 1 |
| रोज़ 08:00 | 30 2 * * * |
| रोज़ 18:30 | 0 13 * * * |
| महीने की 1 तारीख़ 07:00 | 30 1 1 * * |
शेड्यूल रन कुछ मिनट देर से शुरू हो सकते हैं (व्यस्त समय में ज़्यादा भी)। सटीक मिनट पर भरोसा न करें।
5. ईमेल स्क्रिप्ट
send_mail.py (कैपस्टोन में भी इस्तेमाल) सारी सेटिंग environment variables से पढ़ती है:
"""
send_mail.py
Email a file as an attachment through SMTP.
Settings are read from environment variables, never written in the code:
SMTP_HOST (default smtp.gmail.com), SMTP_PORT (default 587), SMTP_USER, SMTP_PASSWORD
Usage:
python send_mail.py Sales_Report.xlsx owner@example.com
"""
import mimetypes
import os
import smtplib
import sys
from email.message import EmailMessage
from pathlib import Path
def send_file(path: Path, to: str, subject: str, body: str) -> None:
user = os.environ["SMTP_USER"]
msg = EmailMessage()
msg["From"] = user
msg["To"] = to
msg["Subject"] = subject
msg.set_content(body)
ctype, _ = mimetypes.guess_type(path.name)
maintype, subtype = (ctype or "application/octet-stream").split("/", 1)
msg.add_attachment(path.read_bytes(), maintype=maintype, subtype=subtype, filename=path.name)
host = os.environ.get("SMTP_HOST", "smtp.gmail.com")
port = int(os.environ.get("SMTP_PORT", "587"))
with smtplib.SMTP(host, port, timeout=60) as server:
server.starttls()
server.login(user, os.environ["SMTP_PASSWORD"])
server.send_message(msg)
if __name__ == "__main__":
if len(sys.argv) != 3:
sys.exit("Usage: python send_mail.py <file> <to-address>")
file_path = Path(sys.argv[1])
send_file(file_path, sys.argv[2], f"Report: {file_path.name}", "Hello,\n\nThe latest report is attached.\n")
print("Email sent.")
6. Secrets — पासवर्ड कभी कोड में नहीं
Repository → Settings → Secrets and variables → Actions → New repository secret:
| नाम | वैल्यू |
|---|---|
SMTP_USER |
भेजने वाला Gmail पता |
SMTP_PASSWORD |
Gmail का App Password (Google Account → Security → 2-Step Verification चालू होना चाहिए → App passwords), सामान्य पासवर्ड नहीं |
REPORT_TO |
रिपोर्ट किसे मिले |
Secrets लॉग में छिपे रहते हैं और वापस पढ़े नहीं जा सकते, आप भी नहीं पढ़ सकते।
7. डेटा कहाँ से आता है?
इस उदाहरण में CSV repo में commit की गई हैं। असली विकल्प:
- कोई हर हफ़्ते नई फ़ाइलें commit करे (आसान)।
- स्क्रिप्ट उन्हें डाउनलोड करे: API (
requests), Google Drive/Sheets API, या क्लाउड स्टोरेज से — क्रेडेंशियल Secrets में रखकर।
निजी डेटा → private repository। public repo की हर चीज़ पूरी दुनिया को दिखती है।
8. जानने लायक बातें
- शेड्यूल workflow सिर्फ़ default branch (आमतौर पर
main) से चलते हैं। - public repo में, 60 दिन तक repository में कोई गतिविधि न होने पर शेड्यूल workflow बंद हो जाते हैं — GitHub पहले ईमेल करता है; एक commit या दोबारा enable करने से फिर चालू।
- private repo को हर महीने मुफ़्त Actions मिनट का कोटा मिलता है (अपना प्लान देखें)। छोटी रिपोर्ट हर रन में लगभग एक मिनट लेती है।
- रन फ़ेल होने पर GitHub ईमेल करता है, और Actions टैब हर स्टेप का पूरा लॉग दिखाता है।
आम गलतियाँ
cron IST में लिखना। ग्राहकों का डेटा public repo में commit करना। App Password की जगह सामान्य Gmail पासवर्ड इस्तेमाल करना (ब्लॉक होता है)। workflow_dispatch भूलना, जिससे जाँचने के लिए हफ़्ता भर रुकना पड़े।