DEV Community

Alex Spinov
Alex Spinov

Posted on

Gitea Actions Has a Free API — Heres How to Self-Host GitHub Actions

Gitea Actions is a CI/CD system compatible with GitHub Actions workflows — self-hosted, free, and runs the same YAML files. Your existing .github/workflows just work.

Why Gitea Actions?

  • GitHub Actions compatible: Same YAML syntax
  • Self-hosted: Your server, your data
  • Free: No per-minute billing
  • Lightweight: Runs on a $5 VPS
  • Built into Gitea: No separate CI service
  • Act runner: Use the same runner locally

Enable Gitea Actions

# app.ini
[actions]
ENABLED = true
Enter fullscreen mode Exit fullscreen mode

Register a Runner

# Install act_runner
wget https://gitea.com/gitea/act_runner/releases/latest/act_runner-linux-amd64
chmod +x act_runner-linux-amd64

# Register with Gitea instance
./act_runner-linux-amd64 register \
  --instance https://gitea.example.com \
  --token YOUR_REGISTRATION_TOKEN \
  --name my-runner

# Start the runner
./act_runner-linux-amd64 daemon
Enter fullscreen mode Exit fullscreen mode

Same GitHub Actions YAML

# .gitea/workflows/ci.yml (or .github/workflows/ci.yml)
name: CI
on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install
      - run: npm test

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install
      - run: npx eslint src/

  build:
    needs: [test, lint]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm install && npm run build
Enter fullscreen mode Exit fullscreen mode

Docker Build and Push

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: gitea.example.com
          username: ${{ secrets.REGISTRY_USER }}
          password: ${{ secrets.REGISTRY_PASS }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: gitea.example.com/myorg/myapp:latest
Enter fullscreen mode Exit fullscreen mode

API: List Workflow Runs

curl https://gitea.example.com/api/v1/repos/owner/repo/actions/runs \
  -H 'Authorization: token YOUR_TOKEN'
Enter fullscreen mode Exit fullscreen mode

API: Trigger Workflow

curl -X POST https://gitea.example.com/api/v1/repos/owner/repo/actions/workflows/ci.yml/dispatches \
  -H 'Authorization: token YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"ref": "main"}'
Enter fullscreen mode Exit fullscreen mode

Scheduled Workflows

on:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A team paid $300/mo for GitHub Actions minutes. They set up Gitea on a $20 Hetzner server — same workflows, unlimited minutes, and their code stays on their infrastructure. Annual savings: $3,360.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)