Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41ad87b3b9 | ||
|
|
4ff0d20c10 |
+8
-2
@@ -50,7 +50,12 @@ ARG CHECK_EPOCH
|
|||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
RUN make test
|
# This cache mount keeps Go's build cache between builds for make test and
|
||||||
|
# make build; -count=1 in script/test keeps test results out of it. Go's cache
|
||||||
|
# does not notice C header changes, so the mount has its own id: change the id
|
||||||
|
# when the C packages installed above change.
|
||||||
|
RUN --mount=type=cache,id=sneak/secret/go-build,target=/root/.cache/go-build \
|
||||||
|
make test
|
||||||
|
|
||||||
# The version stamped into the binary: the VERSION build argument when one
|
# The version stamped into the binary: the VERSION build argument when one
|
||||||
# is given, otherwise `git describe --tags --always` of the .git the build
|
# is given, otherwise `git describe --tags --always` of the .git the build
|
||||||
@@ -58,7 +63,8 @@ RUN make test
|
|||||||
# one, the short commit when no tag is reachable. A context that carries .git
|
# one, the short commit when no tag is reachable. A context that carries .git
|
||||||
# and still yields no version fails the build.
|
# and still yields no version fails the build.
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
RUN version="${VERSION:-$(git describe --tags --always)}"; \
|
RUN --mount=type=cache,id=sneak/secret/go-build,target=/root/.cache/go-build \
|
||||||
|
version="${VERSION:-$(git describe --tags --always)}"; \
|
||||||
if [ -e .git ] && { [ -z "$version" ] || [ "$version" = dev ] || \
|
if [ -e .git ] && { [ -z "$version" ] || [ "$version" = dev ] || \
|
||||||
[ "$version" = unknown ]; }; then \
|
[ "$version" = unknown ]; }; then \
|
||||||
echo "no version could be derived although the build context carries .git" >&2; \
|
echo "no version could be derived although the build context carries .git" >&2; \
|
||||||
|
|||||||
@@ -604,7 +604,8 @@ provide:
|
|||||||
- `script/build` — build the `secret` binary into the repo root, stamping the
|
- `script/build` — build the `secret` binary into the repo root, stamping the
|
||||||
version (`VERSION` from the environment, else `git describe`) and the git
|
version (`VERSION` from the environment, else `git describe`) and the git
|
||||||
commit
|
commit
|
||||||
- `script/test` — run `go vet` and the test suite (verbose rerun on failure)
|
- `script/test` — run `go vet` and the test suite (verbose rerun on failure),
|
||||||
|
every test on every run, never a result from Go's test cache
|
||||||
- `script/lint` — run `golangci-lint` in docker only: builds `Dockerfile.lint`,
|
- `script/lint` — run `golangci-lint` in docker only: builds `Dockerfile.lint`,
|
||||||
where the linter is a build step that runs on every call, also on an unchanged
|
where the linter is a build step that runs on every call, also on an unchanged
|
||||||
tree
|
tree
|
||||||
@@ -624,7 +625,8 @@ provide:
|
|||||||
- `script/cibuild` — CI entrypoint: `docker build --ulimit memlock=-1:-1 .`
|
- `script/cibuild` — CI entrypoint: `docker build --ulimit memlock=-1:-1 .`
|
||||||
(memguard needs mlock; the Dockerfile runs the checks), with a new
|
(memguard needs mlock; the Dockerfile runs the checks), with a new
|
||||||
`CHECK_EPOCH` build argument on every run so the checks run again on an
|
`CHECK_EPOCH` build argument on every run so the checks run again on an
|
||||||
unchanged tree
|
unchanged tree; the `Dockerfile` keeps Go's build cache between builds, so
|
||||||
|
`make test` and `make build` compile only what changed
|
||||||
- `script/precommit` — pre-commit checks: `go mod tidy` verification, then
|
- `script/precommit` — pre-commit checks: `go mod tidy` verification, then
|
||||||
`script/check`
|
`script/check`
|
||||||
- `script/install-precommit` — install the git pre-commit hook that runs
|
- `script/install-precommit` — install the git pre-commit hook that runs
|
||||||
|
|||||||
@@ -18,20 +18,32 @@ https://git.eeqj.de/sneak/secret/milestone/12
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-06: `make test` in `script/cibuild` no longer compiles the standard
|
||||||
|
library and every dependency from nothing on every build
|
||||||
|
(https://git.eeqj.de/sneak/secret/issues/124). The `Dockerfile` runs it and
|
||||||
|
`make build` with Go's build cache in a BuildKit cache mount, which docker
|
||||||
|
keeps between builds, so each compiles only what changed since the last build.
|
||||||
|
The mount has an id of its own, so other repositories' builds do not share it.
|
||||||
|
`script/test` passes `-count=1`, so every test runs on every build and no
|
||||||
|
result comes from Go's test cache. A build with an empty cache, such as the
|
||||||
|
first after docker's build cache is cleared, compiles everything in
|
||||||
|
`make test` as before.
|
||||||
- 2026-10-06: The tests run quickly with the race detector on
|
- 2026-10-06: The tests run quickly with the race detector on
|
||||||
(https://git.eeqj.de/sneak/secret/issues/120). Most of their time went to
|
(https://git.eeqj.de/sneak/secret/issues/120). Most of their time went to
|
||||||
deriving keys from passphrases with scrypt, which is slow on purpose. The new
|
deriving keys from passphrases with scrypt, which is slow on purpose. The new
|
||||||
`secret.ScryptWorkFactor`, when not zero, replaces age's scrypt work factor
|
`secret.ScryptWorkFactor`, when not zero, replaces age's scrypt work factor
|
||||||
when a passphrase encrypts; the tests of `internal/secret`, `internal/vault`
|
when a passphrase encrypts; the tests of `internal/secret`, `internal/vault`
|
||||||
and `internal/cli` set it to 1 before any test runs, and the program never
|
and `internal/cli` set it to 1 before any test runs, and the program never
|
||||||
sets it. `TestRemovalAsksWithoutHoldingLock` and
|
sets it; `TestGetCommandOutputsToStdout` checks that the passphrase unlocker
|
||||||
`TestFailedCommandReleasesLock` no longer run in parallel with other tests:
|
the built binary's `secret init` writes names age's work factor, 18.
|
||||||
each waits at most 10 seconds for the in-memory lock that every test in the
|
`TestRemovalAsksWithoutHoldingLock` and `TestFailedCommandReleasesLock` no
|
||||||
package shares, and other tests' commands held it longer.
|
longer run in parallel with other tests: each waits at most 10 seconds for the
|
||||||
`TestConcurrentAddsKeepEveryVersion`, which times nothing, and
|
in-memory lock that every test in the package shares, and other tests'
|
||||||
`TestGetCommandOutputsToStdout`, which no longer sets an environment variable
|
commands held it longer. `TestConcurrentAddsKeepEveryVersion`, which times
|
||||||
its commands do not read, now run in parallel. The `script/cibuild` comment no
|
nothing, and `TestGetCommandOutputsToStdout`, which no longer sets an
|
||||||
longer says that tests are skipped without its memlock ulimit.
|
environment variable its commands do not read, now run in parallel. The
|
||||||
|
`script/cibuild` comment no longer says that tests are skipped without its
|
||||||
|
memlock ulimit.
|
||||||
- 2026-10-05: No test stores a secret larger than 1 MiB
|
- 2026-10-05: No test stores a secret larger than 1 MiB
|
||||||
(https://git.eeqj.de/sneak/secret/issues/52). The size tests for `secret add`,
|
(https://git.eeqj.de/sneak/secret/issues/52). The size tests for `secret add`,
|
||||||
`secret import` and the stdin buffer no longer try 2 MB, 10 MB, 99 MB, 100 MB
|
`secret import` and the stdin buffer no longer try 2 MB, 10 MB, 99 MB, 100 MB
|
||||||
|
|||||||
@@ -41,6 +41,18 @@ func TestGetCommandOutputsToStdout(t *testing.T) {
|
|||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
require.NoError(t, err, "init should succeed: %s", string(output))
|
require.NoError(t, err, "init should succeed: %s", string(output))
|
||||||
|
|
||||||
|
// The binary, unlike these tests, encrypts the passphrase unlocker's key
|
||||||
|
// at age's scrypt work factor, 18. age writes the work factor last on the
|
||||||
|
// second line of priv.age: "-> scrypt <salt> <work factor>".
|
||||||
|
vaultDir := filepath.Join(tempDir, "vaults.d", "default")
|
||||||
|
unlockerName := readFile(t, filepath.Join(vaultDir, "current-unlocker"))
|
||||||
|
unlockerDir := filepath.Join(vaultDir, "unlockers.d", string(unlockerName))
|
||||||
|
privAge := readFile(t, filepath.Join(unlockerDir, "priv.age"))
|
||||||
|
header := strings.SplitN(string(privAge), "\n", 3)
|
||||||
|
require.Len(t, header, 3, "priv.age should start with an age header")
|
||||||
|
assert.Regexp(t, `^-> scrypt \S+ 18$`, header[1],
|
||||||
|
"the passphrase unlocker should be encrypted at scrypt work factor 18")
|
||||||
|
|
||||||
// Add a secret
|
// Add a secret
|
||||||
//nolint:gosec // G204: test executes the freshly built secret binary
|
//nolint:gosec // G204: test executes the freshly built secret binary
|
||||||
cmd = exec.CommandContext(t.Context(), secretPath, "add", "test/secret")
|
cmd = exec.CommandContext(t.Context(), secretPath, "add", "test/secret")
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
# the lower limit of a plain `docker build .`.
|
# the lower limit of a plain `docker build .`.
|
||||||
# A cached build checks nothing: a new CHECK_EPOCH on every run makes the
|
# A cached build checks nothing: a new CHECK_EPOCH on every run makes the
|
||||||
# Dockerfile's check steps run again on an unchanged tree, while its base
|
# Dockerfile's check steps run again on an unchanged tree, while its base
|
||||||
# images and module downloads stay cached.
|
# images, module downloads and the Go build cache that make test and make
|
||||||
|
# build use stay cached.
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||||
|
|||||||
+3
-1
@@ -9,7 +9,9 @@ main() {
|
|||||||
# CGO is required (Makefile exports this too)
|
# CGO is required (Makefile exports this too)
|
||||||
export CGO_ENABLED=1
|
export CGO_ENABLED=1
|
||||||
go vet ./...
|
go vet ./...
|
||||||
go test ./... || go test -v ./...
|
# -count=1: run every test, never take a result from Go's test cache,
|
||||||
|
# which the Dockerfile keeps between builds
|
||||||
|
go test -count=1 ./... || go test -count=1 -v ./...
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user