-
Notifications
You must be signed in to change notification settings - Fork 4.4k
(pipelines): additionalinputs cannot mount deep directory #16936
Description
What is the problem?
As part of a CodePipeline, if I specify an additional input that should be placed somewhere within the primary input tree, that input appears within another directory inside the directory that it should be in.
As an example, with this configuration:
pipeline = pipelines.CodePipeline(
[...]
synth=pipelines.CodeBuildStep(
"Synth",
input=source,
additional_inputs={"./web/dist": frontend_build},
)
)I would expect the files from frontend_build to appear inside web/dist/ in the tree. However, in fact they appear under web/dist/01/.
I have determined the cause, and it is here (this isn't the commit that added the bug, just a recent permalink):
if (!['.', '..'].includes(path.dirname(input.directory))) {
fragments.push(`mkdir -p -- "${input.directory}"`);
}That is: if the additional input should be placed anywhere other than one directory away from the build root (in my example it is two away), then that directory is created first. But now the subsequent behaviour of ln -s ... changes:
ln -s -- source destwill place source at dest if it doesn't exist, but in dest if it does.
The solution is straightforward: just drop one directory from the mkdir call:
fragments.push(`mkdir -p -- "${path.dirname(input.directory)}"`);Reproduction Steps
A simple minimal reproducible bit of code is difficult to produce with pipelines due to the nature of the sources. Assuming you have a bootstrapped environment and a standard cdk.json file, put this into app.py, add any source entity that you have access to where noted, and deploy. The pipeline will fail in its Synth step because I'm not creating a cdk.out directory, but the log output of that step should show that file_from_src2 is in web/dist/01/ rather than web/dist/ where it should be.
from aws_cdk import (
core as cdk,
pipelines,
)
class PipelineStack(cdk.Stack):
def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
source1 = pipelines.CodePipelineSource.<some source>
source2 = pipelines.ShellStep(
"src2",
commands=[
"touch file_from_src2",
],
primary_output_directory=".",
)
pipelines.CodePipeline(
self,
"MyPipeline",
synth=pipelines.ShellStep(
"Synth",
input=source1,
additional_inputs={"web/dist": source2},
commands=[
f"find web",
],
),
)
pipeline_app = cdk.App()
PipelineStack(pipeline_app, "PipelineStack2")
pipeline_app.synth()What did you expect to happen?
I expect the files from the additional inputs to appear directly in the directory that I have configured.
What actually happened?
The files from the additional inputs appear in a directory 01/ inside the directory that I have configured (I assume if more than one additional input is configured, subsequent ones will go to 02/, 03/, etc).
CDK CLI Version
1.126.0 (build f004e1a)
Framework Version
1.126
Node.js Version
v16.10.0
OS
Debian Linux
Language
Python
Language Version
3.8.12
Other information
See above for suggested fix.