Skip to content

Commit

Permalink
Fix breaking change in imageUri output of ecr.Image (#1467)
Browse files Browse the repository at this point in the history
  • Loading branch information
flostadler authored Jan 8, 2025
1 parent bd4fe97 commit d20e16a
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
55 changes: 55 additions & 0 deletions awsx/ecr/image.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2016-2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { removeTagFromRef } from "./image";

describe("removeTagFromRef", () => {
it("should remove tag from standard ECR image reference", () => {
const input =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/repository-29552ef:7a3c38f0-container@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
const expected =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/repository-29552ef@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
expect(removeTagFromRef(input)).toBe(expected);
});

it("should handle ECR references with nested repository paths", () => {
const input =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/team/project/service:v1.0.0@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
const expected =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/team/project/service@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
expect(removeTagFromRef(input)).toBe(expected);
});

it("should handle complex but valid tag names", () => {
const input =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo:1.0.0-alpha.1_build-123@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
const expected =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
expect(removeTagFromRef(input)).toBe(expected);
});

it("should return original string if no tag is present", () => {
const input =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/my-repo@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
expect(removeTagFromRef(input)).toBe(input);
});

it("should handle repository names with underscores and hyphens", () => {
const input =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/my_repo-name:latest@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
const expected =
"123456789012.dkr.ecr.us-west-2.amazonaws.com/my_repo-name@sha256:ccf572fa3e9a9b9316761f749c3020c5748e1c47052e5781eec04e0a53954428";
expect(removeTagFromRef(input)).toBe(expected);
});
});
19 changes: 18 additions & 1 deletion awsx/ecr/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export function computeImageFromAsset(
pulumi.log.debug(` build complete: ${ref}`, parent);
});

return image.ref;
// Return the image reference without the tag. This is necessary for backwards compatibility with earlier versions of the awsx provider
// that used pulumi-docker and in order to allow passing this output to Lambda functions (they expect an image URI without a tag).
return image.ref.apply(removeTagFromRef);
}

function createUniqueImageName(inputs: pulumi.Unwrap<schema.DockerBuildInputs>): string {
Expand All @@ -128,3 +130,18 @@ function createUniqueImageName(inputs: pulumi.Unwrap<schema.DockerBuildInputs>):
buildSig += pulumi.getStack();
return `${utils.sha1hash(buildSig)}-container`;
}

/**
* Removes the tag from the image reference.
* @param ref The image reference to remove the tag from.
* @returns The image reference without the tag.
*/
export function removeTagFromRef(ref: string): string {
// Match pattern: everything up to the tag, the tag itself, and the digest
// The image ref looks like this: ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/REPOSITORY_NAME:TAG_NAME@sha256:1234567890123456789012345678901234567890123456789012345678901234
// Neither repository name nor tag name can contain a colon, so we can safely split on the colon and take the first part.
const pattern = /^(.*):([^@]+)(@sha256:.+)$/;

// If the pattern is found, return the image without the tag. I.e. only the image name and digest.
return ref.replace(pattern, "$1$3");
}
4 changes: 4 additions & 0 deletions examples/examples_nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,10 @@ func TestDockerUpgrade(t *testing.T) {
updatedImageUri := result.Outputs["image"].Value.(string)
require.NotEmpty(t, updatedImageUri, "imageUri should not be empty")

originalImage := strings.Split(originalImageUri, "@sha256:")[0]
updatedImage := strings.Split(updatedImageUri, "@sha256:")[0]
require.Equal(t, originalImage, updatedImage, "original and updated image should be the same")

require.Contains(t, result.Outputs, "repositoryName", "repositoryName should be in the outputs")
repoName := result.Outputs["repositoryName"].Value.(string)
require.NotEmpty(t, repoName, "repositoryName should not be empty")
Expand Down

0 comments on commit d20e16a

Please sign in to comment.