Home›Developer docs›CI/CD

CI/CD

Updated Nov 13, 20262 min read

Test and deploy your SashiDo app's cloud code automatically. Staging and production apps, GitHub Actions that test, push and wait for the deployment, and environment variables from CI.

SashiDo deploys whatever is pushed to your app's repository's master branch: a push is a deploy. A pipeline adds what comes before (tests, a staging app) and after (waiting until the deployment is live, then checking it).

Staging and production

Use two SashiDo apps, e.g. shop-staging and shop, each with its own repository, keys and database. Keep your code in your own repository, and add both SashiDo repositories as remotes:

git remote add staging    git@github.com:<sashido-org>/<staging-repo>.git
git remote add production git@github.com:<sashido-org>/<production-repo>.git

git push staging main:master       # deploy to staging
git push production main:master    # promote the same commit

The repositories' addresses are in Core › Cloud Code of each app.

A GitHub Actions pipeline

Test, deploy to staging, wait until it's live and healthy:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 18 }
      - run: npm ci
      - run: npx jest

  staging:
    needs: test
    runs-on: ubuntu-latest
    env:
      SASHIDO_TOKEN: ${{ secrets.SASHIDO_TOKEN }}
      APP: ${{ vars.SASHIDO_STAGING_APP }}
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Push to the staging app
        run: |
          git remote add staging "https://x-access-token:${{ secrets.SASHIDO_REPO_TOKEN }}@github.com/${{ vars.SASHIDO_STAGING_REPO }}.git"
          git push staging HEAD:master --force
      - name: Wait until it's live
        run: |
          api() { curl -sf -H "Authorization: Bearer $SASHIDO_TOKEN" -H "X-SashiDo-Client: github-actions" "$@"; }
          before=$(api "https://api.sashido.io/apps/$APP/deployments?limit=1" | jq '.data[0].number')
          for i in $(seq 1 90); do
            read number phase <<< "$(api "https://api.sashido.io/apps/$APP/deployments?limit=1" | jq -r '.data[0] | "\(.number) \(.phase)"')"
            if [ "$number" != "$before" ]; then
              case "$phase" in
                Active) break ;;
                Failed|Cancelled) echo "Deployment $number: $phase"; exit 1 ;;
              esac
            fi
            sleep 10
          done
          api "https://api.sashido.io/apps/$APP/parse/health" | jq -e '.status == "ok"'

What it needs:

Secret or variable
SASHIDO_TOKEN A personal access token with apps:read, limited to the staging app
SASHIDO_REPO_TOKEN A GitHub token of an account with access to the SashiDo repository
SASHIDO_STAGING_APP The app's objectId (GET /users/info)
SASHIDO_STAGING_REPO The repository, <org>/<repo>

A push builds first and then deploys, so the loop waits for a deployment newer than the one before the push. Promote to production the same way, e.g. on a release tag or with a manual approval.

Environment variables from CI

Keep secrets in your CI's secret store and set them through the API: PUT /apps/{id}/env replaces your variables and redeploys the app with them. See the recipe.

Before a Parse Server upgrade

Run your tests against the new version locally (npm install parse-server@<new version>), and ask plan_parse_server_upgrade through MCP what your code needs. Then switch the staging app's version, run the pipeline, and only then production.

Reading this with an AI assistant? This page as Markdown.