blob: 8e72b170dc58de69aa2eb32598811775d7e7abd5 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package main
import (
var cmdYaml = &subcommands.Command{
UsageLine: "yaml [...]",
ShortDesc: "deploys one or more deployable GAE YAML (e.g. dispatch.yaml)",
LongDesc: `Deploys one or more deployable GAE YAML (e.g. dispatch.yaml).
Fetches and unpacks the tarball, then simply calls:
gcloud app deploy --project <app-id> [list of deployable yamls]
Where paths to deployable YAMLs are provided via repeated "-deployable-yaml"
flag. Only specified YAMLs will be deployed.
CommandRun: func() subcommands.CommandRun {
c := &cmdYamlRun{}
return c
type cmdYamlRun struct {
deployableYaml stringlistflag.Flag // -deployable-yaml flag, required
func (c *cmdYamlRun) init() {
c.commandBase.init(c.exec, extraFlags{
appID: true,
tarball: true,
cacheDir: true,
dryRun: true,
c.Flags.Var(&c.deployableYaml, "deployable-yaml", "Path within the tarball to a YAML to deploy (can be repeated multiple times).")
func (c *cmdYamlRun) exec(ctx context.Context) error {
if len(c.deployableYaml) == 0 {
return errBadFlag("-deployable-yaml", "a value is required")
// Scope this command only to non-module YAMLs. There's a separate command
// for modules. They are significantly different.
allowedYAMLs := stringset.NewFromSlice(
for _, p := range c.deployableYaml {
if !allowedYAMLs.Has(filepath.Base(p)) {
return errBadFlag("-deployable-yaml", fmt.Sprintf("%s is not a valid target", p))
logging.Infof(ctx, "App ID: %s", c.appID)
logging.Infof(ctx, "Tarball: %s", c.tarballSource)
logging.Infof(ctx, "Cache: %s", c.cache.Root)
logging.Infof(ctx, "YAML(s): %s", c.deployableYaml)
return c.cache.WithTarball(ctx, c.source, func(path string) error {
for _, localPath := range c.deployableYaml {
if _, err := os.Stat(filepath.Join(path, localPath)); err != nil {
return errors.Annotate(err, "bad YAML file %q", localPath).Err()
return gcloud.Run(ctx, append([]string{
"app", "deploy",
"--project", c.appID,
"--quiet", // disable interactive prompts
}, c.deployableYaml...), path, nil, c.dryRun)