Donavan Fritz a1a09d988e fix: pass local_hostname to smtplib so EHLO is FQDN-shaped
Gitea runner pods don't set setHostnameAsFQDN, so socket.getfqdn() returns
the single-label pod name. Stalwart's reject-non-fqdn rule (mail.md
<smtp-from-k8s-pod>) refuses the EHLO before MAIL FROM. Pass an explicit
FQDN to keep the action self-contained.
2026-05-13 09:22:04 -07:00

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

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.
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_name by actor)
  • "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 | info
  • X-Fritzlab-Source: action/notify-email
  • X-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.

S
Description
Composite action: send a fritzlab-themed CI notification email via mail.fritzlab.net.
Readme 45 KiB
Languages
Python 100%