> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/go-gitea/gitea/llms.txt
> Use this file to discover all available pages before exploring further.

# Gitea Actions

> Built-in CI/CD automation system compatible with GitHub Actions for workflows, testing, and deployments

## Overview

Gitea Actions is a built-in CI/CD system that enables automated workflows for building, testing, and deploying your code. With GitHub Actions compatibility, you can reuse existing workflows and actions from the broader ecosystem.

## Key Features

<CardGroup cols={2}>
  <Card title="GitHub Actions Compatible" icon="github">
    * Reuse GitHub Actions workflows
    * Use actions from marketplace
    * Compatible YAML syntax
    * Familiar workflow patterns
  </Card>

  <Card title="Self-Hosted Runners" icon="server">
    * Run on your infrastructure
    * Full control over environment
    * Custom runner labels
    * Secure execution
  </Card>

  <Card title="Matrix Builds" icon="table-cells">
    * Test multiple versions
    * Cross-platform builds
    * Parallel execution
    * Efficient resource usage
  </Card>

  <Card title="Workflow Automation" icon="robot">
    * Event-driven triggers
    * Scheduled workflows
    * Manual dispatch
    * Conditional execution
  </Card>
</CardGroup>

## Getting Started

<Steps>
  <Step title="Enable Actions">
    Repository administrators must enable Actions in **Settings** → **Actions**. Instance administrators must enable Actions in the Gitea configuration.
  </Step>

  <Step title="Create Workflow File">
    Create `.gitea/workflows/` or `.github/workflows/` directory in your repository:

    ```bash theme={null}
    mkdir -p .gitea/workflows
    touch .gitea/workflows/ci.yml
    ```
  </Step>

  <Step title="Define Workflow">
    Write your workflow configuration in YAML format
  </Step>

  <Step title="Commit and Push">
    Commit the workflow file and push to trigger execution:

    ```bash theme={null}
    git add .gitea/workflows/ci.yml
    git commit -m "Add CI workflow"
    git push origin main
    ```
  </Step>
</Steps>

## Workflow Syntax

### Basic Workflow

```yaml theme={null}
name: CI Pipeline

# Trigger events
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
  workflow_dispatch:  # Manual trigger

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Run tests
        run: npm test
      
      - name: Build
        run: npm run build
```

### Workflow Components

<Accordion title="Workflow Structure">
  **name**: Workflow display name

  **on**: Event triggers that start the workflow

  * `push`: When code is pushed
  * `pull_request`: When PR is created/updated
  * `schedule`: Cron-based scheduling
  * `workflow_dispatch`: Manual trigger
  * `release`: When release is published

  **jobs**: Individual units of work

  * Run in parallel by default
  * Can have dependencies
  * Each runs in fresh environment

  **steps**: Sequential tasks within a job

  * Execute in order
  * Share job environment
  * Can use actions or run commands
</Accordion>

## Action Run Model

```go theme={null}
// From models/actions/run.go
type ActionRun struct {
    ID                int64
    Title             string
    RepoID            int64
    Repo              *repo_model.Repository
    OwnerID           int64
    WorkflowID        string  // Workflow file name
    Index             int64   // Unique number per repo
    TriggerUserID     int64
    TriggerUser       *user_model.User
    Ref               string  // Branch/tag that triggered run
    CommitSHA         string
    Event             webhook_module.HookEventType
    EventPayload      string  // JSON payload
    Status            Status
    Started           timeutil.TimeStamp
    Stopped           timeutil.TimeStamp
    PreviousDuration  time.Duration
}

func (run *ActionRun) HTMLURL() string {
    if run.Repo == nil {
        return ""
    }
    return fmt.Sprintf("%s/actions/runs/%d", 
                      run.Repo.HTMLURL(), run.Index)
}
```

## Triggers

### Push Events

```yaml theme={null}
on:
  push:
    branches:
      - main
      - 'release/**'  # Branch patterns
    tags:
      - 'v*'          # Tag patterns
    paths:
      - 'src/**'      # Only when these paths change
      - '!docs/**'    # Ignore docs changes
```

### Pull Request Events

```yaml theme={null}
on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
    branches:
      - main
    paths-ignore:
      - '**.md'       # Ignore markdown changes
```

### Scheduled Workflows

```yaml theme={null}
on:
  schedule:
    # Run at 2:00 AM every day
    - cron: '0 2 * * *'
    # Run every Monday at 9:00 AM
    - cron: '0 9 * * 1'
```

### Manual Dispatch

```yaml theme={null}
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to deploy to'
        required: true
        type: choice
        options:
          - development
          - staging
          - production
      debug_enabled:
        description: 'Enable debug logging'
        required: false
        type: boolean
        default: false
```

## Jobs and Steps

### Job Dependencies

```yaml theme={null}
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm run build
  
  test:
    needs: build      # Wait for build to complete
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm test
  
  deploy:
    needs: [build, test]  # Wait for both
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - run: ./deploy.sh
```

### Matrix Strategy

```yaml theme={null}
jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: [16, 18, 20]
        exclude:
          - os: macos-latest
            node: 16
    
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node }}
      - run: npm test
```

### Conditional Execution

```yaml theme={null}
steps:
  - name: Run on main branch only
    if: github.ref == 'refs/heads/main'
    run: echo "Main branch"
  
  - name: Run on PR only
    if: github.event_name == 'pull_request'
    run: echo "Pull request"
  
  - name: Run when tests pass
    if: success()
    run: echo "Tests passed"
  
  - name: Run on failure
    if: failure()
    run: echo "Something failed"
  
  - name: Always run
    if: always()
    run: echo "Cleanup"
```

## Using Actions

### Built-in Actions

```yaml theme={null}
steps:
  # Checkout repository
  - uses: actions/checkout@v3
    with:
      fetch-depth: 0  # Full history
  
  # Setup language runtime
  - uses: actions/setup-node@v3
    with:
      node-version: '18'
      cache: 'npm'
  
  # Upload artifacts
  - uses: actions/upload-artifact@v3
    with:
      name: build-output
      path: dist/
  
  # Download artifacts
  - uses: actions/download-artifact@v3
    with:
      name: build-output
```

### Custom Actions

Create reusable actions in your repository or organization:

```yaml theme={null}
# .gitea/actions/my-action/action.yml
name: 'My Custom Action'
description: 'Does something useful'
inputs:
  input-param:
    description: 'Input parameter'
    required: true
outputs:
  result:
    description: 'Action result'
runs:
  using: 'composite'
  steps:
    - run: echo "${{ inputs.input-param }}"
      shell: bash
```

Use custom action:

```yaml theme={null}
steps:
  - uses: ./.gitea/actions/my-action
    with:
      input-param: 'value'
```

## Secrets and Variables

### Repository Secrets

Store sensitive data securely:

<Steps>
  <Step title="Add Secrets">
    Navigate to **Settings** → **Secrets** and add secrets like API keys, tokens, and passwords
  </Step>

  <Step title="Use in Workflows">
    ```yaml theme={null}
    steps:
      - name: Deploy
        env:
          API_KEY: ${{ secrets.API_KEY }}
          DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
        run: ./deploy.sh
    ```
  </Step>
</Steps>

<Note>
  Secrets are encrypted and never exposed in logs. They're only available to workflows in the repository where they're defined.
</Note>

### Variables

```yaml theme={null}
env:
  # Workflow-level variables
  NODE_ENV: production
  API_URL: https://api.example.com

jobs:
  build:
    env:
      # Job-level variables
      BUILD_DIR: ./dist
    
    steps:
      - name: Build
        env:
          # Step-level variables
          CUSTOM_VAR: value
        run: npm run build
```

### Context Variables

Access workflow metadata:

```yaml theme={null}
steps:
  - name: Print context
    run: |
      echo "Repository: ${{ github.repository }}"
      echo "Ref: ${{ github.ref }}"
      echo "SHA: ${{ github.sha }}"
      echo "Actor: ${{ github.actor }}"
      echo "Event: ${{ github.event_name }}"
      echo "Run ID: ${{ github.run_id }}"
      echo "Run Number: ${{ github.run_number }}"
```

## Runners

### Runner Labels

Target specific runners:

```yaml theme={null}
jobs:
  build-linux:
    runs-on: ubuntu-latest
  
  build-windows:
    runs-on: windows-latest
  
  build-mac:
    runs-on: macos-latest
  
  custom-runner:
    runs-on: [self-hosted, gpu, linux]
```

### Self-Hosted Runners

Register custom runners:

<Steps>
  <Step title="Download Runner">
    Download the Gitea Actions runner for your platform from the Gitea releases page
  </Step>

  <Step title="Register Runner">
    ```bash theme={null}
    ./act_runner register \
      --instance https://gitea.example.com \
      --token YOUR_RUNNER_TOKEN \
      --name my-runner \
      --labels linux,x64,gpu
    ```
  </Step>

  <Step title="Start Runner">
    ```bash theme={null}
    ./act_runner daemon
    ```
  </Step>
</Steps>

<Note>
  Self-hosted runners can access your internal network and resources. Only use them with trusted repositories.
</Note>

## Artifacts and Caching

### Artifacts

```yaml theme={null}
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: npm run build
      
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: |
            dist/
            build/
          retention-days: 7
  
  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Download artifacts
        uses: actions/download-artifact@v3
        with:
          name: build-artifacts
      
      - run: ./deploy.sh
```

### Caching Dependencies

```yaml theme={null}
steps:
  - uses: actions/checkout@v3
  
  - name: Cache node modules
    uses: actions/cache@v3
    with:
      path: ~/.npm
      key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-node-
  
  - run: npm ci
```

## Status Badges

Display workflow status in README:

```markdown theme={null}
![CI](https://gitea.example.com/user/repo/actions/workflows/ci.yml/badge.svg)

<!-- With branch -->
![CI](https://gitea.example.com/user/repo/actions/workflows/ci.yml/badge.svg?branch=main)
```

## Notifications

Gitea Actions integrates with the notification system:

<CardGroup cols={2}>
  <Card title="Success Notifications" icon="circle-check">
    * Workflow completion
    * Job success
    * Deployment success
    * Custom success actions
  </Card>

  <Card title="Failure Notifications" icon="circle-xmark">
    * Build failures
    * Test failures
    * Deployment errors
    * Timeout notifications
  </Card>
</CardGroup>

## Example Workflows

<Tabs>
  <Tab title="Node.js CI">
    ```yaml theme={null}
    name: Node.js CI

    on:
      push:
        branches: [main]
      pull_request:
        branches: [main]

    jobs:
      test:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            node-version: [16, 18, 20]
        
        steps:
          - uses: actions/checkout@v3
          
          - name: Setup Node.js ${{ matrix.node-version }}
            uses: actions/setup-node@v3
            with:
              node-version: ${{ matrix.node-version }}
              cache: 'npm'
          
          - run: npm ci
          - run: npm run build
          - run: npm test
    ```
  </Tab>

  <Tab title="Docker Build">
    ```yaml theme={null}
    name: Docker Build

    on:
      push:
        tags:
          - 'v*'

    jobs:
      docker:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          
          - name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v2
          
          - name: Login to Registry
            uses: docker/login-action@v2
            with:
              registry: gitea.example.com
              username: ${{ github.actor }}
              password: ${{ secrets.REGISTRY_TOKEN }}
          
          - name: Build and push
            uses: docker/build-push-action@v4
            with:
              context: .
              push: true
              tags: gitea.example.com/user/app:${{ github.ref_name }}
    ```
  </Tab>

  <Tab title="Go CI">
    ```yaml theme={null}
    name: Go CI

    on: [push, pull_request]

    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          
          - name: Setup Go
            uses: actions/setup-go@v4
            with:
              go-version: '1.21'
          
          - name: Build
            run: go build -v ./...
          
          - name: Test
            run: go test -v -race -coverprofile=coverage.out ./...
          
          - name: Upload coverage
            uses: actions/upload-artifact@v3
            with:
              name: coverage
              path: coverage.out
    ```
  </Tab>
</Tabs>

## Best Practices

<Accordion title="Workflow Optimization">
  **Performance**

  * Use caching for dependencies
  * Run jobs in parallel when possible
  * Use matrix builds efficiently
  * Clean up artifacts regularly

  **Security**

  * Store secrets securely
  * Limit secret exposure
  * Use minimal permissions
  * Pin action versions
  * Review third-party actions

  **Maintainability**

  * Use descriptive job and step names
  * Document complex workflows
  * Reuse workflows with templates
  * Keep workflows DRY (Don't Repeat Yourself)
  * Version control workflow files

  **Reliability**

  * Handle failures gracefully
  * Use appropriate timeouts
  * Add retry logic for flaky tests
  * Monitor workflow execution
  * Set up failure notifications
</Accordion>

## See Also

* [Pull Requests](/features/pull-requests) - Integrate Actions with PR workflows
* [Packages](/features/packages) - Build and publish packages
* [Repositories](/features/repositories) - Repository management
