Create a CI/CD Pipeline for Shopware Frontends

In this blog post I will explain how to set up a CI/CD pipeline for Shopware Frontends. It will be based on the demo store template Shopware Frontends ships with. We will use Github actions to run tests and then build and deploy to Vercel, which plays nice with the demo’s Nuxt framework.

To follow this post, you need npm installed locally. Further you need Vercel and Github accounts, which are both free and easy to use.

Now lets begin.

First you have to clone the Shopware Frontends demo project and install the dependencies:

npx tiged shopware/frontends/templates/vue-demo-store demo-store && cd demo-store
npm i

With this you have a ready to use project. When you run npm run dev you can visit localhost:3000 and take a look.
At this point we are using the demo store from Shopware, you should use your own Shopware instance. To do this change the Shopware configuration in the nuxt.config.ts file, which is at the root folder of the project. Set the endpoint to your store’s URL and get an access token from a sales channel in your shop admin area.

Next we load some packages so we can run tests on our code. I use Vitest here, as it is easy to integrate into Nuxt projects. To install the necessary dependencies execute this in the root of your project:
npm i vitest @nuxt/test-utils @vitejs/plugin-vue @vue/test-utils --save-dev

To take effect we have to modify some files. First add "test": "vitest" to the project’s package.json, in the scripts section. Then create a vitest.config.ts file the project’s root directory and add this:

import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'

export default defineConfig({
    plugins: [
        Vue(),
    ],
    test: {
        globals: true
    },
})

This will tell Vitest how to read Vue files.

Create a folder named test and in here a file named productPriceImport.test.ts. Add the following content:

import { test, expect } from 'vitest'

test('Product price component import', async () => {
    const cmp = await import('../components/product/ProductPrice.vue')
    expect(cmp).toBeDefined()
})

This tests if a certain Vue component is loadable. It is only a dummy test, to see if our pipeline works. We can add further tests later.

These were the changes needed to run tests, now we take a look at the deployment part.

We add two folders. First .github and in there workflows. In this folder create a file named workflow.yaml and add the following code. It creates two jobs for Github actions, first it builds and tests our project and in the second step in builds and deploys it to Vercel, if the tests are successful.

name: Test and Deploy
env:
  VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
  push:
    branches:
      - main
jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Node.js environment
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies
        run: npm install

      - name: Build nuxt
        run: npm run build

      - name: Run Vitest tests
        run: npm run test

  deploy:
    runs-on: ubuntu-latest
    needs: test

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install Vercel CLI
        run: npm install --global vercel@canary

      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build Project Artifacts
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

To make Nitro, the server software Nuxt uses, aware that we want to deploy to Vercel add this to the nitro entry in the nuxt.config.ts: preset: 'vercel'.

Now you can create a git repository for this project and add all the code in the project folder. The .gitignore is already created and filled with relevant files.
When this is done, push the repository to Github. The workflow will be executed when you do this and fail, we fix this later.

Now we have to prepare Vercel.

First, add a new project in Vercel. This can be done directly from the Vercel dashboard. You have to link the Github repository we just created. In the next step you have to configure the project, you can leave everything as it is and click deploy. The deployment will still fail, but we are getting closer.

Visit the Vercel Settings and create a new token. As scope you can choose the just created project. Copy the token. Move to your repository on Github. Go to Settings > Secrets and variables > Actions and add a new repository secret. Name it VERCEL_TOKEN and paste the token you just created. Save the secret.

Now for the last step. We have to install the Vercel CLI. This can be done with npm install -g Vercel followed by the vercel login command, where you enter your credentials.
When this is done, the project has to be linked to Vercel. This can be done with the vercel link command, to be executed in the root folder of your project. You will be asked to choose a project, choose the one we just created. Vercel creates a new .vercel folder and adds it to the .gitignore file. The new folder contains a file named project.json. Here you find the projectId and orgId. Create two new secrets in Github, named VERCEL_PROJECT_ID and VERCEL_ORG_ID and paste the values from the project.json file.

And this is it. Now when you push changes to the main branch our pipeline runs tests and deploys the project, if successful, to Vercel. You can find the code for my demo project here.