CI/CD

To automate build and deploy process of the application we need to leverage a CI/CD tool. Vue Storefront is an Open Source project with the repository hosted on GitHub. GitHub is one of the most popular GUI for Git repositories and it offers a great CI/CD solution - GitHub Actions (opens new window).

Can I use another CI/CD

Yes - Vue Storefront is not limited to Github Actions, but it is the one that we officialy support. All examples in this documentation are based on GitHub Actions - if you examine closely you will notice that eventually a Vue Storefront Cloud API is called. Generally, this way you can call API endpoints using any CI/CD tool.

Managing environment variables

Instead of hardcoding sensitive credentials in our configuration files, it is a much better practice to store them as environment variables (opens new window):

// middleware.config.js

module.exports = {
  integrations: {
    sb: {
      configuration: {
-       token: 'our-hardcoded-token',
+       token: process.env.STORYBLOK_TOKEN
      }
    }
  }
}

When running the application locally, you can provide these variables from the .env file located at the root level of our project. However, for security reasons, you should add the .env file to the .gitignore file to prevent it from being pushed to the version control system. Consequently, it won't be available to the application that is being deployed our Cloud. How do we inject environment variables and use them in the application?

This guide is based on Github

If you are using a different version control platform, consult its documentation to learn more about CI/CD and how to store environment variables.

In a cloud environment, your application is running inside a Docker container. While deploying, you need to make sure every environment variable your application needs is also injected into the container. The easiest way to achieve that would be by defining the variables in your Dockerfile (opens new window) (Not recommended).

ENV STORYBLOK_TOKEN="our-hardcoded-token"

However, this wouldn't be any better than hardcoding them in the middleware.config.js file since you also must push the Dockerfile to the version control. Instead of hardcoding environment variables, you can read their values from build arguments (opens new window) passed on dynamically at build time.

ARG STORYBLOK_TOKEN
ENV STORYBLOK_TOKEN=${STORYBLOK_TOKEN}

The way build arguments are are being passed depends on how you build a docker image within your workflow. By default, Vue Storefront leverages a dedicated Github action (opens new window) which allows us to do it the following way:

jobs:
  build:
    steps:
      - name: Build and publish docker image
      uses: elgohr/Publish-Docker-Github-Action@master
      with:
        buildargs: STORYBLOK_TOKEN
      env:
        STORYBLOK_TOKEN: our-hardcoded-token

Now, using a feature known as Encrypted Secrets (opens new window) you can store credentials securely in the repository. It allows to define variables (opens new window) for use in the CI/CD workflows.

Creating a secret

Once you've created the secret, you can use it in the workflow file (opens new window) and replace the hardcoded value of the STORYBLOK_TOKEN.

jobs:
  build:
    steps:
      - name: Build and publish docker image
      uses: elgohr/Publish-Docker-Github-Action@master
      with:
        buildargs: STORYBLOK_TOKEN
      env:
        STORYBLOK_TOKEN: ${{ secrets.STORYBLOK_TOKEN }}

Congratulations! Now your sensitive credentials will be passed securely into the Docker container during the build.

Handling multiple environments

Before you read

If you're using the appropriate paid plan (opens new window) on Github, you can skip the below guide and handle multi-environment setup using Encrypted secrets for an environment (opens new window). It allows creating separate secrets for every branch without making any changes to workflow files.

An example from the previous section will work in simple scenarios where you have a single application using a single set of repository secrets. If your project is more complex and deploys multiple applications from multiple branches, you will likely need to have more than a single set of repository secrets.

To bind a secret to a specific branch, we recommend prefixing its name with the name of the branch. For example, if we have branches dev and stage in our project, we can create two secrets: DEV_STORYBLOK_TOKEN and STAGE_STORYBLOK_TOKEN.

To retrieve the right secret dynamically in the workflow, you need to get the name of the branch that triggered its run. In the job, you can create a separate step (opens new window) which extracts the branch name from the $GITHUB_REF environment variable (opens new window) and makes it available for all subsequent steps.

jobs:
  build:
    steps:
      - name: Get branch name
        id: get_branch
        run: echo ::set-output name=branch::${GITHUB_REF#refs/*/}

To retrieve the secret dynamically, leverage the newly created variable and the format() function provided by the Github actions (opens new window).

name: Deploy to Vue Storefront Cloud
on:
  push:
    branches:
      - dev
      - stage
jobs:
  build:
    steps:
      - name: Get branch name
        id: get_branch
        run: echo ::set-output name=branch::${GITHUB_REF#refs/*/}
      - name: Build and publish docker image
        uses: elgohr/Publish-Docker-Github-Action@master
        with:
          buildargs: STORYBLOK_TOKEN
        env:
          STORYBLOK_TOKEN: ${{ secrets[format('{0}_STORYBLOK_TOKEN', steps.get_branch.outputs.value)] }}

As a result, a workflow run triggered by a push to the dev branch will utilize the DEV_STORYBLOK_TOKEN secret. If the stage branch is the trigger, wokflow will instead use the STAGE_STORYBLOK_TOKEN secret.

Adding environment variables through Vue Storefront Cloud API

Our API allows to add environment variables in either instance creation time or after the instance has been already created. Use a PATCH request and specify request data as shown below to update existing instance with an environment variable:

curl -s -H 'X-App-Ip: $VSFC_USER_ID  -H 'X-Api-Key: $VSFC_API_KEY' -H 'Content-Type: application/json' -X PATCH -d'
{
  "vsf": {
    "env_var": [
      {
        "is_secret": false,
        "name": "<env-var-name>",
        "value": "<env-var-value>"
      }
    ]
  }
}' https://farmer.storefrontcloud.io/instance/<your-instance-name>

To add a secret environment variable to your instance, simply change the value of is_secret to true:

{
  "vsf": {
    "env_var": [
      {
-       "is_secret": false,
+       "is_secret": true,
        ...
      }
    ]
  }
}

Secret values will not be displayed when fetching the instance details through API.