Skip to content
Browse files

Improve error handling for environment property (#295)

* Improve error handling for environment property

Improve the error messages that we get for a bad or missing environment
property.  Move the property processing into the main build so that we do it
only once and configure all of the appengine deployment tasks to check that a
project has been defined and print a friendly error if it hasn't.

Note that even if the check isn't configured, this change prevents deployment
because the gcpProject will be set to null.  It just won't print as useful an
error message.

Tested: ran appengineDeployAll with and without the environment property, ran
"build" to verify that we don't get any complaints for non-deployment targets.

* Changes for review.

* Changes for review

* Changes for review.

* Changes for review.
  • Loading branch information...
mindhog committed Oct 4, 2019
1 parent aa4e242 commit 31b5abb9a1d9d61a439a1780d618106695da7285
Showing with 71 additions and 48 deletions.
  1. +16 −2 appengine_war.gradle
  2. +52 −9 build.gradle
  3. +3 −0
  4. +0 −37 projects.gradle
@@ -12,7 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

apply from: "${rootDir.path}/projects.gradle"
apply plugin: 'war'

def environment = rootProject.environment
@@ -68,6 +67,10 @@ appengine {
if (!rootProject.prodOrSandboxEnv) {
version = 'GCLOUD_CONFIG'

// Don't set gcpProject directly, it gets overriden in ./build.gradle.
// Do -P environment={crash,alpha} instead. For sandbox/production,
// use Spinnaker.
projectId = gcpProject
@@ -92,4 +95,15 @@ explodeWar.doLast {

rootProject.deploy.dependsOn appengineDeployAll
rootProject.stage.dependsOn appengineStage
appengineDeployAll.dependsOn rootProject.verifyDeployment

// Impose verification for all of the deployment tasks. We haven't found a
// better way to do this other than to apply to each of them independently.
// If a new task gets added, it will still fail if "environment" is not defined
// because gcpProject is null. We just won't get as friendly an error message.
appengineDeployAll.configure rootProject.verifyDeploymentConfig
appengineDeploy.configure rootProject.verifyDeploymentConfig
appengineDeployCron.configure rootProject.verifyDeploymentConfig
appengineDeployDispatch.configure rootProject.verifyDeploymentConfig
appengineDeployDos.configure rootProject.verifyDeploymentConfig
appengineDeployIndex.configure rootProject.verifyDeploymentConfig
appengineDeployQueue.configure rootProject.verifyDeploymentConfig
@@ -109,21 +109,64 @@ task deploy {
description = 'Deploys all services to App Engine.'

task verifyDeployment {
task stage {
group = 'deployment'
description = 'Ensure that one cannot deploy to production or sandbox.'
doFirst {
if (rootProject.prodOrSandboxEnv) {
throw new GradleException("Cannot deploy to production or sandbox.");
description = 'Generates application directories for all services.'

// App-engine environment configuration. We set up all of the variables in
// the root project.

def environments = ['production', 'sandbox', 'alpha', 'crash']

// TODO(mmuller): Move this into internal specialization code.
def projects = ['production': 'domain-registry',
'sandbox' : 'domain-registry-sandbox',
'alpha' : 'domain-registry-alpha',
'crash' : 'domain-registry-crash']

def gcpProject = null

if (environment == '') {
// Keep the project null, this will prevent deployment. Set the
// environment to "alpha" because other code needs this property to
// explode the war file.
environment = 'alpha'
} else if (environment != 'production' && environment != 'sandbox') {
gcpProject = projects[environment]
if (gcpProject == null) {
throw new GradleException("-Penvironment must be one of ${environments}.")

task stage {
group = 'deployment'
description = 'Generates application directories for all services.'
rootProject.ext.environment = environment
rootProject.ext.gcpProject = gcpProject
rootProject.ext.prodOrSandboxEnv = environment in ['production', 'sandbox']

// Function to verify that the deployment parameters have been set.
def verifyDeploymentParams() {
if (prodOrSandboxEnv) {
// Do not deploy to prod or sandbox. Print a prominent error in bright red.
System.err.println('*** DANGER WILL ROBINSON!')
System.err.println('*** You may not deploy to production or sandbox from gradle. Do a')
System.err.println('*** release from Spinnaker, see deployment playbook.')
throw new GradleException('Aborting. See prominent error above.')
} else if (gcpProject == null) {
def error = 'You must specify -P environment={alpha,crash}'
throw GradleException("Aborting: ${error}")

// Closure that we can just drop into all of our deployment tasks.
rootProject.ext.verifyDeploymentConfig = {
doFirst { verifyDeploymentParams() }

// Subproject configuration.

allprojects {
// Skip no-op project
if ( == 'services') return
@@ -8,6 +8,9 @@ verboseTestOutput=false

# GAE Environment for deployment and staging.

# Cloud SQL properties

# A registry environment name (e.g., 'alpha') or a host[:port] string

This file was deleted.

0 comments on commit 31b5abb

Please sign in to comment.
You can’t perform that action at this time.