Automatyzacja pipeline'ów z AI
ENAutomatyzacja pipeline’ów z AI oznacza, że agent kodujący, taki jak Claude Code, Codex czy Cursor, edytuje samą konfigurację CI: joby świadome zmian, które pomijają nietknięte serwisy, triage oddzielający niestabilne testy od prawdziwych regresji oraz naprawy zepsutych workflowów. Pipeline pozostaje wiarygodny tylko wtedy, gdy lintery, zawsze uruchamiany check zbiorczy i code ownerzy weryfikują każdą zmianę agenta.
Twoje monorepo uruchamia każdy job przy każdym pushu. Jednolinijkowa zmiana w README czeka na pełny build sześciu serwisów, te same trzy specy end-to-end padają w części przebiegów i przechodzą po ponownym uruchomieniu, a cały zespół nauczył się klikać Re-run failed jobs bez czytania logu. Chcesz, żeby agent to naprawił, ale CI jest bramką, która chroni main. Agent, który po cichu osłabi tę bramkę, sprawia, że każdy późniejszy zielony check kłamie.
Ta strona jest dla developerów, którzy odpowiadają za CI repozytorium, i dla tech leadów, którzy decydują, które checki są wymagane. Dotyczy agenta, który edytuje pipeline. Uruchamianie agenta jako kroku w pipelinie opisuje strona agenci headless w CI, a wypuszczanie scalonej zmiany na produkcję — progressive delivery dla zmian pisanych przez agentów.
Co zyskujesz dzięki automatyzacji pipeline’ów
Dział zatytułowany „Co zyskujesz dzięki automatyzacji pipeline’ów”ci.ymlświadomy zmian, zbudowany nadorny/paths-filter, z minimalnymi uprawnieniami, akcjami przypiętymi do commita i jednym checkiem zbiorczym, który oznaczasz jako wymagany.- Pętlę triage niestabilnych testów: log nieudanego przebiegu trafia do agenta, a każdy werdykt „niestabilny” potwierdzasz ponownym uruchomieniem speca, zanim cokolwiek trafi do kwarantanny.
- Job lintujący workflowy (
actionlintizizmor), który sprawdza każdą zmianę agenta w.github/bez czytania YAML-a linia po linii. - Trzy prompty do skopiowania, polecenia dla Claude Code, Codeksa i Cursora oraz tryby awarii, w których zielony pipeline staje się fałszywym sygnałem.
Co się zmienia, gdy agent edytuje CI?
Dział zatytułowany „Co się zmienia, gdy agent edytuje CI?”Agent szybko pisze wiarygodnie wyglądający YAML. Ryzykiem nie jest błąd składni, bo CI zgłasza go od razu. Ryzykiem jest pipeline, który się uruchamia, świeci na zielono i już nie sprawdza tego, co sprawdzał wcześniej: filtr, który pomija job z testami, retry, który ukrywa regresję, albo uprawnienie, które poszerza token. Wytyczne DORA dotyczące wdrażania AI przypisują tę samą rolę kontroli wersji: „As AI increases the volume and velocity of code generation, version control becomes your critical safety net” (blog Google Cloud, Nathen Harvey i Allison Park, 2025-12-10). CI to ta część siatki bezpieczeństwa, która działa przy każdej zmianie.
Dlatego każdy workflow na tej stronie ma tę samą kolejność:
- Najpierw kontrakt. Powiedz agentowi, których checków nie wolno pominąć (sprawdzanie typów, lint, testy każdego zmienionego pakietu) i który job jest wymaganym checkiem statusu.
- Pozwól agentowi edytować. Użyj promptu do danego zadania, na prawdziwym układzie katalogów.
- Zweryfikuj mechanicznie. Job lintujący, check zbiorczy i jeden celowy testowy push dowodzą poprawności zmiany. Czytasz wynik weryfikacji, a nie każdą linię YAML-a.
- Zatwierdź przez własność. Wpis w
CODEOWNERSdla/.github/kieruje każdą zmianę pipeline’u do osoby odpowiedzialnej za bramkę.
Buduj tylko to, co się zmieniło, z dorny/paths-filter
Dział zatytułowany „Buduj tylko to, co się zmieniło, z dorny/paths-filter”W monorepo największa oszczędność w CI zwykle bierze się z nieuruchamiania jobów, których wejścia się nie zmieniły. dorny/paths-filter porównuje diff ze wzorcami ścieżek i wystawia jedno wyjście na filtr, które kolejne joby czytają w warunkach if:. Przy pull_request pobiera listę zmienionych plików przez API GitHuba, więc job potrzebuje pull-requests: read. Przy push używa gita, więc potrzebuje checkoutu.
Agent powinien wygenerować plik o takim kształcie, wyprowadzony z twoich prawdziwych workspace’ów, a nie skopiowany:
name: CIon: pull_request: push: branches: [main]
permissions: {}
jobs: changes: runs-on: ubuntu-latest permissions: contents: read pull-requests: read outputs: api: ${{ steps.filter.outputs.api }} web: ${{ steps.filter.outputs.web }} workflows: ${{ steps.filter.outputs.workflows }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: filters: | api: - 'services/api/**' - 'packages/shared/**' - 'package-lock.json' - '.github/workflows/**' web: - 'services/web/**' - 'packages/shared/**' - 'package-lock.json' - '.github/workflows/**' workflows: - '.github/**'
test-api: needs: changes if: ${{ needs.changes.outputs.api == 'true' }} runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - run: npm ci && npm test --workspace=services/api
# test-web: the same shape, gated on needs.changes.outputs.web
required: if: ${{ always() }} needs: [changes, test-api] runs-on: ubuntu-latest steps: - name: Fail if any needed job failed or was cancelled if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} run: exit 1Cztery szczegóły tego pliku agenci najczęściej psują, więc nazwij je w prompcie:
- Współdzielone wejścia są w każdym filtrze.
packages/shared/**, lockfile i katalog workflowów przebudowują każdego konsumenta. Zmiana w samym CI uruchamia więc raz cały zestaw testów. - Porównanie jest jawne. Wyjścia filtra to napisy
'true'i'false', więc warunek porównuje z== 'true'. - Wymaganym checkiem jest jeden job zbiorczy. Dokumentacja GitHuba mówi, że pominięty job zgłasza status „Success” i nie blokuje scalenia, nawet jeśli jest wymaganym checkiem. W ochronie gałęzi oznacz jako wymagany tylko
required. Uruchamia się przy każdym zdarzeniu i pada, gdy którykolwiek z potrzebnych mu jobów zawiódł albo został anulowany. - Akcje są przypięte do commita. Komentarz zachowuje czytelną wersję.
zizmor, używany w jobie lintującym poniżej, od wersji 1.20.0 domyślnie wymaga przypięcia wszystkich akcji do hasha.
Sposób pracy różni się między narzędziami. Cursor edytuje plik w edytorze i pokazuje diff. Claude Code i Codex mogą działać headless z terminala i zlintować wynik w tej samej sesji.
Uruchom w trybie print z katalogu głównego repozytorium, z lokalnie zainstalowanym actionlint (brew install actionlint). acceptEdits pozwala agentowi zapisywać pliki bez pytania, a allowlista pozwala mu uruchomić actionlint na własnym wyniku:
claude -p "$(cat prompts/change-aware-ci.md)" \ --permission-mode acceptEdits \ --allowedTools "Bash(actionlint *)"Zapisz prompt poniżej jako prompts/change-aware-ci.md, żeby zespół uruchamiał tę samą instrukcję po dodaniu serwisu. Żeby używać go w sesjach interaktywnych, zrób z niego skill projektu w .claude/skills/.
Uruchom nieinteraktywnie z profilem uprawnień workspace, który pozwala Codeksowi edytować pliki w repozytorium (profile uprawnień są w wersji beta w Codex CLI 0.157.1):
codex exec -c default_permissions=":workspace" \ -o ci-change-summary.md \ "$(cat prompts/change-aware-ci.md)"-o zapisuje ostatnią wiadomość agenta do pliku, który wklejasz do opisu pull requesta. Żeby uruchomić to samo zadanie w Codex cloud na gałęzi, użyj codex cloud exec --env ENV_ID --branch BRANCH "…", gdzie ENV_ID to środowisko z listy codex cloud.
Otwórz repozytorium, rozpocznij nowy czat z agentem i wklej prompt poniżej. Cursor czyta pole workspaces i drzewo services/, a potem proponuje .github/workflows/ci.yml jako diff. Przed akceptacją sprawdź w widoku diffu cztery szczegóły wymienione wyżej. To cała powierzchnia przeglądu tej zmiany. Jeśli repozytorium ma więcej niż jeden workflow, zacznij od Plan Mode, żeby agent wypisał joby, które zamierza objąć warunkami, zanim cokolwiek zmieni.
Zweryfikuj wynik bez czytania każdej linii. Tabela na końcu promptu to twierdzenie agenta o zachowaniu pipeline’u. Sprawdź je na pull requeście: wypchnij jeden commit, który zmienia tylko README.md, i sprawdź stany jobów poleceniem gh pr checks. test-api powinien być pominięty, required powinien przejść, a commit w packages/shared/ powinien uruchomić wszystkie joby testowe. Jeśli którykolwiek wiersz tabeli nie zgadza się z tym, co zrobiło CI, filtr jest błędny, niezależnie od tego, jak wygląda YAML.
Triage niestabilnych testów bez ukrywania regresji
Dział zatytułowany „Triage niestabilnych testów bez ukrywania regresji”Test, który w części przebiegów pada, a w części przechodzi, jest albo niestabilny, albo jest prawdziwym sporadycznym błędem, na przykład wyścigiem w kodzie produktu. Globalne retry traktują oba przypadki tak samo, a to ukrywa ten drugi. Zadaniem agenta jest sklasyfikować każdą awarię, a twoim — potwierdzić każdy werdykt „niestabilny” ponownym uruchomieniem, zanim cokolwiek trafi do kwarantanny.
Najpierw przekaż agentowi log nieudanego przebiegu. GitHub CLI wypisuje tylko nieudane kroki przebiegu:
RUN_ID=$(gh run list --workflow ci.yml --status failure --limit 1 \ --json databaseId --jq '.[0].databaseId')gh run view "$RUN_ID" --log-failed > failed.logZ podłączonym serwerem GitHub MCP agent może pobrać ten sam log sam, gdy wskażesz przebieg. W sesji interaktywnej oszczędza to kopiowanie. W skrypcie prostszy jest potok z gh, który nie wymaga tokena w konfiguracji agenta.
Przekaż log przez potok i ogranicz agenta do czytania plików oraz uruchamiania test runnera, żeby klasyfikacja nie zamieniła się w edycję. --permission-mode dontAsk utrzymuje to u każdego dostawcy, bo -p startuje w trybie auto u zewnętrznych dostawców lub z wyłączoną telemetrią (od v2.1.285):
claude -p "$(cat prompts/flaky-triage.md)" \ --permission-mode dontAsk \ --allowedTools "Read,Grep,Bash(npx playwright test *)" < failed.logcodex exec dołącza wejście z potoku do promptu jako blok <stdin>. Profil read-only pozwala przeglądać repozytorium i uruchamiać polecenia bez zapisu:
codex exec -c default_permissions=":read-only" \ "$(cat prompts/flaky-triage.md)" < failed.logPonowne uruchomienie Playwrighta zapisuje wyniki testów na dysku, a profil read-only to blokuje. Jeśli przebiegi potwierdzające padają na błędach zapisu, na czas tego kroku przełącz się na :workspace.
Dołącz failed.log do nowego czatu z agentem albo poproś agenta o odczytanie przebiegu przez serwer GitHub MCP, a potem wklej prompt poniżej. Cursor uruchamia polecenia potwierdzające w swoim terminalu; to, czy pyta przed każdym z nich, zależy od ustawień run mode.
Zapisz ten prompt jako prompts/flaky-triage.md.
Kwarantannę wprowadź jako osobną zmianę, przeglądaną jak każda inna zmiana wyroczni testowej. Trzymaj testy w kwarantannie na liście z datą i właścicielem. Kwarantanna bez właściciela nigdy się nie kończy.
Lintuj każdą zmianę agenta w pipelinie
Dział zatytułowany „Lintuj każdą zmianę agenta w pipelinie”Pliki workflowów mają dwie klasy defektów, których testy nie wyłapią: wyrażenia, które nie ewaluują się tak, jak zakładał autor, oraz problemy bezpieczeństwa, takie jak template injection, zbyt szerokie tokeny czy nieprzypięte akcje. Pokrywają je dwa analizatory statyczne. actionlint sprawdza typy w składni i wyrażeniach workflowów. zizmor audytuje workflowy pod kątem bezpieczeństwa. Oba działają w kilka sekund, więc uruchamiaj je przy każdej zmianie w .github/, z warunkiem na filtr workflows z pierwszej sekcji. Dodaj ten job do ci.yml i dopisz go do listy needs joba required:
lint-workflows: needs: changes if: ${{ needs.changes.outputs.workflows == 'true' }} runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: actionlint run: | bash <(curl -sSfL https://raw.githubusercontent.com/rhysd/actionlint/v1.7.12/scripts/download-actionlint.bash) 1.7.12 ./actionlint -color - name: zizmor run: pipx run --spec zizmor==1.30.1 zizmor --offline --format=github .github/workflows/Ten job działa na pull_request z tokenem tylko do odczytu i nie wykonuje żadnego kodu z gałęzi kontrybutora, a jedynie uruchamia dwa przypięte lintery na plikach workflowów, więc jest bezpieczny dla pull requestów z forków. Pilnuj, żeby tak zostało: agent poproszony o „przyspieszenie checków” potrafi przełączyć workflow na pull_request_target, który działa z sekretami repozytorium bazowego. Zasady uruchamiania agenta obok sekretów opisuje strona agenci headless w CI.
Jedna linia celowo łamie regułę przypinania po hashu z tego samego joba: skrypt pobierający actionlint jest ściągany po tagu wydania, a instalowaną binarkę ustala argument wersji 1.7.12. Traktuj to jako zaakceptowany wyjątek albo, jeśli Twoja polityka nie dopuszcza żadnych wyjątków, trzymaj kopię skryptu w repozytorium.
Potem ustal własność. Jedna linia w .github/CODEOWNERS i włączone Require review from Code Owners w ochronie gałęzi kierują każdą zmianę pipeline’u do osób odpowiedzialnych za bramkę:
/.github/ @your-org/platformCode owner nie czyta YAML-a linia po linii. Czyta trzy rzeczy: wynik joba lintującego, tabelę agenta „które joby się uruchamiają” zestawioną z tym, co pokazało gh pr checks, oraz diff listy needs joba required, która nie może się skurczyć bez uzasadnienia w opisie pull requesta.
Wklej ten prompt do sesji interaktywnej na gałęzi pull requesta albo zapisz go jako prompts/pipeline-review.md, żeby każdy recenzent przechodził tę samą listę kontrolną.
Gdzie w tym wszystkim jest krok wdrożenia?
Dział zatytułowany „Gdzie w tym wszystkim jest krok wdrożenia?”Trzymaj wdrożenie poza zasięgiem agenta i poza pull requestami. Uruchamiaj job wdrożeniowy tylko na push do chronionej gałęzi domyślnej, za środowiskiem GitHuba z własnymi sekretami i wymaganymi recenzentami. Agent może napisać i zmieniać ten job jak każdy inny plik workflowu, pod tym samym jobem lintującym i tymi samymi code ownerami, ale żadna sesja agenta nie powinna mieć poświadczeń wdrożeniowych.
To, co dzieje się po starcie joba wdrożeniowego, to progressive delivery: canary, feature flagi i automatyczny rollback na sygnał z poziomu usługi. Ta strona opisuje kontrolery rolloutu i budżet zasięgu awarii dla każdej klasy ryzyka. Joby wdrożeniowe dla konkretnych narzędzi znajdziesz na stronach konfiguracja pipeline’u z Claude Code, Codex w CI/CD z GitHub Action i pipeline’y CI/CD z Cursorem.
Który model powinien edytować CI?
Dział zatytułowany „Który model powinien edytować CI?”Edycja pipeline’u wymaga rozumowania obejmującego wiele plików, bo filtr jest poprawny tylko względem grafu pakietów. Zacznij od domyślnego modelu narzędzia i podnieś effort, zanim zmienisz model. Na 2026-10-12 oznacza to Claude Opus 5.5 w Claude Code od v2.1.280 (na obu kanałach wydań; effort podnosisz przez /effort) i GPT-6.1 Sol w Codeksie (domyślny od CLI 0.159.1). Cursor nie wskazuje jednego modelu domyślnego (strona o modelach i cenach, sprawdzone 2026-10-12), więc sprawdź wybór modelu we własnej instalacji Cursora. Ceny i pełną ofertę modeli znajdziesz w przeglądzie modeli.