Files
runner-test/.github/workflows/00-suite-runner.yml
T
tqcq 060158eb2e
Gitea Actions Compatibility Suite / c7 (push) Failing after 0s
Gitea Actions Compatibility Suite / c9 (push) Failing after 0s
Gitea Actions Compatibility Suite / probe (push) Successful in 0s
Gitea Actions Compatibility Suite / c1 (push) Failing after 0s
Gitea Actions Compatibility Suite / c2 (push) Failing after 0s
Gitea Actions Compatibility Suite / c3 (push) Failing after 0s
Gitea Actions Compatibility Suite / c4 (push) Failing after 0s
Gitea Actions Compatibility Suite / c5 (push) Failing after 0s
Gitea Actions Compatibility Suite / c6 (push) Failing after 0s
Gitea Actions Compatibility Suite / c8 (push) Failing after 0s
Gitea Actions Compatibility Suite / c10 (push) Failing after 0s
Gitea Actions Compatibility Suite / aggregate (push) Failing after 0s
feat: Gitea Actions compatibility test suite
A self-validating test suite that proves Gitea's implementations of
GitHub-style actions behave like GitHub's. Push to any Gitea instance
with a registered runner — on push or manual dispatch, it runs 10
independent test workflows covering checkout, artifacts, caching,
language setup, expression contexts, workflow commands, services,
composite/reusable workflows, control flow, and known divergences.

Components:
- lib/assert.sh — self-asserting shell helper library (assert_eq,
  assert_contains, assert_exists, assert_not_exists, assert_match,
  sha256_of) with verified negative fail path
- 10 reusable workflows (on: workflow_call):
  01-checkout, 02-artifacts, 03-cache, 04-setup-runtime,
  05-contexts, 06-workflow-commands, 07-services,
  08-composite-reusable, 09-control-flow, 10-gitea-divergences
- 00-suite-runner.yml — sole entry (on: push + workflow_dispatch):
  probe gate (Gitea >= 1.22.0) -> c1-c10 parallel callers
  (c5/c8 forward secrets: inherit for act_runner #125) ->
  aggregate (if: always, skipped-as-failure)
- Fixtures: LFS 5MB binary, git tag v1-test, 4 language lockfiles
  (npm/go/pip/maven), sparse-cone layout
- Makefile: make lint (actionlint static gate)
- README: prerequisites, per-test expectations, correction table,
  manual eyeball checklist for UI-only behaviors
2026-07-07 16:08:49 +00:00

157 lines
6.2 KiB
YAML

---
# 00-suite-runner.yml - entry point for the Gitea Actions compatibility suite.
#
# This is the SOLE entry workflow. It has the push/workflow_dispatch triggers.
# The ten sub-workflows (01-10) are `on: workflow_call` only and are invoked by
# the caller jobs c1..c10 below. Numeric filename prefixes are for HUMAN reading
# order only; execution order comes exclusively from `needs:` dependencies.
#
# Flow: probe (hard gate) -> c1..c10 (parallel callers) -> aggregate (must-all-pass).
# If probe fails, every cN is skipped (it needs probe), and aggregate (if: always())
# sees them as non-success and turns the run red - never green.
name: Gitea Actions Compatibility Suite
on: [push, workflow_dispatch]
permissions:
contents: read
jobs:
probe:
runs-on: ubuntu-24.04
outputs:
gitea-version: ${{ steps.check.outputs.gitea-version }}
steps:
- name: check-gitea-version
id: check
run: |
# Probe the Gitea instance version. GITHUB_API_URL is the GitHub-Actions
# compatible endpoint Gitea exposes; GITEA_API_URL is the native one.
VERSION=""
if [ -n "${GITHUB_API_URL:-}" ]; then
VERSION=$(curl -sf "${GITHUB_API_URL}/version" 2>/dev/null | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) || true
fi
if [ -n "${GITEA_API_URL:-}" ]; then
VERSION=$(curl -sf "${GITEA_API_URL}/version" 2>/dev/null | grep -o '"version":"[^"]*"' | head -1 | cut -d'"' -f4) || true
fi
echo "Detected Gitea version: ${VERSION:-unknown}"
echo "gitea-version=${VERSION:-unknown}" >> "$GITHUB_OUTPUT"
# Assert >= 1.22.0 (minimum to parse/accept workflows).
MAJOR=0; MINOR=0; PATCH=0
if [[ "$VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+) ]]; then
MAJOR="${BASH_REMATCH[1]}"
MINOR="${BASH_REMATCH[2]}"
PATCH="${BASH_REMATCH[3]}"
fi
if [ "$MAJOR" -lt 1 ] || { [ "$MAJOR" -eq 1 ] && [ "$MINOR" -lt 22 ]; }; then
echo "::error::Gitea version ${VERSION:-unknown} is below 1.22.0 (minimum to parse/accept workflows). Suite aborted."
exit 1
fi
echo "Gitea version ${VERSION} (major=${MAJOR} minor=${MINOR} patch=${PATCH}) >= 1.22.0: OK"
- name: check-action-mirroring
continue-on-error: true
run: |
# Best-effort: check that action mirroring can resolve at least one actions/* ref.
echo "Best-effort action mirroring check (informational only, not a hard gate)"
echo "If actions fail to resolve at runtime, check ACTIONS_URL / DEFAULT_ACTIONS_URL settings"
- name: check-storage-cache
continue-on-error: true
run: |
# Best-effort: note about storage and cache.
echo "Storage backend and cache server should be configured. Artifacts and cache tests will fail if not."
# --- Caller jobs: each invokes a reusable workflow via `uses:`.
# Execution order is governed ONLY by `needs:` here, NOT by the numeric
# filename prefixes of the referenced workflows. The cN jobs are independent
# of each other (they all only need probe) and run in parallel.
c1:
needs: probe
uses: ./.github/workflows/01-checkout.yml
c2:
needs: probe
uses: ./.github/workflows/02-artifacts.yml
c3:
needs: probe
uses: ./.github/workflows/03-cache.yml
c4:
needs: probe
uses: ./.github/workflows/04-setup-runtime.yml
c5:
needs: probe
uses: ./.github/workflows/05-contexts.yml
secrets: inherit
c6:
needs: probe
uses: ./.github/workflows/06-workflow-commands.yml
c7:
needs: probe
uses: ./.github/workflows/07-services.yml
c8:
needs: probe
uses: ./.github/workflows/08-composite-reusable.yml
with:
who: gitea-compat-suite
secrets: inherit
c9:
needs: probe
uses: ./.github/workflows/09-control-flow.yml
c10:
needs: probe
uses: ./.github/workflows/10-gitea-divergences.yml
aggregate:
needs: [probe, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10]
if: always()
runs-on: ubuntu-24.04
steps:
- name: aggregate-results
run: |
# Fail unless probe AND every cN is 'success'.
# A skipped (probe failed) or cancelled component counts as failure,
# which is why `if: always()` runs this job even when upstream failed.
#
# NOTE: GitHub Actions expressions are evaluated by the runner BEFORE
# shell runs, so the needs context cannot be indexed by a shell
# variable (writing needs.$j.result would never substitute $j into the
# pre-evaluated expression). Each needs.<job>.result is written out
# explicitly below.
echo "probe=${{ needs.probe.result }}"
echo "c1=${{ needs.c1.result }}"
echo "c2=${{ needs.c2.result }}"
echo "c3=${{ needs.c3.result }}"
echo "c4=${{ needs.c4.result }}"
echo "c5=${{ needs.c5.result }}"
echo "c6=${{ needs.c6.result }}"
echo "c7=${{ needs.c7.result }}"
echo "c8=${{ needs.c8.result }}"
echo "c9=${{ needs.c9.result }}"
echo "c10=${{ needs.c10.result }}"
all_ok=true
if [ "${{ needs.probe.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c1.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c2.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c3.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c4.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c5.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c6.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c7.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c8.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c9.result }}" != "success" ]; then all_ok=false; fi
if [ "${{ needs.c10.result }}" != "success" ]; then all_ok=false; fi
if [ "$all_ok" != "true" ]; then
echo "::error::Suite FAILED: not all components reported success"
exit 1
fi
echo "Suite PASSED: all components reported success"