From c956f054d4ffabb01528b8350e863799ce4222a5 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 14:19:36 -0500 Subject: [PATCH 1/7] feat: update to config-file-validator v2.2 - schemastore input is now a boolean flag enabling embedded catalog with remote fetching - New schemastore-path input for local SchemaStore clones (air-gapped environments) - JSONC file type support - Add schemastore test job - Update README with new inputs and examples --- .github/workflows/test.yml | 11 +++++++++++ README.md | 18 ++++++++++++++++-- action.yaml | 7 ++++++- cmd/entrypoint/main.go | 14 +++++++++++--- go.mod | 3 ++- go.sum | 6 ++++-- 6 files changed, 50 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c3d2ad..924dad3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -206,3 +206,14 @@ jobs: echo "Expected validation to fail when schema is required but not declared" exit 1 fi + + # Embedded schemastore with remote fetching + test-schemastore: + name: "Test: schemastore (embedded)" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: ./ + with: + search-paths: test/good.json + schemastore: "true" diff --git a/README.md b/README.md index 9e88e63..150bf27 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * HCL * HOCON * INI +* JSONC * JSON * Properties * SARIF @@ -49,7 +50,8 @@ Validation errors automatically appear as inline annotations on pull request dif | globbing | false | `"false"` | If set to `true`, enables glob pattern matching for search paths | | require-schema | false | `"false"` | If set to `true`, fail validation for files that support schema validation but do not declare a schema | | no-schema | false | `"false"` | If set to `true`, disable all schema validation (syntax-only). Cannot be used with `require-schema`, `schema-map`, or `schemastore` | -| schemastore | false | `""` | Path to a local SchemaStore clone for automatic schema lookup by filename | +| schemastore | false | `"false"` | If set to `true`, enables automatic schema lookup using the embedded SchemaStore catalog with remote fetching | +| schemastore-path | false | `""` | Path to a local SchemaStore clone for automatic schema lookup. For air-gapped environments. Implies `schemastore` | | type-map | false | `""` | Comma-separated glob pattern to file type mappings. Format: `pattern:type` | | schema-map | false | `""` | Comma-separated glob pattern to schema file mappings. Format: `pattern:schema_path` | @@ -229,6 +231,18 @@ jobs: ### Automatic schema lookup with SchemaStore +```yml +jobs: + validate-config-files: + runs-on: ubuntu-latest + steps: + - uses: Boeing/validate-configs-action@v2.0.0 + with: + schemastore: "true" +``` + +### Automatic schema lookup with local SchemaStore clone + ```yml jobs: validate-config-files: @@ -238,7 +252,7 @@ jobs: - run: git clone --depth=1 https://github.com/SchemaStore/schemastore.git - uses: Boeing/validate-configs-action@v2.0.0 with: - schemastore: "./schemastore" + schemastore-path: "./schemastore" ``` ### Map file types with glob patterns diff --git a/action.yaml b/action.yaml index 35806ef..cf1aaad 100644 --- a/action.yaml +++ b/action.yaml @@ -49,7 +49,11 @@ inputs: required: false default: "false" schemastore: - description: 'Path to a local SchemaStore clone for automatic schema lookup by filename' + description: 'If set to true, enables automatic schema lookup using the embedded SchemaStore catalog with remote fetching' + required: false + default: "false" + schemastore-path: + description: 'Path to a local SchemaStore clone for automatic schema lookup (implies schemastore). For air-gapped environments' required: false default: "" type-map: @@ -77,6 +81,7 @@ runs: - ${{ inputs.require-schema }} - ${{ inputs.no-schema }} - ${{ inputs.schemastore }} + - ${{ inputs.schemastore-path }} - ${{ inputs.type-map }} - ${{ inputs.schema-map }} diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 2cd5244..25872c9 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -48,9 +48,10 @@ func run() int { globbing := os.Args[9] requireSchema := os.Args[10] noSchema := os.Args[11] - schemaStorePath := os.Args[12] - typeMap := os.Args[13] - schemaMap := os.Args[14] + schemaStoreEnabled := os.Args[12] + schemaStorePath := os.Args[13] + typeMap := os.Args[14] + schemaMap := os.Args[15] // Build finder options var fsOpts []finder.FSFinderOptions @@ -142,6 +143,13 @@ func run() int { return 1 } cliOpts = append(cliOpts, cli.WithSchemaStore(store)) + } else if schemaStoreEnabled == "true" { + store, err := schemastore.OpenEmbedded() + if err != nil { + fmt.Fprintf(os.Stderr, "Error opening embedded schemastore: %v\n", err) + return 1 + } + cliOpts = append(cliOpts, cli.WithSchemaStore(store)) } // Build reporters — user-specified plus a capture reporter for annotations diff --git a/go.mod b/go.mod index 936d077..1c4da80 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/Boeing/validate-configs-action go 1.26.1 require ( - github.com/Boeing/config-file-validator/v2 v2.1.0 + github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf github.com/bmatcuk/doublestar/v4 v4.10.0 ) @@ -26,6 +26,7 @@ require ( github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/owenrumney/go-sarif/v3 v3.3.0 // indirect github.com/pelletier/go-toml/v2 v2.3.0 // indirect + github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd // indirect github.com/toon-format/toon-go v0.0.0-20251108125615-44b4cd22477f // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect diff --git a/go.sum b/go.sum index 7ad44f2..e0c363d 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Boeing/config-file-validator/v2 v2.1.0 h1:3OrOjsx6ySZ/UoLqDFoa8425Ov0E3ItE8oqvZMrKxvA= -github.com/Boeing/config-file-validator/v2 v2.1.0/go.mod h1:ZlcTuAwvot3E55UyN5muDRsob0ThU1Lc3PAtiZhim8Y= +github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf h1:iTwXyiPeF7U4xtbaa8FAq2GQLocGYvA2utP2z3Kj+jI= +github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf/go.mod h1:Abm/TYToZCNMSJeFfzgZ87rIr17gkdvOsFvkqRKlotU= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= @@ -57,6 +57,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd h1:Rf9uhF1+VJ7ZHqxrG8pJ6YacmHvVCmByDmGbAWCc/gA= +github.com/tailscale/hujson v0.0.0-20260302212456-ecc657c15afd/go.mod h1:EbW0wDK/qEUYI0A5bqq0C2kF8JTQwWONmGDBbzsxxHo= github.com/toon-format/toon-go v0.0.0-20251108125615-44b4cd22477f h1:qIMJqAPGPH7S4uVRaHflMfJ/ZenGp7W1tWECmVoJitM= github.com/toon-format/toon-go v0.0.0-20251108125615-44b4cd22477f/go.mod h1:j/BOnpF2ihnz4lELs99h9mwGJBx/zdleOUCnLLRPCsc= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= From a2e6cad6466b56a46ee0c449d6b8c1ae707e5fe4 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 14:43:10 -0500 Subject: [PATCH 2/7] feat: add outputs, job summary, notes, only-changed mode - Outputs: files-validated, files-failed, exit-code written to GITHUB_OUTPUT - Job summary: markdown table with pass/fail counts and failed file details written to GITHUB_STEP_SUMMARY - Notes: validator notes (e.g. JSONC hints) emitted as ::notice annotations - only-changed: new input to validate only files changed in the PR using git diff against the base branch - Update all README examples to @v2 - Add test jobs for outputs and only-changed --- .github/workflows/test.yml | 33 +++++++ Dockerfile | 1 + README.md | 81 ++++++++++++----- action.yaml | 13 +++ cmd/entrypoint/main.go | 178 +++++++++++++++++++++++++++++++++++-- 5 files changed, 278 insertions(+), 28 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 924dad3..3cf1d04 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -217,3 +217,36 @@ jobs: with: search-paths: test/good.json schemastore: "true" + + # Validate only changed files + test-only-changed: + name: "Test: only-changed" + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + fetch-depth: 0 + - uses: ./ + with: + only-changed: "true" + + # Verify outputs are set + test-outputs: + name: "Test: outputs" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: ./ + id: validate + with: + search-paths: test/good.json + - name: Verify outputs + run: | + if [ -z "${{ steps.validate.outputs.files-validated }}" ]; then + echo "Missing files-validated output" + exit 1 + fi + echo "files-validated=${{ steps.validate.outputs.files-validated }}" + echo "files-failed=${{ steps.validate.outputs.files-failed }}" + echo "exit-code=${{ steps.validate.outputs.exit-code }}" diff --git a/Dockerfile b/Dockerfile index b8c2810..29fe7f4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ COPY cmd/ cmd/ RUN CGO_ENABLED=0 go build -ldflags='-w -s' -o /entrypoint cmd/entrypoint/main.go FROM alpine:3.23@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 +RUN apk --no-cache add git COPY --from=builder /entrypoint /entrypoint RUN chmod 0755 /entrypoint WORKDIR /github/workspace diff --git a/README.md b/README.md index 150bf27..098c350 100644 --- a/README.md +++ b/README.md @@ -54,11 +54,16 @@ Validation errors automatically appear as inline annotations on pull request dif | schemastore-path | false | `""` | Path to a local SchemaStore clone for automatic schema lookup. For air-gapped environments. Implies `schemastore` | | type-map | false | `""` | Comma-separated glob pattern to file type mappings. Format: `pattern:type` | | schema-map | false | `""` | Comma-separated glob pattern to schema file mappings. Format: `pattern:schema_path` | +| only-changed | false | `"false"` | If set to `true`, only validate files changed in the current pull request | ## Outputs -N/A +| Output | Description | +| ---------------- | ----------- | +| files-validated | Total number of files scanned | +| files-failed | Number of files that failed validation | +| exit-code | Exit code from validation (0=success, 1=validation errors, 2=runtime error) | ## Example usage @@ -69,7 +74,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 ``` ### Custom search path @@ -79,7 +84,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: search-paths: ./project/configs ``` @@ -91,7 +96,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: search-paths: ./project/configs ./project/devops ``` @@ -103,7 +108,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: exclude-dirs: "tests,vendor" ``` @@ -115,7 +120,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: exclude-file-types: "json,xml" ``` @@ -127,7 +132,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: file-types: "json,yaml" ``` @@ -139,7 +144,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: depth: 0 ``` @@ -151,7 +156,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: reporter: "json" ``` @@ -163,7 +168,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: reporter: "json:output.json,junit:results.xml" ``` @@ -175,7 +180,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: group-by: "pass-fail" ``` @@ -187,7 +192,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: quiet: "true" ``` @@ -199,7 +204,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: globbing: "true" search-paths: "**/*.json" @@ -212,7 +217,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: require-schema: "true" ``` @@ -224,7 +229,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: no-schema: "true" ``` @@ -236,7 +241,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: schemastore: "true" ``` @@ -250,7 +255,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: git clone --depth=1 https://github.com/SchemaStore/schemastore.git - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: schemastore-path: "./schemastore" ``` @@ -262,7 +267,7 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: type-map: "**/inventory:ini,**/*.cfg:json" ``` @@ -274,7 +279,43 @@ jobs: validate-config-files: runs-on: ubuntu-latest steps: - - uses: Boeing/validate-configs-action@v2.0.0 + - uses: Boeing/validate-configs-action@v2 with: schema-map: "**/package.json:schemas/package.schema.json,**/config.xml:schemas/config.xsd" -``` \ No newline at end of file +``` + + +### Validate only changed files in a PR + +```yml +jobs: + validate-config-files: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: Boeing/validate-configs-action@v2 + with: + only-changed: "true" +``` + +### Using outputs + +```yml +jobs: + validate-config-files: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Boeing/validate-configs-action@v2 + id: validate + continue-on-error: true + - run: | + echo "Files validated: ${{ steps.validate.outputs.files-validated }}" + echo "Files failed: ${{ steps.validate.outputs.files-failed }}" +``` + +## PR inline annotations + +Validation errors automatically appear as inline annotations on pull request diffs. When a config file fails validation, the action emits GitHub Actions workflow commands that annotate the exact file and line where the error occurred. For config types that do not support line numbers in the error output, an annotation will be added at line 1. diff --git a/action.yaml b/action.yaml index cf1aaad..6a7fdc5 100644 --- a/action.yaml +++ b/action.yaml @@ -64,6 +64,18 @@ inputs: description: 'Comma separated list of glob pattern to schema file mappings. Format: pattern:schema_path. Example: "**/package.json:schemas/pkg.json,**/config.xml:schemas/config.xsd"' required: false default: "" + only-changed: + description: 'If set to true, only validate files changed in the current pull request' + required: false + default: "false" + +outputs: + files-validated: + description: 'Total number of files scanned' + files-failed: + description: 'Number of files that failed validation' + exit-code: + description: 'Exit code from validation (0=success, 1=validation errors, 2=runtime error)' runs: using: 'docker' @@ -84,6 +96,7 @@ runs: - ${{ inputs.schemastore-path }} - ${{ inputs.type-map }} - ${{ inputs.schema-map }} + - ${{ inputs.only-changed }} branding: color: 'blue' diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 25872c9..02f6910 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -3,6 +3,8 @@ package main import ( "fmt" "os" + "os/exec" + "path/filepath" "regexp" "strconv" "strings" @@ -22,7 +24,6 @@ var ( reColNum = regexp.MustCompile(`column (\d+)`) ) -// captureReporter captures reports for annotation processing type captureReporter struct { reports []reporter.Report } @@ -52,6 +53,7 @@ func run() int { schemaStorePath := os.Args[13] typeMap := os.Args[14] schemaMap := os.Args[15] + onlyChanged := os.Args[16] // Build finder options var fsOpts []finder.FSFinderOptions @@ -64,7 +66,7 @@ func run() int { expanded, err := expandGlobs(paths) if err != nil { fmt.Fprintf(os.Stderr, "Error expanding globs: %v\n", err) - return 1 + return 2 } paths = expanded } @@ -105,7 +107,7 @@ func run() int { overrides, err := parseTypeMap(typeMap) if err != nil { fmt.Fprintf(os.Stderr, "Error parsing type-map: %v\n", err) - return 1 + return 2 } fsOpts = append(fsOpts, finder.WithTypeOverrides(overrides)) } @@ -113,7 +115,19 @@ func run() int { // Build CLI options var cliOpts []cli.Option - fileFinder := finder.FileSystemFinderInit(fsOpts...) + var fileFinder finder.FileFinder + fileFinder = finder.FileSystemFinderInit(fsOpts...) + + // Filter to only changed files if requested + if onlyChanged == "true" { + changed, err := getChangedFiles() + if err != nil { + fmt.Fprintf(os.Stderr, "Warning: could not determine changed files: %v\n", err) + } else if len(changed) > 0 { + fileFinder = &changedFilesFilter{inner: fileFinder, changed: changed} + } + } + cliOpts = append(cliOpts, cli.WithFinder(fileFinder)) if quiet == "true" { @@ -132,7 +146,7 @@ func run() int { sm, err := parseSchemaMap(schemaMap) if err != nil { fmt.Fprintf(os.Stderr, "Error parsing schema-map: %v\n", err) - return 1 + return 2 } cliOpts = append(cliOpts, cli.WithSchemaMap(sm)) } @@ -140,19 +154,18 @@ func run() int { store, err := schemastore.Open(schemaStorePath) if err != nil { fmt.Fprintf(os.Stderr, "Error opening schemastore: %v\n", err) - return 1 + return 2 } cliOpts = append(cliOpts, cli.WithSchemaStore(store)) } else if schemaStoreEnabled == "true" { store, err := schemastore.OpenEmbedded() if err != nil { fmt.Fprintf(os.Stderr, "Error opening embedded schemastore: %v\n", err) - return 1 + return 2 } cliOpts = append(cliOpts, cli.WithSchemaStore(store)) } - // Build reporters — user-specified plus a capture reporter for annotations capture := &captureReporter{} reporters := buildReporters(reporterArg) reporters = append(reporters, capture) @@ -165,10 +178,159 @@ func run() int { } emitAnnotations(capture.reports) + emitNotes(capture.reports) + writeOutputs(capture.reports, exitStatus) + writeJobSummary(capture.reports) return exitStatus } +// changedFilesFilter wraps a FileFinder and filters results to only changed files. +type changedFilesFilter struct { + inner finder.FileFinder + changed map[string]struct{} +} + +func (f *changedFilesFilter) Find() ([]finder.FileMetadata, error) { + all, err := f.inner.Find() + if err != nil { + return nil, err + } + var filtered []finder.FileMetadata + for _, file := range all { + rel := file.Path + if abs, err := filepath.Abs(file.Path); err == nil { + if wd, err := os.Getwd(); err == nil { + if r, err := filepath.Rel(wd, abs); err == nil { + rel = r + } + } + } + if _, ok := f.changed[rel]; ok { + filtered = append(filtered, file) + } + } + return filtered, nil +} + +func getChangedFiles() (map[string]struct{}, error) { + baseBranch := os.Getenv("GITHUB_BASE_REF") + if baseBranch == "" { + return nil, fmt.Errorf("GITHUB_BASE_REF not set (not a pull request?)") + } + + // Fetch the base branch for comparison + fetch := exec.Command("git", "fetch", "origin", baseBranch, "--depth=1") + fetch.Stderr = os.Stderr + if err := fetch.Run(); err != nil { + return nil, fmt.Errorf("git fetch: %w", err) + } + + cmd := exec.Command("git", "diff", "--name-only", "origin/"+baseBranch+"...HEAD") + out, err := cmd.Output() + if err != nil { + return nil, fmt.Errorf("git diff: %w", err) + } + + changed := make(map[string]struct{}) + for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") { + if line != "" { + changed[line] = struct{}{} + } + } + return changed, nil +} + +func writeOutputs(reports []reporter.Report, exitCode int) { + outputFile := os.Getenv("GITHUB_OUTPUT") + if outputFile == "" { + return + } + + total := len(reports) + failed := 0 + for _, r := range reports { + if !r.IsValid { + failed++ + } + } + + f, err := os.OpenFile(outputFile, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return + } + defer f.Close() + + fmt.Fprintf(f, "files-validated=%d\n", total) + fmt.Fprintf(f, "files-failed=%d\n", failed) + fmt.Fprintf(f, "exit-code=%d\n", exitCode) +} + +func writeJobSummary(reports []reporter.Report) { + summaryFile := os.Getenv("GITHUB_STEP_SUMMARY") + if summaryFile == "" { + return + } + + total := len(reports) + passed := 0 + failed := 0 + var failedReports []reporter.Report + for _, r := range reports { + if r.IsValid { + passed++ + } else { + failed++ + failedReports = append(failedReports, r) + } + } + + f, err := os.OpenFile(summaryFile, os.O_APPEND|os.O_WRONLY, 0644) + if err != nil { + return + } + defer f.Close() + + if failed == 0 { + fmt.Fprintf(f, "### ✅ Config Validation Passed\n\n") + fmt.Fprintf(f, "All **%d** configuration files are valid.\n", total) + return + } + + fmt.Fprintf(f, "### ❌ Config Validation Failed\n\n") + fmt.Fprintf(f, "| | Count |\n|---|---|\n") + fmt.Fprintf(f, "| ✅ Passed | %d |\n", passed) + fmt.Fprintf(f, "| ❌ Failed | %d |\n", failed) + fmt.Fprintf(f, "| **Total** | **%d** |\n\n", total) + + fmt.Fprintf(f, "#### Failed Files\n\n") + fmt.Fprintf(f, "| File | Errors |\n|---|---|\n") + for _, r := range failedReports { + path := r.FilePath + if strings.HasPrefix(path, "/github/workspace/") { + path = path[len("/github/workspace/"):] + } + errors := strings.Join(r.ValidationErrors, "
") + fmt.Fprintf(f, "| `%s` | %s |\n", path, errors) + } +} + +func emitNotes(reports []reporter.Report) { + const workspacePrefix = "/github/workspace/" + for _, r := range reports { + if len(r.Notes) == 0 { + continue + } + path := r.FilePath + if strings.HasPrefix(path, workspacePrefix) { + path = path[len(workspacePrefix):] + } + for _, note := range r.Notes { + fmt.Printf("::notice file=%s,title=Note::%s\n", path, escapeAnnotation(note)) + } + } +} + func buildReporters(arg string) []reporter.Reporter { if arg == "" { return []reporter.Reporter{reporter.NewStdoutReporter("")} From 295622b0d1f6de6074b851b608bce56c518c0585 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 14:46:51 -0500 Subject: [PATCH 3/7] fix: add git safe.directory for Docker workspace ownership --- cmd/entrypoint/main.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index 02f6910..f488bee 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -219,7 +219,10 @@ func getChangedFiles() (map[string]struct{}, error) { return nil, fmt.Errorf("GITHUB_BASE_REF not set (not a pull request?)") } - // Fetch the base branch for comparison + // Docker containers run as root but the workspace is owned by the runner user + safe := exec.Command("git", "config", "--global", "--add", "safe.directory", "/github/workspace") + safe.Run() + fetch := exec.Command("git", "fetch", "origin", baseBranch, "--depth=1") fetch.Stderr = os.Stderr if err := fetch.Run(); err != nil { From dce2f0739a6e4a62fc2d76facee8445689aad621 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 14:54:31 -0500 Subject: [PATCH 4/7] docs: rewrite README in popular action style with quick start, collapsible examples, and file type table --- README.md | 451 +++++++++++++++++++++++++----------------------------- 1 file changed, 212 insertions(+), 239 deletions(-) diff --git a/README.md b/README.md index 098c350..4121df4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Validate Configs Github Action +> [GitHub Action](https://github.com/features/actions) for [config-file-validator](https://github.com/Boeing/config-file-validator) +

OpenSSF Scorecard @@ -9,313 +11,284 @@

-:octocat: Github Action to validate your config files using the [config-file-validator](https://github.com/Boeing/config-file-validator). The config-file-validator will recursively scan the provided search path for the following configuration file types: +Validate configuration files in your repository and get inline PR annotations for errors. Supports syntax validation and JSON Schema validation for 16 file formats. + +## Supported File Types + +| Format | Syntax | Schema | +|--------|:------:|:------:| +| Apple PList XML | ✅ | | +| CSV | ✅ | | +| EDITORCONFIG | ✅ | | +| ENV | ✅ | | +| HCL | ✅ | | +| HOCON | ✅ | | +| INI | ✅ | | +| JSON | ✅ | ✅ | +| JSONC | ✅ | ✅ | +| Properties | ✅ | | +| SARIF | ✅ | ✅ | +| TOML | ✅ | ✅ | +| TOON | ✅ | ✅ | +| XML | ✅ | ✅ | +| YAML | ✅ | ✅ | + +## Quick Start + +```yaml +- uses: Boeing/validate-configs-action@v2 +``` -* Apple PList XML -* CSV -* EDITORCONFIG -* ENV -* HCL -* HOCON -* INI -* JSONC -* JSON -* Properties -* SARIF -* TOML -* TOON -* XML -* YAML +That's it. By default the action scans the entire repository for configuration files, validates them, and fails the workflow if any are invalid. Errors appear as inline annotations on the PR diff. -Each file will get validated for the correct syntax and the results collected into a report showing the path of the file and if it is invalid or valid. If the file is invalid an error will be displayed along with the line number and column where the error ocurred. By default the `$GITHUB_WORKDIR` is scanned. +## Usage -Files that declare a schema (JSON Schema for JSON/YAML/TOML/TOON, XSD for XML) are automatically validated against it. +### Basic -## PR inline annotations +```yaml +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: Boeing/validate-configs-action@v2 +``` -Validation errors automatically appear as inline annotations on pull request diffs. When a config file fails validation, the action emits GitHub Actions workflow commands that annotate the exact file and line where the error occurred. For config types that do not support line numbers in the error output, an annotation will be added at line 1. +### Validate specific paths -## Inputs +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + search-paths: ./configs ./deploy +``` -| Input | Required | Default Value | Description | -| ------------------ | -------- | ------------- | ----------- | -| search-paths | false | `"."` | The path that will be recursively searched for configuration files | -| exclude-dirs | false | `""` | A comma-separated list of subdirectories to exclude from validation | -| exclude-file-types | false | `""` | A comma-separated list of file extensions to exclude | -| file-types | false | `""` | A comma-separated list of file types to validate. Cannot be used with exclude-file-types | -| depth | false | `""` | An integer value limiting the depth of recursion for the search paths. Setting depth to 0 disables recursion | -| reporter | false | `"standard"` | Comma-separated report formats with optional output paths. Format: `type:path`. Options are `standard`, `json`, `junit`, and `sarif` | -| group-by | false | `""` | Group output by `filetype`, `directory`, or `pass-fail` | -| quiet | false | `"false"` | If set to `true`, suppresses all output to stdout | -| globbing | false | `"false"` | If set to `true`, enables glob pattern matching for search paths | -| require-schema | false | `"false"` | If set to `true`, fail validation for files that support schema validation but do not declare a schema | -| no-schema | false | `"false"` | If set to `true`, disable all schema validation (syntax-only). Cannot be used with `require-schema`, `schema-map`, or `schemastore` | -| schemastore | false | `"false"` | If set to `true`, enables automatic schema lookup using the embedded SchemaStore catalog with remote fetching | -| schemastore-path | false | `""` | Path to a local SchemaStore clone for automatic schema lookup. For air-gapped environments. Implies `schemastore` | -| type-map | false | `""` | Comma-separated glob pattern to file type mappings. Format: `pattern:type` | -| schema-map | false | `""` | Comma-separated glob pattern to schema file mappings. Format: `pattern:schema_path` | -| only-changed | false | `"false"` | If set to `true`, only validate files changed in the current pull request | +### Validate only changed files in a PR +```yaml +- uses: actions/checkout@v4 + with: + fetch-depth: 0 +- uses: Boeing/validate-configs-action@v2 + with: + only-changed: "true" +``` -## Outputs +### Schema validation with SchemaStore -| Output | Description | -| ---------------- | ----------- | -| files-validated | Total number of files scanned | -| files-failed | Number of files that failed validation | -| exit-code | Exit code from validation (0=success, 1=validation errors, 2=runtime error) | +Automatically validate files against [SchemaStore](https://www.schemastore.org/) schemas (e.g. `package.json`, `tsconfig.json`, GitHub Actions workflows): -## Example usage +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + schemastore: "true" +``` -### Standard Run +### Using outputs -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 +```yaml +- uses: Boeing/validate-configs-action@v2 + id: validate + continue-on-error: true +- run: | + echo "Files validated: ${{ steps.validate.outputs.files-validated }}" + echo "Files failed: ${{ steps.validate.outputs.files-failed }}" ``` -### Custom search path +## PR Inline Annotations -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - search-paths: ./project/configs -``` +Validation errors automatically appear as inline annotations on pull request diffs. When a config file fails validation, the action emits GitHub Actions workflow commands that annotate the exact file and line where the error occurred. For config types that do not support line numbers in the error output, an annotation will be added at line 1. -### Multiple search paths +## Inputs -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - search-paths: ./project/configs ./project/devops -``` +| Input | Default | Description | +|-------|---------|-------------| +| `search-paths` | `"."` | Space-separated list of directories or files to scan | +| `exclude-dirs` | `""` | Comma-separated list of subdirectories to exclude | +| `exclude-file-types` | `""` | Comma-separated list of file extensions to exclude | +| `file-types` | `""` | Comma-separated list of file types to validate. Cannot be used with `exclude-file-types` | +| `depth` | `""` | Recursion depth limit. `0` disables recursion | +| `reporter` | `"standard"` | Report format(s). Options: `standard`, `json`, `junit`, `sarif`. Supports `type:path` for file output | +| `group-by` | `""` | Group output by `filetype`, `directory`, or `pass-fail` | +| `quiet` | `"false"` | Suppress all output to stdout | +| `globbing` | `"false"` | Enable glob pattern matching for search paths | +| `require-schema` | `"false"` | Fail files that support schema validation but don't declare a schema | +| `no-schema` | `"false"` | Disable all schema validation (syntax-only) | +| `schemastore` | `"false"` | Enable automatic schema lookup using the embedded [SchemaStore](https://www.schemastore.org/) catalog | +| `schemastore-path` | `""` | Path to a local SchemaStore clone. For air-gapped environments. Implies `schemastore` | +| `type-map` | `""` | Map glob patterns to file types. Format: `pattern:type` | +| `schema-map` | `""` | Map glob patterns to schema files. Format: `pattern:schema_path` | +| `only-changed` | `"false"` | Only validate files changed in the current pull request | -### Exclude a directory +## Outputs -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - exclude-dirs: "tests,vendor" -``` +| Output | Description | +|--------|-------------| +| `files-validated` | Total number of files scanned | +| `files-failed` | Number of files that failed validation | +| `exit-code` | Exit code from validation (0=success, 1=validation errors, 2=runtime error) | -### Exclude file type +## Examples -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - exclude-file-types: "json,xml" +
+Filtering + +#### Exclude directories + +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + exclude-dirs: "tests,vendor,node_modules" ``` -### Include only specific file types +#### Exclude file types -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - file-types: "json,yaml" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + exclude-file-types: "json,xml" ``` -### Disable recursive scanning +#### Include only specific file types -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - depth: 0 +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + file-types: "json,yaml" ``` -### JSON Report +#### Disable recursive scanning -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - reporter: "json" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + depth: 0 ``` -### Multiple reporters with output files +#### Glob pattern matching -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - reporter: "json:output.json,junit:results.xml" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + globbing: "true" + search-paths: "**/*.json" ``` -### Group By Pass/Fail +
-```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - group-by: "pass-fail" +
+Reporters + +#### JSON report + +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + reporter: "json" ``` -### Quiet mode +#### Multiple reporters with file output -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - quiet: "true" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + reporter: "json:output.json,junit:results.xml,sarif:results.sarif" ``` -### Glob pattern matching +#### Group by pass/fail -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - globbing: "true" - search-paths: "**/*.json" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + group-by: "pass-fail" ``` -### Require schema declarations +#### Quiet mode -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - require-schema: "true" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + quiet: "true" ``` -### Disable schema validation +
-```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - no-schema: "true" +
+Schema Validation + +#### Automatic schema lookup with SchemaStore + +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + schemastore: "true" ``` -### Automatic schema lookup with SchemaStore +#### Local SchemaStore clone (air-gapped) -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - schemastore: "true" +```yaml +- run: git clone --depth=1 https://github.com/SchemaStore/schemastore.git +- uses: Boeing/validate-configs-action@v2 + with: + schemastore-path: "./schemastore" ``` -### Automatic schema lookup with local SchemaStore clone +#### Require schema declarations -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - run: git clone --depth=1 https://github.com/SchemaStore/schemastore.git - - uses: Boeing/validate-configs-action@v2 - with: - schemastore-path: "./schemastore" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + require-schema: "true" ``` -### Map file types with glob patterns +#### Disable schema validation -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - type-map: "**/inventory:ini,**/*.cfg:json" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + no-schema: "true" ``` -### Map schemas to files +#### Map schemas to files -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: Boeing/validate-configs-action@v2 - with: - schema-map: "**/package.json:schemas/package.schema.json,**/config.xml:schemas/config.xsd" +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + schema-map: "**/package.json:schemas/package.schema.json,**/config.xml:schemas/config.xsd" ``` +
-### Validate only changed files in a PR +
+Advanced -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - uses: Boeing/validate-configs-action@v2 - with: - only-changed: "true" +#### Map file types with glob patterns + +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + type-map: "**/inventory:ini,**/*.cfg:json" ``` -### Using outputs +#### Validate only changed files in a PR -```yml -jobs: - validate-config-files: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: Boeing/validate-configs-action@v2 - id: validate - continue-on-error: true - - run: | - echo "Files validated: ${{ steps.validate.outputs.files-validated }}" - echo "Files failed: ${{ steps.validate.outputs.files-failed }}" +```yaml +- uses: actions/checkout@v4 + with: + fetch-depth: 0 +- uses: Boeing/validate-configs-action@v2 + with: + only-changed: "true" ``` -## PR inline annotations +#### Using outputs -Validation errors automatically appear as inline annotations on pull request diffs. When a config file fails validation, the action emits GitHub Actions workflow commands that annotate the exact file and line where the error occurred. For config types that do not support line numbers in the error output, an annotation will be added at line 1. +```yaml +- uses: Boeing/validate-configs-action@v2 + id: validate + continue-on-error: true +- run: | + echo "Files validated: ${{ steps.validate.outputs.files-validated }}" + echo "Files failed: ${{ steps.validate.outputs.files-failed }}" +``` + +
From 9eedc4ffba7e704918163df7033370a5bdd824f2 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 15:07:59 -0500 Subject: [PATCH 5/7] docs: rewrite README with cleaner tone and structure --- README.md | 50 +++++++------------------------------------------- 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 4121df4..ff2b6bb 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # Validate Configs Github Action -> [GitHub Action](https://github.com/features/actions) for [config-file-validator](https://github.com/Boeing/config-file-validator) -

OpenSSF Scorecard @@ -11,27 +9,9 @@

-Validate configuration files in your repository and get inline PR annotations for errors. Supports syntax validation and JSON Schema validation for 16 file formats. - -## Supported File Types - -| Format | Syntax | Schema | -|--------|:------:|:------:| -| Apple PList XML | ✅ | | -| CSV | ✅ | | -| EDITORCONFIG | ✅ | | -| ENV | ✅ | | -| HCL | ✅ | | -| HOCON | ✅ | | -| INI | ✅ | | -| JSON | ✅ | ✅ | -| JSONC | ✅ | ✅ | -| Properties | ✅ | | -| SARIF | ✅ | ✅ | -| TOML | ✅ | ✅ | -| TOON | ✅ | ✅ | -| XML | ✅ | ✅ | -| YAML | ✅ | ✅ | +Validate every config file in your repo — JSON, YAML, TOML, XML, INI, HCL, and [more](#inputs). If something's wrong, you'll see the error right on the PR diff, exactly where it broke. + +Files with a schema declaration (JSON Schema, XSD) get validated against it automatically. You can optionally add [SchemaStore](#schemastore) to get schema validation for hundreds of common files like `package.json`, `tsconfig.json`, and GitHub Actions workflows with no additional configuration. ## Quick Start @@ -39,12 +19,8 @@ Validate configuration files in your repository and get inline PR annotations fo - uses: Boeing/validate-configs-action@v2 ``` -That's it. By default the action scans the entire repository for configuration files, validates them, and fails the workflow if any are invalid. Errors appear as inline annotations on the PR diff. - ## Usage -### Basic - ```yaml jobs: validate: @@ -54,15 +30,7 @@ jobs: - uses: Boeing/validate-configs-action@v2 ``` -### Validate specific paths - -```yaml -- uses: Boeing/validate-configs-action@v2 - with: - search-paths: ./configs ./deploy -``` - -### Validate only changed files in a PR +### Only changed files ```yaml - uses: actions/checkout@v4 @@ -73,9 +41,9 @@ jobs: only-changed: "true" ``` -### Schema validation with SchemaStore +### SchemaStore -Automatically validate files against [SchemaStore](https://www.schemastore.org/) schemas (e.g. `package.json`, `tsconfig.json`, GitHub Actions workflows): +Validate files against [SchemaStore](https://www.schemastore.org/) schemas (`package.json`, `tsconfig.json`, GitHub Actions workflows, etc.) with no configuration: ```yaml - uses: Boeing/validate-configs-action@v2 @@ -83,7 +51,7 @@ Automatically validate files against [SchemaStore](https://www.schemastore.org/) schemastore: "true" ``` -### Using outputs +### Outputs ```yaml - uses: Boeing/validate-configs-action@v2 @@ -94,10 +62,6 @@ Automatically validate files against [SchemaStore](https://www.schemastore.org/) echo "Files failed: ${{ steps.validate.outputs.files-failed }}" ``` -## PR Inline Annotations - -Validation errors automatically appear as inline annotations on pull request diffs. When a config file fails validation, the action emits GitHub Actions workflow commands that annotate the exact file and line where the error occurred. For config types that do not support line numbers in the error output, an annotation will be added at line 1. - ## Inputs | Input | Default | Description | From 76567e1e7389230fd8a3127ed84d6fccaae727c6 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Fri, 10 Apr 2026 15:28:43 -0500 Subject: [PATCH 6/7] docs: improve README for advanced users - flag conflicts, valid types, combined example --- README.md | 45 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ff2b6bb..3aa1fab 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ jobs: ### Only changed files +For large repos, you probably don't want to validate everything on every PR. This only checks files that were actually changed: + ```yaml - uses: actions/checkout@v4 with: @@ -41,9 +43,21 @@ jobs: only-changed: "true" ``` +`fetch-depth: 0` is required so git has the history to determine which files changed. + +### Exclude directories + +Skip directories you don't care about — vendored deps, test fixtures, generated files: + +```yaml +- uses: Boeing/validate-configs-action@v2 + with: + exclude-dirs: "vendor,testdata,node_modules" +``` + ### SchemaStore -Validate files against [SchemaStore](https://www.schemastore.org/) schemas (`package.json`, `tsconfig.json`, GitHub Actions workflows, etc.) with no configuration: +[SchemaStore](https://www.schemastore.org/) is a community catalog of JSON Schemas for common config files. Turn it on and files like `package.json`, `tsconfig.json`, and GitHub Actions workflows get validated against their schema automatically — no `$schema` declarations needed in your files: ```yaml - uses: Boeing/validate-configs-action@v2 @@ -71,16 +85,16 @@ Validate files against [SchemaStore](https://www.schemastore.org/) schemas (`pac | `exclude-file-types` | `""` | Comma-separated list of file extensions to exclude | | `file-types` | `""` | Comma-separated list of file types to validate. Cannot be used with `exclude-file-types` | | `depth` | `""` | Recursion depth limit. `0` disables recursion | -| `reporter` | `"standard"` | Report format(s). Options: `standard`, `json`, `junit`, `sarif`. Supports `type:path` for file output | +| `reporter` | `"standard"` | Report format(s). Options: `standard`, `json`, `junit`, `sarif`. Supports `type:path` for file output. Multiple reporters can be comma-separated. If you only specify file reporters, add `standard` to keep console output | | `group-by` | `""` | Group output by `filetype`, `directory`, or `pass-fail` | | `quiet` | `"false"` | Suppress all output to stdout | -| `globbing` | `"false"` | Enable glob pattern matching for search paths | -| `require-schema` | `"false"` | Fail files that support schema validation but don't declare a schema | -| `no-schema` | `"false"` | Disable all schema validation (syntax-only) | +| `globbing` | `"false"` | Enable glob pattern matching for search paths. Cannot be used with `exclude-dirs`, `exclude-file-types`, or `file-types` | +| `require-schema` | `"false"` | Fail files that support schema validation but don't declare a schema. Cannot be used with `no-schema` | +| `no-schema` | `"false"` | Disable all schema validation (syntax-only). Cannot be used with `require-schema`, `schema-map`, or `schemastore` | | `schemastore` | `"false"` | Enable automatic schema lookup using the embedded [SchemaStore](https://www.schemastore.org/) catalog | | `schemastore-path` | `""` | Path to a local SchemaStore clone. For air-gapped environments. Implies `schemastore` | -| `type-map` | `""` | Map glob patterns to file types. Format: `pattern:type` | -| `schema-map` | `""` | Map glob patterns to schema files. Format: `pattern:schema_path` | +| `type-map` | `""` | Map glob patterns to file types. Format: `pattern:type`. Valid types: `csv`, `editorconfig`, `env`, `hcl`, `hocon`, `ini`, `json`, `jsonc`, `plist`, `properties`, `sarif`, `toml`, `toon`, `xml`, `yaml` | +| `schema-map` | `""` | Map glob patterns to schema files. Format: `pattern:schema_path`. Use JSON Schema (`.json`) for JSON/JSONC/YAML/TOML/TOON, XSD (`.xsd`) for XML. Paths are relative to the repo root | | `only-changed` | `"false"` | Only validate files changed in the current pull request | ## Outputs @@ -225,6 +239,23 @@ Validate files against [SchemaStore](https://www.schemastore.org/) schemas (`pac
Advanced +#### Combined options + +```yaml +- uses: actions/checkout@v4 + with: + fetch-depth: 0 +- uses: Boeing/validate-configs-action@v2 + id: validate + with: + only-changed: "true" + exclude-dirs: "vendor,generated,testdata" + schema-map: "**/app-config.json:schemas/app.schema.json,**/deploy.xml:schemas/deploy.xsd" + type-map: "**/inventory:ini,**/.env.*:env" + reporter: "standard,junit:results.xml" + schemastore: "true" +``` + #### Map file types with glob patterns ```yaml From b501b611ef572b477de4195570e544caee8f9183 Mon Sep 17 00:00:00 2001 From: Clayton Kehoe Date: Mon, 27 Apr 2026 14:58:22 -0500 Subject: [PATCH 7/7] feat: update to config-file-validator v2.2.0 - Update dependency to config-file-validator v2.2.0 - Use per-error ErrorLines/ErrorColumns for annotation positioning - Add gitignore input to skip .gitignore-matched files - Add justfile test fixture for new file type support --- .github/workflows/test.yml | 2 +- README.md | 1 + action.yaml | 5 ++++ cmd/entrypoint/main.go | 23 ++++++++++++++++--- go.mod | 18 +++++++++++---- go.sum | 47 +++++++++++++++++++++++++++++--------- test/justfile | 2 ++ 7 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 test/justfile diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3cf1d04..be3d36b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - uses: ./ with: - search-paths: test/good.json test/good.yaml test/good.toml test/good.xml test/good.ini + search-paths: test/good.json test/good.yaml test/good.toml test/good.xml test/good.ini test/justfile # Validate that bad files cause a non-zero exit test-failing-files: diff --git a/README.md b/README.md index 3aa1fab..d2997a1 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Skip directories you don't care about — vendored deps, test fixtures, generate | `type-map` | `""` | Map glob patterns to file types. Format: `pattern:type`. Valid types: `csv`, `editorconfig`, `env`, `hcl`, `hocon`, `ini`, `json`, `jsonc`, `plist`, `properties`, `sarif`, `toml`, `toon`, `xml`, `yaml` | | `schema-map` | `""` | Map glob patterns to schema files. Format: `pattern:schema_path`. Use JSON Schema (`.json`) for JSON/JSONC/YAML/TOML/TOON, XSD (`.xsd`) for XML. Paths are relative to the repo root | | `only-changed` | `"false"` | Only validate files changed in the current pull request | +| `gitignore` | `"false"` | Skip files and directories matched by `.gitignore` patterns | ## Outputs diff --git a/action.yaml b/action.yaml index 6a7fdc5..914d18c 100644 --- a/action.yaml +++ b/action.yaml @@ -64,6 +64,10 @@ inputs: description: 'Comma separated list of glob pattern to schema file mappings. Format: pattern:schema_path. Example: "**/package.json:schemas/pkg.json,**/config.xml:schemas/config.xsd"' required: false default: "" + gitignore: + description: 'If set to true, skip files and directories matched by .gitignore patterns' + required: false + default: "false" only-changed: description: 'If set to true, only validate files changed in the current pull request' required: false @@ -96,6 +100,7 @@ runs: - ${{ inputs.schemastore-path }} - ${{ inputs.type-map }} - ${{ inputs.schema-map }} + - ${{ inputs.gitignore }} - ${{ inputs.only-changed }} branding: diff --git a/cmd/entrypoint/main.go b/cmd/entrypoint/main.go index f488bee..f4d34e5 100644 --- a/cmd/entrypoint/main.go +++ b/cmd/entrypoint/main.go @@ -53,7 +53,8 @@ func run() int { schemaStorePath := os.Args[13] typeMap := os.Args[14] schemaMap := os.Args[15] - onlyChanged := os.Args[16] + gitignoreEnabled := os.Args[16] + onlyChanged := os.Args[17] // Build finder options var fsOpts []finder.FSFinderOptions @@ -112,6 +113,10 @@ func run() int { fsOpts = append(fsOpts, finder.WithTypeOverrides(overrides)) } + if gitignoreEnabled == "true" { + fsOpts = append(fsOpts, finder.WithGitignore(true)) + } + // Build CLI options var cliOpts []cli.Option @@ -451,7 +456,7 @@ func emitAnnotations(reports []reporter.Report) { path = path[len(workspacePrefix):] } - for _, errMsg := range r.ValidationErrors { + for i, errMsg := range r.ValidationErrors { title := "Validation Error" msg := errMsg if strings.HasPrefix(errMsg, "schema: ") { @@ -462,7 +467,19 @@ func emitAnnotations(reports []reporter.Report) { msg = errMsg[8:] } - line, col := parseLine(msg) + // Use per-error positions from report when available, + // fall back to regex parsing for compatibility. + var line, col int + if i < len(r.ErrorLines) && r.ErrorLines[i] > 0 { + line = r.ErrorLines[i] + } + if i < len(r.ErrorColumns) && r.ErrorColumns[i] > 0 { + col = r.ErrorColumns[i] + } + if line == 0 { + line, col = parseLine(msg) + } + key := fmt.Sprintf("%s|%d|%d|%s", path, line, col, title) if a, ok := groups[key]; ok { a.msgs = append(a.msgs, msg) diff --git a/go.mod b/go.mod index 1c4da80..a682577 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,27 @@ module github.com/Boeing/validate-configs-action go 1.26.1 require ( - github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf + github.com/Boeing/config-file-validator/v2 v2.2.0 github.com/bmatcuk/doublestar/v4 v4.10.0 ) require ( + github.com/Boeing/go-just v0.0.0 // indirect github.com/agext/levenshtein v1.2.1 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/editorconfig/editorconfig-core-go/v2 v2.6.4 // indirect github.com/fatih/color v1.19.0 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.8.0 // indirect + github.com/go-git/go-git/v5 v5.18.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gurkankaymak/hocon v1.2.23 // indirect github.com/hashicorp/go-envparse v0.1.0 // indirect github.com/hashicorp/hcl/v2 v2.23.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/lestrrat-go/helium v0.0.1 // indirect github.com/lestrrat-go/pdebug v0.0.0-20210111095411-35b07dbf089b // indirect github.com/magiconair/properties v1.8.10 // indirect @@ -32,12 +38,14 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/zclconf/go-cty v1.13.0 // indirect - golang.org/x/mod v0.33.0 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.52.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.35.0 // indirect - golang.org/x/tools v0.42.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.43.0 // indirect gopkg.in/ini.v1 v1.67.1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.1 // indirect ) diff --git a/go.sum b/go.sum index e0c363d..81454a1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf h1:iTwXyiPeF7U4xtbaa8FAq2GQLocGYvA2utP2z3Kj+jI= -github.com/Boeing/config-file-validator/v2 v2.1.1-0.20260410183803-3b3739c9a3cf/go.mod h1:Abm/TYToZCNMSJeFfzgZ87rIr17gkdvOsFvkqRKlotU= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= @@ -8,6 +6,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs= github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -15,6 +15,12 @@ github.com/editorconfig/editorconfig-core-go/v2 v2.6.4 h1:CHwUbBVVyKWRX9kt5A/Otw github.com/editorconfig/editorconfig-core-go/v2 v2.6.4/go.mod h1:JWRVKHdVW+dkv6F8p+xGCa6a+TyMrqsFbFkSs/aQkrQ= github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= +github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= +github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM= +github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -27,7 +33,13 @@ github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdm github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc= github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lestrrat-go/helium v0.0.1 h1:jNr9x4TOWH9JQpFPtJzAyWiuFuimILNuySL/RJwEf8Y= github.com/lestrrat-go/helium v0.0.1/go.mod h1:IWo9QUgTVpC8nSbOr+NlOF+t6CXnViTvfR0p/k9IhQQ= github.com/lestrrat-go/pdebug v0.0.0-20210111095411-35b07dbf089b h1:2v0K4PeWeccG1wpznCE71PqO5scFzSj3jZGkQaVYEWg= @@ -40,12 +52,18 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/owenrumney/go-sarif/v3 v3.3.0 h1:p5oSxEV0uPWBRpAspTmwWr4t1YZyKUpdoFzSB7WE90A= github.com/owenrumney/go-sarif/v3 v3.3.0/go.mod h1:72MaugkExDexbSauRuPq6BvUAAqAX0TwoNYMIQyZCMw= github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM= github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -71,21 +89,28 @@ github.com/zclconf/go-cty v1.13.0 h1:It5dfKTTZHe9aeppbNOda3mN7Ag7sg6QkBNm6TkyFa0 github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/test/justfile b/test/justfile new file mode 100644 index 0000000..1477033 --- /dev/null +++ b/test/justfile @@ -0,0 +1,2 @@ +default: + echo "hello"