func (d *DeployAgent) Push() error {
	return d.agent.PushImage(fmt.Sprintf("%s:%s", d.imageRepo, d.tag))
}
Push pushes a local image to the remote repository linked in the release
package deploy
import (
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"github.com/porter-dev/porter/api/client"
	"github.com/porter-dev/porter/api/types"
	"github.com/porter-dev/porter/cli/cmd/docker"
	"github.com/porter-dev/porter/cli/cmd/github"
	"github.com/porter-dev/porter/internal/templater/utils"
	"k8s.io/client-go/util/homedir"
)
type DeployBuildType string
const (
	DeployBuildTypeDocker DeployBuildType = "docker"
	DeployBuildTypePack DeployBuildType = "pack"
)
type DeployAgent struct {
	App string
	client         *client.Client
	release        *types.GetReleaseResponse
	agent          *docker.Agent
	opts           *DeployOpts
	tag            string
	envPrefix      string
	env            map[string]string
	imageExists    bool
	imageRepo      string
	dockerfilePath string
}
type DeployOpts struct {
	*SharedOpts
	Local bool
}
func NewDeployAgent(client *client.Client, app string, opts *DeployOpts) (*DeployAgent, error) {
	deployAgent := &DeployAgent{
		App:    app,
		opts:   opts,
		client: client,
		env:    make(map[string]string),
	}
	release, err := client.GetRelease(context.TODO(), opts.ProjectID, opts.ClusterID, opts.Namespace, app)
	if err != nil {
		return nil, err
	}
	deployAgent.release = release
	deployAgent.envPrefix = fmt.Sprintf("PORTER_%s", strings.Replace(
		strings.ToUpper(app), "-", "_", -1,
	))
	agent, err := docker.NewAgentWithAuthGetter(client, opts.ProjectID)
	if err != nil {
		return nil, err
	}
	deployAgent.agent = agent
	if opts.Method == "" {
		if release.GitActionConfig != nil {
			if release.GitActionConfig.DockerfilePath != "" {
				deployAgent.opts.Method = DeployBuildTypeDocker
			} else {
				deployAgent.opts.Method = DeployBuildTypePack
			}
		} else {
			deployAgent.opts.Method = DeployBuildTypeDocker
		}
	}
	if deployAgent.opts.Method == DeployBuildTypeDocker {
		if release.GitActionConfig != nil {
			deployAgent.dockerfilePath = release.GitActionConfig.DockerfilePath
		}
		if deployAgent.opts.LocalDockerfile != "" {
			deployAgent.dockerfilePath = deployAgent.opts.LocalDockerfile
		}
		if deployAgent.dockerfilePath == "" && deployAgent.opts.LocalDockerfile == "" {
			deployAgent.dockerfilePath = "./Dockerfile"
		}
	}
	if release.GitActionConfig == nil {
		deployAgent.opts.Local = true
		imageRepo, err := deployAgent.getReleaseImage()
		if err != nil {
			return nil, err
		}
		deployAgent.imageRepo = imageRepo
		deployAgent.dockerfilePath = deployAgent.opts.LocalDockerfile
	} else {
		deployAgent.imageRepo = release.GitActionConfig.ImageRepoURI
		deployAgent.opts.LocalPath = release.GitActionConfig.FolderPath
	}
	deployAgent.tag = opts.OverrideTag
	return deployAgent, nil
}
func (d *DeployAgent) GetBuildEnv() (map[string]string, error) {
	return GetEnvFromConfig(d.release.Config)
}
func (d *DeployAgent) SetBuildEnv(envVars map[string]string) error {
	d.env = envVars
	for key, val := range envVars {
		prefixedKey := fmt.Sprintf("%s_%s", d.envPrefix, key)
		err := os.Setenv(prefixedKey, val)
		if err != nil {
			return err
		}
	}
	return nil
}
func (d *DeployAgent) WriteBuildEnv(fileDest string) error {
	lines := make([]string, 0)
	for _, line := range os.Environ() {
		if strings.Contains(line, d.envPrefix+"_") {
			lines = append(lines, strings.Split(line, d.envPrefix+"_")[1])
		}
	}
	output := strings.Join(lines, "\n")
	if fileDest != "" {
		ioutil.WriteFile(fileDest, []byte(output), 0700)
	} else {
		fmt.Println(output)
	}
	return nil
}
func (d *DeployAgent) Build() error {
	var basePath string
	buildCtx := d.opts.LocalPath
	var err error
	if !d.opts.Local {
		repoSplit := strings.Split(d.release.GitActionConfig.GitRepo, "/")
		if len(repoSplit) != 2 {
			return fmt.Errorf("invalid formatting of repo name")
		}
		zipResp, err := d.client.GetRepoZIPDownloadURL(
			context.Background(),
			d.opts.ProjectID,
			int64(d.release.GitActionConfig.GitRepoID),
			"github",
			repoSplit[0],
			repoSplit[1],
			d.release.GitActionConfig.GitBranch,
		)
		if err != nil {
			return err
		}
		basePath, err = d.downloadRepoToDir(zipResp.URLString)
		if err != nil {
			return err
		}
		if d.tag == "" {
			shortRef := fmt.Sprintf("%.7s", zipResp.LatestCommitSHA)
			d.tag = shortRef
		}
	} else {
		basePath, err = filepath.Abs(".")
		if err != nil {
			return err
		}
	}
	if d.tag == "" {
		currImageSection := d.release.Config["image"].(map[string]interface{})
		d.tag = currImageSection["tag"].(string)
	}
	err = d.pullCurrentReleaseImage()
	buildAgent := &BuildAgent{
		SharedOpts:  d.opts.SharedOpts,
		client:      d.client,
		imageRepo:   d.imageRepo,
		env:         d.env,
		imageExists: d.imageExists,
	}
	if err != nil && err != docker.PullImageErrNotFound {
		return err
	} else if err != nil && err == docker.PullImageErrNotFound {
		fmt.Println("could not find image, moving to build step")
		d.imageExists = false
	}
	if d.opts.Method == DeployBuildTypeDocker {
		return buildAgent.BuildDocker(
			d.agent,
			basePath,
			buildCtx,
			d.dockerfilePath,
			d.tag,
		)
	}
	return buildAgent.BuildPack(d.agent, buildCtx, d.tag)
}