New optional inputs (all default to off / safe):
- auto-log: when true and details is empty, fetch and render the run's
failing-job log via /api/v1/repos/<repo>/actions/jobs/<id>/logs.
- token: defaults to github.token (per-run, repo-scoped). Overridable.
- log-lines: tail-length fallback when no ::error:: annotation present.
Selection heuristic: if any line has ::error::, return those + 12 lines of
context above each (merged windows). Otherwise the last `log-lines` lines.
Timestamp prefixes (act_runner's leading ISO-8601 + Z) are stripped.
The details block already existed; this just makes it cheap for failure
emails to surface the actual build error inline instead of forcing the
reader to click "view run →".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
action/notify-email
Composite Gitea Action that sends a fritzlab-themed email from a CI workflow.
Renders an HTML body (with plain-text fallback) styled to match the
websites/fritzlab.net/theme.css palette, and relays via mail.fritzlab.net:25
under the trusted-CIDR rule (no SMTP auth — see k8s-manager skill mail.md).
Gating is the caller's responsibility (typically if: failure()). The action
always sends when invoked.
Usage
Minimal failure notification:
- name: notify on failure
if: failure()
uses: https://code.fritzlab.net/action/notify-email@v1
with:
status: failure
summary: "agent deploy failed"
With richer context:
- name: notify on failure
if: failure()
uses: https://code.fritzlab.net/action/notify-email@v1
with:
status: failure
subject: "agent deploy failed: ${{ github.sha }}"
summary: "Deploy of ${{ github.sha }} to bob@${{ vars.DEPLOY_HOST }} failed"
details: |
Target host: ${{ vars.DEPLOY_HOST }}
Branch: ${{ github.ref_name }}
from: agent-ci@fritzlab.net
Auto-include the actual build error from the failing step in the email body:
- name: notify on failure
if: failure()
uses: https://code.fritzlab.net/action/notify-email@v1
with:
status: failure
summary: "latchkey build failed"
auto-log: 'true'
# token defaults to ${{ github.token }} which has read access to the
# current repo's actions; no caller-side config needed
auto-log fetches the run's failing-job log via the Gitea API, surfaces the
::error:: annotation context (or the last 40 lines if there isn't one),
strips the runner's timestamp prefixes, and renders it in the details block.
Skipped if details: is already set (manual takes precedence).
Success notification (e.g. confirm a base-image rebuild cascaded):
- if: success()
uses: https://code.fritzlab.net/action/notify-email@v1
with:
status: success
summary: "base #${{ github.run_number }} cascaded to runner"
Inputs
| Name | Required | Default | Description |
|---|---|---|---|
summary |
yes | — | One-line headline rendered at the top of the email body. |
status |
no | info |
failure / success / info — drives accent colour + subject prefix. |
subject |
no | summary |
Mail subject after the status prefix. |
details |
no | — | Multiline preformatted block, rendered in a monospace card. |
auto-log |
no | false |
When true and details is empty, fetch the failing-job log via the Gitea API and render its error context. |
token |
no | ${{ github.token }} |
Gitea API token used for auto-log. The per-run GITHUB_TOKEN normally suffices. |
log-lines |
no | 40 |
Tail length used by auto-log when no ::error:: annotation is found. |
to |
no | noc@fritzlab.net |
Recipient address. |
from |
no | ci@fritzlab.net |
Sender address. Must be permitted by the relay. |
smtp-host |
no | mail.fritzlab.net |
SMTP relay host. |
smtp-port |
no | 25 |
SMTP port. |
Auto-injected fields
The action reads the following from ${{ github.* }} and includes them in
both HTML and text bodies — callers do not need to pass these:
- Repository (linked to Gitea repo page)
- Branch (
ref_name) - Commit (short SHA linked to commit page)
- Workflow / job
- Run number (+ attempt if
> 1) - Trigger (
event_namebyactor) - "view run" button linking to the Actions run
Status styling
| Status | Subject prefix | Accent |
|---|---|---|
failure |
[FAILED] |
red (#fca5a5) |
success |
[OK] |
green (#86efac) |
info |
[INFO] |
violet (#7c5cff) — fritzlab default accent |
Headers added
X-Fritzlab-Status: failure | success | infoX-Fritzlab-Source: action/notify-emailX-Fritzlab-Repo: <owner>/<repo>
These can be used as Sieve filters in Stalwart to route or tag CI mail.
Why HTML in a CI email
Email clients strip <style> blocks and @import and cannot fetch web fonts,
so the fritzlab palette is inlined per-element. Dark-only — fritzlab brand has
no light variant. The plain-text alternative covers terminal mail readers and
spam-filter previews.