Deploy content via CI/CD pipelines
One of the most common use-cases for Quant is having a CI/CD pipeline trigger a build and deploy action from a static site generator, or other custom solution that generates or compiles content to publish to the edge.
This guide will configure a CI pipeline to build and deploy development & production branches for an example Astro project to the Quant static edge using GitHub Actions.
Code example
Section titled “Code example”This is the full code example responsible for building, deploying, and clearing the caches. For those familiar with GitHub actions already the portion responsible for deployment and cache clearing is highlighted, you can simply copy and tweak to suit your project.
We will break it down in further detail below.
name: "Deploy Astro project to QuantCDN"
on: push: branches: - develop - main
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true
jobs: deploy: runs-on: ubuntu-latest steps: - name: Set environment for branch run: | echo "QUANT_CUSTOMER=quant-demo" >> "$GITHUB_ENV" if [[ $GITHUB_REF == 'refs/heads/main' ]]; then echo "QUANT_PROJECT=astro-example-prod" >> "$GITHUB_ENV" echo "QUANT_TOKEN=${{ secrets.QUANT_TOKEN_PRODUCTION }}" >> "$GITHUB_ENV" else echo "QUANT_PROJECT=astro-example-dev" >> "$GITHUB_ENV" echo "QUANT_TOKEN=${{ secrets.QUANT_TOKEN_DEV }}" >> "$GITHUB_ENV" fi
- uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm'
- name: Install dependencies run: npm ci
- name: Restore revision log uses: actions/cache@v5 with: path: .quant-revision key: quant-revision-${{ github.ref }}-${{ github.run_id }} restore-keys: | quant-revision-${{ github.ref }}-
- name: Build site run: npm run build
- name: Deploy to QuantCDN uses: quantcdn/deploy-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" dir: dist skip-purge: true revision-log: .quant-revision
- name: Purge CDN cache uses: quantcdn/purge-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" url_pattern: "/*"Configure GitHub secrets
Section titled “Configure GitHub secrets”Your QuantCDN project token is used to connect to the Quant API when content is pushed up. This token should never be shared or made publicly available, so you will want to define this value as a GitHub secret.
To do this, navigate to your projects settings screen in GitHub and add the value in the “Secrets and Variables” > “Actions” section as a repository secret.
In our example we are building both a development and production version of our Astro site, so we will set both QUANT_TOKEN_PRODUCTION and QUANT_TOKEN_DEV.
You can retrieve the project tokens from the Integrations section of the Quant Dashboard.
Setting the environment variables (optional)
Section titled “Setting the environment variables (optional)”At the beginning of the deployment process we are setting environment variables for the QUANT_PROJECT and QUANT_TOKEN values depending on the branch.
If you are only interested in deploying a single branch you can skip this step, as the values can be input directly into the deployment stage.
- name: Set environment for branch run: | echo "QUANT_CUSTOMER=quant-demo" >> "$GITHUB_ENV"
if [[ $GITHUB_REF == 'refs/heads/master' ]]; then echo "QUANT_PROJECT=astro-example-prod" >> "$GITHUB_ENV" echo "QUANT_TOKEN=${{ secrets.QUANT_TOKEN_PRODUCTION }}" >> "$GITHUB_ENV" else echo "QUANT_PROJECT=astro-example-dev" >> "$GITHUB_ENV" echo "QUANT_TOKEN=${{ secrets.QUANT_TOKEN_DEV }}" >> "$GITHUB_ENV" fiRunning the deployment
Section titled “Running the deployment”The deployment itself uses our GitHub Action.
This action can optionally track the previous deployment state, including all of the md5 hashes for assets in the compiled build. This allows for must faster ongoing deployments, as assets that have not changed since the last build can be skipped.
- name: Deploy to QuantCDN uses: quantcdn/deploy-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" dir: dist skip-purge: true revision-log: .quant-revisionIn this example we are setting the dir value to the directory of our compiled Astro build.
We are also setting the skip-purge value to true which will skip purging CDN caches during the actual deployment step. We will issue a bulk purge in the next step.
Deploying edge functions
Section titled “Deploying edge functions”Add the functions input to deploy edge functions in the same step. The value is the path to a function manifest:
- name: Deploy to QuantCDN uses: quantcdn/deploy-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" dir: dist functions: quant/edge-functions.json skip-purge: true revision-log: .quant-revisionFrom v7, every manifest entry must have a uuid, and the step fails before any upload if one is missing. The v6 tag does not change, so a workflow on @v6 keeps working until you move it. To pin an exact release, use the commit SHA of the tag, for example quantcdn/deploy-action@9bf8cae8497ab6628d4b248db9eb11464f37e1e5 # v7.0.1.
Deploying edge rules
Section titled “Deploying edge rules”Add the rules input to deploy the rules that run your functions from a rules file. Rules use the platform API, so they need two more inputs: api-token (a separate project-scoped token with projects:read, rules:read and rules:write; the content token never works for rules) and api-base-url ({dashboard}/api/v2).
- name: Deploy to QuantGov uses: quantcdn/deploy-action@9bf8cae8497ab6628d4b248db9eb11464f37e1e5 # v7.0.1 with: customer: "${{ vars.QUANT_CUSTOMER }}" project: "${{ vars.QUANT_PROJECT }}" token: "${{ secrets.QUANT_TOKEN }}" endpoint: https://api.quantgov.cloud/v1 dir: dist functions: quant/edge-functions.json rules: quant/edge-rules.json api-token: "${{ secrets.QUANT_API_TOKEN }}" api-base-url: https://dash.quantgov.cloud/api/v2On QuantCDN, use https://dashboard.quantcdn.io/api/v2 and leave out endpoint (it defaults to https://api.quantcdn.io/v1). On QuantGov, set endpoint as shown, or the uploads go to the QuantCDN content API.
The step checks rules access first (a dry run), then deploys the functions, then dir, then the rules. Functions deployed this way are published at once. A rule that someone changed in the dashboard stops the deploy with a list of the changed fields; rules-force: true overwrites it.
Clearing caches after the deployment completes
Section titled “Clearing caches after the deployment completes”We use our cache purge GitHub Action here.
- name: Purge CDN cache uses: quantcdn/purge-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" url_pattern: "/*"This one is fairly self explanatory, we are purging the entire cache for the project (/*) which will ensure the CDN caches are reset at the end of the deployment.
(Optional): Scoping the purge to an environment
Section titled “(Optional): Scoping the purge to an environment”A single QuantCDN project sometimes hosts more than one environment — for example a test and a production hostname. Purging /* clears the cache for the whole project, including environments you didn’t just deploy.
To purge only the environment you deployed, use cache keys instead of a URL pattern. Have each environment’s origin emit a Cache-Keys response header identifying itself (e.g. Cache-Keys: env:test on the test environment), then purge just that key:
- name: Purge CDN cache (test) if: github.ref == 'refs/heads/develop' uses: quantcdn/purge-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" cache_keys: "env:test"
- name: Purge CDN cache (production) if: github.ref == 'refs/heads/main' uses: quantcdn/purge-action@v7 with: customer: "${{ env.QUANT_CUSTOMER }}" project: "${{ env.QUANT_PROJECT }}" token: "${{ env.QUANT_TOKEN }}" cache_keys: "env:production"cache_keys and url_pattern are mutually exclusive — provide one per step. See Using cache keys for how to emit the Cache-Keys header from your origin.
(Optional): Caching npm dependencies
Section titled “(Optional): Caching npm dependencies”The setup-node action has built-in support for caching the npm download cache. Add cache: 'npm' to skip re-downloading packages that haven’t changed:
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '22' cache: 'npm'(Optional): Using the Quant revision log
Section titled “(Optional): Using the Quant revision log”The Quant revision log tracks the md5 hashes of all assets deployed in the previous build, so unchanged assets can be skipped on subsequent deploys.
This is an optional performance optimization, but it is recommended to ensure your pipeline runs as efficiently as possible.
- name: Restore revision log uses: actions/cache@v5 with: path: .quant-revision key: quant-revision-${{ github.ref }}-${{ github.run_id }} restore-keys: | quant-revision-${{ github.ref }}-The cache is scoped per branch using github.ref, so production and staging deployments maintain separate revision logs. The github.run_id suffix ensures a new cache entry is saved after every deploy, while restore-keys restores the most recent previous entry.
