• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

astronomer / astro-cli / 06dfac41-e870-4621-b93a-ad7f46b90b80

21 Oct 2025 06:42AM UTC coverage: 38.506% (-0.008%) from 38.514%
06dfac41-e870-4621-b93a-ad7f46b90b80

Pull #1964

circleci

neel-astro
Add wait time flag instead of hardcoded timeouts
Pull Request #1964: Add wait time flag instead of hardcoded timeouts

25 of 35 new or added lines in 7 files covered. (71.43%)

2 existing lines in 1 file now uncovered.

24132 of 62670 relevant lines covered (38.51%)

10.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/cmd/cloud/deploy.go
1
package cloud
2

3
import (
4
        "fmt"
5
        "time"
6

7
        cloud "github.com/astronomer/astro-cli/cloud/deploy"
8
        "github.com/astronomer/astro-cli/cmd/utils"
9
        "github.com/astronomer/astro-cli/config"
10
        "github.com/astronomer/astro-cli/pkg/git"
11
        "github.com/astronomer/astro-cli/pkg/util"
12
        "github.com/pkg/errors"
13
        "github.com/spf13/cobra"
14
)
15

16
var (
17
        forceDeploy       bool
18
        forcePrompt       bool
19
        saveDeployConfig  bool
20
        pytest            bool
21
        parse             bool
22
        dags              bool
23
        waitForDeploy     bool
24
        waitTime          time.Duration
25
        image             bool
26
        dagsPath          string
27
        pytestFile        string
28
        envFile           string
29
        imageName         string
30
        deploymentName    string
31
        deployDescription string
32
        deployExample     = `
33
Specify the ID of the Deployment on Astronomer you would like to deploy this project to:
34

35
  $ astro deploy <deployment ID>
36

37
Menu will be presented if you do not specify a deployment ID:
38

39
  $ astro deploy
40
`
41

42
        DeployImage      = cloud.Deploy
43
        EnsureProjectDir = utils.EnsureProjectDir
44
        buildSecrets     = []string{}
45
)
46

47
const (
48
        registryUncommitedChangesMsg = "Project directory has uncommitted changes, use `astro deploy [deployment-id] -f` to force deploy."
49

50
        deployWaitTime = 300 * time.Second
51
)
52

53
func NewDeployCmd() *cobra.Command {
13✔
54
        cmd := &cobra.Command{
13✔
55
                Use:     "deploy DEPLOYMENT-ID",
13✔
56
                Short:   "Deploy your project to a Deployment on Astro",
13✔
57
                Long:    "Deploy your project to a Deployment on Astro. This command bundles your project files into a Docker image and pushes that Docker image to Astronomer. In Deployments with Remote Execution enabled, this only updates the Orchestration Plane components (the API Server and Scheduler). For all other components, use `astro remote deploy` instead. It does not include any metadata associated with your local Airflow environment.",
13✔
58
                Args:    cobra.MaximumNArgs(1),
13✔
59
                PreRunE: EnsureProjectDir,
13✔
60
                RunE:    deploy,
13✔
61
                Example: deployExample,
13✔
62
        }
13✔
63
        cmd.Flags().BoolVarP(&forceDeploy, "force", "f", false, "Force deploy even if project contains errors or uncommitted changes")
13✔
64
        cmd.Flags().BoolVarP(&forcePrompt, "prompt", "p", false, "Force prompt to choose target deployment")
13✔
65
        cmd.Flags().BoolVarP(&saveDeployConfig, "save", "s", false, "Save deployment in config for future deploys")
13✔
66
        cmd.Flags().StringVar(&workspaceID, "workspace-id", "", "Workspace for your Deployment")
13✔
67
        cmd.Flags().BoolVar(&pytest, "pytest", false, "Deploy code to Astro only if the specified Pytests are passed")
13✔
68
        cmd.Flags().StringVarP(&envFile, "env", "e", ".env", "Location of file containing environment variables for Pytests")
13✔
69
        cmd.Flags().StringVarP(&pytestFile, "test", "t", "", "Location of Pytests or specific Pytest file. All Pytest files must be located in the tests directory")
13✔
70
        cmd.Flags().StringVarP(&imageName, "image-name", "i", "", "Name of a custom image to deploy, or image name with custom tag when used with --client")
13✔
71
        cmd.Flags().BoolVarP(&dags, "dags", "d", false, "Push only DAGs to your Astro Deployment")
13✔
72
        cmd.Flags().BoolVarP(&image, "image", "", false, "Push only an image to your Astro Deployment. If you have DAG Deploy enabled your DAGs will not be affected.")
13✔
73
        cmd.Flags().StringVar(&dagsPath, "dags-path", "", "If set deploy dags from this path instead of the dags from working directory")
13✔
74
        cmd.Flags().StringVarP(&deploymentName, "deployment-name", "n", "", "Name of the deployment to deploy to")
13✔
75
        cmd.Flags().BoolVar(&parse, "parse", false, "Succeed only if all DAGs in your Astro project parse without errors")
13✔
76
        cmd.Flags().BoolVarP(&waitForDeploy, "wait", "w", false, "Wait for the Deployment to become healthy before ending the command")
13✔
77
        cmd.Flags().DurationVar(&waitTime, "wait-time", deployWaitTime, "Wait time for the Deployment to become healthy before ending the command. Can only be used with --wait=true")
13✔
78
        cmd.Flags().MarkHidden("dags-path") //nolint:errcheck
13✔
79
        cmd.Flags().StringVarP(&deployDescription, "description", "", "", "Add a description for more context on this deploy")
13✔
80
        cmd.Flags().StringSliceVar(&buildSecrets, "build-secrets", []string{}, "Mimics docker build --secret flag. See https://docs.docker.com/build/building/secrets/ for more information. Example input id=mysecret,src=secrets.txt")
13✔
81
        cmd.Flags().Bool("force-upgrade-to-af3", false, "This flag is no longer required for Airflow 2 to Airflow 3 upgrades. Support will be removed in a future release.")
13✔
82
        cmd.Flags().MarkDeprecated("force-upgrade-to-af3", "this flag is no longer required for Airflow 2 to Airflow 3 upgrades. Support will be removed in a future release.") //nolint:errcheck
13✔
83
        return cmd
13✔
84
}
13✔
85

86
func deployTests(parse, pytest, forceDeploy bool, pytestFile string) string {
10✔
87
        if pytest && pytestFile == "" {
15✔
88
                pytestFile = "all-tests"
5✔
89
        }
5✔
90

91
        if !parse && !pytest && !forceDeploy || parse && !pytest && !forceDeploy || parse && !pytest && forceDeploy {
13✔
92
                pytestFile = "parse"
3✔
93
        }
3✔
94

95
        if parse && pytest {
13✔
96
                pytestFile = "parse-and-all-tests"
3✔
97
        }
3✔
98

99
        return pytestFile
10✔
100
}
101

102
func deploy(cmd *cobra.Command, args []string) error {
12✔
103
        deploymentID = ""
12✔
104

12✔
105
        // Get deploymentId from args, if passed
12✔
106
        if len(args) > 0 {
23✔
107
                deploymentID = args[0]
11✔
108
        }
11✔
109

110
        if cmd.Flags().Changed("wait-time") && !waitForDeploy {
12✔
NEW
111
                return errors.New("cannot use --wait-time with --wait=false")
×
NEW
112
        }
×
113

114
        if deploymentID == "" || forcePrompt || workspaceID == "" {
24✔
115
                var err error
12✔
116
                workspaceID, err = coalesceWorkspace()
12✔
117
                if err != nil {
12✔
118
                        return errors.Wrap(err, "failed to find a valid workspace")
×
119
                }
×
120
        }
121

122
        if dags && image {
12✔
123
                return errors.New("cannot use both --dags and --image together. Run 'astro deploy' to update both your image and dags")
×
124
        }
×
125

126
        // Save deploymentId in config if specified
127
        if deploymentID != "" && saveDeployConfig {
13✔
128
                err := config.CFG.ProjectDeployment.SetProjectString(deploymentID)
1✔
129
                if err != nil {
1✔
130
                        return nil
×
131
                }
×
132
        }
133

134
        if git.HasUncommittedChanges("") && !forceDeploy {
12✔
135
                fmt.Println(registryUncommitedChangesMsg)
×
136
                return nil
×
137
        }
×
138

139
        // case for astro deploy --dags whose default operation should be not running any tests
140
        if dags && !parse && !pytest {
14✔
141
                pytestFile = ""
2✔
142
        } else {
12✔
143
                pytestFile = deployTests(parse, pytest, forceDeploy, pytestFile)
10✔
144
        }
10✔
145

146
        // Silence Usage as we have now validated command input
147
        cmd.SilenceUsage = true
12✔
148

12✔
149
        BuildSecretString := util.GetbuildSecretString(buildSecrets)
12✔
150

12✔
151
        deployInput := cloud.InputDeploy{
12✔
152
                Path:              config.WorkingPath,
12✔
153
                RuntimeID:         deploymentID,
12✔
154
                WsID:              workspaceID,
12✔
155
                Pytest:            pytestFile,
12✔
156
                EnvFile:           envFile,
12✔
157
                ImageName:         imageName,
12✔
158
                DeploymentName:    deploymentName,
12✔
159
                Prompt:            forcePrompt,
12✔
160
                Dags:              dags,
12✔
161
                Image:             image,
12✔
162
                WaitForStatus:     waitForDeploy,
12✔
163
                WaitTime:          waitTime,
12✔
164
                DagsPath:          dagsPath,
12✔
165
                Description:       deployDescription,
12✔
166
                BuildSecretString: BuildSecretString,
12✔
167
        }
12✔
168

12✔
169
        return DeployImage(deployInput, platformCoreClient, astroCoreClient)
12✔
170
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc