SynfraCore
Synfracore
Start Learning
Navigation

Academies

Platform

RoadmapsLabsCertificationsInterviewPYQsAI AssistantCareer
Start Learning Free Learning Roadmaps

GitHub ActionsInstallation

Step-by-step setup and installation guide

📄
Last updated Aug 2026
Expert Content

GitHub Actions — Installation Guide

No Installation Needed for GitHub-Hosted Runners

GitHub Actions is built into GitHub — there's no server to install. Add a workflow file and it runs automatically:

bash
mkdir -p .github/workflows
cat > .github/workflows/ci.yml << 'EOF'
name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Hello from GitHub Actions"
EOF

git add .github/workflows/ci.yml
git commit -m "Add first workflow"
git push
# Check the Actions tab in the GitHub UI — the workflow runs automatically

Install a Self-Hosted Runner (Single Machine)

Needed for custom hardware, persistent caches, or network access to internal resources — matching Advanced's coverage of self-hosted tradeoffs:

bash
# From the repo/org's Settings > Actions > Runners > New self-hosted runner —
# GitHub generates a registration command specific to your repo, similar to:
mkdir actions-runner && cd actions-runner
curl -o actions-runner.tar.gz -L https://github.com/actions/runner/releases/latest/download/actions-runner-linux-x64.tar.gz
tar xzf actions-runner.tar.gz

./config.sh --url https://github.com/myorg/myrepo --token <REGISTRATION_TOKEN>
./run.sh

# Verify it shows "Listening for Jobs" and appears online in Settings > Actions > Runners

Install Actions Runner Controller (ARC) — Kubernetes Autoscaling Fleet

The production-scale option, matching Advanced's "runner as a pod" model:

bash
helm install arc-controller \
  oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller \
  --namespace arc-systems --create-namespace

helm install ci-runners \
  oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set \
  --namespace arc-runners --create-namespace \
  --set githubConfigUrl="https://github.com/myorg/myrepo" \
  --set githubConfigSecret.github_token=<PAT_OR_APP_TOKEN>

kubectl get pods -n arc-systems
kubectl get pods -n arc-runners

Set Up OIDC for Cloud Authentication (No Long-Lived Secrets)

The modern pattern Module 03 introduces — a workflow requests a short-lived credential directly from the cloud provider rather than storing a long-lived secret in GitHub:

yaml
# In the workflow — request the OIDC token and assume a cloud role
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy
          aws-region: us-east-1

The corresponding AWS IAM trust policy must reference the GitHub OIDC provider and scope the sub claim to your specific repo — a genuinely separate, cloud-side configuration step from the workflow YAML itself.

Verify Everything Works

bash
# 1. Confirm a GitHub-hosted workflow runs on push (no setup required)

# 2. If self-hosted: confirm the runner shows "Idle" (not offline) in
#    Settings > Actions > Runners after `./run.sh` starts

# 3. If ARC: confirm runner pods scale up when a workflow is queued
kubectl get pods -n arc-runners -w

# 4. If OIDC: confirm a workflow using role-to-assume succeeds without
#    any AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY secret configured

Common Installation Issues

Self-hosted runner registers but never picks up jobs

bash
./run.sh
# Confirm the workflow's runs-on: label actually matches the runner's
# registered labels — a mismatch leaves jobs queued indefinitely with
# no error, just silence

ARC runner pods never scale up

bash
kubectl logs -n arc-systems deploy/arc-controller-...
# Check the githubConfigSecret token has the correct scope/permissions
# for the target repo or org

OIDC role assumption fails with "not authorized to perform sts:AssumeRoleWithWebIdentity"

The IAM trust policy's sub claim condition almost always doesn't match the actual workflow's repo/branch/environment context — this is the single most common OIDC setup failure, and the fix is checking the trust policy condition against the workflow's real sub claim value, not the workflow YAML itself.

Self-hosted runner on a public repo — security exposure

Advanced flags this directly: self-hosted runners on a public repo are a real risk, since a malicious PR's workflow can run arbitrary code on infrastructure the org controls. Never enable self-hosted runners for pull_request_target or auto-run on fork PRs without review.

What's Installed

GitHub-hosted runners — nothing to install; ephemeral, isolated VMs provisioned per run automatically
Self-hosted runner (if configured) — a persistent process (run.sh) polling GitHub for jobs matching its labels
ARC (if configured) — a Kubernetes-native controller and autoscaling runner-pod fleet
OIDC trust (if configured) — no artifact in GitHub itself; a trust relationship configured on the cloud provider's IAM side

Next Steps

Go to the Fundamentals section to build your first multi-job workflow.

Share:
Join our Community
Daily tips, job alerts, interview help — join engineers learning together
Up Next
🔤
GitHub ActionsFundamentals
Core concepts and commands — hands-on from the start
Also Worth Exploring
← Back to all GitHub Actions modules
PrerequisitesFundamentals