Každý řádek kódu, který se dostane do produkčního prostředí, byl commitován někým, kdo věřil, že je správný. Statická analýza kódu je automatizovaný systém, který kontroluje, zda je toto přesvědčení správné, nikoli spuštěním kódu, ale čtením jeho struktury, sledováním jeho datových toků a porovnáváním se známými vzorci zranitelností, chyb a porušení kvality. Otázkou není, zda kód spustit, ale kde v produktovém procesu ho spustit, který nástroj spustit, jaké prahové hodnoty vynutit a jak udržet zpětnou vazbu dostatečně rychlou, aby na ni vývojáři skutečně reagovali, a ne ji ignorovali.
Rozdíl mezi statickou analýzou jako aktivitou s checkboxem a statickou analýzou jako skutečnou kvalitativní bránou spočívá v konfiguraci. Skener, který běží a vytváří zprávu, kterou nikdo nečte, je divadlo. Kvalitativní brána, která selže při sestavení, když se objeví nové kritické zranitelnosti, zablokuje sloučení, když pokrytí klesne pod prahovou hodnotu, a zobrazí přesnou zpětnou vazbu k souborům a řádkům v rozhraní pro kontrolu pull requestů, je systém, který mění chování v okamžiku, kdy jsou učiněna rozhodnutí.
Kde v kanálu spustit statickou analýzu
Statická analýza by měla probíhat na více místech, z nichž každé slouží jinému účelu. Její spuštění pouze na jednom místě vytváří slepá místa; její spuštění všude rovnoměrně vytváří pomalé kanály, které vývojáři obcházejí.
| Fáze potrubí | Co běžet | Latenční rozpočet | Účel |
|---|---|---|---|
| Předběžné potvrzení (lokální) | Pouze rychlé linters (ESLint, Clippy, rustfmt) | Do 5 sekund | Zastavte zjevné problémy dříve, než se dostanou do repozitáře |
| Žádost o natažení / žádost o sloučení | Kompletní linting + SAST + inkrementální skenování SonarQube | Méně než 3 minuty | Sloučení bloků u nových kritických problémů |
| Sestavení hlavní pobočky | Kompletní analýza včetně pokrytí, duplikace, technického dluhu | Méně než 10 minuty | Sledování trendů kvality, aktualizace dashboardů |
| Naplánováno každou noc | Hloubkové skenování, audit závislostí, kontroly shody s předpisy | Žádný rozpočet | Zachycení problémů s pomalou výstavbou a rizik dodavatelského řetězce |
Nejcennější fází je pull request.Analýza, která běží na push to main, dorazí až po rozhodnutí o sloučení. Analýza, která běží na pull requestu a vkládá inline komentáře s přesným kontextem souboru a řádku, dorazí, když je vývojář stále v kódu a náklady na opravu jsou nejnižší.
Spouštění náročné analýzy před každým uložením ničí zkušenosti vývojářů. Rychlé lintery, které se dokončí za méně než 5 sekund, patří tam. Všechno ostatní patří do CI.
Akce GitHubu: Dokončení funkční konfigurace
GitHub Actions je nejpoužívanější platforma pro CI. Následující pracovní postup spouští vrstvený kanál pro kontrolu kvality: kontrola formátování, linting, sestavení, bezpečnostní kontrola SAST a kontrola kvality SonarCloud.
yaml
# .github/workflows/quality.yml
name: Code Quality
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
# ── Layer 1: Fast checks (under 60 seconds) ─────────────────────────────
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Lint (fail on warnings)
run: npx eslint src/ --max-warnings 0
- name: Format check
run: npx prettier --check src/
- name: TypeScript type check
run: npx tsc --noEmit
# ── Layer 2: Security SAST (Semgrep) ────────────────────────────────────
sast:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Semgrep SAST scan
uses: semgrep/semgrep-action@v1
with:
config: p/javascript p/nodejs p/owasp-top-ten
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
# ── Layer 3: SonarCloud quality gate ────────────────────────────────────
sonar:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history required for blame data
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Run tests with coverage
run: npm test -- --coverage --coverageReporters=lcov
- name: SonarCloud scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
vlastnosti
# sonar-project.properties
sonar.projectKey=my-org_my-project
sonar.organization=my-org
sonar.sources=src
sonar.tests=tests
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.coverage.exclusions=**/*.test.js,**/*.spec.js
Klíčová konfigurační rozhodnutí v tomto pracovním postupu:
--max-warnings 0Na ESLintu: jakékoli varování je selhání sestavení. Týmy, které povolují varování, je hromadí, dokud si je nikdo nepřečte.fetch-depth: 0při platbě: SonarCloud potřebuje kompletní historii gitu, aby mohl správně přiřadit vinu zavedeným problémům a vypočítat metriky nového kódu.- Semgrep běží po lint paralelně se Sonarem: bezpečnost a skenování kvality jsou nezávislé záležitosti; jejich paralelní spuštění zkracuje celkový čas zpracování.
- Testy probíhají s
lcovvýstup pokrytí: SonarCloud toto načte, aby zobrazil pokrytí pro každý soubor a vynutil prahové hodnoty pokrytí v bráně kvality.
GitLab CI/CD: Procesor kvality s branami kvality
yaml
# .gitlab-ci.yml
stages:
- lint
- test
- analyze
- security
variables:
SONAR_HOST_URL: "https://sonarcloud.io"
lint:
stage: lint
image: node:20
cache:
paths: [node_modules/]
script:
- npm ci
- npx eslint src/ --max-warnings 0
- npx prettier --check src/
- npx tsc --noEmit
rules:
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_BRANCH == "main"
test:
stage: test
image: node:20
script:
- npm ci
- npm test -- --coverage --coverageReporters=lcov cobertura
coverage: '/Lines\s*:\s*(\d+\.?\d*)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
sonarcloud:
stage: analyze
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
cache:
key: "${CI_JOB_NAME}"
paths: [.sonar/cache]
script:
- sonar-scanner
rules:
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_BRANCH == "main"
semgrep:
stage: security
image: returntocorp/semgrep:latest
script:
- semgrep scan --config=p/owasp-top-ten --config=p/javascript
--sarif --output=semgrep.sarif src/
artifacts:
reports:
sast: semgrep.sarif
rules:
- if: $CI_MERGE_REQUEST_IID
- if: $CI_COMMIT_BRANCH == "main"
Jedno artifacts: reports: sast: Blok integruje výstup SARIF ze Semgrepu přímo do bezpečnostního panelu GitLabu, kde se zjištění zobrazují v bezpečnostní zprávě o merge requestu, nikoli jako nezpracovaný výstup CI logu.
Jenkins: Deklarativní kanál se SonarQube
prima
// Jenkinsfile
pipeline {
agent any
tools {
nodejs "NodeJS-20"
}
environment {
SONAR_TOKEN = credentials('sonar-token')
}
stages {
stage('Lint') {
steps {
sh 'npm ci'
sh 'npx eslint src/ --max-warnings 0'
sh 'npx tsc --noEmit'
}
}
stage('Test') {
steps {
sh 'npm test -- --coverage --coverageReporters=lcov'
}
post {
always {
publishHTML([
allowMissing: false,
reportDir: 'coverage/lcov-report',
reportFiles: 'index.html',
reportName: 'Coverage Report'
])
}
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('SonarQube') {
sh '''
npx sonar-scanner \
-Dsonar.projectKey=my-project \
-Dsonar.sources=src \
-Dsonar.javascript.lcov.reportPaths=coverage/lcov.info
'''
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 5, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
post {
failure {
emailext(
subject: "Quality Gate FAILED: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
body: "Build failed quality gate. Review: ${env.BUILD_URL}",
to: "${env.CHANGE_AUTHOR_EMAIL}"
)
}
}
}
waitForQualityGate abortPipeline: true je kritický řádek. Dotazuje SonarQube, dokud není analýza dokončena, a sestavení selže, pokud není splněna kritéria kvality. Bez toho se pipeline dokončí, zatímco analýza stále běží, a výsledek kritéria kvality se nikdy nevymáhá.
Konfigurace bran kvality, které týmy skutečně respektují
Brána kvality, která selže při každém potvrzení, protože prahové hodnoty jsou nastaveny příliš agresivně, se deaktivuje. Brána, která nikdy neselže, protože prahové hodnoty jsou příliš tolerantní, neposkytuje žádnou hodnotu. Cílem je brána kalibrovaná na skutečný rizikový profil projektu.
Doporučená počáteční konfigurace pro novou bránu kvality SonarQube:
| metrický | Stav | Práh |
|---|---|---|
| Nové chyby | Větší než | 0 |
| Nové zranitelnosti | Větší než | 0 |
| Nová bezpečnostní hotspoty zkontrolovány | Méně než | 100% |
| Nové pokrytí kódu | Méně než | 80% |
| Nové duplicitní řádky | Větší než | 3% |
| Nový kód voní | Větší než | 10 |
Použijte tyto prahové hodnoty na pouze nový kód (období „nového kódu“ v SonarQube). Nepoužívejte je na celou kódovou základnu staršího projektu, protože selhání každého sestavení kvůli technickému dluhu nahromaděnému za pět let způsobí, že týmy bránu zcela deaktivují. Přístup s novým kódem vám umožňuje zastavit krvácení, zatímco stávající dluh se řeší samostatně.
Prahové hodnoty rohatky v průběhu času. Začněte s konzervativními prahovými hodnotami a poté je každé čtvrtletí zpřísňujte, jakmile tým vyřídí nahromaděné zásoby. Hodnota, která dnes projde s pokrytím 75 %, může být aktualizována na 80 %, jakmile je základní hodnota pohodlně nad touto hranicí. Postupné zpřísňování je udržitelnější než skok k dokonalosti.
Zvládání výkonu statické analýzy ve velkých kódových databázích
Nejčastějším důvodem, proč týmy v CI deaktivují nebo obcházejí statickou analýzu, je to, že příliš zpomaluje vývojové procesy. Patnáctiminutová kontrola kvality při každém odeslání do větve funkcí brzdí tok vývojářů. Několik strategií udržuje analýzu rychlou:
Inkrementální analýza (pouze nový kód). SonarQube a většina podnikových nástrojů pro statickou analýzu podporují analýzu pouze změněných souborů v žádosti o změnu, nikoli celé kódové základny. sonar.pullrequest.base, sonar.pullrequest.branch, a sonar.pullrequest.key parametry pro povolení inkrementálního skenování specifického pro PR. Úplná analýza stále běží při sloučení do hlavního složky; skenování PR probíhá na většině kódových základen za méně než 2 minuty.
Ukládání do mezipaměti. Nejdražší částí mnoha běhů statické analýzy je stažení nástroje a jeho definic pravidel. Mezi jednotlivými běhy ukládejte do mezipaměti binární soubor skeneru, databázi pravidel a všechny vyřešené závislosti:
yaml
# GitHub Actions: cache SonarCloud scanner
- name: Cache SonarCloud packages
uses: actions/cache@v4
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
Rovnoběžnost. Linting, bezpečnostní skenování a analýza Quality Gate jsou nezávislé záležitosti. Spouštějte je paralelně, nikoli postupně. Celkový čas zpracování v kanálu je určen nejpomalejší úlohou, nikoli součtem všech úloh.
Selektivní aktivace nástroje. Ne každý nástroj musí běžet na každé větvi. Úplné bezpečnostní skenování a kontroly shody s předpisy lze spustit na žádostech o změnu nastavení a hlavních větvích, zatímco větve před sloučením běží pouze na rychlých linterech. Pro použití různých analytických profilů použijte filtry větví v konfiguraci CI.
Statická analýza v bezpečnostních kanálech: SAST a skenování závislostí
Bezpečnostně zaměřené kanály přidávají nad rámec standardní analýzy kvality dvě vrstvy: SAST (Static Application Security Testing) pro zranitelnosti kódu aplikací a skenování závislostí pro známé CVE v knihovnách třetích stran.
Nástroje SAST (Semgrep, CodeQL, Snyk Code, Checkmarx) analyzují, jak nedůvěryhodná data proudí aplikačním kódem a dosahují citlivých operací. Nacházejí SQL injection, XSS, injection příkazů, nezabezpečenou deserializaci a pevně zakódované přihlašovací údaje, které standardní lintery nedokážou detekovat.
yaml
# GitHub Actions: CodeQL analysis for deep vulnerability detection
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: javascript-typescript
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:javascript-typescript"
Skenování závislostí Kontroly package.json, pom.xml, requirements.txta ekvivalentní soubory manifestu proti databázím zranitelností:
yaml
# Dependency audit in the pipeline
- name: Dependency audit
run: |
npm audit --audit-level=high
# Fail if high or critical vulnerabilities are found
Vrstvený model zabezpečení umisťuje na každý PR rychlý SAST založený na vzorcích (Semgrep) pro okamžitou zpětnou vazbu od vývojářů a hluboký sémantický SAST (CodeQL) podle plánu pro důkladné pokrytí. Skenování závislostí probíhá u každého sestavení, protože nové CVE jsou publikovány denně.
Časté chyby v integraci a jak se jim vyhnout
Spuštění analýzy pouze na hlavní větvi. Hodnota statické analýzy spočívá v zachycení problémů před jejich sloučením, nikoli po něm. Analýza, která se spouští až po sloučení, slouží jako report, nikoli jako brána.
Nastavení kvalitativních bran pro varování, nikoli pro selhání. Varování, které neblokuje proces, je oznámení, které se vývojáři naučí ignorovat. Brány, které neselžou, nebudují kulturu kvality.
Nevylučování testovacích souborů z prahových hodnot pokrytí. Testování kódu testováním jiného testovacího kódu vytváří nadsazená čísla pokrytí. Vyloučte testovací adresáře z výpočtů pokrytí, abyste získali přesná měření pokrytí produkčního kódu.
Ignorování nevyřízených analýz u starších kódových bází. Zapnutí SonarQube poprvé na milionu řádků staré kódové základny a získání 40 000 problémů je demotivující a kontraproduktivní. Použijte přístup základní úrovně nového kódu: definujte datum zahájení „nového kódu“, aplikujte brány pouze na kód napsaný po tomto datu a zacházejte se stávajícím nevyřízeným seznamem problémů jako se samostatným programem na snižování technického dluhu.
Nezapojování výsledků do komentářů v žádostech o změnu obsahu (pull request) Výsledky analýzy zveřejněné na samostatném dashboardu, který musí vývojáři navštívit, jsou ignorovány. Řeší se výsledky analýzy zveřejněné jako vložené komentáře na konkrétních řádcích, které způsobily problémy, v rozhraní pro kontrolu žádostí o změny. Konfigurace sonar.pullrequest.* parametry pro integraci s GitHubem, GitLabem nebo Bitbucketem, aby se nálezy zobrazovaly tam, kde probíhá kontrola kódu.
Jak SMART TS XL Integruje se s CI/CD Pipelines
Většina nástrojů pro statickou analýzu v CI/CD pipelinech vidí vždy jen jeden jazyk. ESLint vidí JavaScript. SonarQube vidí Javu, Python, JavaScript a C#. Žádný z nich nevidí COBOL, JCL, RPG ani závislosti mezi jazyky, které propojují dávkový program na mainframe s mikroslužbou Java, která spotřebovává její výstup a která se připojuje k frontendu JavaScriptu, který jej zobrazuje.
SMART TS XL integruje se do CI/CD pipelines jako vrstva statické analýzy napříč jazyky, která pokrývá všechny jazyky v podnikovém prostředí současně. Když je služba Java upravena, SMART TS XLJe analýza dopadu Sleduje graf závislostí, aby identifikoval, které programy v COBOLu, schémata databází a následné služby jsou touto změnou ovlivněny, a to ještě před jejím nasazením. Při úpravě COBOL copybooku identifikuje všechny programy v celém portfoliu aplikací, které daný copybook obsahují a které by vyžadovaly ověření.
Toto uvědomění si mezijazyčných závislostí je schopností, která umožňuje SMART TS XLIntegrace CI/CD se liší od přidání dalšího jazyka do SonarQube. Nejde jen o analýzu kódu v změněném souboru. Jde o pochopení toho, co dalšího v systému tato změna ovlivní, což je architektonická analýza, která určuje skutečný rozsah změny před jejím provedením.
Pro týmy podnikového vývoje pracující napříč staršími i moderními platformami, SMART TS XLJe Integrace DevOps Tato funkce integruje tuto strukturální analýzu do pracovního postupu kontroly pipeline a poskytuje architektonický přehled, který jazykově specifické nástroje nemohou poskytnout. Výsledkem jsou kritéria kvality, která vynucují standardy nejen v rámci jazykových hranic, ale v celém systému, a zajišťují, že změna v jakékoli komponentě nezpůsobí neočekávané selhání v komponentách, které jsou na ní závislé.
Statická analýza jako stálý občan potrubí
Týmy, které zvládnou statickou analýzu správně, k ní přistupují stejně jako k testování: ne jako k fázi, kterou je třeba projít, ale jako k průběžné praxi zabudované do každého commitu. Analýza běží u každého pull requestu. Výsledky Quality Gate se zobrazují v rámci kontroly kódu. Prahové hodnoty se zpřísňují s tím, jak se kódová základna zlepšuje. S rostoucí vyspělostí týmu v oblasti zabezpečení a kvality se přidávají nové kategorie analýzy.
Šablony konfigurace kanálu v tomto článku slouží jako výchozí body. Konkrétní nástroje, prahové hodnoty a podmínky brán by měly být kalibrovány podle jazykového stacku projektu, rizikového profilu a vyspělosti týmu. Co by se nemělo měnit, je princip: analýza, která neomezuje slučování, nemění chování a chování je to, co se programy pro kvalitu kódu snaží změnit.