跳转至

GitHub Actions

GitHub Actions 中通过 Mailexam 验证外发邮件的分步指南。应用经 SMTP 发送邮件;流水线通过 mailexam-cli 等待投递并断言主题与正文。

参考仓库:github.com/mailexam/GitHub-Actions

准备工作

  • Mailexam 账户及带 SMTP 凭据的项目
  • 控制台 中的 API 令牌 — 仅用于 CLI,不用于 SMTP。
  • 已启用 Actions 的 GitHub 仓库。

欢迎邮件(或控制台)复制项目凭据:

  • YOUR_LOGIN — SMTP 登录名(例如 xxxxx);
  • YOUR_PASSWORD — SMTP 密码(与登录名成对);
  • 主机 — YOUR_LOGIN.mailexam.cn登录名一致)。

为什么在 CI 中使用 Mailexam

在共享 GitHub runner 上,应用旁没有本地 Mailpit 或 MailHog。Mailexam 可从任意 runner 接收 SMTP,并在浏览器与 REST API 中展示邮件。参见 MailHog/Mailpit vs Mailexam

密钥与变量

Settings → Secrets and variables → Actions。

名称 说明
MAILEXAM_API_TOKEN mailexam-cli 的 API 令牌
MAILEXAM_LOGIN 欢迎邮件中的 SMTP 登录名
MAILEXAM_PASSWORD SMTP 密码(与登录名成对)
名称 说明
MAILEXAM_PROJECT_UUID 项目 UUID — 控制台或 mailexam project list

SMTP 与 API 令牌

MAILEXAM_LOGIN / MAILEXAM_PASSWORD 供应用发送邮件。MAILEXAM_API_TOKEN 供 CLI 读取邮件 — 请勿混用。

来自 fork 的 Pull Request

GitHub 不会向 fork PR 触发的 workflow 暴露仓库密钥。请使用 workflow_dispatch、推送到自有分支,或单独的测试仓库。

典型流程

sequenceDiagram
    participant App as 应用 / 脚本
    participant SMTP as Mailexam SMTP
    participant GHA as GitHub Actions
    participant CLI as mailexam CLI
    participant API as REST API

    GHA->>App: 运行测试 / 发送邮件
    App->>SMTP: sendMail()
    Note over SMTP: 邮件进入 sandbox
    GHA->>CLI: mailexam email assert
    CLI->>API: 轮询 GET /email
    API-->>CLI: 找到邮件
    CLI->>CLI: 校验主题、正文
    Note over CLI: 退出码 0 或 1
  1. 某 job 步骤经 SMTP 发送邮件(应用或测试脚本)。
  2. 另一步运行 mailexam email waitmailexam email assert
  3. 非零退出码即失败 — 无需额外包装脚本。

参考 workflow

完整可运行示例见 mailexam/GitHub-Actions

name: Mailexam email test

on:
  workflow_dispatch:
  push:
    branches: [main]

jobs:
  email-test:
    runs-on: ubuntu-latest
    env:
      MAILEXAM_API_BASE: https://mailexam.cn/api/v1
      MAILEXAM_PROJECT_UUID: ${{ vars.MAILEXAM_PROJECT_UUID }}
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Send test email
        env:
          MAILEXAM_LOGIN: ${{ secrets.MAILEXAM_LOGIN }}
          MAILEXAM_PASSWORD: ${{ secrets.MAILEXAM_PASSWORD }}
          MAILEXAM_PORT: '587'
        run: npm run send-test-email

      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'

      - name: Install mailexam CLI
        run: go install github.com/mailexam/mailexam-cli/cmd/mailexam@latest

      - name: Add Go bin to PATH
        run: echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

      - name: Assert email delivered
        env:
          MAILEXAM_API_TOKEN: ${{ secrets.MAILEXAM_API_TOKEN }}
        run: >
          mailexam email assert
          --subject "GitHub Actions + Mailexam"
          --contains "Mailexam CI check"

复制 .github/workflows/mailexam.ymlscripts/send-test-email.js 到您的仓库(中国区请将 SMTP 主机改为 YOUR_LOGIN.mailexam.cn)。

为应用配置 SMTP

在 job 的 env 中传入 SMTP 凭据,使测试使用 Mailexam 而非真实邮箱:

env:
  MAILEXAM_LOGIN: ${{ secrets.MAILEXAM_LOGIN }}
  MAILEXAM_PASSWORD: ${{ secrets.MAILEXAM_PASSWORD }}
  MAIL_HOST: ${{ secrets.MAILEXAM_LOGIN }}.mailexam.cn
  MAIL_PORT: '587'

各框架的 .env 映射见集成示例(Laravel、Django、Express 等)。

流水线中的 mailexam-cli

安装 Go 1.22+ 后:

- uses: actions/setup-go@v5
  with:
    go-version: '1.22'
- run: go install github.com/mailexam/mailexam-cli/cmd/mailexam@latest
- run: echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH"

常用断言:

mailexam email assert --subject "Order confirmed" --contains "Thank you"
mailexam email assert --subject "Code" --contains "123456" --timeout 60

命令说明与退出码:命令行接口 (CLI)

Environments(可选)

针对 staging / production,在 GitHub Environments(Settings → Environments)中为各环境配置不同的密钥与 MAILEXAM_PROJECT_UUID

jobs:
  email-test:
    runs-on: ubuntu-latest
    environment: staging

常见问题

api token is required

  • 在仓库 Secrets 中添加 MAILEXAM_API_TOKEN,或使用 --token

退出码 2 (403)

退出码 3 (timeout)

  • 增大 --timeout — 冷启动 runner 上 SMTP 投递可能需要数秒。
  • 确认 MAILEXAM_PROJECT_UUID 与所用 SMTP 登录名所属项目一致。

mailexam: command not found

  • go install 后将 $(go env GOPATH)/bin 加入 PATH(见上文 workflow)。

SMTP 连接错误

  • 主机须为 YOUR_LOGIN.mailexam.cn — 与 MAILEXAM_LOGIN 相同,不要加 smtp. 前缀。
  • 使用端口 587 与 STARTTLS。

参见