GRM-51: ci: add actionlint and act_runner exec for workflow verification

This commit is contained in:
emil
2026-06-22 05:03:34 +00:00
parent 7a6d93cddc
commit bec7b59671
7 changed files with 78 additions and 12 deletions
+9
View File
@@ -0,0 +1,9 @@
# actionlint configuration for Gitea Actions workflows
# https://github.com/rhysd/actionlint/blob/main/docs/config.md
#
# Run: actionlint -config-file .gitea/actionlint.yaml .gitea/workflows/*.yml
# Custom self-hosted runner labels used in runs-on
self-hosted-runner:
labels:
- docker
+8 -4
View File
@@ -18,10 +18,14 @@ jobs:
REPO_TOKEN: ${{ secrets.REPO_TOKEN }}
VIKUNJA_TOKEN: ${{ secrets.VIKUNJA_TOKEN }}
PYTHONPATH: src
HEAD_REF: ${{ github.head_ref }}
PR_TITLE: ${{ github.event.pull_request.title }}
REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.number }}
run: |
python3 scripts/ci/auto_merge.py \
"${{ github.head_ref }}" \
"${{ github.event.pull_request.title }}" \
"${{ github.repository }}" \
"${{ github.event.number }}" \
"$HEAD_REF" \
"$PR_TITLE" \
"$REPOSITORY" \
"$PR_NUMBER" \
"ready-to-merge"
+12 -4
View File
@@ -13,9 +13,16 @@ jobs:
- uses: actions/checkout@v4
- name: Set up environment
run: make setup
- name: Install actionlint
run: |
set -euo pipefail
mkdir -p "$HOME/.local/bin"
bash <(curl -sL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) latest "$HOME/.local/bin"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Lint all
run: |
. .venv/bin/activate
export PATH="$HOME/.local/bin:$PATH"
make lint-all
- name: Unit tests with 100% coverage
run: |
@@ -150,14 +157,14 @@ jobs:
# Skip if runner index exceeds available runners
if [ "$RUNNER_INDEX" -gt "$MAX_RUNNERS" ]; then
echo "Skipping — runner index $RUNNER_INDEX > max runners $MAX_RUNNERS"
echo "TEST_PAIRS=" >> $GITHUB_ENV
echo "SKIP=true" >> $GITHUB_ENV
echo "TEST_PAIRS=" >> "$GITHUB_ENV"
echo "SKIP=true" >> "$GITHUB_ENV"
exit 0
fi
PAIRS=$(python3 scripts/ci/distribute_molecule.py --runner-index "$RUNNER_INDEX" --max-runners "$MAX_RUNNERS")
echo "Assigned pairs: $PAIRS"
echo "TEST_PAIRS=$PAIRS" >> $GITHUB_ENV
echo "SKIP=false" >> $GITHUB_ENV
echo "TEST_PAIRS=$PAIRS" >> "$GITHUB_ENV"
echo "SKIP=false" >> "$GITHUB_ENV"
- name: Run molecule tests
if: env.SKIP != 'true'
run: |
@@ -167,6 +174,7 @@ jobs:
echo "No test pairs assigned — skipping"
exit 0
fi
# shellcheck disable=SC2086 # intentional word splitting for argument expansion
python3 scripts/ci/molecule_ci_guard.py $TEST_PAIRS
env:
GITEA_URL: ${{ github.server_url }}
+1 -1
View File
@@ -155,7 +155,7 @@ jobs:
git checkout --orphan badges
git rm -rf .
cp -r .badges/* .
git add *.svg
git add ./*.svg
git commit --no-verify -m "Update badges [skip ci]"
git push origin badges --force
- name: Notify on failure
+9
View File
@@ -48,6 +48,15 @@ repos:
pass_filenames: false
stages: [pre-commit]
- id: workflow-lint
name: actionlint (workflow YAML)
entry: make workflow-lint
language: system
files: ^\.gitea/workflows/
types: [yaml]
pass_filenames: false
stages: [pre-commit]
- id: pytest-cov
name: pytest with 100% coverage
entry: make pytest-cov
+22 -1
View File
@@ -4,14 +4,35 @@
```bash
make setup # Create venv, install deps, set up hooks
make lint-all # ruff + pyright + bandit + ansible-lint + checkmake
make lint-all # ruff + pyright + bandit + ansible-lint + checkmake + actionlint
make pytest-cov # Unit tests with 100% coverage enforcement
make test-unit # Unit tests without coverage
make molecule # All 6 scenarios on Ubuntu 22.04
make molecule-all # All 6 scenarios on all 4 supported OSes
make test-all # pytest-cov + molecule
make workflow-lint # Static lint of .gitea/workflows/*.yml (actionlint)
make workflow-dryrun # Dry-run all workflows in Docker (act_runner exec --dryrun)
make workflow-check # workflow-lint + workflow-dryrun
```
## Workflow Verification (Before Push)
Workflow YAML files (`.gitea/workflows/*.yml`) are verified with two tools:
1. **actionlint** — Static linter that catches syntax errors, invalid
expressions, unknown keys, type mismatches, and shellcheck issues.
Config: `.gitea/actionlint.yaml` (registers custom `docker` runner label).
Install: `bash <(curl -sL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)`
2. **act_runner exec --dryrun** — Gitea's own runner in dry-run mode.
Validates job dependencies, step ordering, and Docker image selection
without starting containers. Install from
[gitea/act_runner releases](https://gitea.com/gitea/act_runner/releases).
Both run via `make workflow-check` and are part of `make lint-all`.
The pre-commit hook runs actionlint automatically when workflow files change.
The CI `quality` job installs actionlint and runs `make lint-all`.
## Architecture
- **Python CLI** (`src/gitea_runner_manager/`) — Click-based CLI that delegates to Ansible
+17 -2
View File
@@ -1,4 +1,4 @@
.PHONY: all setup install update lint ansible-lint makefile-lint lint-all test test-unit pytest-cov molecule molecule-all test-all clean
.PHONY: all setup install update lint ansible-lint makefile-lint lint-all test test-unit pytest-cov molecule molecule-all test-all clean workflow-lint workflow-dryrun workflow-check
PYTHON := python3
VENV := .venv
@@ -86,7 +86,22 @@ ansible-lint:
makefile-lint:
@$(CHECKMAKE) Makefile
lint-all: lint ansible-lint makefile-lint
lint-all: lint ansible-lint makefile-lint workflow-lint
workflow-lint:
@command -v actionlint >/dev/null 2>&1 || { \
echo "actionlint not found. Install: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)"; \
exit 1; \
}
actionlint -config-file .gitea/actionlint.yaml .gitea/workflows/*.yml
workflow-dryrun:
@command -v act_runner >/dev/null 2>&1 || { echo "act_runner not found. Install: https://gitea.com/gitea/act_runner/releases"; exit 1; }
@echo "Dry-running all workflows (no Docker containers started)..."
act_runner exec --dryrun -W .gitea/workflows/ 2>&1 | grep -E 'DRYRUN|ERROR|FAIL|Job'
workflow-check: workflow-lint workflow-dryrun
@echo "Workflow checks passed (static lint + dry-run)."
test-unit:
$(BIN)/pytest tests/unit/ -v --no-cov