Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 73 additions & 4 deletions pkg/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package build

import (
"context"
"encoding/json"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -289,11 +290,24 @@ func Build(_ context.Context, c *cli.Command) error {
}
}

err = writeOutputs(imageName, additionalTags, cacheTag)
if err != nil {
return cli.Exit(err, 1)
}

return nil
}

func writeOutputs(
imageName string,
additionalTags []string,
cacheTag string,
) error {
outputDirectory := os.TempDir() + "/3lv-cli-output"
if _, err := os.Stat(outputDirectory); os.IsNotExist(err) {
err := os.Mkdir(outputDirectory, 0o700)
if err != nil {
return cli.Exit(err, 1)
return err
}
}

Expand All @@ -307,13 +321,29 @@ func Build(_ context.Context, c *cli.Command) error {
return cacheTag
}()

imageNameWithTag := imageName + ":" + firstAdditionalTagThatsNotCacheTag

err := os.WriteFile(
outputDirectory+"/image-name-tag",
[]byte(imageNameWithTag),
0o700,
)
if err != nil {
return err
}

imageDigest, err := getImageDigest(imageNameWithTag)
if err != nil {
return err
}

err = os.WriteFile(
outputDirectory+"/image-name",
[]byte(imageName+":"+firstAdditionalTagThatsNotCacheTag),
outputDirectory+"/image-digest",
[]byte(imageDigest),
0o700,
)
if err != nil {
return cli.Exit(err, 1)
return err
}

return nil
Expand Down Expand Up @@ -479,3 +509,42 @@ func copyDockerfileToCurrentDirectory(dockerfilePath string, nonInteractive bool

return newDockerfilePath, nil
}

// Incomplete, since we only need digest.
type DockerManifest struct {
Descriptor struct {
Digest string `json:"digest"`
} `json:"Descriptor"`
}

func getImageDigest(imageNameWithTag string) (string, error) {
dockerManifestInspectCommand := dockerManifestInspectCommand(imageNameWithTag, nil)
if command.IsError(dockerManifestInspectCommand) {
return "", dockerManifestInspectCommand.Error
}

var manifest DockerManifest

err := json.Unmarshal([]byte(dockerManifestInspectCommand.Output), &manifest)
if err != nil {
return "", err
}

return manifest.Descriptor.Digest, nil
}

func dockerManifestInspectCommand(
imageNameWithTag string,
options *command.RunOptions,
) command.Output {
return command.Run(
*exec.Command(
"docker",
"manifest",
"inspect",
"-v",
imageNameWithTag,
),
options,
)
}
65 changes: 9 additions & 56 deletions pkg/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package deploy

import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"slices"
"strings"

"github.com/3lvia/cli/pkg/auth"
"github.com/3lvia/cli/pkg/build"
"github.com/3lvia/cli/pkg/command"
"github.com/3lvia/cli/pkg/shared"
"github.com/3lvia/cli/pkg/style"
Expand All @@ -35,6 +33,13 @@ func Command() *cli.Command {
Name: "image-tag",
Aliases: []string{"i"},
Usage: "The image tag to deploy.",
Sources: cli.EnvVars("3LV_IMAGE_TAG"),
},
&cli.StringFlag{
Name: "image-digest",
Aliases: []string{"I"},
Usage: "The image digest to deploy.",
Sources: cli.EnvVars("3LV_IMAGE_DIGEST"),
},
&cli.StringFlag{
Name: "environment",
Expand Down Expand Up @@ -200,8 +205,9 @@ func Deploy(ctx context.Context, c *cli.Command) error {

return configForApplication.HelmValuesFile
}()

imageTag := c.String("image-tag")
imageDigest := getImageDigest(systemName, applicationName, imageTag)
imageDigest := c.String("image-digest")

commitHash, err := utils.ResolveCommitHash(c.String("commit-hash"))
if err != nil {
Expand Down Expand Up @@ -432,56 +438,3 @@ func setupKubernetes(

return nil
}

func dockerManifestInspectCommand(
imageNameWithTag string,
runOptions *command.RunOptions,
) command.Output {
return command.Run(
*exec.Command(
"docker",
"manifest",
"inspect",
imageNameWithTag,
"-v",
),
runOptions,
)
}

// Incomplete, since we only need digest.
type DockerManifest struct {
Ref string `json:"Ref"`
Descriptor struct {
Digest string `json:"digest"`
} `json:"Descriptor"`
}

func getImageDigest(
systemName string,
applicationName string,
imageTag string,
) string {
imageName, err := build.GetImageName(
build.DefaultElviaContainerRegistry,
systemName,
applicationName,
)
if err != nil {
return ""
}

dockerManifestInspectCommand := dockerManifestInspectCommand(imageName+":"+imageTag, nil)
if command.IsError(dockerManifestInspectCommand) {
return ""
}

var manifest DockerManifest

err = json.Unmarshal([]byte(dockerManifestInspectCommand.Output), &manifest)
if err != nil {
return ""
}

return manifest.Descriptor.Digest
}
37 changes: 0 additions & 37 deletions pkg/deploy/deploy_test.go

This file was deleted.

10 changes: 5 additions & 5 deletions pkg/deploy/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func TestHelmDeployCommand1(t *testing.T) {
)
}

func TestHelmDeployCommand2(t *testing.T) {
func TestHelmDeployCommandWithDigestAndStatefulSet(t *testing.T) {
t.Parallel()

const (
Expand Down Expand Up @@ -217,7 +217,7 @@ func TestHelmDeployCommand2(t *testing.T) {
)
}

func TestHelmDeployCommand3(t *testing.T) {
func TestHelmDeployCommandWithInvalidWorkloadType(t *testing.T) {
t.Parallel()

const (
Expand Down Expand Up @@ -252,7 +252,7 @@ func TestHelmDeployCommand3(t *testing.T) {
}
}

func TestHelmDeployCommand4(t *testing.T) {
func TestHelmDeployCommandWithIssRepository(t *testing.T) {
t.Parallel()

const (
Expand Down Expand Up @@ -313,7 +313,7 @@ func TestHelmDeployCommand4(t *testing.T) {
)
}

func TestHelmDeployCommand5(t *testing.T) {
func TestHelmDeployCommandWithDigestAndStatefulSetAndIssRepository(t *testing.T) {
t.Parallel()

const (
Expand All @@ -322,7 +322,7 @@ func TestHelmDeployCommand5(t *testing.T) {
applicationName = "demo-api"
environment = "prod"
workloadType = "statefulset"
imageTag = "v420"
imageTag = ""
imageDigest = "sha256:abcdef"
repositoryName = "iss-demo-api"
commitHash = "abcdef"
Expand Down
2 changes: 1 addition & 1 deletion setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: 'Setup 3lv'
description: 'Sets up the Elvia CLI on your GitHub Actions runner.'
inputs:
version:
description: 'The version of 3lv to install. Specify `git` to build and install the latest version from the default branch.'
description: 'The version of 3lv to install. Specify a branch name to build and install from git.'
required: false
default: 'latest'

Expand Down
2 changes: 1 addition & 1 deletion tests/deploy/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test_disabled_deploy() {
if 3lv deploy \
-s core \
-f tests/deploy/values.yml \
-i latest-cache \
-i containerregistryelvia.azurecr.io/core-demo-api:latest-cache \
demo-api; then
echo "Should fail since CI is not set"
exit 1
Expand Down
Loading