Skip to content

fix: defer cache key generation to pre-command and fix stdout log pollution#11

Open
karlchu wants to merge 1 commit into
buildkite-plugins:mainfrom
karlchu:main
Open

fix: defer cache key generation to pre-command and fix stdout log pollution#11
karlchu wants to merge 1 commit into
buildkite-plugins:mainfrom
karlchu:main

Conversation

@karlchu

@karlchu karlchu commented Jul 17, 2026

Copy link
Copy Markdown

This pull request resolves two critical bugs in the plugin's cache-key generation lifecycle and logging mechanism, and introduces fail-fast configuration validation.

The Bugs Resolved

  1. Incorrect Lifecycle Timing (Environment Hook)

    • Problem: Cache key generation was originally run during the environment hook (hooks/environment). In Buildkite's lifecycle, the environment hook executes before repository checkout. As a result, the plugin was looking for local files (like a custom cache-key Dockerfile or lockfiles) before they were cloned onto the runner.
    • Consequence: Hashing would either process files that did not exist yet (resulting in an empty hash) or process stale files from a previous run on persistent runners.
  2. Stdout Log Contamination

    • Problem: The logging functions log_info, log_success, and log_warning were printing to stdout.
    • Consequence: In generate_cache_key(), the loop output is piped directly to sha1sum (done | sha1sum). When a file was missing, the warning message [WARNING]: Cache key file not found <file> was written to stdout, polluting the pipe. This resulted in the plugin generating a constant cache key hash of faad270761e3125b46cc97fbde55722f536114f1 (the SHA-1 of the warning string itself).

Key Changes

  1. Deferred Key Generation

    • Removed cache key generation from hooks/environment. The plugin now generates the key on-demand in the pre-command hook, which executes safely after checkout.
  2. Diagnostic Log Redirection to Stderr

    • Modified log_info, log_success, and log_warning in lib/shared.bash to write to stderr (>&2). This adheres to standard Unix logging practices and keeps diagnostic logs from contaminating functional stdout streams used in command substitutions and pipelines.
  3. Fail-Fast Validation

    • Updated generate_cache_key in lib/plugin.bash. If a user explicitly configures a cache-key pointing to file paths, the plugin now verifies their existence in the main shell context before hashing. If any file is missing, the plugin fails-fast immediately with a clear error (exit 1) instead of silently building using a corrupted/empty hash.
  4. Added Test Cases

    • Added three new automated BATS tests to tests/pre-command.bats:
      • "Pre-command hook generates cache key on demand after checkout": Verifies correct key generation from workspace files.
      • "Pre-command hook fails fast if cache key file is missing": Verifies that missing files trigger an immediate build step failure.
      • "Pre-command hook treats cache key without slash as a literal string": Verifies string-literal cache key treatment and hashing when no slash is present in the value.

How This Was Tested

The entire Bats test suite was executed locally using the official Docker plugin-tester image:

docker run --rm -v "$PWD:/plugin" buildkite/plugin-tester

All 69 tests passed successfully (including the 3 new test cases).

@karlchu
karlchu marked this pull request as ready for review July 17, 2026 10:31
@karlchu
karlchu requested a review from a team as a code owner July 17, 2026 10:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant