Skip to content

Commit 2bb0648

Browse files
committed
Init: Support Push-Only Re-Tagging and Source Image Override in Drone Buildx Plugins
1 parent 52d1f01 commit 2bb0648

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

app.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,14 @@ func Run() {
417417
},
418418
cli.BoolFlag{
419419
Name: "push-only",
420-
Usage: "push only mode, skips build process",
420+
Usage: "skip build and only push images",
421421
EnvVar: "PLUGIN_PUSH_ONLY",
422422
},
423+
cli.StringFlag{
424+
Name: "source-image",
425+
Usage: "source image to tag and push (format: repo:tag)",
426+
EnvVar: "PLUGIN_SOURCE_IMAGE",
427+
},
423428
cli.StringFlag{
424429
Name: "source-tar-path",
425430
Usage: "path to Docker image tar file to load and push",
@@ -526,6 +531,7 @@ func run(c *cli.Context) error {
526531
BaseImageUsername: c.String("docker.baseimageusername"),
527532
BaseImagePassword: c.String("docker.baseimagepassword"),
528533
PushOnly: c.Bool("push-only"),
534+
SourceImage: c.String("source-image"),
529535
SourceTarPath: c.String("source-tar-path"),
530536
TarPath: c.String("tar-path"),
531537
}

docker.go

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ type (
115115
PushOnly bool // Push only mode, skips build process
116116
SourceTarPath string // Path to Docker image tar file to load and push
117117
TarPath string // Path to save Docker image as tar file
118+
SourceImage string // Source image to push (optional)
118119
}
119120

120121
Card []struct {
@@ -1002,12 +1003,72 @@ func (p Plugin) pushOnly() error {
10021003
}
10031004
}
10041005

1005-
// For each tag, verify image exists and push
1006+
// Check if source image is specified
1007+
sourceImageName := p.SourceImage
1008+
var sourceTags []string
1009+
1010+
if sourceImageName == "" {
1011+
// If no source image specified, use the repo (original behavior)
1012+
sourceImageName = p.Build.Repo
1013+
sourceTags = p.Build.Tags
1014+
} else {
1015+
// If source image is specified, check if it has a tag
1016+
parts := strings.Split(sourceImageName, ":")
1017+
if len(parts) > 1 {
1018+
sourceImageName = parts[0]
1019+
sourceTags = []string{parts[1]}
1020+
} else {
1021+
// Default to "latest" if no tag specified
1022+
sourceTags = []string{"latest"}
1023+
}
1024+
fmt.Printf("Using source image: %s with tag(s): %s\n", sourceImageName, strings.Join(sourceTags, ", "))
1025+
}
1026+
1027+
// For each source tag and target tag combination
10061028
var digest string
1029+
taggedForPush := make(map[string]bool)
1030+
1031+
for _, sourceTag := range sourceTags {
1032+
sourceFullImageName := fmt.Sprintf("%s:%s", sourceImageName, sourceTag)
1033+
1034+
// Check if the source image exists in local daemon
1035+
if !imageExists(sourceFullImageName) {
1036+
fmt.Printf("Warning: Source image %s not found\n", sourceFullImageName)
1037+
// Continue to the next source tag if available, otherwise return error
1038+
if len(sourceTags) > 1 {
1039+
continue
1040+
}
1041+
return fmt.Errorf("source image %s not found, cannot push", sourceFullImageName)
1042+
}
1043+
1044+
// For each target tag, tag and push
1045+
for _, targetTag := range p.Build.Tags {
1046+
targetFullImageName := fmt.Sprintf("%s:%s", p.Build.Repo, targetTag)
1047+
1048+
// Skip if source and target are identical
1049+
if sourceFullImageName == targetFullImageName {
1050+
fmt.Printf("Source and target image names are identical: %s\n", sourceFullImageName)
1051+
} else {
1052+
// Tag the source image with the target name
1053+
fmt.Printf("Tagging %s as %s\n", sourceFullImageName, targetFullImageName)
1054+
tagCmd := commandTag(Build{Name: sourceFullImageName}, targetFullImageName)
1055+
tagCmd.Stdout = os.Stdout
1056+
tagCmd.Stderr = os.Stderr
1057+
trace(tagCmd)
1058+
if err := tagCmd.Run(); err != nil {
1059+
return fmt.Errorf("failed to tag image %s as %s: %w", sourceFullImageName, targetFullImageName, err)
1060+
}
1061+
}
1062+
1063+
taggedForPush[targetFullImageName] = true
1064+
}
1065+
}
1066+
1067+
// Push all successfully tagged images
10071068
for _, tag := range p.Build.Tags {
10081069
fullImageName := fmt.Sprintf("%s:%s", p.Build.Repo, tag)
10091070

1010-
// Check if image exists in local daemon
1071+
// Verify the image exists (it should since we just tagged it)
10111072
if !imageExists(fullImageName) {
10121073
return fmt.Errorf("image %s not found, cannot push", fullImageName)
10131074
}

0 commit comments

Comments
 (0)