feat(cli): output formats, GL034-GL041 lint rules, include inputs and cache
Bundles three patch releases (v0.2.16–v0.2.18): v0.2.18 — output formats (--format flag on glint check): - json: stable JSON report (schema_version: 1, findings array, summary) - sarif: SARIF 2.1.0 for GitHub Code Scanning / GitLab SAST - junit: JUnit XML for CI test-report artifacts (artifacts:reports:junit) - github: GitHub Actions ::error:: / ::warning:: annotation lines - Unknown --format value exits 2 with a helpful error message - Summary line routed to stderr in structured formats; context suppressed v0.2.17 — include resolution improvements: - Recursive include depth capped at 100 (matches GitLab's own limit) - project: and component: includes tracked in visited set (cycle detection) - $[[ inputs.KEY ]] / $[[ inputs.KEY | default(…) ]] substituted from with: - --cache-dir: persist fetched remote templates to disk (SHA-256 keyed) - --offline: serve from cache only; defaults to ~/.cache/glint v0.2.16 — new lint rules (GL034–GL041): - GL034: services map form requires name; alias must be valid DNS label - GL035: rules:changes / rules:exists absolute path detection - GL036: timeout format validation (job-level + default.timeout) - GL037: id_tokens entries must have an aud key - GL038: secrets entries must declare a provider (vault / gcp / azure) - GL039: pages: keyword + artifacts.paths consistency - GL040: duplicate stage names in stages: list - GL041: cache.key.files must be exact paths, not globs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,8 @@ func (f Finding) String() string {
|
||||
func Lint(p *model.Pipeline) []Finding {
|
||||
var findings []Finding
|
||||
findings = append(findings, checkStages(p)...)
|
||||
findings = append(findings, checkDuplicateStages(p)...)
|
||||
findings = append(findings, checkDefault(p)...)
|
||||
findings = append(findings, checkWorkflow(p)...)
|
||||
findings = append(findings, checkJobs(p)...)
|
||||
findings = append(findings, checkNeeds(p)...)
|
||||
@@ -85,6 +87,32 @@ func checkStages(p *model.Pipeline) []Finding {
|
||||
return findings
|
||||
}
|
||||
|
||||
// GL040: warn when a stage name appears more than once in stages:.
|
||||
func checkDuplicateStages(p *model.Pipeline) []Finding {
|
||||
seen := make(map[string]bool, len(p.Stages))
|
||||
var findings []Finding
|
||||
for _, s := range p.Stages {
|
||||
if seen[s] {
|
||||
findings = append(findings, Finding{
|
||||
Severity: Warning,
|
||||
Rule: RuleDuplicateStage,
|
||||
File: p.SourceFile,
|
||||
Message: fmt.Sprintf("stage %q appears more than once in 'stages'; GitLab silently merges duplicate stage entries", s),
|
||||
})
|
||||
}
|
||||
seen[s] = true
|
||||
}
|
||||
return findings
|
||||
}
|
||||
|
||||
// checkDefault validates the pipeline-level default: block.
|
||||
func checkDefault(p *model.Pipeline) []Finding {
|
||||
if p.Default == nil {
|
||||
return nil
|
||||
}
|
||||
return checkDefaultTimeout(p.Default.Timeout, p.SourceFile)
|
||||
}
|
||||
|
||||
func checkWorkflow(p *model.Pipeline) []Finding {
|
||||
if p.Workflow == nil {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user