lib/Serverless.js/Serverless/run
class Serverless:  run() {
    const config = configUtils.getConfig();
    const currentId = config.userId;
    const globalConfig = configUtils.getGlobalConfig();

    let isTokenExpired = false;
    if (globalConfig
      && globalConfig.users
      && globalConfig.users[currentId]
      && globalConfig.users[currentId].auth
      && globalConfig.users[currentId].auth.id_token
      && !globalConfig.users[currentId].dashboard) {
      isTokenExpired = true;
    }

    if (isTokenExpired && !this.processedInput.commands[0] === 'login') {
      this.cli
        .log('WARNING: Your login token has expired. Please run "serverless login" to login.');
    }

    this.utils.logStat(this).catch(() => BbPromise.resolve());

    if (this.cli.displayHelp(this.processedInput)) {
      return BbPromise.resolve();
    }

    // make sure the command exists before doing anything else
    this.pluginManager.validateCommand(this.processedInput.commands);

    // populate variables after --help, otherwise help may fail to print
    // (https://github.com/serverless/serverless/issues/2041)
    return this.variables.populateService(this.pluginManager.cliOptions).then(() => {
      if ((!this.processedInput.commands.includes('deploy') &&
        !this.processedInput.commands.includes('remove')) || !this.config.servicePath) {
        return BbPromise.resolve();
      }

      return getUser().then(user => {
        if (!user) return BbPromise.resolve();
        if (!this.service.tenant && !this.service.app) {
          this.cli.log('WARNING: Missing "tenant" and "app" properties in serverless.yml. Without these properties, you can not publish the service to the Serverless Platform.'); // eslint-disable-line
          return BbPromise.resolve();
        } else if (this.service.tenant && !this.service.app) {
          const errorMessage = ['Missing "app" property in serverless.yml'].join('');
          throw new this.classes.Error(errorMessage);
        } else if (!this.service.tenant && this.service.app) {
          const errorMessage = ['Missing "tenant" property in serverless.yml'].join('');
          throw new this.classes.Error(errorMessage);
        }

        const listTenantsData = {
          idToken: user.idToken,
          username: user.username,
        };

        return platform.listTenants(listTenantsData).then((tenants) => {
          const tenantsList = tenants.map(tenant => tenant.tenantName);
          if (!tenantsList.includes(this.service.tenant)) {
            const errorMessage = [`tenant "${this.service
              .tenant}" does not exist.`].join('');
            throw new this.classes.Error(errorMessage);
          }
        });
      });
    }).then(() => {
      // merge arrays after variables have been populated
      // (https://github.com/serverless/serverless/issues/3511)
      this.service.mergeArrays();

      // populate function names after variables are loaded in case functions were externalized
      // (https://github.com/serverless/serverless/issues/2997)
      this.service.setFunctionNames(this.processedInput.options);

      // validate the service configuration, now that variables are loaded
      this.service.validate();

      // trigger the plugin lifecycle when there's something which should be processed
      return this.pluginManager.run(this.processedInput.commands);
    });
  }