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!