integration.yml

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