lib/plugins/platform/platform.js/Platform/publishService
class Platform:  publishService() {
    const authToken = this.getAuthToken();
    if (!authToken) {
      // NOTE publishService is an opt-in feature and no warning is needed
      return BbPromise.resolve();
    }

    if (authToken && authToken.length > 8000) {
      this.serverless.cli.log('Your serverless login has expired');
      this.serverless.cli.log('Please run `serverless login` again');
      return BbPromise.resolve();
    }

    this.serverless.cli.log('Publish service to Serverless Platform...');

    const clientWithAuth = createApolloClient(config.GRAPHQL_ENDPOINT_URL, authToken);

    const region = this.serverless.service.provider.region;
    const stage = this.serverless.processedInput.options.stage;

    return this.provider.getAccountId().then(accountId =>
      fetchEndpoint(this.provider, stage, region).then(endpoint => {
        const funcs = this.serverless.service.getAllFunctions().map(key => {
          const arnName = functionInfoUtils.aws.getArnName(key, this.serverless);
          let funcAttributes = {
            name: key,
            runtime: functionInfoUtils.aws.getRuntime(key, this.serverless),
            memory: functionInfoUtils.aws.getMemorySize(key, this.serverless),
            timeout: functionInfoUtils.aws.getTimeout(key, this.serverless),
            provider: this.serverless.service.provider.name,
            originId: `arn:aws:lambda:${region}:${accountId}:function:${arnName}`,
            endpoints: functionInfoUtils.aws.getEndpoints(key, this.serverless, endpoint),
          };
          if (this.serverless.service.functions[key].readme) {
            funcAttributes = addReadme(
              funcAttributes,
              this.serverless.service.functions[key].readme
            );
          }
          if (this.serverless.service.functions[key].description) {
            funcAttributes.description = this.serverless.service.functions[key].description;
          }
          return funcAttributes;
        });
        const serviceData = {
          name: this.serverless.service.service,
          stage: this.serverless.processedInput.options.stage,
          functions: funcs,
        };
        if (this.serverless.service.serviceObject.description) {
          serviceData.description = this.serverless.service.serviceObject.description;
        }
        if (this.serverless.service.serviceObject.license) {
          serviceData.license = this.serverless.service.serviceObject.license;
        }
        if (this.serverless.service.serviceObject.bugs) {
          serviceData.bugs = this.serverless.service.serviceObject.bugs;
        }
        if (this.serverless.service.serviceObject.repository) {
          serviceData.repository = this.serverless.service.serviceObject.repository;
        }
        if (this.serverless.service.serviceObject.homepage) {
          serviceData.homepage = this.serverless.service.serviceObject.homepage;
        }

        // NOTE can be improved by making sure it captures multiple variations
        // of readme file name e.g. readme.md, readme.txt, Readme.md
        const readmePath = path.join(this.serverless.config.servicePath, 'README.md');
        const serviceDataWithReadme = addReadme(serviceData, readmePath);

        return new BbPromise((resolve, reject) => {
          this.publishServiceRequest(serviceDataWithReadme, clientWithAuth)
            .then(() => {
              const username = jwtDecode(authToken).nickname;
              const serviceName = this.serverless.service.service;
              const url = `${config.PLATFORM_FRONTEND_BASE_URL}services/${username}/${serviceName}`;
              console.log('Service successfully published! Your service details are available at:');
              console.log(chalk.green(url));
              resolve();
            })
            .catch(error => {
              this.serverless.cli.log(
                "Couldn't publish this deploy information to the Serverless Platform."
              );
              reject(error);
            });
        });
      })
    );
  }