RabbitMQ: GitHub Actions & GitLab CI

Avvia un vero servizio RabbitMQ dalla tua pipeline GitHub Actions o GitLab CI, esegui i tuoi test su di esso e rimuovilo automaticamente

Questa guida ti accompagnerà nell'esecuzione di un servizio RabbitMQ reale e dedicato all'interno della tua pipeline CI utilizzando GitHub Actions o GitLab CI. Seguendo questi passaggi, potrai testare il tuo codice su un'istanza RabbitMQ attiva in condizioni simili a quelle di produzione, senza dover ricorrere a mock o simulazioni. RabbitMQ is a widely-deployed open source message broker that moves work between your services reliably and at scale.

Ad ogni esecuzione della pipeline, verrà creata una nuova istanza RabbitMQ. In questo modo, i tuoi test interagiranno con lo stesso tipo di servizio che i tuoi utenti vedranno in produzione. Il workflow crea automaticamente uno stack temporaneo, aggiunge RabbitMQ, attende che sia pronto, recupera le credenziali generate, esegue uno smoke test tramite curl e, al termine, esegue sempre la pulizia di tutte le risorse.

Utilizzerai il Stackhero CLI, uno strumento da riga di comando standalone che rende il lancio e la gestione dei servizi Stackhero semplice e veloce.

Per consentire al CLI di funzionare in modalità non interattiva, avrai bisogno di un access token (formato: usr-xxxxxx:tokenId). È sufficiente creare questo token una sola volta e poi aggiungerlo alla pipeline CI come secret sicuro e cifrato.

  1. Crea il token: Nel tuo dashboard Stackhero, clicca sulla tua immagine profilo in alto a destra, vai su Il tuo account, poi su Access tokens e clicca su Crea token.
  2. Per GitHub Actions: Nel tuo repository, vai su Settings > Secrets and variables > Actions > New repository secret e inserisci il token come STACKHERO_TOKEN.
  3. Per GitLab CI: Nel tuo progetto, vai su Settings > CI/CD > Variables > Add variable, imposta la chiave su STACKHERO_TOKEN e seleziona Masked (e Protected se la tua CI viene eseguita solo su branch protetti).

Non inserire mai il tuo access token direttamente nel file YAML della pipeline. Se presente nel YAML, potrebbe essere esposto a chiunque abbia accesso al repository e potrebbe comparire nei log di build. Salvarlo come secret CI garantisce che rimanga cifrato e mascherato, mantenendo il token sicuro.

Ecco un esempio completo di script che gestisce l'intero ciclo di vita del servizio. Dimostra quanto sia semplice la configurazione, con pochi comandi. Puoi copiare il file YAML già pronto per la tua piattaforma dalle sezioni sottostanti.

#!/bin/bash
set -euo pipefail

# STACKHERO_TOKEN viene fornito dal secret CI, il CLI lo rileva automaticamente.

stackName="ci-rabbitmq-$$"          # Nome stack univoco per ogni esecuzione
serviceStore="rabbitmq"             # Il service store di RabbitMQ
instance="200"        # Modifica se necessario (vedi step 3)
region="europe"                         # Nome regione (vedi stackhero regions-list)

# 1. Installa il CLI sul runner
curl -fsSL https://www.stackhero.io/install.sh | sh

# 2. Installa il client necessario per lo smoke test (jq + curl sono la base)
apt-get update && apt-get install -y --no-install-recommends jq curl

# 3. Crea uno stack dedicato per questa esecuzione
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack creato: $stackId"

# 4. Aggiungi RabbitMQ e ottieni il suo service id
serviceId=$(stackhero --format=script service-add \
  --stack="$stackId" \
  --service-store="$serviceStore" \
  --instance="$instance" \
  --region="$region")
echo "Servizio aggiunto: $serviceId"

# 5. Attendi che il servizio sia operativo (può richiedere alcuni minuti)
stackhero service-wait-for --service="$serviceId"

# 6. Leggi la configurazione (contiene le credenziali generate)
config=$(stackhero service-configuration-get --service="$serviceId" --format=json)

# 7. Estrai le credenziali necessarie
host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.password')

# 8. Smoke test: Call the management API (health check, falling back to overview).
curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
  || curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'

echo "✅ RabbitMQ è raggiungibile dalla CI."

La fase di teardown, che elimina il servizio, attende la sua rimozione e poi elimina lo stack, viene gestita nelle sezioni specifiche per ciascuna piattaforma qui sotto. Questo approccio garantisce che la pulizia venga sempre eseguita, anche se uno smoke test fallisce.

Uno stack può essere eliminato solo quando è vuoto. Elimina sempre prima il servizio e attendi la sua rimozione, poi elimina lo stack. Il comando service-wait-for assicura che il servizio sia in esecuzione o eliminato prima di procedere, rendendolo lo strumento ideale anche per attendere la cancellazione.

Gli esempi qui sotto utilizzano di default l'istanza entry-level 200 per RabbitMQ. È una scelta solida per la maggior parte dei carichi di lavoro, ma puoi modificarla secondo le tue esigenze. Per visualizzare tutte le tipologie di istanza disponibili per RabbitMQ, puoi eseguire:

# La colonna NAME mostra il valore da passare a --instance
stackhero instances-store-list --service-store=rabbitmq

Per iniziare, puoi salvare il seguente contenuto come .github/workflows/ci.yml. Da questo momento, ogni push e pull request eseguirà i test su una vera istanza RabbitMQ.

name: CI con RabbitMQ

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
      STACK_NAME: ci-rabbitmq-${{ github.run_id }}-${{ github.run_attempt }}
      INSTANCE: "200"   # Modifica se necessario (vedi step 3)
      REGION: europe
    steps:
      - uses: actions/checkout@v4

      - name: Installa Stackhero CLI e il client
        run: |
          curl -fsSL https://www.stackhero.io/install.sh | sh
          apt-get update && apt-get install -y --no-install-recommends jq curl

      - name: Crea il servizio RabbitMQ
        run: |
          set -euo pipefail
          STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
          echo "STACK_ID=$STACK_ID" >> "$GITHUB_ENV"
          SERVICE_ID=$(stackhero --format=script service-add \
            --stack="$STACK_ID" \
            --service-store="rabbitmq" \
            --instance="$INSTANCE" \
            --region="$REGION")
          echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
          stackhero service-wait-for --service="$SERVICE_ID"

      - name: Esegui i test su RabbitMQ
        run: |
          set -euo pipefail
          config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
          host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.password')
          # Call the management API (health check, falling back to overview).
          curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
  || curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'
          echo "✅ RabbitMQ è raggiungibile dalla CI."
          # Puoi eseguire la tua suite di test qui utilizzando le credenziali sopra ...

      - name: Teardown (sempre, anche in caso di errore)
        if: always()
        run: |
          if [ -n "${SERVICE_ID:-}" ]; then
            stackhero service-delete --service="$SERVICE_ID" --confirm
            stackhero service-wait-for --service="$SERVICE_ID"
          fi
          if [ -n "${STACK_ID:-}" ]; then
            stackhero stack-delete --stack="$STACK_ID" --confirm
          fi

La fase di teardown è configurata con if: always() così da essere sempre eseguita, garantendo che la tua istanza RabbitMQ venga eliminata e che non vengano addebitate risorse inutilizzate.

Puoi salvare questa configurazione come .gitlab-ci.yml. Con questa impostazione, ogni esecuzione della pipeline avvierà una nuova istanza reale di RabbitMQ per i tuoi test.

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-rabbitmq-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "200"   # Modifica se necessario (vedi step 3)
    REGION: "europe"
    SERVICE_STORE: "rabbitmq"
  # STACKHERO_TOKEN proviene dalla variabile CI/CD creata allo step 1.
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
password=$(echo "$config" | jq -r '.configuration.password')
    # Call the management API (health check, falling back to overview).
    - curl -fsS -u "admin:$password" "https://$host/api/health/checks/alarms" | grep -q '"status":"ok"' \
  || curl -fsS -u "admin:$password" "https://$host/api/overview" | grep -q '"rabbitmq_version"'
    - echo "✅ RabbitMQ è raggiungibile dalla CI."
    # Puoi eseguire la tua suite di test qui utilizzando le credenziali sopra ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

In GitLab, la pulizia avviene nella sezione after_script. Questa parte viene sempre eseguita, anche in caso di errore del job, così le risorse RabbitMQ vengono eliminate e non ti vengono addebitate risorse non utilizzate.

In GitLab, after_script viene eseguito in una shell pulita. Per gestire questa situazione, lo script salva gli ID di servizio e stack in deploy.env durante il job e li ricarica prima della pulizia. In questo modo, anche in caso di errore durante il job, le tue risorse vengono comunque eliminate.

Questo è l'intero ciclo CI per RabbitMQ: crea uno stack, aggiungi il servizio, attendi, recupera le credenziali, smoke test e sempre teardown. Ogni esecuzione della pipeline ottiene un servizio reale e isolato, senza lasciare nulla in esecuzione al termine. Per ulteriori informazioni sui comandi disponibili e sull'autenticazione non interattiva tramite STACKHERO_TOKEN, puoi consultare la documentazione CLI completa.