Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 12 additions & 29 deletions .cspell.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
{
"language": "en",
"dictionaries": [
"companies",
"filetypes",
"fullstack",
"softwareTerms"
],
"dictionaries": ["companies", "filetypes", "fullstack", "softwareTerms"],
"words": [
"aquasecurity",
"artipacked",
Expand All @@ -20,49 +15,39 @@
"credstore",
"ehthumbs",
"esac",
"flagwords",
"fprintln",
"gjson",
"goarch",
"gobin",
"gofmt",
"golangci",
"goos",
"gopath",
"kics",
"gotoolchain",
"jdoe",
"kwallet",
"ldflags",
"lfid",
"lfx",
"lfxv",
"linuxfoundation",
"localappdata",
"memprof",
"mgechev",
"mktemp",
"mtimes",
"nolint",
"passwordstore",
"pipefail",
"rundll",
"techdocs",
"tidwall",
"trimpath",
"urfave",
"zizmor"
],
"flagWords": [
"abort: cancel, end, fail, halt, stop, terminate",
"abortion: cancelation, ending, failure, halting, stopping, termination",
"blackhat: attacker, malicious",
"black-hat: attacker, malicious",
"whitehat: ethical, security, researcher",
"white-hat: ethical, security, researcher",
"cripple: disable, degrade, impact",
"crippled: disabled, degraded, impacted",
"grandfathered: legacy, exempted, preauthorized",
"master: controller, primary, main, leader, parent",
"slave: agent, replica, secondary, follower, child",
"tribe: squad, team, group",
"sanity-check: test, verify, validate",
"whitelist: allowlist",
"white-list: allow-list",
"blacklist: denylist",
"black-list: deny-list"
],
"flagWords": [],
"ignorePaths": [
".cspell.json",
"CODEOWNERS",
Expand All @@ -74,9 +59,7 @@
"languageSettings": [
{
"languageId": "markdown",
"ignoreRegExpList": [
"/^\\s*```\\s*(mermaid)[\\s\\S]*?^\\s*```/gm"
]
"ignoreRegExpList": ["/^\\s*```\\s*(mermaid)[\\s\\S]*?^\\s*```/gm"]
}
]
}
5 changes: 4 additions & 1 deletion .github/workflows/mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
id: ml
# Use the Go flavor. Keep this version in sync with the
# `megalinter` target in the Makefile.
uses: oxsecurity/megalinter/flavors/go@ef3e84b8b836d76db562d0f3ed7da61e8fd538bc # v9.6.0
uses: oxsecurity/megalinter/flavors/go@9949bad031045f366be2467e00e8371a7328a2e2 # v10.1.0
env:
# Only Actions-specific values (secrets, runner behavior) belong
# here. Generic MegaLinter/repo config belongs in .mega-linter.yml
Expand All @@ -44,6 +44,9 @@ jobs:
# All available variables are described in documentation
# https://megalinter.io/latest/configuration/
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Lets Go-based linters download the go.mod toolchain when it is
# newer than the Go bundled in the MegaLinter image.
GOTOOLCHAIN: auto
# Allow GITHUB_TOKEN for working around rate limits (aquasecurity/trivy#7668).
REPOSITORY_TRIVY_UNSECURED_ENV_VARIABLES: GITHUB_TOKEN
# zizmor's "artipacked" audit needs the GitHub API (to verify
Expand Down
22 changes: 16 additions & 6 deletions .mega-linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@
# SPDX-License-Identifier: MIT
---
GITHUB_COMMENT_REPORTER: false
# Excludes locally generated CLI binaries from repository scans.
ADDITIONAL_EXCLUDED_DIRECTORIES:
- bin
DISABLE_LINTERS:
# Prefer Revive.
- GO_GOLANGCI_LINT
# yamllint is sufficient for us.
- YAML_PRETTIER
DISABLE_ERRORS_LINTERS:
# Currently disabled upstream by MegaLinter itself (supply chain
# compromise). Keep it non-blocking here so a future upstream restore
# doesn't unexpectedly break the build before we've reviewed it.
- REPOSITORY_KICS
# There's no easy local feedback loop for spelling issues before
# pushing, so keep them non-blocking to avoid unnecessary PR cycles
# for words that just need adding to the dictionary.
- SPELL_CSPELL
YAML_YAMLLINT_CONFIG_FILE: .yamllint
SPELL_CSPELL_ANALYZE_FILE_NAMES: false
SPELL_CSPELL_PRE_COMMANDS:
- command: >-
cp .cspell.json /tmp/cspell.json.orig &&
curl -sSf --connect-timeout 5 --max-time 15 https://raw.githubusercontent.com/linuxfoundation/lfx-public-workflows/737873e045a02df2f66b09d8061b98997cdf1880/cspell/flagwords.json.snippet -o /tmp/flagwords.json.snippet &&
test "$(grep -c '^[[:space:]]*"flagWords"[[:space:]]*:[[:space:]]*\[\],[[:space:]]*$' .cspell.json)" -eq 1 &&
sed -i -e '/^[[:space:]]*"flagWords"[[:space:]]*:[[:space:]]*\[\],[[:space:]]*$/{r /tmp/flagwords.json.snippet' -e 'd}' .cspell.json
cwd: workspace
continue_if_failed: false
SPELL_CSPELL_POST_COMMANDS:
- command: cp /tmp/cspell.json.orig .cspell.json
cwd: workspace
# Allows Grype to complete repository scans over Docker bind mounts.
REPOSITORY_GRYPE_TIMEOUT_SECONDS: 600
# Ignore YAML files with templating macros; these typically fail linting and/or
# schema checking.
FILTER_REGEX_EXCLUDE: '(templates/.*\.yml|templates/.*\.yaml)'
42 changes: 3 additions & 39 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,44 +236,8 @@ release binaries may be missing even though the GitHub Release exists.
keep dependencies current. This upgrades module dependencies only, not the
Go toolchain itself (`go.mod`'s `go` directive) -- see the toolchain policy
below before touching that.
4. **Go toolchain version**: Freely bump `go.mod`'s `go` directive to the
latest available *patch* release (e.g. `1.X.Y` → `1.X.{Y+1}`) to pick up
security fixes. Do **not** bump the *minor* version (e.g. `1.X.x` →
`1.{X+1}.x`) unless the user explicitly asks for it, **and** you've
validated it against the Go version MegaLinter itself bundles --
MegaLinter runs several linters (e.g. `golangci-lint`) against its own
bundled Go version, and a `go.mod` directive newer than that bundled
version breaks those checks.

To find MegaLinter's bundled Go version:

```bash
# 1. Find the MegaLinter flavor and pinned version tag used in CI.
grep -A1 'oxsecurity/megalinter' .github/workflows/*.yml
# e.g. "uses: oxsecurity/megalinter/flavors/<flavor>@<sha> # <tag>"

# 2. Fetch that flavor's Dockerfile and read its GO_ALPINE_VERSION (or
# GO_IMAGE_VERSION) build arg.
curl -s "https://raw.githubusercontent.com/oxsecurity/megalinter/<tag>/flavors/<flavor>/Dockerfile" \
| grep -i 'GO_ALPINE_VERSION\|GO_IMAGE_VERSION'
```

`go.mod`'s `go` directive must never exceed that bundled version. Staying
one minor version behind it (rather than matching its minor *and* patch
exactly) leaves room to always take the latest patch release for security
fixes without ever being blocked by MegaLinter's own bundled patch version
lagging behind a newly disclosed vulnerability.

There's no built-in `go` subcommand to look up the latest patch release
for a given minor version -- query the official `go.dev/dl` JSON feed
instead:

```bash
# Find the latest patch release for the minor version pinned in go.mod.
MINOR=$(grep '^go ' go.mod | awk '{print $2}' | cut -d. -f1,2)
curl -s "https://go.dev/dl/?mode=json&include=all" \
| jq -r --arg m "go${MINOR}." '.[].version | select(startswith($m))' \
| sort -V | tail -1
```
4. **Go toolchain version**: Follow the `lfx-megalinter` skill's Go version
policy. It sets `go.mod` to the latest patch of the previous stable Go
minor and caps it at the minor bundled by the pinned MegaLinter release.
5. **Code Quality**: Run `make check` before commits
6. **Documentation**: Update README.md for user-facing changes
10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ BINARY_NAME=lfx
CMD_DIR=./cmd/lfx
BUILD_DIR=./bin

# Run MegaLinter locally via Docker (matches CI Go flavor at v10.1.0).
# Keep this digest in sync with .github/workflows/mega-linter.yml.
MEGALINTER_IMAGE := ghcr.io/oxsecurity/megalinter-go@sha256:42e091a4bcbe9141fe420c2520ed7addf75ae60a0c9d42e3df1278eef1c90a88 # v10.1.0

# Build flags. Version is not injected via -ldflags: `go build` already
# embeds a pseudo-version (encoding the VCS revision, commit time, and
# dirty state) into the binary's module version, which main.go reads via
Expand Down Expand Up @@ -104,11 +108,9 @@ install-tools:
*) echo "Warning: $$gobin is not in your PATH; installed tools (golangci-lint, revive) won't be found. Add it to your PATH, e.g.: export PATH=\"$$PATH:$$gobin\"" ;; \
esac

# Run MegaLinter locally via Docker (matches CI Go flavor at v9.6.0).
# Keep this version in sync with .github/workflows/mega-linter.yml.
megalinter:
docker pull ghcr.io/oxsecurity/megalinter-go:v9.6.0
docker run --rm --platform linux/amd64 -v '$(CURDIR):/tmp/lint:rw' ghcr.io/oxsecurity/megalinter-go:v9.6.0
docker pull $(MEGALINTER_IMAGE)
docker run --rm --platform linux/amd64 -e GOTOOLCHAIN=auto -v '$(CURDIR):/tmp/lint:rw' $(MEGALINTER_IMAGE)

# Show help
help:
Expand Down
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// SPDX-License-Identifier: MIT
module github.com/linuxfoundation/lfx-cli

go 1.25.14
go 1.26.9

require (
github.com/99designs/keyring v1.2.2
github.com/tidwall/gjson v1.19.0
github.com/tidwall/gjson v1.20.0
github.com/urfave/cli-docs/v3 v3.1.0
github.com/urfave/cli/v3 v3.13.0
golang.org/x/oauth2 v0.36.0
github.com/urfave/cli/v3 v3.14.0
golang.org/x/oauth2 v0.37.0
)

require (
Expand All @@ -22,7 +22,7 @@ require (
github.com/mtibben/percent v0.2.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
github.com/tidwall/pretty v1.2.2 // indirect
golang.org/x/sys v0.49.0 // indirect
golang.org/x/term v0.47.0 // indirect
)
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,23 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU=
github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
github.com/tidwall/gjson v1.20.0 h1:+agJ3rEzKcCXKDKo0ml26UROcpcAlnZyjq+TjbY5Fto=
github.com/tidwall/gjson v1.20.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc=
github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM=
github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.2 h1:dz1jrRuE7or/74V490B4/GP1pZm5WKlt2bgCP5A83w8=
github.com/tidwall/pretty v1.2.2/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/urfave/cli-docs/v3 v3.1.0 h1:Sa5xm19IpE5gpm6tZzXdfjdFxn67PnEsE4dpXF7vsKw=
github.com/urfave/cli-docs/v3 v3.1.0/go.mod h1:59d+5Hz1h6GSGJ10cvcEkbIe3j233t4XDqI72UIx7to=
github.com/urfave/cli/v3 v3.13.0 h1:Dr6jqMfIyyFsRVn7Nz5mqLsMY+ZMpfh3a0aMs+umPVY=
github.com/urfave/cli/v3 v3.13.0/go.mod h1:vXn6HxPNccJSzQr2QvwVncOKrgYGIHU0HY5h8B2nQj4=
github.com/urfave/cli/v3 v3.14.0 h1:a8414NQlHJs0c/iBsulKLzlES0n/lEAskbL2LKpU4/s=
github.com/urfave/cli/v3 v3.14.0/go.mod h1:vXn6HxPNccJSzQr2QvwVncOKrgYGIHU0HY5h8B2nQj4=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/term v0.47.0 h1:cpyOwQkr2Nzxe2p6KnrTG7Ei2wtzjsuSjhpXXepZ/BM=
golang.org/x/term v0.47.0/go.mod h1:efAfAuG6RKABvg1ArGebRkvX6LXul14SM67o2e4mUCY=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Loading