A 05-02 vam desplegar servei-comandes a Kubernetes escrivint kubectl apply a mà. És exactament el que TechCorp no es pot permetre: amb sis serveis i un gateway, cadascun desplegant diverses vegades per setmana, la mà humana és lenta, inconsistent i la font dels "desplegaments de dijous a la nit amb reversions" del mòdul 1. La integració contínua (CI) fa que cada canvi es provi automàticament en minuts; el desplegament continu (CD) porta el que passa les proves fins a producció sense intervenció. Aquesta lliçó construeix el pipeline de servei-comandes amb GitHub Actions: proves unitàries, d'integració amb Testcontainers i de contracte amb Pact (04-05), construcció i publicació de la imatge de 05-01, can-i-deploy com a porta, actualització dels manifestos Kustomize de 05-02 i desplegament amb GitOps. Al final apliquem la regla del Luis perquè els altres cinc serveis no copiïn 150 línies de YAML, i mesurem el resultat amb les mètriques DORA. Com canviar de versió sense tallar el servei és de 05-04.

Contingut

  1. Què canvia el CI/CD amb microserveis
  2. Les etapes del pipeline de TechCorp
  3. .github/workflows/ci.yml de servei-comandes, línia a línia
  4. Proves de contracte al pipeline: Pact Broker i can-i-deploy
  5. Desplegament continu: .github/workflows/cd.yml
  6. GitOps amb Argo CD: techcorp/plataforma com a font de veritat
  7. Versions, etiquetes i changelogs per servei
  8. Entorns i promoció: dev → staging → prod
  9. Secrets a CI
  10. El pipeline de @techcorp/comu-http
  11. La regla del Luis: un workflow reutilitzable per als sis serveis
  12. Mètriques DORA: mesurar el pipeline

  1. Què canvia el CI/CD amb microserveis

El monòlit techcorp-shop tenia un pipeline: 40 minuts de suite, un artefacte, un desplegament coordinat. Amb microserveis:

Aspecte Monòlit Microserveis (TechCorp)
Nombre de pipelines Un de gran Un per repositori: sis serveis + gateway + llibreria + plataforma
Durada 40 min (tot es prova sempre) 5-8 min per servei (només es prova el que canvia)
Artefacte Un paquet Una imatge per servei, amb la seva versió
Desplegament Tot o res, coordinat Independent: Comandes desplega sense esperar Catàleg
Versionat Una versió global Semver per servei; la compatibilitat la garanteixen els contractes (03-06) i Pact (04-05)
Risc per desplegament Alt (molt canvi junt) Baix (poc canvi, fàcil de revertir)
Cost ocult Pocs Molts pipelines per mantenir: cal estandarditzar-los (apartat 11)

La independència de desplegament és la promesa central de l'arquitectura (01-02, 02-01) i només es compleix si el pipeline de cada servei pot desplegar sol, sense un "tren de releases" que els agrupi tots. La condició per atrevir-s'hi és la confiança que donen les proves de contracte: és Pact, no una prova E2E de tot el sistema, qui respon "trencaré algú?".

  1. Les etapes del pipeline de TechCorp

flowchart LR
    A[lint] --> B[unitàries + component<br/>npm test] --> C[integració<br/>Testcontainers] --> D[contracte<br/>Pact + publicar pactes]
    D --> E[build imatge<br/>ghcr.io] --> F[escaneig<br/>Trivy] --> G[can-i-deploy<br/>staging]
    G --> H[desplegar staging<br/>Job + rollout] --> I[E2E mínima<br/>gateway 8080] --> J[can-i-deploy prod] --> K[promoció a prod<br/>GitOps]
    style E fill:#dfe,stroke:#393
    style G fill:#ffd,stroke:#a90
    style J fill:#ffd,stroke:#a90
Etapa Què fa Quan Falla si...
Lint eslint amb la configuració de la plantilla Cada push i PR Estil o errors estàtics
Unitàries + component npm test (Jest, Supertest, sense Docker; 04-05) Cada push i PR Lògica de domini o rutes
Integració npm run test:integracio amb Testcontainers (PostgreSQL 16, RabbitMQ) Cada push i PR Outbox, consumidor de saga, SQL
Contracte npm run test:contracte genera pactes (consumidor) o verifica (proveïdor); publicació al Broker Cada push i PR Un contracte trencat
Build + push Imatge de 05-01 amb etiquetes sha-<commit> i semver Només a main i en tags Dockerfile o npm ci
Escaneig Trivy sobre la imatge Després del build CVE crítica (política a 07-04)
can-i-deploy És compatible amb el que hi ha a l'entorn destí? Abans de cada desplegament Algun pacte no verificat
Desplegament a staging Job de migracions + kubectl apply -k + rollout status Cada push a main Migració o arrencada
E2E mínima L'única E2E de 04-05 contra staging Després de desplegar staging Cablejat
Promoció a prod Canvi d'imatge a l'overlay prod (GitOps) Manual o automàtic segons el servei

Tot el que és anterior a la imatge és CI: ràpid, a cada canvi. El que ve després és CD.

  1. .github/workflows/ci.yml de servei-comandes, línia a línia

# techcorp/servei-comandes/.github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
    tags: ["v*"]                    # v1.0.1 → imatge 1.0.1 (apartat 7)
  pull_request:

permissions:
  contents: read
  packages: write                   # necessari per fer push a ghcr.io amb GITHUB_TOKEN

env:
  IMATGE: ghcr.io/techcorp/servei-comandes
  PACT_BROKER_BASE_URL: https://pact.techcorp.example

jobs:
  proves:
    runs-on: ubuntu-latest          # porta Docker instal·lat: Testcontainers funciona sense configuració extra
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm                # desa ~/.npm a la memòria cau entre execucions a partir del package-lock.json
          registry-url: https://npm.pkg.github.com
          scope: "@techcorp"        # @techcorp/comu-http es resol contra GitHub Packages (04-01)

      - run: npm ci
        env:
          NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}   # lectura de paquets de l'organització

      - run: npm run lint
      - run: npm test                                    # unitàries + component + esdeveniments: segons, sense Docker
      - run: npm run test:integracio                     # Testcontainers aixeca postgres:16 i rabbitmq al runner
      - run: npm run test:contracte                      # genera pactes/servei-comandes-servei-cataleg.json

      - name: Publicar pactes al Broker
        run: |
          npx pact-broker publish pactes \
            --consumer-app-version ${{ github.sha }} \
            --branch ${{ github.head_ref || github.ref_name }} \
            --broker-token ${{ secrets.PACT_BROKER_TOKEN }}

  imatge:
    needs: proves
    if: github.event_name == 'push'                       # en PR no es publica imatge
    runs-on: ubuntu-latest
    outputs:
      etiqueta: ${{ steps.meta.outputs.version }}
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3               # BuildKit: necessari per a --mount=type=secret i memòria cau remota
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - id: meta
        uses: docker/metadata-action@v5                   # calcula les etiquetes segons l'esdeveniment
        with:
          images: ${{ env.IMATGE }}
          tags: |
            type=sha,prefix=sha-,format=short             # sempre: sha-9f3c2ab
            type=semver,pattern={{version}}               # només en tags v1.0.1 → 1.0.1
      - name: Preparar .npmrc per al build (secret, no capa)
        run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" > /tmp/npmrc
      - uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          secrets: npmrc=/tmp/npmrc                       # el --secret id=npmrc del Dockerfile de 05-01
          cache-from: type=gha                            # memòria cau de capes entre execucions (l'npm ci de 05-01 §4)
          cache-to: type=gha,mode=max
      - name: Escaneig de vulnerabilitats (detall a 07-04)
        uses: aquasecurity/[email protected]
        with:
          image-ref: ${{ env.IMATGE }}:sha-${{ github.sha }}
          severity: CRITICAL
          exit-code: "1"

Notes de lectura:

  • Dos jobs (proves, imatge) amb needs: la imatge només es construeix si tot passa; en un PR (pull_request) només corre proves.
  • ubuntu-latest porta Docker, així que test:integracio funciona tal qual: Testcontainers descarrega postgres:16 i rabbitmq:3-management al runner. És la raó per la qual a 04-05 vam separar test (sense Docker) de test:integracio.
  • docker/metadata-action produeix les dues etiquetes de 05-01 sense scripts a mà: sha-<commit> sempre, i la semver quan l'esdeveniment és un tag v1.0.1.
  • secrets: npmrc= a build-push-action alimenta el --mount=type=secret,id=npmrc del Dockerfile: el token no queda en cap capa.
  • cache-from/to: type=gha desa les capes a la memòria cau de GitHub Actions: un canvi a src/ no repeteix npm ci a CI, igual que al portàtil.
  • permissions mínims: contents: read per clonar, packages: write per publicar. Res de tokens personals.

  1. Proves de contracte al pipeline: Pact Broker i can-i-deploy

A 04-05 el fitxer de pacte viatjava a mà de servei-comandes a servei-cataleg. A CI viatja pel Pact Broker (autoallotjat o PactFlow), que desa cada pacte amb la versió (github.sha) i la branca del consumidor, i cada resultat de verificació amb la versió del proveïdor:

sequenceDiagram
    participant P as CI servei-comandes (consumidor)
    participant B as Pact Broker
    participant C as CI servei-cataleg (proveïdor)
    P->>B: publish pactes (version sha-9f3c2ab, branch main)
    B-->>C: webhook: hi ha un pacte nou per verificar
    C->>C: npm run test:contracte (Verifier amb stateHandlers, 04-05)
    C->>B: resultat de la verificació (cataleg sha-1a2b3c: OK)
    P->>B: can-i-deploy --pacticipant servei-comandes --version sha-9f3c2ab --to-environment staging
    B-->>P: sí: el catàleg desplegat a staging va verificar aquest pacte

Al CI del proveïdor (servei-cataleg), el test:contracte de 04-05 s'executa amb pactBrokerUrl en lloc de pactUrls, amb publishVerificationResult: true i providerVersion: process.env.GITHUB_SHA, i després de desplegar registra a quin entorn hi ha cada versió (pact-broker record-deployment --environment staging). Amb això, la porta abans de desplegar és una línia:

  porta-staging:
    needs: imatge
    runs-on: ubuntu-latest
    steps:
      - run: |
          npx pact-broker can-i-deploy \
            --pacticipant servei-comandes --version ${{ github.sha }} \
            --to-environment staging \
            --broker-base-url ${{ env.PACT_BROKER_BASE_URL }} --broker-token ${{ secrets.PACT_BROKER_TOKEN }}

can-i-deploy respon "sí" només si totes les versions de proveïdors actualment desplegades a staging han verificat amb èxit els pactes d'aquesta versió de Comandes (i, si Comandes fos proveïdor d'algú, si els seus consumidors desplegats continuen satisfets). És la garantia d'integració al cost d'una consulta HTTP: la raó per la qual l'única E2E de TechCorp pot continuar sent una.

  1. Desplegament continu: .github/workflows/cd.yml

El desplegament a staging és directe des del workflow: actualitza l'etiqueta d'imatge a l'overlay de Kustomize (05-02), llança el Job de migracions, aplica i espera el rollout, i executa l'E2E.

# techcorp/servei-comandes/.github/workflows/cd.yml
name: CD staging
on:
  workflow_run:
    workflows: [CI]
    branches: [main]
    types: [completed]

permissions: { contents: read }

jobs:
  staging:
    if: github.event.workflow_run.conclusion == 'success'
    runs-on: ubuntu-latest
    environment: staging                              # entorn de GitHub: secrets propis i regles de protecció
    env:
      ETIQUETA: sha-${{ github.event.workflow_run.head_sha }}
    steps:
      - uses: actions/checkout@v4
        with:
          repository: techcorp/plataforma             # els manifestos viuen al repo de plataforma (05-02)
          token: ${{ secrets.PLATAFORMA_TOKEN }}
      - uses: azure/setup-kubectl@v4
      - name: Credencials del clúster de staging
        run: echo "${{ secrets.KUBECONFIG_STAGING }}" | base64 -d > $HOME/.kube/config
      - name: Fixar la imatge a l'overlay de staging
        working-directory: k8s/servei-comandes/overlays/staging
        run: kustomize edit set image ghcr.io/techcorp/servei-comandes=ghcr.io/techcorp/servei-comandes:${{ env.ETIQUETA }}
      - name: Migracions (Job de 05-02): esborrar l'anterior, aplicar, esperar
        run: |
          kubectl -n techcorp delete job servei-comandes-migracions --ignore-not-found
          kubectl kustomize k8s/servei-comandes/overlays/staging | kubectl apply -f -
          kubectl -n techcorp wait --for=condition=complete job/servei-comandes-migracions --timeout=180s
      - name: Esperar el rollout
        run: kubectl -n techcorp rollout status deploy/servei-comandes --timeout=180s
      - name: E2E mínima contra staging (04-05)
        run: GATEWAY_URL=https://api-staging.techcorp.example npm run test:e2e
      - name: Registrar el desplegament al Pact Broker
        run: npx pact-broker record-deployment --pacticipant servei-comandes --version ${{ github.event.workflow_run.head_sha }} --environment staging --broker-token ${{ secrets.PACT_BROKER_TOKEN }}

Dos detalls respecte de 05-02: el Job de migracions passa a dir-se servei-comandes-migracions a seques i el workflow esborra l'anterior abans d'aplicar (un Job és immutable); és l'alternativa al nom versionat, i funciona perquè migrar.js és idempotent. I kustomize edit set image modifica la línia images: que vam deixar preparada a l'overlay: el YAML continua sent la font de veritat, el pipeline només canvia una etiqueta. Amb Helm l'equivalent seria helm upgrade --set image.tag=$ETIQUETA.

rollout status és el que converteix "he aplicat" en "està desplegat i llest": espera que les rèpliques noves passin el readinessProbe i falla (i el job falla) si en 180 s no ho aconsegueixen. Què fa Kubernetes mentrestant amb les rèpliques velles és 05-04.

  1. GitOps amb Argo CD: techcorp/plataforma com a font de veritat

Per a producció, TechCorp no vol que un workflow amb un kubeconfig en un secret executi kubectl apply contra el clúster de producció. Adopta GitOps: l'estat desitjat de producció és el que hi ha a git (techcorp/plataforma, branca main, overlays/prod), i un agent dins del clúster (Argo CD; Flux és equivalent) el llegeix i l'aplica contínuament.

flowchart LR
    CI[CI servei-comandes] -->|imatge sha-9f3c2ab| REG[(ghcr.io)]
    CI -->|PR: overlays/prod images newTag=1.0.1| GIT[(techcorp/plataforma)]
    REV[Revisió + merge<br/>el Luis o el pipeline] --> GIT
    ARGO[Argo CD<br/>al clúster prod] -->|pull cada 3 min / webhook| GIT
    ARGO -->|kubectl apply| K8S[Clúster producció]
    ARGO -.->|detecta drift| K8S
# techcorp/plataforma/argocd/servei-comandes-prod.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata: { name: servei-comandes-prod, namespace: argocd }
spec:
  project: techcorp
  source:
    repoURL: https://github.com/techcorp/plataforma
    targetRevision: main
    path: k8s/servei-comandes/overlays/prod
  destination: { server: https://kubernetes.default.svc, namespace: techcorp }
  syncPolicy:
    automated: { prune: true, selfHeal: true }   # aplica el que hi ha a git; reverteix canvis manuals al clúster

Per què TechCorp ho adopta: (1) auditoria: cada desplegament a producció és un commit revisable a plataforma; (2) sense credencials del clúster fora del clúster: Argo CD fa pull, ningú no fa push; (3) detecció de desviacions: si algú fa kubectl scale a mà un divendres, Argo ho torna a l'estat de git (o avisa); (4) rollback = revertir el commit. El Job de migracions s'anota com a argocd.argoproj.io/hook: PreSync amb hook-delete-policy: BeforeHookCreation, que és la manera GitOps d'"esborrar l'anterior i executar abans del Deployment". Argo CD i Flux també poden desplegar a staging; TechCorp comença amb el workflow directe a staging per aprendre i amb GitOps a producció, i ho unificarà més endavant.

  1. Versions, etiquetes i changelogs per servei

  • Semver per servei: servei-comandes 1.0.1 no té res a veure amb servei-cataleg 1.4.2. Major = canvi incompatible de contracte (que a 03-06 vol dir /v2/), menor = funcionalitat compatible, pedaç = correcció.
  • La imatge sha-<commit> es construeix sempre; la semver, en etiquetar: git tag v1.0.1 && git push --tags dispara ci.yml amb el tag i metadata-action afegeix 1.0.1 a la mateixa imatge (mateix digest) que ja va passar per staging com a sha-.... No es reconstrueix res per a producció.
  • Changelog: CHANGELOG.md a cada repositori, alimentat a mà o generat a partir de missatges de commit amb la convenció conventional commits (feat:, fix:, feat!:), que eines com semantic-release o release-please fan servir per calcular la versió i publicar la release automàticament. TechCorp adopta la convenció de missatges; l'automatització de la versió queda com a pas següent.

  1. Entorns i promoció: dev → staging → prod

Entorn Clúster Qui desplega Quina imatge Dades
dev kind al portàtil o Compose (05-01) El desenvolupador :local o sha-... Llavor
staging Clúster compartit, gestionats en mida petita cd.yml a cada push a main sha-<commit> Sintètiques, anonimitzades
prod Clúster de producció, Argo CD Merge del PR de promoció (revisió humana per a Comandes i Pagaments; automàtic per a Catàleg i Notificacions) 1.0.1 (mateixa imatge) Reals

Els tres entorns apliquen la mateixa base Kustomize amb overlays diferents (05-02): l'única cosa que canvia entre staging i prod és l'etiqueta d'imatge, les rèpliques i dues claus de ConfigMap. Promocionar és obrir un PR a plataforma que canvia newTag a overlays/prod (el workflow l'obre sol amb peter-evans/create-pull-request); revisar i fusionar és l'aprovació.

  1. Secrets a CI

  • secrets.GITHUB_TOKEN: el genera GitHub per a cada execució, amb els permissions declarats; serveix per a ghcr.io i GitHub Packages sense crear res.
  • Secrets de repositori/organització (PACT_BROKER_TOKEN, PLATAFORMA_TOKEN) i d'entorn (KUBECONFIG_STAGING, lligat a l'environment: staging, amb revisors obligatoris si es vol).
  • OIDC en lloc de claus de llarga durada: per parlar amb el núvol (AWS/GCP/Azure) o amb un registre extern, el workflow obté un token efímer per identitat federada (permissions: id-token: write + aws-actions/configure-aws-credentials) en lloc de desar una access key en un secret. És la pràctica recomanada i la que TechCorp farà servir per al clúster de producció si algun dia un workflow necessita tocar-lo (amb GitOps, no ho necessita).
  • Mai echo d'un secret als logs; GitHub els emmascara, però base64 o transformacions els destapen.

  1. El pipeline de @techcorp/comu-http

La llibreria (04-01) té el seu propi workflow, més curt: npm ci, npm test, i en tag v*, npm publish a GitHub Packages:

# techcorp/comu-http/.github/workflows/publicar.yml (extracte)
on: { push: { tags: ["v*"] } }
permissions: { contents: read, packages: write }
jobs:
  publicar:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: npm, registry-url: https://npm.pkg.github.com, scope: "@techcorp" }
      - run: npm ci && npm test
      - run: npm publish
        env: { NODE_AUTH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" }

Cada servei fixa al seu package.json la versió que fa servir ("@techcorp/comu-http": "^2.3.0") i l'actualitza quan vol, amb Renovate/Dependabot obrint el PR: la llibreria no obliga a redesplegar ningú, que era la condició perquè existís (04-01).

  1. La regla del Luis: un workflow reutilitzable per als sis serveis

"Si es fa més d'una vegada per servei, s'automatitza abans de la segona." El ci.yml de l'apartat 3 té 80 línies i seria idèntic a Catàleg, Inventari, Pagaments, Notificacions i Clients tret del nom. GitHub Actions permet un workflow reutilitzable (workflow_call) que viu a techcorp/plataforma:

# techcorp/plataforma/.github/workflows/servei-node-ci.yml
on:
  workflow_call:
    inputs:
      nom-servei: { required: true, type: string }
      amb-integracio: { type: boolean, default: true }      # Notificacions no té BD: la pot desactivar
    secrets:
      PACT_BROKER_TOKEN: { required: true }
jobs:
  proves: ...           # exactament els passos de l'apartat 3, amb ${{ inputs.nom-servei }} on hi havia servei-comandes
  imatge:  ...

I a cada servei, el ci.yml es redueix a:

# techcorp/servei-cataleg/.github/workflows/ci.yml
name: CI
on: { push: { branches: [main], tags: ["v*"] }, pull_request: }
permissions: { contents: read, packages: write }
jobs:
  ci:
    uses: techcorp/plataforma/.github/workflows/servei-node-ci.yml@v1     # @v1: tag del repo plataforma; s'actualitza a consciència
    with: { nom-servei: servei-cataleg }
    secrets: inherit

El workflow reutilitzable és als pipelines el que @techcorp/comu-http als serveis: es versiona (@v1), cada servei adopta la versió nova quan vol, i la plantilla plantilla-servei-node (04-01) ja porta aquestes nou línies. Un canvi al pipeline (afegir Trivy, canviar la versió d'una acció) es fa una vegada.

  1. Mètriques DORA: mesurar el pipeline

Les quatre mètriques DORA (DevOps Research and Assessment) mesuren si tot l'anterior serveix per a alguna cosa:

Mètrica Què mesura TechCorp abans (monòlit, 01-05) Objectiu amb el pipeline
Freqüència de desplegament Quantes vegades s'arriba a producció Dijous a la nit, quinzenal Diverses vegades al dia, per servei
Lead time de canvis Del commit a producció 1-2 setmanes (esperar el tren) < 1 dia (< 1 hora per a hotfixes)
Taxa de fallada de canvis % de desplegaments que provoquen incident o reversió Alta: reversions freqüents < 15 %
Temps de restauració (MTTR) Quant es triga a recuperar el servei després d'una fallada 50 min sense vendre el Black Friday Minuts: rollout undo o revertir el commit (05-04)

Les dues primeres les dona el mateix pipeline (data del commit, data del sync d'Argo); les altres dues necessiten la gestió d'incidents de 06-05. L'important és la relació entre elles: desplegar més sovint amb canvis més petits abaixa la taxa de fallada i el MTTR, que és el contrari de la intuïció del dijous a la nit ("despleguem poc per arriscar poc").

Errors Comuns i Consells

  • Un pipeline "de sistema" que prova i desplega tots els serveis junts. És el tren de releases del monòlit amb més YAML. Un pipeline per servei i contractes com a garantia.
  • Reconstruir la imatge per a producció. El que es va provar no és el que es desplega. Etiqueta semver sobre la imatge sha- ja provada.
  • can-i-deploy com a pas opcional o continue-on-error. S'acaba ignorant. És una porta: si diu que no, no es desplega.
  • kubectl apply sense rollout status. El pipeline és verd i les rèpliques noves en CrashLoopBackOff.
  • Copiar ci.yml entre repositoris. A la tercera versió d'una acció, sis PR idèntics. workflow_call.
  • Secrets de llarga durada en variables quan OIDC està disponible; tokens personals d'un desenvolupador en secrets de l'organització (deixen de funcionar quan marxa).
  • Consell: executa el workflow localment amb act per depurar; i desa en un README de cada repositori l'enllaç al workflow reutilitzable i als runbooks, perquè "com es desplega això" tingui resposta.

Exercicis

Exercici 1. El CI de servei-cataleg (proveïdor) ha de verificar els pactes que publiquen els seus consumidors. Escriu els passos del job contracte del seu ci.yml (sense repetir checkout/setup-node) i explica quines variables d'entorn necessita el Verifier de 04-05 per treballar amb el Broker en lloc d'un fitxer local, i per què ha d'executar record-deployment després de desplegar.

Exercici 2. Un desenvolupador de Pagaments obre un PR que canvia el payload de l'esdeveniment pagament.confirmat. En quina etapa del pipeline de Pagaments es detectaria una incompatibilitat amb servei-comandes, amb les eines de 04-05, i què caldria afegir perquè can-i-deploy la bloquegés?

Exercici 3. La Marta demana que Catàleg i Notificacions es promocionin a producció automàticament després de passar l'E2E a staging, però que Comandes i Pagaments requereixin aprovació humana. Descriu com s'implementa amb el que s'ha vist (entorns de GitHub, workflow_call, PR de promoció, Argo CD) sense duplicar el workflow.

Solucions

Solució 1. Passos: npm cinpm run test:contracte amb PACT_BROKER_BASE_URL, PACT_BROKER_TOKEN, GIT_COMMIT=${{ github.sha }} i GIT_BRANCH=${{ github.ref_name }} a env; el Verifier de 04-05 fa servir pactBrokerUrl i pactBrokerToken en lloc de pactUrls, providerVersion: process.env.GIT_COMMIT, providerVersionBranch, publishVerificationResult: true (només a CI: process.env.CI === 'true') i consumerVersionSelectors: [{ mainBranch: true }, { deployedOrReleased: true }] per verificar tant els pactes de la branca principal de cada consumidor com els de les versions desplegades. Després de desplegar a un entorn, pact-broker record-deployment --pacticipant servei-cataleg --version $GIT_COMMIT --environment staging diu al Broker quina versió de Catàleg hi ha a staging: sense aquest registre, el can-i-deploy de Comandes no sap contra quin proveïdor comprovar i respon "no" per manca d'informació.

Solució 2. A l'etapa contracte, però del costat del consumidor: 04-05 va fixar JSON Schema d'esdeveniments amb Ajv i una prova que servei-comandes tolera camps nous de pagament.confirmat; si Pagaments treu o reanomena un camp (importquantitat), ho detecta la prova d'esquema del mateix Pagaments si l'esquema està compartit a contractes/asyncapi.yaml (falla a l'npm test de Pagaments), o, si no, la prova d'esdeveniments de Comandes quan actualitzi l'esquema. Perquè can-i-deploy ho bloquegi caldria un pacte de missatges (Pact suporta message pacts: Comandes declara el missatge que espera; Pagaments el verifica amb un MessageProviderPact que produeix l'esdeveniment real) publicat al mateix Broker: llavors la relació Pagaments→Comandes apareix com qualsevol altra i can-i-deploy la comprova. És l'evolució natural del JSON Schema de 04-05.

Solució 3. El workflow reutilitzable de CD (servei-node-cd.yml) rep un input promocio-automatica: boolean. El seu últim job obre el PR de promoció a techcorp/plataforma (canvi de newTag a overlays/prod); si promocio-automatica és true, el mateix job el fusiona (gh pr merge --auto), i Argo CD sincronitza; si és false, el PR queda obert i el CODEOWNERS de k8s/servei-comandes/ i k8s/servei-pagaments/ exigeix la revisió del Luis o del líder de Pagaments. A més, el job de producció fa servir environment: production a GitHub amb required reviewers per a aquests dos serveis. Cap workflow no es duplica: Catàleg crida amb promocio-automatica: true, Comandes amb false.

Conclusió

El pipeline de TechCorp converteix cada push en una seqüència automàtica i per servei: ci.yml amb actions/setup-node@v4 (Node 20, memòria cau d'npm, GitHub Packages), npm run lint, npm test, npm run test:integracio amb Testcontainers al runner, npm run test:contracte i publicació de pactes al Pact Broker, docker/build-push-action amb etiquetes sha-<commit> i semver cap a ghcr.io/techcorp/servei-comandes (amb permissions: packages: write i el .npmrc com a secret de build), escaneig amb Trivy, i can-i-deploy com a porta; cd.yml que fixa la imatge a l'overlay de Kustomize (kustomize edit set image), executa el Job de migracions, fa kubectl apply + rollout status i llança l'E2E contra staging; GitOps amb Argo CD i techcorp/plataforma com a font de veritat per a producció; semver i sha- sobre la mateixa imatge; entorns amb els mateixos manifestos; secrets de GitHub i OIDC; el pipeline de @techcorp/comu-http; el workflow reutilitzable servei-node-ci.yml@v1 que aplica la regla del Luis; i les mètriques DORA per comprovar que els dijous a la nit s'han acabat. Queda una pregunta que rollout status amaga: què passa exactament amb el trànsit mentre les rèpliques de la 1.0.0 deixen pas a les de la 1.0.1, i com es desplega una versió a un 10 % dels usuaris abans de donar-la a tothom? Això és la lliçó següent: estratègies de desplegament.

Curs de Microserveis

Mòdul 1: Introducció als Microserveis

Mòdul 2: Disseny de Microserveis

Mòdul 3: Comunicació entre Microserveis

Mòdul 4: Implementació de Microserveis

Mòdul 5: Desplegament i Orquestració

Mòdul 6: Monitoratge i Manteniment

Mòdul 7: Seguretat en Microserveis

Mòdul 8: Casos d'Estudi i Exemples Pràctics

© Copyright 2026. Tots els drets reservats