Wzorce Pipeline CI/CD
Twoje wdrożenie przeszło wszystkie sprawdzenia i mimo to położyło produkcję. Testy jednostkowe były zielone, build Dockera się powiódł, kubectl set image zwróciło 0 - ale obraz wypuścił CRITICAL CVE w zależności przechodniej, bo nic w pipeline jej nigdy nie przeskanowało. CI mówiło ci, że wszystko jest w porządku, dokładnie do chwili, w której pager powiedział ci, że nie jest.
Rozwiązaniem nie jest „napisz lepszy YAML ręcznie”. Rozwiązaniem jest użycie narzędzia AI do wygenerowania pipeline’u, który ma już bramki, jakie dodałby starszy inżynier platformowy - cachowanie zależności, skan podatności, który faktycznie wywala build, oraz wdrożenie produkcyjne czekające na prawdziwy health check - a następnie przejrzenie tego, co powstało, zamiast pisania 200 linii boilerplate’u od zera.
Co z tego wyniesiesz
Dział zatytułowany „Co z tego wyniesiesz”- Gotowy do wklejenia prompt, który zamienia istniejący
package.json+Dockerfilew kompletny workflow GitHub Actions z matrycą wersji Node, cachowaniem zależności i skanem Trivy, który bramkuje build. - Prompt, który zamienia czerwony log CI w diagnozę przyczyny źródłowej plus konkretną poprawkę, abyś przestał ręcznie bisekować nieudane uruchomienia.
- Prompt do dodania bramkowanego metrykami rolloutu canary do istniejącego wdrożenia
kubectl. - Trójnarzędziowy workflow (Cursor, Claude Code, Codex) do generowania, przeglądania i uruchamiania zmian w pipeline - łącznie z oficjalnymi GitHub Actions dla Claude Code i Codex, dzięki czemu ten sam model, który napisał pipeline, może przeglądać twoje PR-y.
- Mapę „Gdy to się zepsuje” obejmującą tryby awarii, na które generowane pipeline’y wpadają najpierw: cache misses, błędy OIDC przy assume role, timeouty rolloutu i fałszywe alarmy skanera.
Workflow: wygeneruj pipeline ze swojego repo
Dział zatytułowany „Workflow: wygeneruj pipeline ze swojego repo”Pułapka promptów typu „stwórz pipeline CI/CD” polega na tym, że produkują one prawdopodobnie wyglądający workflow oderwany od twojego rzeczywistego projektu - zły menedżer pakietów, zmyślone skrypty testowe, wersja Node, której nie używasz. Zakotwicz prompt w plikach, które już są w repo, aby wynik odpowiadał rzeczywistości.
Otwórz repo w Cursorze, dodaj package.json, Dockerfile oraz dowolne istniejące .github/workflows/* do kontekstu Agenta przez @, a następnie uruchom poniższy prompt w trybie Agent. Cursor edytuje plik workflow w miejscu, a ty przeglądasz diff w edytorze przed zaakceptowaniem. Trzymaj package.json w kontekście, aby czytał twój prawdziwy blok scripts zamiast zgadywać npm test.
Z katalogu głównego repo Claude Code ma już dostęp do systemu plików, więc sam czyta package.json i Dockerfile - nie wklejasz ich. Uruchom claude i podaj mu prompt. Najpierw dodaj serwer GitHub MCP, jeśli chcesz, by Claude czytał istniejące uruchomienia workflow i metadane sekretów Actions podczas pracy:
claude mcp add --transport http github https://api.githubcopilot.com/mcp/Serwer GitHub MCP to ten sam endpoint HTTP w Cursorze, Claude Code i Codeksie - różni się tylko komenda rejestrująca. Przestarzały transport /sse zniknął; użyj --transport http.
Z katalogu głównego repo uruchom codex i podaj mu prompt - Codex czyta package.json i Dockerfile z drzewa roboczego. Ponieważ edycje pipeline’u dotykają tylko .github/, to bezpieczny kandydat do większej autonomii:
codex --full-auto "<the prompt below>"--full-auto to samodzielna flaga (sandbox workspace-write, bez zatwierdzania każdej edycji); nie jest to wartość dla --ask-for-approval. Do przeglądu pipeline’u na niezaufanym PR pomiń ją i pozwól Codeksowi zapytać przed zapisem.
Dobry wygenerowany wynik wygląda jak ten szkielet - zwróć uwagę na krok skanu, który faktycznie bramkuje build, czyli część, o której zapominają ręcznie pisane pipeline’y:
name: CIon: push: { branches: [main] } pull_request: release: { types: [published] }
permissions: contents: read
jobs: test: runs-on: ubuntu-latest strategy: matrix: { node: [20, 22] } steps: - uses: actions/checkout@v6 - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} cache: 'npm' - run: npm ci - run: npm test # the real script, read from package.json
build: needs: test runs-on: ubuntu-latest permissions: contents: read packages: write id-token: write # OIDC, no stored registry password steps: - uses: actions/checkout@v6 - uses: docker/setup-buildx-action@v4 - uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v7 id: build with: push: true tags: ghcr.io/${{ github.repository }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max - name: Scan image (fails build on CRITICAL/HIGH) uses: aquasecurity/trivy-action@v0.36.0 with: image-ref: ghcr.io/${{ github.repository }}:${{ github.sha }} severity: 'CRITICAL,HIGH' exit-code: '1' ignore-unfixed: true
deploy-prod: needs: build if: github.event_name == 'release' runs-on: ubuntu-latest environment: production # required reviewers enforce the gate steps: - uses: actions/checkout@v6 # ... cloud auth + rollout belowDecyzją do przejrzenia jest tutaj exit-code: '1' w kroku Trivy. Bez niej skan tworzy raport, którego nikt nie czyta, a build pozostaje zielony. Z nią podatny obraz bazowy blokuje wdrożenie. Ta jedna linia to różnica między zepsutym pipeline’em z wstępu a bezpiecznym.
Diagnozowanie czerwonego uruchomienia
Dział zatytułowany „Diagnozowanie czerwonego uruchomienia”Wygenerowanie pipeline’u to łatwiejsza połowa. Połowa, która zżera twoje popołudnie, to uruchomienie, które wywala się w linii 1 z 400-liniowego logu z npm ci kończącym się kodem 1 i bez oczywistego powodu. Wklej log do narzędzia AI, zamiast go przewijać.
Sformułowanie „działa lokalnie, ale wywala się w CI” ma znaczenie: popycha model w stronę przyczyn specyficznych dla środowiska - nieaktualnego klucza actions/cache przywracającego node_modules zbudowane pod złą wersją Node, lockfile’a zacommitowanego niezgodnie z package.json, brakującego kontenera serwisowego - zamiast ogólnikowych porad „sprawdź swoje testy”.
Dodawanie bramkowanego metrykami canary
Dział zatytułowany „Dodawanie bramkowanego metrykami canary”Gdy podstawowe wdrożenie już działa, kolejna prośba brzmi zwykle „wypuść na 10% ruchu, obserwuj error rate, automatycznie promuj albo wycofaj”. To właśnie tutaj wygenerowany blok kubectl jest niebezpieczny, jeśli nie jest bramkowany prawdziwym sygnałem - więc uczyń bramkę jawną w prompcie.
Nalegaj na „plain shell with explicit thresholds”. Canary, który promuje na podstawie nieprzejrzystego inputu akcji, jest nieaudytowalny; taki, w którym próg error rate 0.01 jest widoczny w workflow, to coś, co twój zespół może zrozumieć i dostroić.
GitLab CI i Jenkins
Dział zatytułowany „GitLab CI i Jenkins”Ta sama pętla generuj-i-przeglądaj dotyczy innych platform - zmienia się tylko plik docelowy. Powyższe prompty działają dosłownie, jeśli podmienisz „GitHub Actions / .github/workflows/ci.yml” na „etapy .gitlab-ci.yml” lub „deklaratywny Jenkinsfile”. Dwie uwagi specyficzne dla platform, które warto przekazać AI:
- GitLab CI: poproś o wbudowane szablony bezpieczeństwa (
include: - template: Security/SAST.gitlab-ci.ymlorazContainer-Scanning.gitlab-ci.yml) zamiast ręcznie sklejanych zadań skanera - są utrzymywane przez GitLab i podłączają wyniki do widgetu MR. Przypnij obrazy zadań do prawdziwego tagu (node:22-alpine) i użyjcache:key:files: [package-lock.json], aby cache unieważniał się przy zmianie lockfile’a. - Jenkins: poproś o
Jenkinsfileużywający równoległych etapów quality-gate (parallel) i agentów Docker, oraz wywołującywithSonarQubeEnv+waitForQualityGate abortPipeline: true, tak by niezaliczona bramka jakości faktycznie zatrzymywała pipeline. Trzymaj logikę wdrożenia w bibliotece współdzielonej, nie inline.
Domknięcie pętli: AI, które przegląda własne pipeline’y
Dział zatytułowany „Domknięcie pętli: AI, które przegląda własne pipeline’y”Najmocniejszy wzorzec to pozwolenie, by ten sam model, który napisał pipeline, przejrzał PR, który go zmienia. Obaj dostawcy dostarczają natywną GitHub Action, więc nie musisz schodzić do npm install -g i ręcznie scrapować git diff.
Cursor nie dostarcza akcji CI - to IDE. Podział pracy: użyj Agenta Cursora oraz agenta w tle (background agent) do napisania i iterowania workflow lokalnie z pełnym kontekstem edytora, a następnie pozwól, by GitHub Action Claude Code albo Codeksa obsłużyła krok przeglądu w CI. Generuj lokalnie, przeglądaj w CI.
Uruchom /install-github-app wewnątrz claude, aby skonfigurować aplikację i sekret ANTHROPIC_API_KEY, a następnie wstaw oficjalną akcję. Sama wykrywa, czy odpowiadać na wzmianki @claude, czy automatycznie uruchamiać prompt:
name: Claude Reviewon: pull_request: types: [opened, synchronize]jobs: review: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - uses: actions/checkout@v6 - uses: anthropics/claude-code-action@v1 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} prompt: "/review" claude_args: "--max-turns 5"Przypnij do aktualnego wydania anthropics/claude-code-action@v1 (advisory ze stycznia 2026 załatano w v1.0.94+); przejrzyj dokumentację bezpieczeństwa akcji przed przyznaniem pull-requests: write na PR-ach z forków.
Codex dostarcza openai/codex-action@v1, która instaluje CLI i uruchamia codex exec w sandboxie, który kontrolujesz. Przechowuj prompty jako pliki w .github/codex/prompts/:
name: Codex Reviewon: pull_request: types: [opened, synchronize, reopened]jobs: codex: runs-on: ubuntu-latest permissions: contents: read pull-requests: write steps: - uses: actions/checkout@v6 - uses: openai/codex-action@v1 with: openai-api-key: ${{ secrets.OPENAI_API_KEY }} prompt-file: .github/codex/prompts/review.md output-file: codex-output.md safety-strategy: drop-sudo sandbox: workspace-writesafety-strategy: drop-sudo (domyślnie) usuwa sudo zanim Codex wystartuje i jest nieodwracalne dla zadania - trzymaj je włączone w każdym workflow wyzwalanym przez PR. Przy uruchomieniu Codeksa na kluczu API możesz przypiąć model przez input model; domyślny model tej powierzchni to GPT-5.5.
Gdy to się zepsuje
Dział zatytułowany „Gdy to się zepsuje”-
Cache się przywraca, ale build i tak rekompiluje wszystko. Klucz
actions/cachesię nie zmienił, ale zawartość jest błędna - zwyklenode_moduleszacachowane pod inną wersją Node albo klucz pozbawiony hasha lockfile’a. Użyj klucza w stylu${{ runner.os }}-node${{ matrix.node }}-${{ hashFiles('**/package-lock.json') }}i preferuj wbudowanecache: 'npm'zactions/setup-node(które cachuje cache pobrań npm, a nienode_modules) zamiast cachowanianode_modulesbezpośrednio. -
Wdrożenie OIDC wywala się z „Not authorized to perform sts:AssumeRoleWithWebIdentity”. Zadanie ma
permissions: id-token: write, ale polityka zaufania po stronie chmury nie dopuszcza tego repo/brancha. Poprawka jest po stronie trust relationship roli IAM (waruneksubmusi pasować dorepo:org/name:ref:refs/heads/mainlub twojego środowiska), a nie w YAML-u. Poproś AI o wygenerowanie polityki zaufania na podstawiepermissionsi wyzwalacza workflow, a następnie zweryfikuj, że claimsubsię zgadza. -
kubectl rollout statuswisi aż zadanie wpadnie w timeout. Nowe pody nie przechodzą w Ready - niedziałający readiness probe, błąd pobrania obrazu albo niewystarczające zasoby klastra. Dodaj--timeout=120s, aby szybko wywaliło, a następniekubectl describe deployment/app -n <ns>ikubectl get events --sort-by=.lastTimestamp, by zobaczyć dlaczego. Rollout, który nigdy się nie kończy, to zablokowane wdrożenie, a nie powolne. -
Trivy wywala build na CVE, którego nie możesz naprawić.
CRITICALw zależności przechodniej bez jeszcze załatanej wersji. Nie usuwaj kroku skanu - tak właśnie wydarzył się scenariusz ze wstępu. Użyjignore-unfixed: true(już jest w szkielecie), aby pominąć CVE bez poprawki, oraz przejrzanego.trivyignorez konkretnym ID CVE i notatką o wygaśnięciu dla reszty. Hurtowe wyłączenie bramki to zła poprawka. -
Wygenerowany workflow przypina akcje do
@masterlub@main. To najczęstsza wada w pipeline’ach generowanych przez AI: ryzyko supply-chain i brak powtarzalności. Przypnij każdą akcję firm trzecich do wydanego tagu (albo commit SHA dla ścieżek wysokiego zaufania). Poproś ponownie z „pin all actions to released tags, no floating refs” lub popraw to przy przeglądzie.