Skip to Content
Apso is in public beta. Get started

CI/CD

A useful Apso pipeline validates the schema, regenerates code, fails on an uncommitted generated diff, runs the framework test suite, and deploys only after those checks pass.

Repository requirements

Commit the files another machine needs to reproduce the service:

  • .apsorc
  • Generated framework source
  • extensions/
  • Migrations
  • Dependency manifests and lockfiles
  • Tests
  • .env.example without secrets

Keep .env, service API keys, database credentials, and platform tokens in the CI secret store.

Validation job

This GitHub Actions example validates a TypeScript service:

.github/workflows/validate.yml
name: Validate backend on: pull_request: push: branches: [main] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: npm - run: npm install -g @apso/cli - run: npm ci - run: apso schema validate - run: apso generate - name: Require generated code to be committed run: git diff --exit-code - run: apso migrate - run: npm test - run: npm run build

apso migrate uses a local PGlite sandbox, so the validation job does not need production database credentials.

Framework checks

npm ci npm test npm run build

Deploy to Apso Cloud

Connect GitHub and the service once from an interactive environment before enabling automated deployment:

apso github connect apso link --workspace your-team --service project-api

The automation token is a platform credential, not a generated service API key. Store it as APSO_TOKEN in the repository or environment secret store.

.github/workflows/deploy.yml
name: Deploy backend on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest permissions: contents: read steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm install -g @apso/cli - name: Authenticate run: apso login --token "$APSO_TOKEN" env: APSO_TOKEN: ${{ secrets.APSO_TOKEN }} - name: Link service run: apso link --workspace your-team --service project-api - name: Deploy committed source run: apso deploy --skip-push --yes

--skip-push is appropriate here because the workflow is already running the commit from the connected repository. Remove it when the job must synchronize a different local source tree.

Do not pass --token to apso deploy. Authentication is a separate apso login --token step.

Self-hosted image

Generated services can use a normal container pipeline. This example publishes an existing project Dockerfile to GitHub Container Registry:

.github/workflows/image.yml
name: Publish backend image on: push: branches: [main] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: image: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v6 with: context: . push: true tags: ghcr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}

Deployment verification

After either deployment path:

  1. Request /health from the deployed endpoint.
  2. Exercise one authenticated read request.
  3. Exercise one write in a non-production smoke-test resource when available.
  4. Record the deployed commit SHA in the release system.
  5. Stop the pipeline when migration, health, or authentication checks fail.
Last updated on