En grön CI-körning är inte alltid ett coverage-besked

Tre separata signaler i en CI-pipeline: testresultat, coverage-rapport och merge-beslut

Kortversion: GitHub Code Quality hoppar numera över coverage-uppladdningen för nya brancher utan öppen pull request, i stället för att låta steget misslyckas. En grön körning säger därför inte ensam att coverage finns i kodgranskningen. Kontrollera era triggers och obligatoriska statuskontroller, och skilj mellan testresultat, rapport och merge-beslut.

När en pipeline slutar falla rött efter en plattformsändring är det lätt att tolka resultatet som att kvalitetssignalen fortfarande finns. Men en lyckad körning kan betyda att testerna passerade, att en rapport skapades – eller bara att ett coverage-uppladdningssteg hoppades över. Team som gör dessa tre tillstånd tydliga bygger mer tillförlitliga merge-regler och slipper felsöka fel signal vid fel tidpunkt.

Varför en grön status kan säga för lite

Kodtäckning är inte ett test i sig. Den beskriver hur stor del av koden som kördes när testsviten gick. För att den ska bli användbar i en pull request behöver flera saker hända i rätt ordning: testerna måste köras, en rapport måste produceras, rapporten måste laddas upp och plattformen måste koppla resultatet till rätt ändring.

Om något av dessa steg saknas kan en pipeline ändå vara grön. Det kan vara helt korrekt – till exempel när en utvecklare sparar ofärdigt arbete i en branch innan en pull request finns. Problemet uppstår när teamet ser den gröna symbolen som ett besked om både testresultat och coverage, fast den bara bekräftar att workflowet inte misslyckades.

Det här spelar särskilt stor roll för mindre produktteam. De har ofta få manuella kontrollpunkter och vill använda CI-statusar för att lägga energi på rätt kodgranskning. Då måste varje status ha en tydlig betydelse.

Vad GitHub ändrade den 1 oktober

GitHub meddelade att upload-code-coverage i GitHub Code Quality inte längre misslyckas när en push görs till en icke-standardbranch utan tillhörande öppen pull request. I stället hoppas uppladdningen över och GitHub visar varför i en Actions-notis och stegsammanfattning.

Det löser ett genuint tekniskt problem. Tidigare kunde API:t kräva ett pull request-nummer för en branchpush, trots att ett sådant nummer ännu inte fanns. GitHub skriver också ut en viktig följd: om workflowet bara triggas av push skapas ingen ny coverage-uppladdning enbart av att en pull request öppnas. Den återupptas vid nästa push. Vill teamet se coverage direkt när pull requesten öppnas behöver workflowet även ha en pull_request-trigger.

Ändringen gäller GitHub Team och GitHub Enterprise Cloud, även med data residency, men inte GitHub Enterprise Server. Kontrollera därför er produktvariant innan ni planerar kring beteendet.

Skilj på tre signaler i er leveransprocess

En enkel modell är att ge varje signal ett eget namn och en egen kontrollfråga.

1. Testresultat: fungerar den kod som faktiskt kördes?

Här är frågan binär: passerade eller misslyckades testsviten? Den säger något om just den körningen, men inte om hur väl koden täcks eller om resultatet visas i en pull request. Testresultatet kan vara relevant redan i en privat feature-branch.

2. Coverage-rapport: finns ett tolkningsbart underlag?

Rapporten uppstår först när testverktyget verkligen genererat ett format som workflowet kan ladda upp. GitHubs dokumentation använder Cobertura XML som exempel och betonar att rapporten ska produceras varje gång testerna körs. En lyckad testsvit utan rapport är alltså inte samma sak som coverage-data.

3. Granskningssignal: går det att fatta merge-beslut nu?

Det tredje steget är den signal som kodgranskaren behöver. GitHubs exempelworkflow kör på standardbranchen för att skapa en baslinje och på pull requests för att jämföra ändringen mot den. Om teamet kräver coverage vid merge är det denna signal – i rätt pull request – som ska granskas, inte bara ett grönt branch-build.

När ni använder en regel som begränsar kodtäckning rekommenderar GitHub att varje förväntad coverage-statuskontroll görs obligatorisk. Det är ett skäl att inventera vilka checks som faktiskt förväntas i varje triggerfall. En check som aldrig körs kan inte ge ett pålitligt merge-besked bara för att workflowet i övrigt lyckades.

Rita flödet innan ni ändrar YAML

Börja med ett vardagligt flöde och markera var respektive signal ska finnas:

  1. En utvecklare pushar till en ny feature-branch utan pull request. Tester kan köras; coverage-uppladdningen kan nu hoppas över utan att det är ett fel.
  2. Pull requesten öppnas. Om coverage ska synas direkt behöver workflowet triggas av pull request-händelsen, inte bara nästa branchpush.
  3. En uppdatering pushas till pull requesten. Tester och coverage ska kunna kopplas till den kod som granskas.
  4. Ändringen mergeas till standardbranchen. Baslinjen uppdateras genom den avsedda standardbranch-körningen.

Detta är mer än en CI-detalj. Flödet avgör när en produktägare eller teknisk granskare kan lita på att en siffra verkligen beskriver den förändring som ska släppas.

En liten kontrollista för teamet

  1. Läs era on:-triggers. Finns både den trigger som etablerar baslinjen och den som visar resultat i pull requesten?
  2. Öppna en pull request utan extra push. Verifiera från faktisk körning om coverage visas när ni förväntar er det.
  3. Kontrollera statuskontrollerna. Gör varje förväntad coverage-statuskontroll vid merge obligatorisk; dokumentera varför den ibland saknas utanför en pull request.
  4. Kontrollera behörigheter. GitHubs exempel ger contents: read och code-quality: write för uppladdningen. Undvik att utöka workflowets rättigheter av slentrian.
  5. Skriv en rad i teamets leveransguide. Exempel: “Grön branch-CI bevisar testutfall; coverage granskas i pull requesten.”

Använd en enkel testbranch för ändringen. En YAML-ändring som ser rimlig ut kan annars visa coverage först efter ett extra push, vilket är precis den sorts processglapp ni försöker undvika.

När ni inte behöver göra något

Alla team använder inte GitHub Code Quality eller coverage som merge-regel. Om ni har en annan tjänst för coverage, eller om er policy uttryckligen bara kräver testresultat, är GitHubs ändring främst information att känna till. Gör inte coverage till ett artificiellt mått bara för att verktyget erbjuder det.

Men om en grön status idag används som beslutssignal för release eller merge bör ni minst kunna svara på vilken av de tre signalerna den representerar. Det är ofta en snabbare förbättring än att höja ett generellt procentmål.

Slutsats: gör kvalitetsbeviset synligt där beslutet tas

GitHubs nya beteende minskar onödiga röda builds på nya brancher. Det är bra. Den praktiska lärdomen är ändå större: en pipeline bör inte lämna granskarna att gissa om ett uteblivet coverage-resultat är ett fel, ett hoppat steg eller en ännu inte skapad pull request. Separera test, rapport och merge-signal. Då blir både grönt och rött mer användbart.

Källor och vidare läsning