GRM-51: ci: add actionlint and act_runner exec for workflow verification
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user