Skip to content

Releases: vertti/preflight

v0.20.0

Choose a tag to compare

@github-actions github-actions released this 16 Aug 16:29
037003b

A correctness release. Five checks could previously report success without verifying anything, or verify the wrong thing.

Upgrade notes

Each of these can turn a check that passed on v0.19.0 red on v0.20.0. That is the point — the old result was not trustworthy — but it may need action in existing pipelines.

Change What used to happen
Version constraints read the right number s3cmd version 2.3.0 parsed as 3.0.0, so --min/--max/--exact/--range answered about a digit in the program name. Also affected bzip2, log4j, x264, p7zip.
file size/content flags reject directories preflight file /etc --min-size 999999999 reported [OK]. --not-empty, --min-size, --max-size, --contains and --match all skipped the constraint on a directory.
cmd --match no longer suppresses version constraints --match 'git version' --min 99 reported [OK] while --min 99 alone correctly failed.
preflight run executes every check It stopped at the first failure, hiding every check after it. Exit code is now 1 if any check failed, rather than the first child's code.
install.sh will not install an unverified binary With neither sha256sum nor shasum present it warned and installed anyway. Set PREFLIGHT_SKIP_CHECKSUM=1 to opt out deliberately.

Also in this release

  • .preflight files support quoted arguments, so a value may contain a space: env GREETING --exact "hello world". Single quotes are literal, which keeps regexes and JSON intact.
  • Multi-line check output is readable again. A program's own line breaks are preserved and indented instead of escaped to \n, so a failing preflight cmd shows real help text. A checked program still cannot forge a result line — those start at column 0 and nothing it emits ever does.
  • --exact "" asserts an empty value in env and json, instead of being indistinguishable from omitting the flag.

What's Changed

  • Fix version extraction picking digits out of program names by @vertti in #239
  • Fix file size and content checks silently passing on directories by @vertti in #240
  • Run every check in a .preflight file, not just up to the first failure by @vertti in #243
  • Fix --match silently disabling version constraints in cmd check by @vertti in #241
  • Add quoting to .preflight files so arguments can contain spaces by @vertti in #244
  • Update ghcr.io/vertti/preflight:latest Docker digest to e108e90 by @renovate[bot] in #242
  • Fail the installer when it cannot verify the downloaded binary by @vertti in #246
  • Remove a redundant null branch and a stale gjson comment in jsoncheck by @vertti in #247
  • Print multi-line check details as indented lines, not escaped newlines by @vertti in #245
  • Make --exact "" assert an empty value in env and json checks by @vertti in #248

Full Changelog: v0.19.0...v0.20.0

v0.19.0

Choose a tag to compare

@github-actions github-actions released this 14 Aug 06:35
28c81ff

What's Changed

  • Test the .preflight command loop by @vertti in #223
  • Give the run-named files and functions distinct names by @vertti in #224
  • Fix --hide-value and --mask-value leaking on failure paths by @vertti in #225
  • Fix memory limit detection under host cgroup namespaces and cgroup v1 by @vertti in #226
  • Escape control characters in printed check results by @vertti in #228
  • Fix --min-cpus ignoring container CPU quotas by @vertti in #229
  • Bound HTTP response body reads by @vertti in #230
  • Add a CA bundle to the released image by @vertti in #231
  • Stop recommending that secrets be echoed into build logs by @vertti in #232
  • Collapse the duplicated retry-failure handling by @vertti in #235
  • Update jdx/mise-action digest to 3c2e0cf by @renovate[bot] in #236
  • Update dependency go to v1.26.6 by @renovate[bot] in #237
  • Update alpine Docker tag to v3.24 by @renovate[bot] in #234
  • Update module go:golang.org/x/vuln/cmd/govulncheck to v1.7.0 by @renovate[bot] in #238
  • Update dependency hk to v1.55.0 by @renovate[bot] in #222
  • Update ghcr.io/vertti/preflight:latest Docker digest to 3921e02 by @renovate[bot] in #216

Full Changelog: v0.18.1...v0.19.0

v0.18.1

Choose a tag to compare

@github-actions github-actions released this 12 Aug 07:53
6a0fee7

Security and reliability fixes

Unlike v0.18.0, nothing here turns a passing check into a failing one. Upgrading is safe for existing pipelines.

Security

preflight prometheus no longer follows redirects. It shared its HTTP client's design with preflight http but not its redirect guard, so a 3xx response sent the request — including custom headers — to whatever host the redirect named. Go strips Authorization and Cookie across hosts but not custom headers, and Mimir, Cortex, Thanos and Grafana Cloud carry tenancy in exactly those. The destination could both harvest credentials and decide the check's verdict. Both commands now share one client with redirects off by default; preflight http --follow-redirects still opts in. (#219)

.preflight files can no longer run other binaries. The format's contract is that every line runs preflight. The parser enforced it with a prefix test, so a line like preflight/../evil.sh counted as already-prefixed while the substitution that rewrites the line to the real binary — which tests for the exact token — did not fire. The path then ran relative to the working directory. Since .preflight is discovered by walking up from the current directory, git clone && cd repo && preflight run was remote code execution from repo content. The parser now compares the first token, and the substitution is unconditional. (#220)

Release binaries are compressed by a verified UPX. Shipped in v0.18.0; noted here because it wasn't called out at the time. (#212)

Reliability

preflight cmd --timeout is now enforced. A version command that leaves a background child holding stdout kept Wait blocked past the deadline, because the context kills only the direct child. A command that daemonizes — a service wrapper, an agent, a docker shim — hung the check indefinitely rather than failing it. Measured at 31s for a 2s timeout; now 1s. In a container entrypoint this was a permanent stall, which is worse than a reported failure. (#218)

Failing checks no longer print the flag reference. Cobra treats any error from a command as a usage mistake, so every failed check emitted Error: check failed plus the full flag list — up to 30 lines to deliver one. Real usage errors (unknown flag, missing argument, bad flag combination) still show usage. (#214)

$ preflight env NOPE
[FAIL] env: NOPE
       not set

Documentation

Every flag in the README and usage guide is now checked against the binary. Four documented invocations did not work at all, including the Quick Start's tcp --retry and the version-constraint example's --min ^1.0. Sixteen working flags were missing from the tables, among them --json-path, which the README advertises as a reason to use preflight. (#215)

The binary size claims were also wrong in both directions: the published binary is UPX-compressed, so it is ~2.5MB rather than the ~6MB the usage guide claimed for copying it into an image.

Internal

The cross-platform CI matrix could not fail — every build step ended in || echo, so the six required Build checks passed through compile errors. Behind them, the Windows test build had been broken by a mock stranded behind a //go:build unix tag; go build skips _test.go files, so the documented verification step could not see it. Both fixed, and the matrix now runs go vet. (#213)

Tests no longer depend on the machine they run on. One created and deleted a directory inside the real $HOME; others inherited the developer's ~/.gitconfig (commit.gpgsign = true broke them) or assumed port 1 was free. (#217)


What's Changed

  • Make the cross-platform CI gate able to fail by @vertti in #213
  • Stop dumping usage on every failed check by @vertti in #214
  • Fix documented flags that don't exist by @vertti in #215
  • Make tests independent of the machine they run on by @vertti in #217
  • Enforce --timeout when a command leaves a child running by @vertti in #218
  • Share one HTTP client and stop promcheck following redirects by @vertti in #219
  • Stop .preflight lines escaping to other binaries by @vertti in #220
  • Derive the subcommand list from cobra by @vertti in #221

Full Changelog: v0.18.0...v0.18.1

v0.18.0

Choose a tag to compare

@github-actions github-actions released this 11 Aug 11:52
38352ab

Checks that were silently passing now fail

This release fixes four cases where preflight reported [OK] while validating nothing. Upgrading may turn a green pipeline red. That is the intended outcome — the environment was already broken, preflight just wasn't saying so — but it means this is not a drop-in upgrade if you use any of the flags below.

If you use You previously got You now get
file <path> --writable / --executable [OK] whenever anyone had the permission bit [OK] only if the current user can actually write/execute
file <path> --mode 0o600 (or any malformed octal) [OK] — the constraint parsed as 0 and matched everything An error naming the bad value
file <path> --symlink-target X without --symlink [OK] — the target was never compared The path must be a symlink pointing at X
preflight -- ./app or preflight --help -- ./app The app started, exit 0 Refuses to exec, exit 1

What to check before upgrading

  • --writable on paths you don't own. The common case is a root-owned directory checked from an unprivileged container user. It passed before and fails now — which is what you wanted the check to tell you.
  • Malformed --mode values. 0o600 is the Go and Python spelling and was silently accepted as "no constraint". Use 0600 or 600.
  • Templated entrypoints. If check arguments can resolve empty, preflight -- /app now exits 1 instead of starting the app unchecked. An empty or comments-only .preflight file behaves the same way.

Fixes

--writable and --executable now ask the OS. They tested mode & 0o222, i.e. whether any of owner/group/other had the bit — not whether this process can act. A root-owned 0644 file returned [OK] for --writable to a non-root user. Now uses faccessat(AT_EACCESS) on unix; Windows keeps the permission-bit approximation, since there is no access(2) and Go reports a synthesized mode. (#211)

--mode rejects malformed octal. Parsing used Sscanf("%o"), which stops at the first non-octal character and reports no error once one digit is consumed. 0o600 became mode 0, and the minimum-permission test actual & 0 != 0 is false for every file — so a 0000 file passed a check the docs recommend for TLS private keys. (#209)

--symlink-target is honored on its own. It was only read inside the --symlink branch, so alone it parsed a target and never compared it. It now implies --symlink. (#209)

Exec mode requires a check to have run. The root command has no handler, so preflight -- ./app printed help, returned success, and started the app. So did preflight --help -- ./app. A gate that verified nothing reported success. (#210)

Supply chain

The UPX download is verified before it runs. release.yml fetched UPX over curl | tar with no integrity check and then compressed every published artifact with it. Because checksums are generated from the compressed output, a substituted UPX would have produced binaries whose checksums were internally consistent. The tarball's SHA-256 is now pinned and verified. (#212)

Note that checksums.txt is still generated in the same workflow that builds the binaries, so it detects corruption, not a compromised release. Signing/provenance attestation is tracked separately.

Internal

Local mise run test-coverage now uses the same -coverpkg as CI, so local coverage matches what Codecov gates on (94.6%, previously reported as 92.9% locally). (#208)


What's Changed

Read more

v0.17.1

Choose a tag to compare

@github-actions github-actions released this 09 Jan 07:53
b44d1fc

What's Changed

  • Pin ghcr.io/vertti/preflight Docker tag to 7113440 by @renovate[bot] in #87
  • Replace Makefile with justfile by @vertti in #88
  • Update dependency just to v1.46.0 by @renovate[bot] in #89
  • Update dependency hk to v1.29.0 by @renovate[bot] in #90
  • Update dependency golangci-lint to v2.8.0 by @renovate[bot] in #91

Full Changelog: v0.17.0...v0.17.1

v0.17.0

Choose a tag to compare

@github-actions github-actions released this 01 Jan 19:21
95bee1c

What's Changed

  • Fix GitHub Actions security issues by @vertti in #75
  • Improve test coverage across packages by @vertti in #76
  • Add Cobra command execution tests by @vertti in #77
  • Update README to lead with value, add FAQ by @vertti in #78
  • Format What It Does section as bullet list by @vertti in #79
  • Add exec mode for shell-less entrypoints by @vertti in #80
  • Add CI tests for distroless and scratch images by @vertti in #81
  • Add tests to improve coverage to 93.5% by @vertti in #82
  • Refactor tests to reduce repetition and boilerplate by @vertti in #84
  • Add FUNDING.yml with thanks.dev and Buy Me a Coffee by @vertti in #85
  • Add testifylint for testify best practices by @vertti in #86

Full Changelog: v0.16.0...v0.17.0

v0.16.0

Choose a tag to compare

@github-actions github-actions released this 30 Dec 07:44
a0b0102

What's Changed

  • Replace Dependabot with Renovate by @vertti in #59
  • Add security scanning to CI by @vertti in #60
  • Add security documentation and nilnesserr linter by @vertti in #61
  • Update dependency golangci-lint to v2.7.2 by @renovate[bot] in #63
  • Update Node.js to v24 by @renovate[bot] in #69
  • Update dependency hk to v1.28.0 by @renovate[bot] in #68
  • Update dependency pkl to v0.30.2 by @renovate[bot] in #66
  • Update dependency dprint to v0.51.1 by @renovate[bot] in #67
  • Replace abandoned dependencies gjson and go-supportscolor by @vertti in #72
  • Update Node.js to b83af04 by @renovate[bot] in #71
  • Update module golang.org/x/term to v0.38.0 by @renovate[bot] in #73

New Contributors

Full Changelog: v0.15.0...v0.16.0

v0.15.0

Choose a tag to compare

@github-actions github-actions released this 08 Dec 11:21
15fcbb0

What's Changed

  • Add documentation for keeping containers clean by @vertti in #56
  • Remove BLAKE2b and BLAKE3 hash algorithms by @vertti in #57
  • Add SHA256 checksums to releases by @vertti in #58

Full Changelog: v0.14.0...v0.15.0

v0.14.0

Choose a tag to compare

@github-actions github-actions released this 07 Dec 18:33
911bfc0

What's Changed

Full Changelog: v0.13.0...v0.14.0

v0.13.0

Choose a tag to compare

@github-actions github-actions released this 07 Dec 17:47
203421e

What's Changed

  • Improve error messages to show actual values by @vertti in #52
  • Color error detail lines red by @vertti in #53

Full Changelog: v0.12.2...v0.13.0