feat: automated tests

This commit is contained in:
Alpha Nerd 2026-05-15 11:46:34 +02:00
parent 6e8f6ff639
commit 9602b84247
Signed by: alpha-nerd
SSH key fingerprint: SHA256:QkkAgVoYi9TQ0UKPkiKSfnerZy2h4qhi3SVPXJmBN+M
2 changed files with 148 additions and 0 deletions

92
run-tests/README.md Normal file
View file

@ -0,0 +1,92 @@
# Run Tests
Language-agnostic composite action that executes a project's test suite with optional setup and failure-artifact upload. Designed for Forgejo Actions (works on GitHub Actions too).
## Inputs
| Input | Required | Default | Description |
|---|---|---|---|
| `command` | yes | — | Test command to execute (multiline allowed) |
| `setup` | no | `""` | Setup commands run before tests (install deps, build, etc.) |
| `working-directory` | no | `.` | Directory to run setup and command in |
| `shell` | no | `bash` | Shell for setup and command |
| `artifacts-path` | no | `""` | Glob of paths to upload on failure. Empty disables upload. |
| `artifacts-name` | no | `test-artifacts` | Name of the uploaded artifact bundle |
## Behavior
1. Runs `setup` if provided. Non-zero exit fails the job immediately.
2. Runs `command`. Exit code is captured but not yet propagated.
3. If `command` failed and `artifacts-path` is set, uploads matching files.
4. Re-exits with failure if `command` failed.
This ordering ensures artifacts are always uploaded on failure, even though the job ultimately fails.
## Usage
### Node.js
```yaml
name: PR Tests
on: [pull_request]
jobs:
test:
runs-on: docker
steps:
- uses: https://code.forgejo.org/actions/checkout@v4
- uses: https://bitfreedom.net/code/apunkt/actions/run-tests@v1
with:
setup: npm ci
command: npm test
artifacts-path: |
coverage/**
junit.xml
```
### Python (pytest)
```yaml
- uses: https://bitfreedom.net/code/apunkt/actions/run-tests@v1
with:
setup: |
python -m pip install --upgrade pip
pip install -e .[test]
command: pytest --junitxml=report.xml
artifacts-path: report.xml
```
### Rust
```yaml
- uses: https://bitfreedom.net/code/apunkt/actions/run-tests@v1
with:
command: cargo test --all
```
### Multi-line command
```yaml
- uses: https://bitfreedom.net/code/apunkt/actions/run-tests@v1
with:
command: |
make lint
make test
make integration-test
```
## Making it a merge gate
This action alone does not block merges. To enforce passing tests before merge on Forgejo:
1. Repo → **Settings → Branches → Protected Branches**
2. Add a rule for `main` (or your default branch)
3. Enable **Require status checks to pass before merging**
4. Add the workflow job name (e.g. `test`) to the required checks list
After the workflow has run at least once on a PR, the check name will appear in the dropdown.
## Notes
- Forgejo runners often use the `docker` label rather than `ubuntu-latest`. Adjust `runs-on` per your runner setup.
- Action references must use full URLs on Forgejo (`https://code.forgejo.org/actions/checkout@v4`), unlike GitHub where `actions/checkout@v4` is shorthand.
- The failure-artifact upload uses [`forgejo/upload-artifact`](https://code.forgejo.org/forgejo/upload-artifact), which is API-compatible with `actions/upload-artifact` and works on both Forgejo and GitHub.

56
run-tests/action.yml Normal file
View file

@ -0,0 +1,56 @@
name: Run Tests
description: Runs a project's test suite with optional setup and failure-artifact upload. Language-agnostic.
inputs:
command:
description: Test command to execute (multiline allowed)
required: true
setup:
description: Setup commands to run before tests (install deps, build, etc.)
required: false
default: ""
working-directory:
description: Directory to run setup and command in
required: false
default: "."
shell:
description: Shell to use for setup and command
required: false
default: bash
artifacts-path:
description: Glob of paths to upload on failure (test reports, logs). Empty disables upload.
required: false
default: ""
artifacts-name:
description: Name of the uploaded artifact bundle
required: false
default: test-artifacts
runs:
using: composite
steps:
- name: Setup
if: inputs.setup != ''
shell: ${{ inputs.shell }}
working-directory: ${{ inputs.working-directory }}
run: ${{ inputs.setup }}
- name: Run tests
id: tests
shell: ${{ inputs.shell }}
working-directory: ${{ inputs.working-directory }}
run: ${{ inputs.command }}
continue-on-error: true
- name: Upload failure artifacts
if: inputs.artifacts-path != '' && steps.tests.outcome == 'failure'
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
with:
name: ${{ inputs.artifacts-name }}
path: ${{ inputs.artifacts-path }}
if-no-files-found: ignore
- name: Propagate failure
if: steps.tests.outcome == 'failure'
shell: bash
run: exit 1