8 Commits

Author SHA1 Message Date
k3nny 02d8e63a98 feat(cli): .glint.yml config and inline suppression comments
ci / vet, staticcheck, test, build (push) Successful in 2m25s
release / Build and publish release (push) Successful in 1m24s
Adds project-level configuration and per-job suppression directives:

.glint.yml (searched from pipeline dir up to the git root):
- ignore: [GL007, GL032] — suppress rules globally for the project
- severity: {GL004: warning} — override rule severity (error/warning/ignore)
- stages: [quality] — extra stages beyond the pipeline's stages: block
- token: / url: / cache_dir: — defaults for flags; lower priority than
  CLI flags and environment variables

Inline suppression (# glint: ignore):
- Place "# glint: ignore GL007" immediately before a job definition to
  suppress that rule for the specific job only
- Multiple rules: "# glint: ignore GL007, GL032" (comma or space separated)
- Wildcard: "# glint: ignore all" suppresses every finding for the job
- Suppressions are scoped to the annotated job; pipeline-level findings
  are unaffected
- Parsed from yaml.Node head/line comments in the first parse pass;
  stored in Pipeline.Suppressions (root file only, not includes)

New packages: internal/config (Load, walk-up search, .git boundary stop)
New files: cmd/glint/filter.go (applyConfig, isSuppressed helpers)
Tests: config_test.go, parser_suppress_test.go, filter_test.go
Validate fixtures: testdata/config_ignored/, config_severity/, config_suppress/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 10:23:33 +02:00
k3nny f5f8546bcf feat(cli): output formats, GL034-GL041 lint rules, include inputs and cache
ci / vet, staticcheck, test, build (push) Successful in 2m16s
release / Build and publish release (push) Successful in 1m9s
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>
2026-06-14 10:09:16 +02:00
k3nny 5fee51ec7d fix(cli): consistent output format, sorted findings, version flag
ci / vet, staticcheck, test, build (push) Successful in 2m9s
release / Build and publish release (push) Successful in 1m13s
- Workflow rules now use strict if: evaluation (parse failure → skip rule,
  not match); fixes premature matching that blocked later rules and injected
  wrong variables into the context
- Single = accepted as alias for == in rules:if: expressions
- File/Line preserved through extends: resolution (lost during YAML
  encode/decode round-trip in the resolver)
- Findings sorted by (File, Line, Rule) so same-file issues group together
- All warnings use ruff-style path: [warning] message format (includes,
  extends chains, workflow non-start)
- Add --version / -v flag; version shown at top of every --help output
- Build injects version via ldflags using git describe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 00:13:51 +02:00
k3nny cbed44b1e9 feat(cli): variable expansion, scalar bool/int support, precedence fix
ci / vet, staticcheck, test, build (push) Successful in 2m15s
release / Build and publish release (push) Successful in 1m13s
- Add $VAR / ${VAR} expansion in effective context (ctx.ExpandVars):
  iterates up to 10 passes to resolve transitive chains; circular
  references are left as-is after the limit.
- Handle non-string YAML scalars (bool, int, float64) in
  ExtractStringVars and varValueString via new ScalarString helper;
  values like BUILD: true no longer render as "(complex)" or get
  silently dropped from the effective context.
- Variable precedence (GitLab spec): pipeline defaults < workflow-rule
  vars < CLI --var flags; implemented correctly in enrichContext;
  expansion applied after all sources are merged.
- Update README, CHANGELOG, ROADMAP for v0.2.13.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 12:32:47 +02:00
k3nny fef1536e1b feat(cli): ruff-style output, implicit context defaults, --list-vars
ci / vet, staticcheck, test, build (push) Successful in 2m16s
release / Build and publish release (push) Successful in 1m6s
- Finding format now follows file:line: RULEID [severity] message,
  matching ruff and other modern linters (GL003 [error] job "x": ...)
- glint check and glint graph default to --branch main --source push
  when no context flag is given; rules:if: is always evaluated
- --list-vars flag on both commands prints sorted KEY=VALUE of all
  collected variables (YAML, workflow-rule union, effective context)
- CHANGELOG [Unreleased] promoted to [0.2.11]; README badge updated;
  ROADMAP marks newly shipped items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 00:36:32 +02:00
k3nny de6a526560 feat(linter): propagate workflow:rules:variables: into job rule evaluation
workflow:rules: can define variables: on matching rules (GitLab CI 15.0+).
These variables are now injected into the evaluation context before job
rules:if: expressions are evaluated, making patterns like:

  workflow:
    rules:
      - if: '$CI_COMMIT_BRANCH == "main"'
        variables:
          DEPLOY_TARGET: production
  deploy:
    rules:
      - if: '$DEPLOY_TARGET == "production"'

work correctly with glint check --branch main.

Changes:
- model.Rule: add Variables map[string]any field (yaml:"variables")
- cicontext.Context: add pinned map tracking which vars must not be
  overwritten; New() pins all shortcut and --var variables; add
  Inject(key, value) which writes only when key is not pinned
- cicontext.ExtractStringVars: shared helper that converts map[string]any
  variable blocks (plain string or {value:...} form) to map[string]string
- cicontext.EvalWorkflow: returns (bool, map[string]string) — the vars of
  the matching workflow rule alongside the runs/no-runs result
- cmd/glint/main.go: enrichContext() injects pipeline-level variable
  defaults then workflow-rule variables before printContext; applied in
  both cmdCheck and cmdGraph

Injection priority (highest wins):
  --var CLI overrides > --branch/--tag/--source shortcuts
  > workflow-rule variables > pipeline variables: defaults

Adds 15 unit tests (TestEvalWorkflow, TestContextInject,
TestExtractStringVars, TestWorkflowVarsJobEval) and a testdata fixture
(workflow_vars.yml) validated across four branch contexts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 22:35:55 +02:00
k3nny 88f20165db feat(cli)!: subcommand CLI, graph tree mode, local include resolution
BREAKING CHANGES:
- `glint <file>` removed; use `glint check <file>`
- `--graph <mode>` removed; use `glint graph [mode]`
- `--graph-out` renamed to `--out` on `glint graph`

feat(cli): ruff-style subcommands — `glint check` and `glint graph [mode]`
feat(graph): `glint graph tree` — terminal job tree with context annotations
feat(graph): context flags (--branch/--tag/--source/--var) on `glint graph`
feat(resolver): recursive local include resolution from disk
fix(resolver): extends unknown base emits warning instead of fatal error
fix(model): script/before_script/after_script accept block scalar string form
test(linter): Samba project CI fixtures as integration tests
chore(build): fix .gitignore to not exclude cmd/glint/ directory
docs: update CHANGELOG, README, ROADMAP for v0.2.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-11 00:27:28 +02:00
k3nny aca37de2b1 fix(ci): fix build 2026-06-10 23:02:06 +02:00