XM Cloud and Netlify - Deploy with GitHub Actions
Summary
Recently, we had a requirement to deploy code from a private repository in GitHub to both Sitecore XM Cloud and Netlify. There are native ways to accomplish this, but the client wanted full control from one location to manage everything. This meant that GitHub actions and leveraging the proper CLI commands for each platform was a good fit.
In previous blog posts I have talked about deploying to XM Cloud (opens in a new tab) and deploying to Netlify (opens in a new tab) using their own CLI tools. While a couple things have changed the general concept and idea is the same. I'm not going to deep dive into these topics individually again, but please feel free to check them out if you haven't already.
In this blog post, we will focus on how to leverage GitHub actions to deploy our code base to XM Cloud and our headless application to Netlify. For this example, we are using the Sitecore XM Cloud Starter Repository (opens in a new tab) as a base, which comes with a Sitecore JSS SXA Headless Next.js application.
The Solution
Netlify leverages a netlify.toml
file with it's CLI. This is a file-based configuration that specifies how Netlify finds, builds and deploys your application. You can read up more on it here (opens in a new tab).
We need a parent level netlify.toml
as we are deploying to XM cloud at our parent directory and then deploying only the headless application to Netlify (src/app
).
At the base netlify.toml
we need to specify where our headless application is in our repository. For example src/app
.
[build]
base = "/src/app"
In the source of your headless application, src/app
, add a netlify.toml
specifying your build command for the headless application. The command will be specific to your use case. We are using pnpm
, but npm
and any other commands will work here as well.
Note that we need to specify both the publish and functions parameters. Additionally, since we are using a next.js site we set the proper Netlify Next.js plugin.
[build]
command = "pnpm run build"
publish = ".next"
functions = "netlify/functions"
[[plugins]]
package = "@netlify/plugin-nextjs"
Once the toml files are set up we can work on building our GitHub Action. In the base of your repo in .github/workflows
folder create and new file called deploy.yml
. To read more about GitHub Actions check out the documentation here (opens in a new tab).
We will walk through the steps of a simple example, this can be fine tuned and optimized for Production use.
The first step is defining the Action and when you want it to run:
In our example we are specifying to only run on commit to the develop
and main
branches. We are setting the concurrency so that the job does not run more than once at a time. Additionally, we leverage GitHub environment variables to control what values are set for each branch so we don't need to write the action multiple times. Please check out the documentation here (opens in a new tab).
The next step is to install all of our dependencies for the XM Cloud deploy:
In our example we make sure we specify using .NET core
, we then restore and install our dotnet tools. Lastly, we had to add the .net global tools to PATH
so we can leverage it.
Next, we authenticate and deploy to XM Cloud:
If you are using the recommended Sitecore XM cloud FED First
approach, then you are most likely deploying your items using SCS and the CLI to non DEV
environments:
Now that the XM Cloud deployment is complete, we can deploy to Netlify. The first step is to install all the necessary dependencies:
In our example we set up Node
so that we can use npm
and ultimately pnpm
. Deno is installed as it is a requirement of Netlify.
Last, we deploy to Netlify
Final Script
Combined, the deploy.yml
GitHub action script looks like this:
name: Deploy to XM Cloud and Netlify
on:
push:
branches:
- develop
- main
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ (github.ref_name == 'main' && 'prod') || (github.ref_name == 'develop' && 'dev') }}
steps:
- name: Checkout code
uses: actions/checkout@v4
## XM Cloud deployment
- name: Setup .NET core
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.0.406'
- name: Restore .net tools
run: dotnet tool restore --add-source https://sitecore.myget.org/F/sc-packages/api/v3/index.json
- name: Install Sitecore CLI globally
run: dotnet tool install --global sitecore.cli --version 5.2.113
- name: Add .net global tools to PATH
run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
- name: Authenticate with Sitecore Cloud
run: |
dotnet sitecore cloud login --client-credentials --client-id ${{ secrets.XM_CLOUD_CLIENT_ID }} --client-secret ${{ secrets.XM_CLOUD_CLIENT_SECRET }}
run: |
dotnet sitecore cloud deployment create --working-dir . --upload --environment-id ${{ secrets.XM_CLOUD_ENVIRONMENT_ID }}
- name: Connect to XM Cloud an Deploy SCS Items
if: github.ref_name == 'qa' || github.ref_name == 'prod'
run: |
dotnet sitecore cloud environment connect --environment-id ${{ secrets.XM_CLOUD_ENVIRONMENT_ID }} --allow-write true
dotnet sitecore serialization push -n ${{ secrets.XM_CLOUD_ENVIRONMENT_NAME }} --exclude RenderingHost
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install Deno
run: npm install -g deno
working-directory: apps/website
- name: Install pnpm
run: npm install -g pnpm
working-directory: apps/website
- name: Install pnpm
run: pnpm install
working-directory: apps/website
# Netlify deployment
- name: Netlify deploy
run: |
npx netlify deploy --build --site ${{ secrets.NETLIFY_SITE_ID }} --auth ${{ secrets.NETLIFY_AUTH_TOKEN }} --prod
working-directory: apps/website
Conclusion
Netlify and Sitecore give us flexible CLI tools to leverage in our CI/CD pipelines. GitHub actions are a great way to control and deploy all your XM Cloud artifacts from one central location. In our example one commit can deploy to XM Cloud and Netlify with ease.