Skip to content

Overview ​

The GitHub Actions Builder provides a way to automatically build applications from source code using GitHub Actions. This allows Nullstone to wait for a build completed by GitHub Actions before deploying the application. Optionally, Nullstone can trigger this workflow so that it is coordinate with preview environments.

Workflow Filename ​

The GitHub Actions Builder needs to know which GitHub Actions workflow is configured to build your application. The workflow filename should be .github/workflows/<workflow-name>.yml.

Trigger Workflow ​

If you configure a Nullstone app with GitHub Actions builder to "Initiate Workflow", Nullstone will start your GitHub Actions workflow with a workflow_dispatch. For these workflows, make sure you have configured on with a workflow_dispatch. Nullstone will trigger this workflow with the following inputs:

  • NULLSTONE_ORG
  • NULLSTONE_STACK
  • NULLSTONE_APP
  • NULLSTONE_ENV
  • NULLSTONE_VERSION
  • NULLSTONE_COMMIT_SHA
yaml
on:
  workflow_dispatch:
    inputs:
      NULLSTONE_ORG:
        type: string
        description: 'Nullstone Organization'
        required: true
      NULLSTONE_STACK:
        type: string
        description: 'Nullstone Stack'
        required: true
      NULLSTONE_APP:
        type: string
        description: 'Nullstone App'
        required: true
      NULLSTONE_ENV:
        type: string
        description: 'Nullstone Environment'
        required: true
      NULLSTONE_VERSION:
        type: string
        description: 'Nullstone Version'
        required: true
      NULLSTONE_COMMIT_SHA:
        type: string
        description: 'Nullstone Commit SHA'
        required: true

Example ​

The following example performs a build in GitHub Actions when a user triggers a deployment in Nullstone. The GitHub Actions workflow file builds and pushes a Docker image to your container registry. When this workflow completes, Nullstone will perform a deployment.

This example caches the build and will only perform a build once for a single commit.

Before starting, make sure you do the following:

  • Add NULLSTONE_API_KEY to your repository secrets.

Then, create 2 files .github/workflows/build-my-app.yml and .github/workflows/push-my-app.yml. Use the following yaml files for each file.

TIP

If you have multiple apps in a single repository, you can duplicate these files for each app. Make sure to change my-app in each file.

yaml
# .github/workflows/build-my-app.yml
name: Build my-app

on:
  push:
    branches: [ $default-branch ]
  pull_request: {}
  workflow_call:
    inputs: {}
    secrets: {}

# Each build workflow will only run one-at-a-time per commit.
# The "first" run will perform the build.
# Each later run will skip building since the image already exists in GHCR.
concurrency:
  group: build-my-app-${{ github.sha }}
  cancel-in-progress: false

env:
  GHCR_IMAGE: ghcr.io/${{ github.repository }}:${{ github.sha }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.sha }}
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      # We use GitHub Container Registry (GHCR) as a single source of truth for all images.
      # If an image tag already exists in GHCR, we don't need to rebuild it.
      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Check for existing image
        id: check-image
        run: |
          if docker manifest inspect "${GHCR_IMAGE}" > /dev/null 2>&1; then
            echo "exists=true" >> "$GITHUB_OUTPUT"
            echo "Image ${GHCR_IMAGE} already exists in GHCR"
          else
            echo "exists=false" >> "$GITHUB_OUTPUT"
          fi
      # Build only if the image doesn't exist in GHCR
      - name: Build Docker image
        if: steps.check-image.outputs.exists == 'false'
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ env.GHCR_IMAGE }}
          provenance: false
          cache-from: type=gha
          cache-to: type=gha,mode=max
yaml
# .github/workflows/push-my-app.yml

name: Push my-app via Nullstone

on:
  workflow_dispatch:
    inputs:
      NULLSTONE_ORG:
        type: string
        description: 'Nullstone Organization'
        required: true
      NULLSTONE_STACK:
        type: string
        description: 'Nullstone Stack'
        required: true
      NULLSTONE_APP:
        type: string
        description: 'Nullstone App'
        required: true
      NULLSTONE_ENV:
        type: string
        description: 'Nullstone Environment'
        required: true
      NULLSTONE_VERSION:
        type: string
        description: 'Nullstone Version'
        required: true

env:
  NULLSTONE_ORG: ${{ inputs.NULLSTONE_ORG }}
  NULLSTONE_API_KEY: ${{ secrets.NULLSTONE_API_KEY }}
  GHCR_IMAGE: ghcr.io/${{ github.repository }}:${{ github.sha }}

jobs:
  build:
    uses: ./.github/workflows/build-my-app.yml

  push:
    runs-on: ubuntu-latest
    needs: [ build ]
    permissions:
      contents: read
      packages: read
    steps:
      - name: Set up Nullstone
        uses: nullstone-io/setup-nullstone-action@v0
      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Pull image from GHCR
        run: |
          docker pull ${{ env.GHCR_IMAGE }}
      - name: Push Docker image to Nullstone
        run: |
          nullstone push \
            --stack=${{ inputs.NULLSTONE_STACK }} \
            --app=${{ inputs.NULLSTONE_APP }} \
            --env=${{ inputs.NULLSTONE_ENV }} \
            --source=${{ env.GHCR_IMAGE }} \
            --version=${{ inputs.NULLSTONE_VERSION }}

Watch Workflow ​

If you don't configure Nullstone to initiate the build workflow, Nullstone will watch a GitHub Actions workflow triggered by GitHub.

Support and examples coming soon!