[rush] Build cache keys do not correctly account for configuration changes in dependencies
dmichon-msft opened this issue · 1 comments
Summary
The following options that may impact the cache key of a given operation incorrectly do not currently affect operations that depend on them:
dependsOnEnvVars
dependsOnAdditionalFiles
- Any CLI parameter that affects some phases but does not (directly) affect others
Repro steps
Create a repository with two projects, A
, and B
as root folders in the repo.
Define two phases:
_phase:first
. no dependencies.
_phase:second
, dependency on upstream: ['_phase:first']
.
Define build
as a phased command with phases: ['_phase:first', '_phase:second']
.
-
Define a CLI flag parameter
--production
that is applicable to the commandbuild
and the phase_phase:first
. -
Configure
dependsOnEnvVars
inA/config/rush-project.json
for_phase:first
to includeTEST_VAR
. -
Configure
dependsOnAdditionalFiles
inA/config/rush-project.json
for_phase:first
to include../common/tmp.log
.
Observe that when running rush build
, the cache key for B (_phase:second)
is not affected by:
- The presence or absence of the
--production
flag. - Any change to the environment variable
TEST_VAR
. - Any change to the file
tmp.log
Details
The root issue here is that the cache key for an operation is computed based on the project dependencies, not the operation dependencies. Cache key for an operation should be a function of:
- The "configuration" of the operation, i.e. the npm script text, the CLI parameters, any configured environment variables, etc.
- The "local state" of the operation, i.e. the content hashes of all Git tracked files and any files identified by the
dependsOnAdditionalFiles
property, sorted deterministically. - The final computed cache keys of all operations upon which the operation depends, sorted deterministically.
Recommended approach to resolve this would be to store the cache key on OperationExecutionRecord
and compute all keys for all operations in the graph sometime between initialization of OperationExecutionManager
and beforeExecuteOperations
.