Take the AWS region and credentials from the environment's dedicated variables - #4
Conversation
…variables The cache commit shelled out to `aws` with no credentials of its own and read a bare AWS_REGION, so both came from whatever the job environment happened to hold: that region variable, and the shared credentials file the default chain finds by expanding $HOME. Both are state the job shares, so a build that configures AWS for its own purposes silently redirected the cache's calls too. The environment now offers a dedicated, absolute-path credentials file plus the profile and region to use with it: BP_CACHE_AWS_CREDENTIALS_FILE, BP_CACHE_AWS_PROFILE, BP_CACHE_AWS_REGION. Prefer those, falling back to the previous values, so this behaves identically wherever they are not set yet. AWS_SHARED_CREDENTIALS_FILE and AWS_PROFILE are placed on the SPAWNED CHILD's environment only, never on process.env: they are global to every AWS CLI process, so mutating our own environment would also redirect the `aws` calls the job itself makes later in the build. With no dedicated file configured the child is spawned with its options untouched, exactly as before. The privileged reads keep `sudo -n -E`. -E preserves the environment, and that is already the mechanism by which the existing credential variables reach the privileged aws, so setting the two variables on the sudo call's child environment is sufficient; no explicit `sudo VAR=value ...` form is needed. Failure policy is unchanged: metric emission stays swallowed, commit failures stay core.warning, and a cache problem still never fails the job. Region and credential resolution move into src/aws-env.js so the two entry points share one definition and it can be unit tested — including the property that matters, that the caller's environment is never mutated. dist/ rebuilt.
There was a problem hiding this comment.
Agent code review
Walkthrough
This PR extracts the AWS credential and region resolution logic that was previously inlined into both src/index.js and src/post.js into a single shared module (src/aws-env.js), then adds a comprehensive unit-test suite (__tests__/aws-env.test.js) covering all key behaviors. The rebuilt dist/index.js and dist/post.js bundles are updated to match. The motivation is both testability and preventing the two entry points from diverging.
Findings
No issues found.
Verdict
The extraction is correct and the module is well-designed. The awsOpts function correctly avoids mutating the caller's environment (confirmed by the test and by inspection of the spread logic), properly inherits the ambient env when no base.env is provided, respects an explicit base.env override, and returns the incoming options object by identity when no dedicated credentials file is configured. The cacheRegion priority chain is correct and matches what both callers require. The seven unit tests cover all critical invariants. Both entry-point callers (src/index.js, src/post.js) import and use the module identically, which is exactly the drift-prevention the PR aims for. The dist bundles are consistent with the sources. No auto-merge red flags detected.
Confidence
HIGH — all 6 changed files were read in full; key function behavior was traced manually against every test case.
💡 Tips for working with the BuildPulse reviewer
- Re-review on demand — comment
@buildpulse reviewon the PR (/buildpulse reviewalso works). The fresh review bills the requester's seat. - Teach it by replying to a finding — reply to any inline comment: "we never do X here" becomes a standing rule for this repository (acknowledged in-thread, not raised again); "not in this PR" mutes the topic for this PR only. Replies are free. Org admins can view or remove learned rules on the AI Features page.
- Every push is re-reviewed automatically — smaller PRs get a fresh full review, larger ones get a delta review of what changed since the last look; an "Update branch" merge with an unchanged diff carries the previous verdict forward without a new billed review.
- Draft PRs are skipped until marked ready for review (repositories can opt in to draft reviews on the AI Features page).
The cache commit shells out to
awswith no credentials of its own and reads a bareAWS_REGION, so both come from whatever the job environment happens to hold: that regionvariable, and the shared credentials file the default credential chain finds by expanding
$HOME. Both are state the job shares, so a build that configures AWS for its ownpurposes silently redirects the cache's calls too.
The environment now offers dedicated variables instead — an absolute-path credentials
file plus the profile and region to use with it. This reads those first and falls back to
the previous behaviour, so it is a no-op wherever they are not set yet.
What changed
AWS_REGION→us-west-2BP_CACHE_AWS_REGION→AWS_REGION→us-west-2BP_CACHE_AWS_CREDENTIALS_FILE+BP_CACHE_AWS_PROFILEwhen set, ambient otherwisesrc/aws-env.js(new) —cacheRegion(env)andawsOpts(opts, env). Extracted so thetwo entry points share one definition and it can be unit tested, the same way
src/refresh-policy.jsis.src/post.js—runAws/awsOut/emitMetricspawn throughawsOpts(...); theregion comes from
cacheRegion(process.env).src/index.js— same foremitHydrateMetric.__tests__/aws-env.test.js— 7 tests. 13 → 20 passing.dist/rebuilt (node 20, as CI uses).Two things worth checking in review
The credential variables go on the spawned child's environment only, never on
process.env.AWS_SHARED_CREDENTIALS_FILEandAWS_PROFILEare global to every AWSCLI process, so assigning them to our own environment would also redirect the
awscallsthe job itself makes later in the build. There is a test asserting the caller's
environment is not mutated.
The privileged reads keep
sudo -n -E.-Epreserves the environment, and that isalready the mechanism by which the existing credential variables reach the privileged
aws, so setting the two variables on the sudo call's child environment is sufficient —no explicit
sudo VAR=value aws ...form is needed.Failure policy unchanged
Metric emission stays swallowed, commit failures stay
core.warning, and a cache problemstill never fails the job. When no dedicated credentials file is configured the options
object is returned untouched, so the spawn is exactly what it was before.