integration.yml

  1name: Integration
  2
  3on:
  4  push:
  5    branches: [master, release/v1]
  6  pull_request:
  7    branches: [master, release/v1]
  8  merge_group:
  9
 10jobs:
 11  imap-smtp:
 12    name: imap + smtp e2e
 13    runs-on: ubuntu-latest
 14    timeout-minutes: 25
 15
 16    services:
 17      greenmail:
 18        image: greenmail/standalone:2.1.8
 19        ports:
 20          - 3025:3025
 21          - 3110:3110
 22          - 3143:3143
 23          - 3465:3465
 24          - 3993:3993
 25          - 3995:3995
 26          - 8080:8080
 27        env:
 28          GREENMAIL_OPTS: "-Dgreenmail.setup.test.all -Dgreenmail.hostname=0.0.0.0 -Dgreenmail.auth.disabled -Dgreenmail.verbose"
 29        # No --health-cmd: greenmail/standalone image has no wget/curl.
 30        # The runner step below polls /api/service/readiness externally instead.
 31
 32    steps:
 33      - uses: actions/checkout@v6
 34
 35      - name: Set up Go
 36        uses: actions/setup-go@v6
 37        with:
 38          go-version: "1.26.4"
 39
 40      - name: Install system dependencies
 41        run: sudo apt-get update && sudo apt-get install -y libpcsclite-dev
 42
 43      - name: Wait for greenmail
 44        run: |
 45          for i in $(seq 1 60); do
 46            if curl -sf http://127.0.0.1:8080/api/configuration >/dev/null; then
 47              echo "greenmail ready"
 48              exit 0
 49            fi
 50            sleep 2
 51          done
 52          echo "greenmail not ready"
 53          curl -v http://127.0.0.1:8080/api/configuration || true
 54          exit 1
 55
 56      - name: Run integration tests
 57        env:
 58          MATCHA_TEST_IMAP_HOST: 127.0.0.1
 59          MATCHA_TEST_IMAP_PORT: "3993"
 60          MATCHA_TEST_SMTP_PORT: "3465"
 61          MATCHA_TEST_API_PORT: "8080"
 62        run: |
 63          go test -v -tags=integration -timeout=10m -count=1 ./tests/integration/...
 64
 65  matrix:
 66    name: cross-platform build matrix
 67    runs-on: ${{ matrix.os }}
 68    strategy:
 69      fail-fast: false
 70      matrix:
 71        os: [ubuntu-latest, macos-latest, windows-latest]
 72        go: ["1.26.3"]
 73    steps:
 74      - uses: actions/checkout@v6
 75
 76      - name: Set up Go
 77        uses: actions/setup-go@v6
 78        with:
 79          go-version: ${{ matrix.go }}
 80
 81      - name: Install system deps (linux)
 82        if: runner.os == 'Linux'
 83        run: sudo apt-get update && sudo apt-get install -y libpcsclite-dev
 84
 85      - name: Race-enabled unit tests
 86        run: go test -race -timeout=10m ./...
 87
 88  fuzz:
 89    name: short fuzz
 90    runs-on: ubuntu-latest
 91    timeout-minutes: 15
 92    steps:
 93      - uses: actions/checkout@v6
 94
 95      - name: Set up Go
 96        uses: actions/setup-go@v6
 97        with:
 98          go-version: "1.26.4"
 99
100      - name: Install system dependencies
101        run: sudo apt-get update && sudo apt-get install -y libpcsclite-dev
102
103      - name: Discover fuzz targets
104        id: discover
105        run: |
106          set -e
107          targets=$(grep -RIl --include='*_test.go' -E '^func Fuzz' . || true)
108          echo "found targets:"
109          echo "$targets"
110          {
111            echo "targets<<EOF"
112            echo "$targets"
113            echo "EOF"
114          } >> "$GITHUB_OUTPUT"
115
116      - name: Run fuzz targets (30s each)
117        if: steps.discover.outputs.targets != ''
118        run: |
119          for file in ${{ steps.discover.outputs.targets }}; do
120            dir=$(dirname "$file")
121            for fn in $(grep -hoE '^func (Fuzz[A-Za-z0-9_]+)' "$file" | awk '{print $2}'); do
122              echo "=== $dir :: $fn ==="
123              go test -run=^$ -fuzz="^${fn}$" -fuzztime=30s "./$dir"
124            done
125          done