# Gitea Actions Reference > Based on Gitea 1.21+ and act_runner v0.2.x > Gitea Actions is compatible with GitHub Actions syntax. Both `github.*` and `gitea.*` context namespaces work; prefer `gitea.*` for Gitea-specific deployments. --- ## Table of Contents 1. [Workflow File Location](#workflow-file-location) 2. [Trigger Events (`on:`)](#trigger-events-on) 3. [Context Variables](#context-variables) 4. [Secrets](#secrets) 5. [Variables (`vars`)](#variables-vars) 6. [Built-in Environment Variables](#built-in-environment-variables) 7. [Expression Syntax & Functions](#expression-syntax--functions) 8. [Runner Labels](#runner-labels) 9. [Differences from GitHub Actions](#differences-from-github-actions) 10. [Unsupported Features](#unsupported-features) 11. [Badge URLs](#badge-urls) --- ## Workflow File Location ``` .gitea/workflows/.yaml ``` Basic structure: ```yaml name: My Workflow run-name: ${{ gitea.actor }} triggered ${{ gitea.event_name }} on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run something run: echo "Hello from ${{ gitea.actor }}" ``` --- ## Trigger Events (`on:`) ### Supported Events | Event | Activity Types | |---|---| | `push` | — | | `pull_request` | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `synchronize`, `labeled`, `unlabeled` | | `pull_request_review` | `submitted`, `edited` | | `pull_request_review_comment` | `created`, `edited` | | `issues` | `opened`, `edited`, `closed`, `reopened`, `assigned`, `unassigned`, `milestoned`, `demilestoned`, `labeled`, `unlabeled` | | `issue_comment` | `created`, `edited`, `deleted` | | `release` | `published`, `edited` | | `registry_package` | `published` | | `create` | — | | `delete` | — | | `fork` | — | | `gollum` | — | | `workflow_dispatch` | — | | `workflow_run` | `requested`, `completed` | | `schedule` | — | ### Filter Options ```yaml on: push: branches: - main - 'feature/**' tags: - 'v*' paths: - 'src/**' pull_request: types: [opened, synchronize] branches: - main schedule: - cron: '0 1 * * *' - cron: '@daily' # Gitea extension (not available in GitHub Actions) - cron: '@hourly' # Gitea extension - cron: '@weekly' # Gitea extension - cron: '@monthly' # Gitea extension - cron: '@yearly' # Gitea extension ``` ### `workflow_dispatch` with Inputs Adds a "Run workflow" button in the Gitea UI. The workflow must be on the **default branch** to appear. ```yaml on: workflow_dispatch: inputs: environment: description: 'Target environment' required: true type: choice options: - staging - production dry_run: description: 'Dry run' required: false type: boolean default: false version: description: 'Version number' type: string ``` Supported input types: `string`, `boolean`, `choice`, `number`, `environment` Access inputs via: `${{ inputs.environment }}` or `${{ gitea.event.inputs.environment }}` --- ## Context Variables ### `gitea.*` / `github.*` Both namespaces are identical. Prefer `gitea.*`. | Variable | Description | |---|---| | `gitea.actor` | Username that triggered the workflow | | `gitea.event_name` | Triggering event name (`push`, `pull_request`, etc.) | | `gitea.event` | Full event payload object | | `gitea.ref` | Full ref (`refs/heads/main`, `refs/pull/1/head`) | | `gitea.ref_name` | Short ref name (`main`, `v1.0`) | | `gitea.ref_type` | `branch` or `tag` | | `gitea.sha` | Full commit SHA | | `gitea.repository` | `owner/repo` | | `gitea.repository_owner` | Repository owner (user or org name) | | `gitea.workspace` | Workspace path on the runner | | `gitea.run_id` | Unique ID for this workflow run | | `gitea.run_number` | Sequential run number for this workflow | | `gitea.server_url` | Gitea instance base URL | | `gitea.api_url` | Gitea API URL | | `gitea.head_ref` | PR source branch name | | `gitea.base_ref` | PR target branch name | | `gitea.token` | Auto-generated short-lived job token | | `gitea.workflow` | Workflow name | | `gitea.job` | Current job ID | > **Note**: `gitea.repository_owner` preserves original casing. Use `tr '[:upper:]' '[:lower:]'` when used in Docker image tags. ### `runner.*` | Variable | Description | |---|---| | `runner.os` | `Linux`, `Windows`, or `macOS` | | `runner.arch` | `X64`, `ARM64`, etc. | | `runner.name` | Runner name | | `runner.tool_cache` | Tool cache directory | | `runner.temp` | Temp directory | ### `steps.*` ```yaml steps..outputs. steps..conclusion # success, failure, cancelled, skipped steps..outcome # success, failure, cancelled, skipped ``` ### `needs.*` ```yaml needs..outputs. needs..result # success, failure, cancelled, skipped ``` ### `secrets.*` ```yaml secrets.GITEA_TOKEN # auto-generated job token (cannot push to package registry) secrets.GITHUB_TOKEN # alias for the same token secrets. # user-defined secrets ``` ### `vars.*` ```yaml vars. # non-sensitive config variables (stored in UPPERCASE) ``` ### `inputs.*` ```yaml inputs. # for workflow_dispatch and workflow_call ``` ### `matrix.*` / `strategy.*` ```yaml matrix. # current matrix combination value strategy.fail-fast strategy.max-parallel ``` --- ## Secrets ### Scope (highest to lowest priority) 1. Repository secrets 2. Organization secrets 3. User secrets ### Rules - Allowed characters: `[a-zA-Z0-9_]` - Cannot start with `GITHUB_`, `GITEA_`, or a number - Case-insensitive ### Usage ```yaml steps: - name: Use secret env: API_KEY: ${{ secrets.API_KEY }} run: ./deploy.sh $API_KEY ``` ### Auto Token (`GITEA_TOKEN`) Automatically injected into every job. Short-lived — invalidated when the job completes. **Known limitation**: `GITEA_TOKEN` / `GITHUB_TOKEN` **cannot push to the Gitea package/container registry**. Use a Personal Access Token (PAT) with `package` scope stored as a manual secret instead. --- ## Variables (`vars`) Non-sensitive configuration values, visible in logs. ### Scope (highest to lowest priority) 1. Repository variables 2. Organization variables 3. User variables ### Rules - Allowed characters: `[a-zA-Z0-9_]` - Cannot start with `GITHUB_`, `GITEA_`, `CI`, or a number - Keys are stored and accessed in **UPPERCASE** ### Usage ```yaml steps: - run: echo "Deploying to ${{ vars.ENVIRONMENT }}" ``` ### Inline `env` (workflow/job/step level) ```yaml env: GLOBAL_VAR: "value" # available to all jobs jobs: build: env: JOB_VAR: "value" # available to all steps in this job steps: - env: STEP_VAR: "value" # only this step run: echo $STEP_VAR ``` --- ## Built-in Environment Variables Automatically injected into every step: | Variable | Description | |---|---| | `CI` | Always `true` | | `GITHUB_WORKFLOW` / `GITEA_WORKFLOW` | Workflow name | | `GITHUB_RUN_ID` / `GITEA_RUN_ID` | Unique run ID | | `GITHUB_RUN_NUMBER` / `GITEA_RUN_NUMBER` | Sequential run number | | `GITHUB_ACTOR` / `GITEA_ACTOR` | Triggering username | | `GITHUB_REPOSITORY` | `owner/repo` | | `GITHUB_EVENT_NAME` | Event name | | `GITHUB_SHA` | Commit SHA | | `GITHUB_REF` | Full ref | | `GITHUB_REF_NAME` | Short ref name | | `GITHUB_REF_TYPE` | `branch` or `tag` | | `GITHUB_HEAD_REF` | PR source branch | | `GITHUB_BASE_REF` | PR target branch | | `GITHUB_WORKSPACE` | Workspace directory | | `GITHUB_SERVER_URL` | Gitea instance URL | | `GITHUB_API_URL` | Gitea API URL | | `GITHUB_TOKEN` / `GITEA_TOKEN` | Auto job token | | `RUNNER_OS` | Runner OS | | `RUNNER_ARCH` | Runner architecture | | `RUNNER_NAME` | Runner name | | `RUNNER_TEMP` | Temp directory | | `RUNNER_TOOL_CACHE` | Tool cache directory | --- ## Expression Syntax & Functions ### Syntax ```yaml ${{ }} # In `if:` blocks, the ${{ }} wrapper is optional: if: github.ref == 'refs/heads/main' if: ${{ github.ref == 'refs/heads/main' }} ``` ### Operators | Operator | Description | |---|---| | `( )` | Grouping | | `[ ]` | Index | | `.` | Property access | | `!` | Not | | `<` `>` `<=` `>=` | Comparison | | `==` `!=` | Equality | | `&&` `\|\|` | Logical AND / OR | ### Functions | Function | Description | |---|---| | `contains(search, item)` | True if string/array contains item | | `startsWith(str, prefix)` | Case-insensitive prefix check | | `endsWith(str, suffix)` | Case-insensitive suffix check | | `format(str, val0, val1, ...)` | String formatting with `{0}`, `{1}` placeholders | | `join(array, separator)` | Join array with delimiter | | `toJSON(value)` | Serialize to JSON string | | `fromJSON(value)` | Parse JSON string to object | | `hashFiles(path)` | SHA-256 hash of file(s) matching glob | | `success()` | True if all previous steps succeeded | | `failure()` | True if any previous step failed | | `cancelled()` | True if workflow was cancelled | | `always()` | Always true; forces step execution | ### Examples ```yaml if: contains(gitea.ref, 'main') if: startsWith(gitea.ref, 'refs/tags/') if: always() if: failure() if: success() && gitea.ref == 'refs/heads/main' run: echo ${{ format('Hello {0}', gitea.actor) }} ``` --- ## Runner Labels Labels map `runs-on:` values in workflows to runner execution environments. ### Label Format ```