# SPDX-License-Identifier: MPL-2.0 name: 'SMTP Notify' description: >- Send a plain-text notification email over implicit TLS (SMTPS) from a workflow. Node-free: one static Zig binary with zero dependencies, whose SMTP session is formally specified in Idris2 and machine-checked. Implements nine dawidd6/action-send-mail input names; it is a migration target, not a full replacement. author: 'hyperpolymath' branding: icon: 'mail' color: 'purple' inputs: server_address: description: 'SMTP server host name' required: true server_port: description: 'SMTP server port' required: false default: '465' secure: description: >- Transport selection, fail-closed. "true" (default) or "implicit" = implicit TLS from the first byte (SMTPS, normally port 465). "false" or "starttls" = STARTTLS on a plain connection, which is accepted but NOT YET IMPLEMENTED, so the step fails with a clear message rather than silently falling back to plaintext (issue #5). "plaintext" = no TLS at all, which sends the password base64-encoded in the clear; use it only against a containerized test sink. Any other value is rejected outright. Note the difference from dawidd6/action-send-mail, where "false" means "STARTTLS when the server offers it": here it fails instead of downgrading, because an unrecognised value used to mean plaintext. required: false default: 'true' username: description: 'AUTH PLAIN username' required: false default: '' password: description: >- AUTH PLAIN password. Reaches the binary via the environment, never argv, so it cannot leak into process listings. required: false default: '' from: description: 'From: header value, e.g. "GitHub Push "' required: false default: '' to: description: 'Recipients, separated by commas and/or whitespace' required: false default: '' subject: description: 'Subject: header value. CR/LF is rejected, never sanitized.' required: false default: '' body: description: 'Plain-text body (dot-stuffed on the wire per RFC 5321)' required: false default: '' handshake_only: description: >- "true" = connect, TLS handshake, EHLO, QUIT. No auth, nothing sent. For canary/CI verification against a real server without delivering mail. required: false default: 'false' timeout_seconds: description: >- Whole-run deadline in seconds. A watchdog bounds the entire run — connection, TLS handshake, and every read and write — and fails the step with a diagnostic if it is exceeded. This is deliberately a whole-run deadline rather than a per-operation one: see BUSTFILE.adoc, BUST-2026-001 and BUST-2026-002. required: false default: '60' runs: using: 'composite' steps: - name: Fetch and verify the smtp-notify binary shell: bash run: | set -euo pipefail # The SHA-256 pins below are part of this commit: the action ref that # consumers pin fully determines the binary that runs. The binaries # are byte-reproducible from source (stripped static musl builds, # zig 0.16.0); the release workflow rebuilds them and refuses to # publish unless the hashes match these pins. # Runner OS gate, BEFORE the architecture gate. Windows and Intel macOS # both report "x86_64" from `uname -m`, so an arch-only gate downloads # the Linux binary, passes the SHA-256 check (the file is intact), and # then dies at exec with a confusing exec-format error. Gate on the OS # first so the failure names the real cause (issue #2). case "$(uname -s)" in Linux) ;; *) echo "smtp-notify: unsupported runner OS: $(uname -s)." >&2 echo "smtp-notify: only Linux runners are supported; the released" >&2 echo "smtp-notify: binaries are static linux-musl builds." >&2 exit 1 ;; esac case "$(uname -m)" in x86_64) asset="smtp-notify-x86_64-linux-musl" sha256="cd0692ae7d4c77dd63f4accea9ad57310d1e12c6cdc75a8bcf4e83efe878b195" ;; aarch64) asset="smtp-notify-aarch64-linux-musl" sha256="6d87e89baed740bf5682aaed7005281fe13c26aef727568542eb2cd967dafbef" ;; *) echo "smtp-notify: unsupported runner architecture: $(uname -m)" >&2 exit 1 ;; esac url="https://github.com/hyperpolymath/smtp-notify-action/releases/download/v0.2.0/${asset}" curl -fsSL --retry 3 --retry-delay 2 -o "${RUNNER_TEMP}/smtp-notify" "$url" echo "${sha256} ${RUNNER_TEMP}/smtp-notify" | sha256sum -c - chmod +x "${RUNNER_TEMP}/smtp-notify" - name: Send the notification shell: bash env: SMTP_ADDR: ${{ inputs.server_address }} SMTP_PORT: ${{ inputs.server_port }} SMTP_SECURE: ${{ inputs.secure }} SMTP_HANDSHAKE_ONLY: ${{ inputs.handshake_only }} SMTP_TIMEOUT_SECONDS: ${{ inputs.timeout_seconds }} SMTP_USER: ${{ inputs.username }} SMTP_PASS: ${{ inputs.password }} MAIL_FROM: ${{ inputs.from }} MAIL_TO: ${{ inputs.to }} MAIL_SUBJECT: ${{ inputs.subject }} MAIL_BODY: ${{ inputs.body }} run: exec "${RUNNER_TEMP}/smtp-notify"