Skip to main content

Other CI/CD Platforms

The official Deploy Walrus Site action targets GitHub Actions only. On any other CI/CD platform, such as GitLab CI/CD, CircleCI, or Bitbucket Pipelines, you drive deployment directly through the site-builder CLI. Because site-builder is a standard Linux binary, the deployment steps are identical on every platform. Only the pipeline syntax differs.

How platform-based deployment works

Because there is no pre-built action for non-GitHub platforms, each pipeline must perform the same steps that the GitHub Action handles automatically:

  1. Reconstruct the Sui configuration: Write the keystore secret from the CI environment to disk so site-builder can read it.
  2. Download site-builder: Fetch the binary for the runner's architecture from the Mysten Labs GCS bucket.
  3. Download sites-config.yaml: Fetch the network configuration from the walrus-sites repository.
  4. Build the site: Compile or bundle your site output (skip for repositories that already contain deployable static files).
  5. Run site-builder deploy: Upload the static output directory to Walrus.

Storing credentials on your platform

Every platform stores secrets differently. In all cases, you need 2 values:

  • SUI_KEYSTORE: The base64WithFlag private key string wrapped as a JSON array: ["AXXXXXXXXXX..."]. Store this as a masked or protected secret. Never expose it in logs.
  • SUI_ADDRESS: The corresponding Sui address. This is not sensitive, but masking it is acceptable.
PlatformSecret location
GitLabSettings → CI/CD → Variables (set visibility to Masked)
CircleCIProject Settings → Environment Variables, or a shared Context
BitbucketRepository settings → Repository variables (enable Secured)
danger

Never paste SUI_KEYSTORE or any private key directly into a pipeline configuration file. Configuration files are committed to version control and visible to anyone with repository access.

The deploy script

The following shell commands contain all setup and deployment logic. Each platform example below inlines these steps in its own syntax.

#!/usr/bin/env bash
set -euo pipefail

# 1. Reconstruct Sui client configuration from CI secrets.
# SUI_KEYSTORE must be a JSON array string, for example: ["AXXXXX..."]
# Replace 'mainnet' with 'testnet' throughout if targeting Testnet.
WALRUS_NETWORK="${WALRUS_NETWORK:-mainnet}"

mkdir -p ~/.sui/sui_config

echo "$SUI_KEYSTORE" > ~/.sui/sui_config/sui.keystore

cat > ~/.sui/sui_config/client.yaml <<EOF
keystore:
File: "$HOME/.sui/sui_config/sui.keystore"
envs:
- alias: ${WALRUS_NETWORK}
rpc: "https://fullnode.${WALRUS_NETWORK}.sui.io:443"
ws: ~
basic_auth: ~
active_env: ${WALRUS_NETWORK}
active_address: "${SUI_ADDRESS}"
EOF

# 2. Download site-builder for ubuntu-x86_64, which matches standard Linux CI runners.
curl -fsSL \
"https://storage.googleapis.com/mysten-walrus-binaries/site-builder-${WALRUS_NETWORK}-latest-ubuntu-x86_64" \
-o /usr/local/bin/site-builder
chmod +x /usr/local/bin/site-builder

# 3. Download the network-specific sites-config.yaml.
mkdir -p ~/.config/walrus
curl -fsSL \
"https://raw.githubusercontent.com/MystenLabs/walrus-sites/refs/heads/${WALRUS_NETWORK}/sites-config.yaml" \
-o ~/.config/walrus/sites-config.yaml

# 4. Deploy. DIST must point to your built static files directory, not the repository root.
site-builder deploy --epochs "${EPOCHS:-5}" "${DIST:?DIST must be set}"

Set the following environment variables before running the script:

  • SUI_KEYSTORE: The keystore secret from your platform's secret store.
  • SUI_ADDRESS: The Sui address that corresponds to your keystore.
  • WALRUS_NETWORK: mainnet (default) or testnet.
  • EPOCHS: Number of storage epochs (default 5; maximum 53). On Mainnet, 1 epoch is 14 days. On Testnet, 1 epoch is 1 day.
  • DIST: Path to your build output directory, for example dist or build.
caution

Always point site-builder deploy at your build output directory, not your repository root. Uploading the project root includes source files, node_modules/, and other artifacts that significantly increase upload time and storage costs.

Understanding ws-resources.json in pipelines

The site-builder deploy command writes a ws-resources.json file to your DIST directory after the first deployment. This file stores the Sui object ID of your deployed site. On subsequent runs, site-builder reads that ID to update the same site rather than creating a new one.

In a CI/CD pipeline, the build output directory is recreated on every run, so ws-resources.json is lost unless you take one of the following approaches:

  • Commit the file to your repository (recommended): Place ws-resources.json in your framework's public/ directory (or equivalent). Most build tools copy everything in public/ into DIST automatically, making the file available at DIST/ws-resources.json on every run without extra configuration.
  • Pass the object ID explicitly: After the first deployment, copy the object_id value from ws-resources.json and store it as a CI variable named SITE_OBJECT_ID. Then add --object-id "$SITE_OBJECT_ID" to the deploy command: site-builder deploy --object-id "$SITE_OBJECT_ID" --epochs "$EPOCHS" "$DIST".

If neither approach is in place, each pipeline run creates a new site object and incurs additional WAL storage costs.

Platform examples

Store your credentials before adding the pipeline file. Then create the configuration file shown for your platform in your repository root.

Store SUI_KEYSTORE and SUI_ADDRESS as masked CI/CD variables under SettingsCI/CDVariables.

Create .gitlab-ci.yml:

stages:
- build
- deploy

variables:
WALRUS_NETWORK: mainnet
EPOCHS: "5"
DIST: dist

build:
stage: build
image: node:lts
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 hour
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

deploy-walrus:
stage: deploy
image: ubuntu:24.04
needs:
- build
before_script:
- apt-get update -qq && apt-get install -y -qq curl ca-certificates
script:
- mkdir -p ~/.sui/sui_config
- echo "$SUI_KEYSTORE" > ~/.sui/sui_config/sui.keystore
- |
cat > ~/.sui/sui_config/client.yaml <<EOF
keystore:
File: "$HOME/.sui/sui_config/sui.keystore"
envs:
- alias: ${WALRUS_NETWORK}
rpc: "https://fullnode.${WALRUS_NETWORK}.sui.io:443"
ws: ~
basic_auth: ~
active_env: ${WALRUS_NETWORK}
active_address: "${SUI_ADDRESS}"
EOF
- |
curl -fsSL \
"https://storage.googleapis.com/mysten-walrus-binaries/site-builder-${WALRUS_NETWORK}-latest-ubuntu-x86_64" \
-o /usr/local/bin/site-builder
chmod +x /usr/local/bin/site-builder
- |
mkdir -p ~/.config/walrus
curl -fsSL \
"https://raw.githubusercontent.com/MystenLabs/walrus-sites/refs/heads/${WALRUS_NETWORK}/sites-config.yaml" \
-o ~/.config/walrus/sites-config.yaml
- site-builder deploy --epochs "$EPOCHS" "$DIST"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

The build job produces a dist/ artifact that GitLab makes available to the deploy-walrus job through the needs dependency. The rules key restricts both jobs to the default branch, preventing deployments from feature branches.

For static sites with no build step, remove the build stage, remove the needs key from deploy-walrus, and point DIST at your static files directory.

Adapting to any other platform

Any CI/CD platform that provides Linux runners can deploy Walrus Sites using the same pattern. The following table maps the concepts from the 3 examples above to their equivalents on other platforms:

ConceptGitLabCircleCIBitbucketGeneral approach
Secret storageCI/CD Variables (Masked)Environment Variables or ContextRepository variables (Secured)Platform secret store
File sharing between jobsartifacts + needspersist_to_workspace + attach_workspaceartifacts (automatic)Platform artifact or cache mechanism
Branch restrictionrules on $CI_DEFAULT_BRANCHfilters on branch namebranches keyPush trigger scoped to main branch
Runner imageimage: per jobdocker: executor per jobimage: per stepAny Ubuntu-based Linux image

The deploy script itself does not change between platforms. Copy the 5-step script from The deploy script section and inline it into your platform's job definition using that platform's multiline script syntax.