webiny / webiny-js

Open-source serverless enterprise CMS. Includes a headless CMS, page builder, form builder, and file manager. Easy to customize and expand. Deploys to AWS.
https://www.webiny.com
Other
7.38k stars 612 forks source link

Create An Initialization Script For Ephemeral Environments #2810

Open adrians5j opened 1 year ago

adrians5j commented 1 year ago

The Issue

At the moment, it's not easy to run any kind of tests tests against ephemeral Webiny project environments. This is because every time we deploy a new Webiny project, it first needs to be installed.

image

Proposed Solution

Ideally, whenever a new ephemeral environment is spun up, it would be useful to have a script that will run the installation steps before any tests are being executed. The following is a list of all the steps that would need to happen in the suggested script. Once completed, the tests should be allowed to be executed.

Steps

1. Run InstallSecurity GraphQL Mutation

mutation InstallSecurity {
  security {
    install {
      data
      error {
        code
        message
        __typename
      }
      __typename
    }
    __typename
  }
}

2. Run InstallAdminUsers GraphQL Mutation

mutation InstallAdminUsers($data: AdminUsersInstallInput!) {
  adminUsers {
    install(data: $data) {
      data
      error {
        code
        message
        __typename
      }
      __typename
    }
    __typename
  }
}

Example variables:

{
  "data": {
    "firstName": "Ad",
    "lastName": "Min",
    "email": "admin@website.com",
    "password": "12345678"
  }
}

3. Login

With the first user created in the previous step, we now need to log in. We log in directly against Amazon Cognito, using amazon-cognito-identity-js package (example).

With this step completed, we'll be able to retrieve user's auth token, and, by attaching it as Authorization header to upcoming GraphQL mutations, be able to finish the installation.

4. Run InstallI18N GraphQL Mutation

mutation InstallI18N($data: I18NInstallInput!) {
  i18n {
    install(data: $data) {
      data
      error {
        code
        message
        __typename
      }
      __typename
    }
    __typename
  }
}

Example variables:

{
  "data": {
    "code": "en-US"
  }
}

5. Run InstallFileManager GraphQL Mutation

mutation InstallFileManager($srcPrefix: String) {
  fileManager {
    install(srcPrefix: $srcPrefix) {
      data
      error {
        code
        message
        data
        __typename
      }
      __typename
    }
    __typename
  }
}

Example variables (srcPrefix should be the URL to deployed apps/api project application's Amazon CloudFront distribution):

{
  "srcPrefix": "https://abc123xyz.cloudfront.net/files"
}

6. Run InstallPageBuilder GraphQL Mutation

mutation InstallPageBuilder($data: PbInstallInput!) {
  pageBuilder {
    install(data: $data) {
      data
      error {
        code
        message
        __typename
      }
      __typename
    }
    __typename
  }
}

Example variables:

{
  "data": {
    "name": "Test"
  }
}

7. Run InstallPageBuilder GraphQL Mutation

mutation InstallFormBuilder($domain: String) {
  formBuilder {
    install(domain: $domain) {
      data
      error {
        code
        message
        __typename
      }
      __typename
    }
    __typename
  }
}

Example variables (srcPrefix should be the URL to deployed apps/api project application's Amazon CloudFront distribution):

{
  "domain": "https://abc123xyz.cloudfront.net"
}

8. Run InstallPageBuilder GraphQL Mutation

mutation InstallCms {
  cms {
    install {
      data
      error {
        code
        message
        data
        __typename
      }
      __typename
    }
    __typename
  }
}
SvenAlHamad commented 1 year ago

A similar approach might be also useful for when you create new tenants in Tenant Manager. Often times when you create a tenant you don’t want to go through the installation steps, but have a tenant that’s ready to use out of the box.

ma-schmidt-de commented 1 year ago

I think, providing a specific installation mutation per app and having the script run at the client grants to user excellent control. He/she can easily decide to, e.g. skip unnecessary apps or add own custom apps to the installation process.

Yet another solution would be, to provide one single mutation that takes all data needed (we could even include the list of apps we want to install) and the actual steps of creating the user and installing apps are performed server-side. This feels more user-friendly and less error-prone as only one initial trigger has to be send and the rest can run on it's own in the cloud.