aws / aws/aws-cdk

aws-codepipeline-actions: CodeStarConnectionsSourceAction.variables inaccurate

Open
#31,000 3 comments 1 reaction 0 assignees View on GitHub
@aws-cdk/aws-codepipeline-actions bug effort/medium p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
2d 3h
Merged PRs (30d)
83

Description

### Describe the bug

If you try to use `CodeStarConnectionsSourceAction.variables.branchName` on an execution triggered by a pull request, your build will fail with:
> An action in this pipeline failed because one or more variables could not be resolved: Action name=XYZ. This can result when a variable is referenced that does not exist. Validate the configuration for this action.

### Detail

#5604 added a `.variables` getter to a number of `codepipeline.Action` subclasses including `CodeStarConnectionsSourceAction`. It's hardcoded to return a particular set of variables, and seems to be the only public way to get at the action's variables.

https://github.com/aws/aws-cdk/blob/9295a85a8fb893d7f5eae06108b68df864096c4c/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codestar-connections/source-action.ts#L119-L128

These variables are correct in some cases, but aren't correct if the execution was triggered by a pull request (see screenshots below.)

With a `pullRequestFilter` in place, `BranchName` will be unavailable, but four additional variables will be set: `DestinationBranchName`, `PullRequestId`, `PullRequestTitle`, `SourceBranchName`. There's no good way to get at these right now.

### Expected Behavior

One of the below:

a. `variables` should return the variables that the source action actually exports (likely impossible to implement at CDK level.)
b. `variables` should return only variables that are always safe to use. I'm not sure if there's a public spec indicating what variables are returned under what circumstances. But `BranchName` is not always defined by the source action and therefore isn't safe to us.

More importantly, since the CDK doesn't/can't know what the possible variables are, I'd expect the underlying `variableExpression(variableName: string)` should be publicly accessible, like it is on some of the other actions:
https://github.com/aws/aws-cdk/blob/9295a85a8fb893d7f5eae06108b68df864096c4c/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codebuild/build-action.ts#L145-L147

https://github.com/aws/aws-cdk/blob/9295a85a8fb893d7f5eae06108b68df864096c4c/packages/aws-cdk-lib/aws-codepipeline/lib/action.ts#L428-L431

### Current Behavior

The cdk-provided `variables` getter misses some variables and returns others that may not exist. It doesn't provide any way to get at the missing ones.

For missed variables, a workaround is to call the protected `variableExpression` method via `action["variableExpression"]("DestinationBranchName")` or similar.

For returned variables that don't exist (`BranchName`), workaround is not to use it.

### Reproduction Steps

Below is a construct that will reproduce the issue. Unfortunately, due to the way CodePipeline works, the minimal reproduction is not especially concise.

To use it, you'll need a CDK stack with a VPC and a CodeConnection to a git repo (I used a Github repo.)

Once you've got the stack deployed, open a pull request in the repo. It should trigger an execution. The `UsesBranchName` build action will fail, because the source action doesn't export the `BranchName` variable.

Now try manually triggering a execution with the "Release Change" button in the console. Here, the `UsesBranchName` build action will succeed, but the `UsesDestinationBranchName` will fail, because the `DestinationBranchName` won't have been defined (this will also happen when the pipeline is first created.)

Reproduction: https://gist.github.com/dleavitt/7950f5073bb0ebe2f3fa5049a2f44ab8

### Possible Solution

1. Add a public `variable(variableName: string): string` method to `CodeStarConnectionsSourceAction`, with the same implementation like this:
https://github.com/aws/aws-cdk/blob/9295a85a8fb893d7f5eae06108b68df864096c4c/packages/aws-cdk-lib/aws-codepipeline-actions/lib/codebuild/build-action.ts#L145-L147

Maybe add it directly to `Action` (or make `variableExpression` public) if there are other actions where the list of variables could be dynamic.

2. (breaking) Consider removing `BranchName` from `CodeStarConnectionsSourceAction.variables()`, since it's not always present and if missing attempting to use it will cause the build to fail.

### Additional Information/Context

From what I can tell, there's an underlying issue with the implementation of the CodeStarSourceConnection Action provider in CodePipeline. For a given pipeline and action:
- Different output variables will be available depending on how the build was triggered.
- There's no way for subsequent stages to determine what variables are available.
- Attempting to use a missing variable causes an unrecoverable failure of the pipeline.

Therefore the only variables that can be safely used are ones available in _all_ cases (which `BranchName` is not.)

I would love to be wrong about this, let me know if there's a workaround!

**Variables from a non-pr trigger**

![Screenshot 2024-07-31 at 17 18 50](https://github.com/user-attachments/assets/d40dbbe8-be7e-478d-8e91-62ec56dc441d)

**Variables from a pull request trigger**

![Screenshot 2024-07-31 at 17 19 09](https://github.com/user-attachments/assets/620f5450-e61f-4b47-a0f1-7e5d4155e146)

### CDK CLI Version

2.150.0 (build 3f93027)

### Framework Version

_No response_

### Node.js Version

v20.11.1

### OS

MacOS 14.3 (23D56)

### Language

TypeScript

### Language Version

Typescript (5.4.5)

### Other information

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with packages/aws-cdk-lib/aws-codepipeline-actions/lib/codestar-connections/source-action.ts and compare its variables getter with variableExpression in packages/aws-cdk-lib/aws-codepipeline-actions/lib/codebuild/build-action.ts and packages/aws-cdk-lib/aws-codepipeline/lib/action.ts. Use the linked reproduction to observe pull-request and manual executions. Done means the action exposes an appropriate way to reference available variables without advertising variables that are unavailable in a trigger context.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, typescript
Domain
cloud, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.