func CreatePublish(sourceVersion, publishVersion, workProject, publishProject, sourceGCS, sourceProject, ce, path string, varMap map[string]string, imagesCache map[string][]*computeAlpha.Image) (*Publish, error) {
	p := Publish{
		sourceVersion:  sourceVersion,
		publishVersion: publishVersion,
	}
	if p.publishVersion == "" {
		p.publishVersion = sourceVersion
	}
	varMap["source_version"] = p.sourceVersion
	varMap["publish_version"] = p.publishVersion
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("%s: %v", path, err)
	}
	tmpl, err := publishTemplate.Parse(string(b))
	if err != nil {
		return nil, fmt.Errorf("%s: %v", path, err)
	}
	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, varMap); err != nil {
		return nil, fmt.Errorf("%s: %v", path, err)
	}
	if err := json.Unmarshal(buf.Bytes(), &p); err != nil {
		return nil, daisy.JSONError(path, buf.Bytes(), err)
	}
	if err := p.SetExpire(); err != nil {
		return nil, fmt.Errorf("%s: error SetExpire: %v", path, err)
	}
	if workProject != "" {
		p.WorkProject = workProject
	}
	if publishProject != "" {
		p.PublishProject = publishProject
	}
	if sourceGCS != "" {
		p.SourceGCSPath = sourceGCS
	}
	if sourceProject != "" {
		p.SourceProject = sourceProject
	}
	if ce != "" {
		p.ComputeEndpoint = ce
	}
	if imagesCache != nil {
		p.imagesCache = imagesCache
	}
	if p.WorkProject == "" {
		if metadata.OnGCE() {
			p.WorkProject, err = metadata.ProjectID()
			if err != nil {
				return nil, err
			}
		} else {
			return nil, fmt.Errorf("%s: WorkProject unspecified", path)
		}
	}
	fmt.Printf("[%q] Created a publish object successfully from %s\n", p.Name, path)
	return &p, nil
}
CreatePublish creates a publish object
package publish
import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"path"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"text/template"
	"time"
	"cloud.google.com/go/compute/metadata"
	"github.com/GoogleCloudPlatform/compute-image-tools/daisy"
	daisyCompute "github.com/GoogleCloudPlatform/compute-image-tools/daisy/compute"
	computeAlpha "google.golang.org/api/compute/v0.alpha"
	"google.golang.org/api/compute/v1"
	"google.golang.org/api/option"
)
type Publish struct {
	Name string `json:",omitempty"`
	WorkProject string `json:",omitempty"`
	SourceProject string `json:",omitempty"`
	SourceGCSPath string `json:",omitempty"`
	PublishProject string `json:",omitempty"`
	ComputeEndpoint string `json:",omitempty"`
	DeleteAfter string `json:",omitempty"`
	expiryDate  *time.Time
	Images []*Image `json:",omitempty"`
	sourceVersion string
	publishVersion string
	toCreate      []string
	toDelete      []string
	toDeprecate   []string
	toObsolete    []string
	toUndeprecate []string
	rolloutPolicy []string
	imagesCache map[string][]*computeAlpha.Image
}
type Image struct {
	Prefix string `json:",omitempty"`
	Family string `json:",omitempty"`
	Description string `json:",omitempty"`
	Licenses []string `json:",omitempty"`
	GuestOsFeatures []string `json:",omitempty"`
	IgnoreLicenseValidationIfForbidden bool `json:",omitempty"`
	ObsoleteDate *time.Time `json:",omitempty"`
	ShieldedInstanceInitialState *computeAlpha.InitialStateConfig `json:",omitempty"`
	RolloutPolicy *computeAlpha.RolloutPolicy `json:",omitempty"`
}
var (
	funcMap = template.FuncMap{
		"trim":       strings.Trim,
		"trimPrefix": strings.TrimPrefix,
		"trimSuffix": strings.TrimSuffix,
	}
	publishTemplate = template.New("publishTemplate").Option("missingkey=zero").Funcs(funcMap)
)