Skip to main content
The GitHub Actions job agent triggers workflow dispatch events to execute your deployments. This is ideal for teams already using GitHub Actions for CI/CD.

How It Works

  1. Ctrlplane creates a job and dispatches it to GitHub
  2. GitHub triggers your workflow with workflow_dispatch
  3. Your workflow fetches job context (version, environment, resource)
  4. Your workflow executes the deployment
  5. Job status is reported back to Ctrlplane

Prerequisites

  • GitHub App installed in your organization
  • Workflow file with workflow_dispatch trigger
  • Repository permissions for the GitHub App

Configuration

Job Agent Setup

Create a job agent with type github-app:
type: JobAgent
name: github-actions
agentType: github-app

Deployment Configuration

Configure the deployment to use GitHub Actions:
type: Deployment
name: api-service
jobAgent: github-actions
jobAgentConfig:
  installationId: 12345678
  owner: your-org
  repo: your-repo
  workflowId: 12345678
  ref: main # optional, defaults to main
FieldRequiredDescription
installationIdYesGitHub App installation ID
ownerYesRepository owner (org or user)
repoYesRepository name
workflowIdYesWorkflow ID (numeric)
refNoGit ref to run workflow on (default: main)

Finding Your Workflow ID

Use the GitHub API to find your workflow ID:
curl -H "Authorization: Bearer $GITHUB_TOKEN" \
  https://api.github.com/repos/OWNER/REPO/actions/workflows

Workflow Setup

Create a workflow file in your repository:
# .github/workflows/deploy.yml
name: Deploy

on:
  workflow_dispatch:
    inputs:
      job_id:
        description: "Ctrlplane Job ID"
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Get job context
        uses: ctrlplanedev/get-job-inputs@v1
        id: job
        with:
          job_id: ${{ inputs.job_id }}
          api_key: ${{ secrets.CTRLPLANE_API_KEY }}

      - name: Deploy
        run: |
          echo "Deploying ${{ steps.job.outputs.version_tag }}"
          echo "Environment: ${{ steps.job.outputs.environment_name }}"
          echo "Resource: ${{ steps.job.outputs.resource_identifier }}"

          # Your deployment commands here

Available Job Context

The get-job-inputs action provides these outputs:
OutputDescription
job_idThe Ctrlplane job ID
version_tagVersion tag being deployed
version_nameVersion name
environment_nameTarget environment name
environment_idTarget environment ID
resource_identifierTarget resource identifier
resource_nameTarget resource name
resource_kindTarget resource kind
resource_configResource config (JSON)
deployment_nameDeployment name
deployment_variablesDeployment variables (JSON)

Templating

You can use Go templates in your job agent config to dynamically configure workflows:
jobAgentConfig:
  installationId: "{{.variables.github_installation_id}}"
  owner: "{{.variables.github_org}}"
  repo: "{{.deployment.slug}}"
  workflowId: "{{.variables.workflow_id}}"
  ref: "{{.version.tag}}"

Status Reporting

The workflow should update job status. You can use the Ctrlplane CLI or API:
- name: Mark job successful
  if: success()
  run: |
    curl -X PATCH "https://app.ctrlplane.dev/api/v1/jobs/${{ inputs.job_id }}" \
      -H "Authorization: Bearer ${{ secrets.CTRLPLANE_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{"status": "successful"}'

- name: Mark job failed
  if: failure()
  run: |
    curl -X PATCH "https://app.ctrlplane.dev/api/v1/jobs/${{ inputs.job_id }}" \
      -H "Authorization: Bearer ${{ secrets.CTRLPLANE_API_KEY }}" \
      -H "Content-Type: application/json" \
      -d '{"status": "failure"}'

Example: Kubernetes Deployment

name: Deploy to Kubernetes

on:
  workflow_dispatch:
    inputs:
      job_id:
        required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Get job context
        uses: ctrlplanedev/get-job-inputs@v1
        id: job
        with:
          job_id: ${{ inputs.job_id }}
          api_key: ${{ secrets.CTRLPLANE_API_KEY }}

      - name: Configure kubectl
        uses: azure/k8s-set-context@v3
        with:
          kubeconfig: ${{ secrets.KUBECONFIG }}

      - name: Deploy
        run: |
          kubectl set image deployment/${{ steps.job.outputs.deployment_name }} \
            app=${{ steps.job.outputs.version_tag }} \
            -n ${{ fromJson(steps.job.outputs.resource_config).namespace }}