गिटहब एक्शन्स वह सीआई है जो कोड के पास ही रहता है। .github/workflows/ के नीचे यामल छोड़ें, पुश करें, और रनर आपके चुने इवेंट पर जॉब उठा लेते हैं: पुल रिक्वेस्ट, main पर पुश, शेड्यूल, या मैन्युअल क्लिक।

यह लेख न्यूनतम मानसिक मॉडल है, साथ में वे टुकड़े जो प्रोडक्शन पाइपलाइन में सच में दिखते हैं: वर्कफ़्लो, जॉब, स्टेप, कैश, सीक्रेट, मैट्रिक्स बिल्ड, और वे गलतियाँ जो हरे चेक को झूठा बनाती हैं या हर रन को १२ मिनट तक खींचती हैं।

मार्केटप्लेस घुमाई नहीं। "हर फीचर चालू करो" सूची नहीं। एक काम करने वाला सीआई रास्ता जिसे कॉपी करके कसा जा सके।


आप वास्तव में क्या कॉन्फ़िगर कर रहे हैं

तीन परतें:

परत क्या है फ़ाइल / जगह
वर्कफ़्लो इवेंट से ट्रिगर होने वाली नामित पाइपलाइन .github/workflows/*.yml
जॉब एक रनर (वीएम या कंटेनर) पर काम की इकाई jobs.<id>:
स्टेप शेल कमांड या दोबारा इस्तेमाल होने वाला एक्शन steps: के नीचे

एक वर्कफ़्लो कई जॉब चला सकता है। जॉब समानांतर चलते हैं या needs से एक-दूसरे का इंतज़ार करते हैं। एक जॉब के अंदर स्टेप हमेशा उसी मशीन पर क्रम में चलते हैं, इसलिए बाद वाले स्टेप पहले वाले की फ़ाइलें और एनव देखते हैं।

इसी वजह से लोग "चेकआउट, फिर इंस्टॉल, फिर टेस्ट" एक ही जॉब में रखते हैं, तीन ठंडे जॉब में नहीं।


सबसे छोटा उपयोगी वर्कफ़्लो

.github/workflows/ci.yml बनाएँ:

name: CI

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: npm

      - name: Install
        run: npm ci

      - name: Test
        run: npm test

यह क्या करता है:

१. हर पुल रिक्वेस्ट और main पर हर पुश पर चलता है। २. नया उबंटू रनर उठाता है। ३. जाँचे जा रहे कमिट पर रिपो चेकआउट करता है। ४. नोड २० लगाता है और जब संभव हो एनपीएम कैश बहाल करता है। ५. npm ci से डिपेंडेंसी (लॉकफ़ाइल-सख्त) और टेस्ट चलाता है।

टेस्ट स्टेप शून्य के अलावा निकले तो जॉब फेल, पुल रिक्वेस्ट पर चेक फेल। पूरा अनुबंध यही है।


ट्रिगर: शोर के बिना on

आम इवेंट:

on:
  pull_request:
    paths:
      - "src/**"
      - "package-lock.json"
      - ".github/workflows/ci.yml"
  push:
    branches: [main]
  workflow_dispatch:   # यूआई में मैन्युअल "Run workflow"
  schedule:
    - cron: "0 6 * * 1"  # सोमवार ०६:०० यूटीसी

दोबारा रन बचाने वाली बातें:

  • paths फ़िल्टर तब वर्कफ़्लो छोड़ देते हैं जब बदलाव सिर्फ़ दस्तावेज़ हो (या जो आप बाहर रखें)। गलत ग्लॉब अक्सर जवाब होता है: "सीआई क्यों नहीं चला?"
  • workflow_dispatch सीक्रेट ठीक करने के बाद बिना डमी कमिट के फिर चलाने का रास्ता है।
  • schedule सिर्फ़ डिफ़ॉल्ट ब्रांच पर चलता है, और लोड में गिटहब कम-प्राथमिकता क्रॉन देर कर सकता है। "हर रिलीज़ से पहले ज़रूर चले" के लिए अकेले क्रॉन मत रखें।
  • फ़ॉर्क पुल रिक्वेस्ट पर सीक्रेट पहुँच सीमित होती है। जान-बूझकर। इसे सुरक्षा सीमा समझें, बग नहीं।

जॉब, रनर और needs

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run lint

  test:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test

  build:
    runs-on: ubuntu-latest
    needs: [lint, test]
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

needs: lint का मतलब test तब तक रुके जब तक lint सफल न हो। lint फेल हो तो test और build छूट जाते हैं (जब तक if: कुछ और न कहे)।

हर जॉब नई मशीन है। lint और test के बीच साझा फ़ाइल सिस्टम नहीं, जब तक आर्टिफ़ैक्ट न भेजें या फिर से इंस्टॉल न करें। इसलिए भोले बहु-जॉब ग्राफ़ डिपेंडेंसी तीन बार लगाते हैं।

जॉब कब बाँटें:

  • अलग ओएस या भाषा संस्करण (मैट्रिक्स)।
  • धीमी स्वतंत्र सूट जिन्हें समानांतर चाहिए।
  • डिप्लॉय जॉब जो टेस्ट पास होने तक न चले, और अतिरिक्त सीक्रेट चाहे।

एक जॉब कब रखें:

  • छोटे रिपो जहाँ इंस्टॉल समय खाता है।
  • स्टेप जो डिस्क पर गर्म लोकल कैश साझा करते हैं (node_modules, target/, .venv)।

स्टेप: run बनाम uses

  • run: रनर पर शेल। लिनक्स पर डिफ़ॉल्ट बैश। उन प्रोजेक्ट स्क्रिप्ट के लिए जिन पर पहले से भरोसा है।
  • uses: प्रकाशित एक्शन (या लोकल ./.github/actions/...)। संस्करण पिन रखें (@v4 या ऊँचे भरोसे वाले रास्तों पर पूरा एसएचए)।
steps:
  - uses: actions/checkout@v4

  - name: Run unit tests
    run: |
      set -euo pipefail
      npm ci
      npm test -- --coverage

actions/checkout लगभग हमेशा पहला स्टेप है। बिना इसके रनर का वर्कस्पेस खाली रहता है।

सीक्रेट या डिप्लॉय क्रेडेंशियल छूने वाले थर्ड-पार्टी एक्शन पर कमिट एसएचए पिन करें और स्रोत देखें। टैग हिल सकते हैं।


डिपेंडेंसी कैश

कैश हर रन पर पूरा इंस्टॉल चुकाने से बचाता है। जहाँ हो, सेटअप एक्शन का बिल्ट-इन कैश लें:

- uses: actions/setup-node@v4
  with:
    node-version: "20"
    cache: npm          # पैकेज-लॉक से की बीज

- uses: actions/setup-python@v5
  with:
    python-version: "3.12"
    cache: pip

- uses: actions/setup-go@v5
  with:
    go-version: "1.22"
    cache: true

ज़रूरत पड़ने पर मैन्युअल कैश:

- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-npm-

अंगूठे के नियम:

  • लॉकफ़ाइल बदलते ही की बदलनी चाहिए। पुरानी की गलत ट्री लगाती है या ज़रूरी अपडेट छोड़ देती है।
  • कैश बेस्ट-एफर्ट है। ७ दिन सुस्ती या नई की पर मिस सामान्य है। जॉब ठंडे भी चलना चाहिए।
  • सीक्रेट या ऐसे बिल्ड आउटपुट कैश न करें जिन्हें पुल रिक्वेस्ट आर्टिफ़ैक्ट में न रखते। कैश डिपेंडेंसी और टूलचेन के लिए है, "कल रात का बाइनरी कैश है तो टेस्ट छोड़ो" के लिए नहीं।
  • restore-keys उपसर्ग हैं: आंशिक हिट पुराना कैश लाकर ऊपर परत चढ़ाती है। इंस्टॉल तेज़, पर ढीले इंस्टॉल पर लॉकफ़ाइल गलती छिप सकती है।

आर्टिफ़ैक्ट अलग चीज़ हैं: actions/upload-artifact / download-artifact उसी वर्कफ़्लो रन के जॉब के बीच बिल्ड आउटपुट भेजते हैं। कैश रन के पार; आर्टिफ़ैक्ट एक रन के अंदर (आपकी रिटेंशन के साथ)।


सीक्रेट और एनवायरनमेंट वेरिएबल

रिपो या ऑर्ग सीक्रेट गिटहब सेटिंग में रहते हैं। वर्कफ़्लो उन्हें ऐसे पढ़ते हैं:

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production   # वैकल्पिक: सुरक्षा नियम, एनव-स्कोप्ड सीक्रेट
    steps:
      - uses: actions/checkout@v4

      - name: Deploy
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
          APP_ENV: production
        run: ./scripts/deploy.sh

सख्त नियम:

  • लॉग में सीक्रेट कभी इको न करें। गिटहब ज्ञात सीक्रेट मान मास्क करता है, हर व्युत्पन्न स्ट्रिंग नहीं। API_TOKEN का बेस६४ या टुकड़ा छप जाए तो लीक हो सकता है।
  • सिर्फ़ सीआई के लिए रिपो या वर्कफ़्लो यामल में सीक्रेट कमिट न करें।
  • फ़ॉर्क से pull_request को pull_request_target जितने राइट सीक्रेट नहीं मिलते। अविश्वसनीय कोड के लिए pull_request चुनें। pull_request_target तभी जब चेकआउट और विशेषाधिकार मॉडल समझें; गलत इस्तेमाल क्लासिक सप्लाई-चेन जाल है।
  • ओआईडीसी + क्लाउड रोल (एडब्ल्यूएस, जीसीपी, एज़्योर) लंबे समय वाले की से बेहतर जब संभव हो। permissions + फ़ेडरेशन से छोटे जीवन वाले टोकन कम स्थायी निशान छोड़ते हैं।
  • वर्कफ़्लो शीर्ष या प्रति जॉब permissions: बाँधें। डिफ़ॉल्ट टोकन अधिकार समय के साथ सख्त हुए; फिर भी ज़रूरत लिखें:
permissions:
  contents: read
  pull-requests: write   # तभी जब बॉट को कमेंट करना हो

मैट्रिक्स बिल्ड

मैट्रिक्स एक जॉब परिभाषा को कई रन में फैलाता है:

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest]
        node: ["18", "20", "22"]
        exclude:
          - os: windows-latest
            node: "18"
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
      - run: npm ci
      - run: npm test

क्या देखें:

  • लागत और कतार आयामों के गुणनफल से बढ़ती है। तीन ओएस × चार संस्करण = बारह जॉब।
  • fail-fast: true (डिफ़ॉल्ट) एक सेल फेल होने पर भाई रन रद्द करता है। पूरा फेलियर नक्शा चाहिए तो false रखें।
  • include / exclude ग्रिड ईमानदार रखते हैं, हर जोड़ी हाथ से गिनने से बेहतर।
  • ओएस-विशेष पथ और शेल अंतर यहीं पहले दिखते हैं (\ बनाम /, पावरशेल बनाम बैश)। प्रोजेक्ट स्क्रिप्ट से अमूर्त करें।

कसकर बहु-भाषा उदाहरण

नोड फ्रंट और पाइथन टेस्ट वाली सेवा:

name: CI

on:
  pull_request:
  push:
    branches: [main]

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  frontend:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: web
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: npm
          cache-dependency-path: web/package-lock.json
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

  backend:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: api
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: pip
          cache-dependency-path: api/requirements.txt
      - run: pip install -r requirements.txt
      - run: pytest -q

  docker:
    runs-on: ubuntu-latest
    needs: [frontend, backend]
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t app:ci .

concurrency उसी ब्रांच पर पुराना चल रहा रन रद्द कर देता है जब फिर पुश करें। एक्शन्स मिनट बिल और यह भ्रम कि कौन सा रन ताज़ा है, दोनों नियंत्रण में रहते हैं।


आम गलतियाँ (महँगी वाली)

१. सोचे से अलग कमिट टेस्ट होना

अविश्वसनीय पुल रिक्वेस्ट सीआई के लिए हमेशा पुल रिक्वेस्ट हेड चेकआउट करें। चेकआउट पर गलत ref (या लापरवाह pull_request_target + मर्ज रेफ़) भरोसेमंद वर्कफ़्लो को हमलावर-नियंत्रित स्रोत पर चला सकता है। pull_request पर डिफ़ॉल्ट actions/checkout@v4 ज़्यादातर टीमों के लिए सुरक्षित आधार है।

२. सीआई में npm install बजाय npm ci

npm install लॉकफ़ाइल व्यवहार बदल सकता है और डेवलपर इंस्टॉल से भटक सकता है। सीआई लॉकफ़ाइल-सख्त रास्ता अपनाए (npm ci, pnpm install --frozen-lockfile, yarn install --immutable, आदि)।

३. सीधे node_modules कैश करना

चलता है जब तक टूट न जाए (वैकल्पिक डिप, नेटिव ऐडऑन, ओएस अंतर)। पैकेज मैनेजर स्टोर कैश करें और साफ़ इंस्टॉल करें। सेटअप-नोड का cache: npm एनपीएम के लिए उबाऊ सही डिफ़ॉल्ट है।

४. "डिबग" स्टेप में run: echo से सीक्रेट

कोई echo "token=$API_TOKEN" "पाँच मिनट" के लिए छोड़ देता है। लॉग पुल रिक्वेस्ट से ज़्यादा जीते हैं। अस्थायी लोकल डिबग करें; मानें कि रन की रीड पहुँच वाले को लॉग दिख सकते हैं।

५. बिना concurrency, अनंत ओवरलैप डिप्लॉय

main पर दो पुश क्रम से बाहर डिप्लॉय कर सकते हैं। डिप्लॉय वर्कफ़्लो पर concurrency समूह, या रिव्यूअर / टाइमर वाला एनवायरनमेंट।

६. डिबग में fail-fast: false के बिना मैट्रिक्स विस्फोट

एक लाल क्रॉस दिखता है, भाई रद्द, और विंडोज़+नोड २२ भी टूटा छूट जाता है। स्थिर करते समय fail-fast पलटें; सूट भरोसेमंद हो तो वापस चालू करें।

७. महत्वपूर्ण एक्शन पर latest टैग

uses: some-org/some-action@main मंगलवार को आपके नीचे बदल सकता है। कम से कम मेजर पिन (@v4)। डिप्लॉय और रिलीज़ पर एसएचए पिन।

८. सुरक्षित ब्रांच पर आवश्यक चेक भूलना

वर्कफ़्लो है, पुल रिक्वेस्ट लाल क्रॉस अनदेखा करके मर्ज। ब्रांच प्रोटेक्शन (या रूलसेट) को उन जॉब नामों की माँग करनी चाहिए जो मायने रखते हैं। जॉब नाम बदलें और आवश्यक चेक अपडेट न करें तो मर्ज मुक्त हो जाते हैं।

९. जीआईटीएचबी_टोकन अनुमति आश्चर्य

इश्यू खोलने या टैग पुश करने वाला स्टेप डिफ़ॉल्ट बदलने के बाद ४०३ देता है। स्पष्ट permissions रखें; समर्पित पीएटी या गिटहब ऐप तभी जब डिफ़ॉल्ट टोकन काफ़ी न हो।

१०. फ्लेकी टेस्ट का दोष एक्शन्स पर

पूरा वर्कफ़्लो दोहराना उत्पाद बग छुपाता है। फ्लेक ठीक करें या स्पष्ट सूची से क्वारंटीन करें। अनंत Re-run jobs स्थिरता रणनीति नहीं।


एक्सप्रेशन, कॉन्टेक्स्ट और if

- name: Publish
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
  run: ./scripts/publish.sh

उपयोगी कॉन्टेक्स्ट: github, env, secrets, matrix, needs, runner, steps

- name: Upload coverage
  if: always() && steps.test.outcome == 'success'
  uses: actions/upload-artifact@v4
  with:
    name: coverage
    path: coverage/

if: always() पिछले स्टेप फेल होने पर भी चलता है (जॉब रद्दीकरण अब भी लागू)। सफ़ाई या सच में चाहिए अपलोड के लिए कम और सोच-समझकर इस्तेमाल करें।


मिनट जलाए बिना लोकल इटरेशन

  • वही स्क्रिप्ट चलाएँ जो एक्शन्स चलाता है: npm ci && npm test। लोकल फेल तो सीआई भी फेल।
  • एक्ट डॉकर से वर्कफ़्लो का अनुमान लगाता है। गिटहब-होस्टेड रनर से एक जैसा नहीं (इमेज, उपलब्ध सॉफ़्टवेयर, नेटवर्क)।
  • मर्ज किए बिना स्टेजिंग डिप्लॉय जाँचने के लिए इनपुट वाला workflow_dispatch
on:
  workflow_dispatch:
    inputs:
      target:
        description: "deploy target"
        required: true
        default: staging

समझदार डिफ़ॉल्ट जाँच सूची

सीआई को "हो गया" कहने से पहले:

१. डिफ़ॉल्ट ब्रांच पर pull_request और push वर्कफ़्लो। २. लॉकफ़ाइल-सख्त इंस्टॉल। ३. भाषा सेटअप एक्शन + बिल्ट-इन कैश। ४. स्पष्ट permissions: contents: read (और केवल ज़रूरत पर)। ५. पुल रिक्वेस्ट ब्रांच पर concurrency। ६. सुरक्षित ब्रांच पर सटीक जॉब नाम वाले आवश्यक स्टेटस चेक। ७. सीक्रेट सिर्फ़ ${{ secrets.* }} / ओआईडीसी से, गिट में कभी नहीं। ८. फर्स्ट-पार्टी एक्शन पर मेजर पिन; डिप्लॉय पर एसएचए। ९. रिलीज़ के लिए दस्तावेज़ित "फिर चलाएँ / मैन्युअल डिस्पैच" रास्ता। १०. समय बजट: इंस्टॉल+टेस्ट ~१० मिनट से ऊपर हो तो मैट्रिक्स सेल जोड़ने से पहले प्रोफ़ाइल करें।


सफलता कैसी दिखती है

पुल रिक्वेस्ट खुलती है, एक मिनट से कम में चेक शुरू, इंस्टॉल ज़्यादातर कैश हिट, टेस्ट वही जो डेवलपर चलाते हैं, और लाल क्रॉस का मतलब "यह कमिट गलत है," न कि "रनर का खराब दिन" या "गलत रेफ़ टेस्ट हुआ।"

ऊपर वाले एकल-जॉब नोड (या पाइथन) वर्कफ़्लो से शुरू करें। कई रनटाइम सपोर्ट हों तो मैट्रिक्स जोड़ें। समानांतर दीवार-घड़ी या डिप्लॉय अलगाव रीइंस्टॉल लागत के लायक हो तब जॉब बाँटें। डिपेंडेंसी कैश करें, बहाने नहीं।

जब हरा हो और फिर भी भरोसा न हो, बग लगभग हमेशा क्या चलाते हैं या कौन सा कमिट चलाते हैं में होता है, यामल इंडेंटेशन में नहीं।