Description
The current change detection logic relies on a simple string startsWith check to determine if a Dockerfile is associated with a changed file. This causes unintended builds when one container directory name is a substring of another (e.g., shopify_general and shopify_general_v2).
If a change occurs in the longer directory name (_v2), the script incorrectly identifies the shorter directory as changed as well, resulting in unnecessary builds and deployments.
Reproduction Inputs Given the following directory structure:
Plaintext
containers/
├── shopify_general/
│ └── Dockerfile
└── shopify_general_v2/
└── Dockerfile
And the following inputs to the Action:
YAML
root-directory: containers/
changed-files: ["containers/shopify_general_v2/Dockerfile"]
Actual Behavior
The script queues both containers for build and deployment:
shopify_general_v2 (Correct)
shopify_general (Incorrect)
Root Cause Analysis
The issue lies in the main function's filtering logic:
const pipelines = matches
.filter((file) => {
const dirname = path.dirname(path.relative(root, file));
// THE BUG IS HERE:
return includesBy(relevantChanges, (change) => change.startsWith(dirname));
})
When evaluating the shopify_general/Dockerfile:
dirname resolves to shopify_general.
The relevantChanges set contains shopify_general_v2/Dockerfile.
The check 'shopify_general_v2/Dockerfile'.startsWith('shopify_general') evaluates to true.
Because the code does not enforce a directory separator (like /) after the dirname, the partial string match triggers a false positive.
Expected Behavior The script should only match directories that are exact parents of the changed files.
Input: shopify_general_v2/Dockerfile
Match: shopify_general_v2
No Match: shopify_general
Description
The current change detection logic relies on a simple string startsWith check to determine if a Dockerfile is associated with a changed file. This causes unintended builds when one container directory name is a substring of another (e.g., shopify_general and shopify_general_v2).
If a change occurs in the longer directory name (_v2), the script incorrectly identifies the shorter directory as changed as well, resulting in unnecessary builds and deployments.
Reproduction Inputs Given the following directory structure:
And the following inputs to the Action:
Actual Behavior
The script queues both containers for build and deployment:
shopify_general_v2 (Correct)
shopify_general (Incorrect)
Root Cause Analysis
The issue lies in the main function's filtering logic:
When evaluating the shopify_general/Dockerfile:
dirname resolves to shopify_general.
The relevantChanges set contains shopify_general_v2/Dockerfile.
The check 'shopify_general_v2/Dockerfile'.startsWith('shopify_general') evaluates to true.
Because the code does not enforce a directory separator (like /) after the dirname, the partial string match triggers a false positive.
Expected Behavior The script should only match directories that are exact parents of the changed files.
Input: shopify_general_v2/Dockerfile
Match: shopify_general_v2
No Match: shopify_general