-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: re-structure the CodePipeline Construct library API #1590
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, would it be okay if I’d review this next week? I am traveling this week and won’t be able to dive deep.
There are few things that pop up from initial glance, but I’d like to take the time and provide a thorough feedback.
In the meantime, it will help if you provide some context and motivation behind this change in the PR description as well as a detailed list of changes for people to be able to migrate from the previous version. This library is heavily used and we should make sure the upgrade is not too painful.
Your title prefix should be changed to |
The changes are not limited to only the |
Updated the PR description, let me know if this is what you had in mind. |
Why not make the stage and action name a part of the props object instead of a separate parameter? This gives you the option to make the name an optional prop (and generate a name when omitted) in the future without breaking compatibility. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good. Definitely looks cleaner in certain areas.
Pre-bind References
There are a bunch of places that actions have public APIs that require that you first add the action to the stage before you can access them. Instead of making these properties optional, how about defining them as getters and throwing a runtime error in case people try to access them before the action has been added to the stage. This will at least not leak this implementation detail to the API, so that users don't have to constantly null-check when they use these properties.
Artifacts
I feel quite strongly about automatically wiring artifacts when it's clearly what the user would want. It's a pretty important design tenet that we try to maintain - don't ask the user to configure something if you can safely deduce it for them. This is even more important since the API for working with artifacts is clumsy and verbose, and the 90% use case it's basically pure boilerplate.
asCodePipelineAction
Generally asXxx
methods are reserved for internal inversion of control (and we plan to actually rename them to _asXxx
to indicate that). I am also wondering if this actually adds value since you will now need to add the action to a stage after you've retrieved it from the resource. Let's just get rid of these methods for now, and we can always add them later if we feel like they add value (the opposite will be a breaking change).
Rethinking about |
I'd guess it's more like 10% of use cases where wiring artifacts are boilerplate (e.g. there's a single artifact). As soon as you have two artifacts and add a new action, which artifact should you choose and why (it's not always the last produced artifact)? I'm happy to iterate on this more, but from a backward compatibility standpoint we can relax the "require artifacts to be wired up explicitly" later. Perhaps one way to address the "clumsy and verbose" is to introduce an artifact object? This would let you generate artifact names if not specified, use the IDE to rename references to the variable (in contrast to strings today) and give you an object to attach a method for path references (e.g. the CloudFormation action configuration references files in an artifact).
Or maybe createCodePipelineAction or newCodePipelineAction because it is a factory method? Finally, bumping this comment so it doesn't get lost: Why not make the stage and action name a part of the props object instead of a separate parameter? This gives you the option to make the name an optional prop (and generate a name when omitted) in the future without breaking compatibility. |
Sure, as you have more artifacts you'll need to be explicit, but as I mentioned, we have a design tenet to provide "smart defaults" and this falls exactly in that category. If 90% of our users will ask themselves "why do I need to specify this" than we should do the right thing for them. Since we already have this capability I am not sure why we want to make our APIs less useful as we iterate...
I remember you suggested this idea and I like it better than strings. It will still feel "clumsy and verbose" in my mind when those artifacts can easily be deduced from the context, but for the explicit case, yes! How would that work for when you specify the stages/actions upon pipeline creation? Would you need to define your artifact objects before?
See my followup comment. This seems like it's going to be a pattern (step functions are another example), and I am proposing maybe
Yeah, why not? |
This isn't solely a question of convenience. The current feature is potentially surprising and dangerous: I can accidentally publish source code instead of a compiled artifact or mistakenly deploy the wrong thing if I rearrange actions in my pipeline. I'd like to start by requiring artifacts to be wired up explicitly (so we trade "potentially surprising and dangerous" for "smart defaults" and get the breaking change out of the way) and then iterate on adding "smart defaults" for use cases where it's safe/makes sense.
I'm not opposed to We may want to include an optional props in the pattern. Example: users could use props to differentiate between instantiating a CodeBuild build or test action. |
Hard to argue when you pull out this card...
Absolutely. |
I think we want the same thing ("smart defaults") and it's mostly a question of whether we start with them or incrementally add them. Stage, action and artifact names are some other examples where we can generate "smart defaults" and let users override them. |
12f1576
to
739da9d
Compare
Iteration nr 2I just pushed the second iteration of the PR. Major changes are:
@aecollver and @eladb , I would appreciate another pass :). Thanks! |
739da9d
to
2aa4d1d
Compare
Iteration 3Just submitted the third iteration, with @eladb's suggestions:
@aecollver and @eladb , hopefully we're getting close :) |
2aa4d1d
to
b971a49
Compare
Rebased on top of newest |
Great stuff dude! |
b971a49
to
2a3dfb5
Compare
One last rebase (a conflict in the ReadMe file for CodeBuild). |
This Pull Request re-structures the API of the CodePipeline Construct library.
There are 2 fundamental changes that are made here:
All of the changes are the just consequences of the above 2 points.
As a side effect, because of the late-binding of the Stages / Actions, we can't really automatically infer the artifacts anymore. So, this changes the API to have the input artifacts to Action always be provided explicitly, same as PR #1389 does for the "old" API.
This contains like 30 BREAKING CHANGES.
Previous experience:
New experience:
Pull Request Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.