Sis lliçons, sis eines i el mateix pipeline de Reservalia traduït sis vegades. Si has arribat fins aquí esperant que aquesta lliçó digui quina és la millor, la resposta decebrà i alhora és el més útil que et pot donar el mòdul: la pregunta està mal plantejada. No perquè sigui de mal gust comparar —compararem amb detall—, sinó perquè "la millor eina" no és una propietat de l'eina: és una propietat de la relació entre l'eina i un context concret, amb el seu codi, el seu equip, les seves restriccions legals, el seu pressupost i el que ja sap operar. Aquesta lliçó fa quatre coses: recapitula el pipeline de Reservalia en les eines vistes i fixa una taula d'equivalències de vocabulari que et servirà la resta de la teva carrera; compara per dimensions, sense guanyadors globals; ordena els criteris de decisió pel seu pes real, que és molt diferent del pes que se'ls dona a les discussions d'equip; i tracta el que gairebé mai no es tracta: quant costa canviar d'eina, com reduir aquest cost abans de necessitar-ho, i com migrar sense aturar l'equip.

Contingut

  1. Per què "quina és la millor?" està mal plantejada
  2. El mateix pipeline, sis vegades: recapitulació
  3. Taula d'equivalències de vocabulari
  4. Comparativa per dimensions
  5. Els criteris de decisió, ordenats per pes real
  6. Un arbre de decisió
  7. Cost total de propietat, amb números
  8. El cost de canviar d'eina i com reduir-lo
  9. Migració entre eines, per fases
  10. Triar per moda, o pel que feia servir la teva antiga empresa
  11. Errors Comuns i Consells
  12. Exercicis
  13. Conclusió i tancament del mòdul

  1. Per què "quina és la millor?" està mal plantejada

La pregunta suposa que existeix un ordre total entre eines que resolen el mateix problema. No existeix, per tres raons concretes.

Primera: les eines convergeixen. Compara el que fan avui les sis i veuràs que el 80 % coincideix: pipeline definit en un fitxer del repositori, jobs amb dependències, execució en contenidors, memòria cau, artefactes, matrius, secrets, aprovacions, identitat federada. Les diferències reals són al 20 % restant i en com se senten quan les fas servir. Triar per una llista de funcionalitats produeix empats constants.

Segona: el cost dominant no és l'eina, és el context. Migrar d'una a una altra costa setmanes; operar una instal·lació autoallotjada costa mitja persona; formar l'equip costa mesos de fluïdesa. Comparat amb això, que una tingui millor sintaxi de matriu és soroll.

Tercera: la majoria de les decisions ja estan preses quan arriba la pregunta. Si el codi és a GitHub, la identitat de l'equip és a GitHub i la protecció de branques és a GitHub, triar un altre CI significa mantenir una integració addicional per sempre. Això no ho compensa gairebé cap avantatge tècnic.

Les preguntes ben plantejades són aquestes, i la resta de la lliçó les respon:

Pregunta útil On es respon
Quines restriccions no negociables tinc? (dades, xarxa, maquinari, compliment) Apartat 5, criteri 2
On viuen el meu codi i la meva identitat? Apartat 5, criteri 1
Què sap operar el meu equip avui, i què està disposat a operar? Apartat 5, criteri 3
Quin és el cost total, incloses les persones? Apartat 7
Què em costaria canviar d'aquí a tres anys, i com ho redueixo ja? Apartat 8

I una pregunta que no és útil: "quina és més potent?". Totes són prou potents per al 95 % dels pipelines. La potència deixa de ser el factor limitant molt aviat.

  1. El mateix pipeline, sis vegades: recapitulació

El pipeline de Reservalia —instal·lar amb memòria cau → lint i test en paral·lel amb sharding → build d'imatge → escaneig → publicar per digest → desplegar amb aprovació— expressat en cada eina, i què va revelar cada traducció:

Eina Com va quedar Què va revelar la traducció
GitHub Actions (base) needs, matrix, composite action, reusable workflow, OIDC, Environments El punt de referència del curs
Jenkins (06-01) Jenkinsfile declaratiu: stages, parallel, matrix, stash, input, post El graf és implícit (arbre, no DAG); l'input reté executor si no es vigila; el stash passa pel controlador
GitLab CI (06-02) stages + needs, parallel, services, environment, registre integrat La distinció cache/artifacts és explícita; el registre i les credencials vénen regalats; rules ho governa tot
CircleCI (06-03) workflows amb requires, parallelism, commands, orbs, contexts Memòria cau totalment manual; workspace ≠ memòria cau ≠ artefactes; repartiment per temps històrics que les altres no porten
Travis CI (06-04) stages + jobs.include, fases fixes No hi cap del tot: sense graf, sense pas d'artefactes entre jobs, sharding copiat quatre vegades, promoció per digest compromesa
Kubernetes (06-05) No és CI: és el destí. Deployment per digest, sondes, rollout undo, GitOps Canvia qui inicia el desplegament i treu les credencials del CI

La conclusió de l'exercici és la que justifica haver-lo fet sis vegades: el pipeline és el mateix problema a tot arreu. Instal·lar de manera reproduïble, verificar en paral·lel, construir un artefacte immutable, escanejar-lo, publicar-lo identificat pel seu contingut i promocionar-lo amb una porta. El que canvia és la sintaxi, el nom de les peces i què et regala l'eina. Qui entén el problema tradueix a qualsevol sintaxi en dies; qui només coneix una sintaxi comença de zero cada vegada.

  1. Taula d'equivalències de vocabulari

Aquesta taula és probablement el més reutilitzable de la lliçó. Guarda-la.

Concepte GitHub Actions GitLab CI Jenkins CircleCI Travis CI
Fitxer de definició .github/workflows/*.yml .gitlab-ci.yml Jenkinsfile .circleci/config.yml .travis.yml
Execució completa Workflow run Pipeline Build / Run Pipeline Build
Unitat amb màquina pròpia Job Job Stage amb agent Job Job de la matriu
Agrupació lògica (no existeix) Stage Stage (no existeix) Stage
Ordre individual Step Línia d'script Step Step Fase (script, install…)
Màquina executora Runner Runner (+ executor) Agent / node Executor Worker
Ranura de concurrència (implícit) concurrent Executor (implícit) (implícit)
Dependència entre unitats needs needs / stages Ordre de stages requires Ordre de stages
Execució paral·lela matrix, jobs parallel, jobs parallel parallelism, jobs Entrades de matriu
Memòria cau de dependències actions/cache cache: Plugin / volum save_cache/restore_cache cache:
Pas de fitxers entre unitats Artefactes artifacts stash/unstash Workspace (no existeix)
Sortida descarregable Artefactes artifacts archiveArtifacts store_artifacts (extern)
Sortida de valors outputs reports:dotenv env / script (fitxer + workspace) (no existeix)
Servei auxiliar services: services: Contenidor del pod Contenidor secundari services:
Secrets secrets Variables protegides Credentials + withCredentials Contexts / variables secure:
Identitat federada OIDC (id-token) id_tokens Plugin / rol d'instància OIDC (no)
Reutilització de passos Composite action extends / include Shared Library (vars/) Command (anchors YAML)
Reutilització de jobs Reusable workflow Component / include Shared Library Orb (no)
Registre de plantilles Marketplace Catàleg de components Repositori de llibreria Registre d'orbs (no)
Entorn de desplegament environment environment (plugin) (no modelat) (no)
Aprovació manual Revisors d'Environment when: manual input type: approval (no)
Cancel·lar obsolets concurrency interruptible disableConcurrentBuilds Auto-cancel (no)
Filtre per rutes paths rules: changes when { changeset } (lògica pròpia) (no)

Dues observacions que es llegeixen entre línies. Primera, la columna de Travis té molts buits, i això no és un descuit: és la diferència entre una eina de CI i una de CI/CD, i explica el seu declivi millor que qualsevol anàlisi de mercat. Segona, "job" significa coses diferents: a Jenkins un job és el que a les altres és un workflow, mentre que la unitat amb màquina pròpia és el stage amb agent. És la confusió de vocabulari que més malentesos causa en equips mixtos.

  1. Comparativa per dimensions

Sense guanyadors globals: cada fila és una dimensió i el que és rellevant és quines t'importen a tu.

Dimensió GitHub Actions GitLab CI Jenkins CircleCI Travis CI
Model d'execució Graf (needs) Etapes → graf Arbre amb paral·lel imbricat Graf des de l'origen Fases fixes
Allotjament SaaS + executors propis SaaS o autoallotjat complet Només autoallotjat SaaS + executors propis SaaS
Configuració Codi Codi Codi (amb herència d'interfície) Codi Codi
Reutilització Composite + reusable + marketplace extends/include/components Shared Libraries Orbs amb versionat immutable Molt limitada
Secrets i identitat federada OIDC natiu, entorns OIDC natiu, variables protegides Plugins; no natiu OIDC, contexts Xifrat al repo
Ecosistema El més gran Mitjà, integrat El més ampli en integracions rares Mitjà Residual
Plataforma integrada Alta (repo, registre, issues) La més completa Cap: peça solta Cap: peça solta Cap
macOS / ARM / GPU Sí (macOS car) Amb executors propis Qualsevol cosa que tinguis Àmplia oferta ARM i arquitectures rares
Maduresa de desplegament i aprovacions Environments amb regles Entorns amb historial i on_stop input, sense model d'entorn type: approval, sense entorn Proveïdors deploy
Observabilitat del pipeline Mitjana (resums, temps) Bona Depèn de plugins La millor Escassa
Model de cost Minuts + emmagatzematge Per usuari + minuts Infraestructura + persones Crèdits + usuaris Crèdits
Cost de sortida Mitjà Alt (repo + CI + registre) Mitjà Baix Baix

Com llegir aquesta taula sense equivocar-se: una fila només importa si és un requisit teu. "Plataforma integrada: la més completa" és un avantatge enorme si busques plataforma i un desavantatge si ja tens un ecosistema muntat i només vols CI. "Només autoallotjat" és descalificant per a un equip de tres i és exactament el que necessita una empresa amb dades que no poden sortir. No hi ha cap columna que guanyi més files i per tant guanyi.

  1. Els criteris de decisió, ordenats per pes real

Aquí hi ha el contingut més valuós de la lliçó, i l'ordre importa més que la llista.

Criteri 1 — On viuen el codi i la identitat de l'equip (decideix ~80 % dels casos)

Si el teu codi és a GitHub i el teu equip s'autentica amb GitHub, GitHub Actions parteix amb un avantatge que gairebé res no compensa. Si és a GitLab, el mateix amb GitLab CI. No és mandra: és que fer servir un CI extern implica, per sempre:

  • Una integració de permisos per mantenir i que es trenca quan algú rota un token.
  • Sincronització d'identitats: qui pot desplegar s'ha de definir dues vegades, i les dues definicions divergeixen.
  • Dos llocs on mirar quan alguna cosa falla, i un salt de context a cada incident.
  • Checks que arriben de fora i una protecció de branca que depèn d'una integració.

Aquest cost és permanent i silenciós. L'avantatge tècnic que el justifiqui ha de ser gran i concret. Aquest criteri no és un empat per desfer: és el punt de partida, i les altres eines se l'han de guanyar.

Corol·lari incòmode: si el teu codi és a GitHub i estàs avaluant cinc eines de CI, probablement estàs resolent el problema equivocat. Comença per la integrada, identifica què et falta amb noms concrets i només llavors mira a fora.

Criteri 2 — Restriccions de compliment i dades (decideix, quan aplica, sense discussió)

Si existeix una restricció legal o contractual real, mana per sobre de tota la resta. Les preguntes que cal fer abans de res:

  • El codi font pot sortir de la nostra xarxa? I els logs, que sovint contenen més del que sembla?
  • Les dades de prova contenen informació personal o regulada?
  • Hi ha obligació de retenció d'auditoria, amb qui va aprovar què i quan?
  • S'exigeix separació de funcions —que qui escriu el canvi no sigui qui l'aprova—?
  • Hi ha requisit de residència de dades en una jurisdicció concreta?

Avís important i freqüent: un executor autoallotjat d'un SaaS no satisfà una restricció estricta. La feina corre a la teva xarxa, sí, però el pla de control, l'orquestració, els logs i sovint els secrets continuen en un tercer. Si l'exigència és literal, la resposta és autoallotjar la plataforma sencera: Jenkins o GitLab autoallotjat. I la primera acció no és tècnica: és llegir el contracte o la norma, perquè la meitat de les vegades la restricció és menys estricta del que l'equip assumeix, i l'altra meitat és més.

Criteri 3 — Què sap operar l'equip avui

Una eina que ningú no sap operar és pitjor que una de menys capaç que l'equip domina. Un Jenkins sense amo es degrada sol (06-01); un clúster de Kubernetes mal operat és pitjor que ECS (06-05).

Preguntes concretes, amb noms i cognoms:

  • Qui actualitza això? Què deixa de fer mentrestant?
  • Qui respon a les tres de la matinada si el CI cau durant un incident?
  • Qui restaura la còpia de seguretat, i quan es va assajar per última vegada?
  • Què passa quan aquesta persona se'n va de vacances o de l'empresa?

Si no hi ha resposta a alguna, l'opció autoallotjada no és sobre la taula per molt que tècnicament convenci. Per a Reservalia —la Marta, en Diego i la Nuria— la resposta és evident i no requereix anàlisi: SaaS.

Criteri 4 — Necessitats de maquinari i plataforma

macOS per compilar iOS (05-02), GPU per a models, ARM natiu, dispositius físics, llicències lligades a una màquina, molta memòria. Aquí l'ordre s'inverteix: si hi ha una necessitat de maquinari que només cobreix una opció, aquesta opció hi entra sí o sí, encara que sigui només per a aquella part del pipeline. El patró habitual i assenyat és híbrid: l'eina principal per a tot, i una peça específica on el maquinari hi obliga.

Criteri 5 — Pressupost i la seva forma

No només quant, també de quin tipus:

Forma del cost Eines Implicacions
Opex variable (per minut/crèdit) Actions, CircleCI, GitLab SaaS Creix amb l'activitat; sense inversió inicial; sorpreses si ningú no ho vigila
Opex per usuari GitLab, en part CircleCI Predictible; castiga els col·laboradors ocasionals
Capex + opex de persones Jenkins, GitLab autoallotjat Cost inicial i persones fixes; predictible; independent de l'activitat

Aquest criteri es creua amb el 3: el cost de les persones és real encara que no aparegui en cap factura, i és precisament el que més s'oblida als fulls de càlcul que comparen "X euros al mes de SaaS" amb "una màquina que ja tenim".

Criteri 6 — Maduresa de l'equip en CI/CD

Un equip que comença es beneficia d'una eina opinada, amb valors per defecte assenyats i molta documentació. Un equip madur amb necessitats particulars valora el control. Adoptar Jenkins amb Shared Libraries i agents a Kubernetes sent tres persones que mai no van fer CI és garantia d'abandonament; adoptar una eina molt opinada tenint requisits rars és garantia de barallar-s'hi cada setmana.

El resum de l'ordre

1. Restriccions no negociables  → si n'hi ha, filtren primer
2. On viu el codi                → decideix el 80 % del que queda
3. Qui opera                     → descarta opcions, no les tria
4. Maquinari                     → afegeix peces híbrides
5. Pressupost i la seva forma    → afina entre les supervivents
6. Maduresa                      → decideix quanta corda donar-se

Fixa't que la qualitat tècnica de l'eina no apareix a la llista. No perquè tant li faci, sinó perquè totes les supervivents dels sis filtres són prou bones, i a aquestes altures la decisió ja està presa.

  1. Un arbre de decisió

flowchart TD
    A["Triar eina de CI/CD"] --> B{"Hi ha restriccio legal o contractual<br/>que impedeixi fer servir un SaaS?"}
    B -->|"Si"| C{"Qui opera la plataforma?"}
    C -->|"Ningu amb temps"| D["Resoldre aixo primer:<br/>no hi ha opcio viable sense operador"]
    C -->|"Hi ha equip"| E{"Es vol plataforma completa<br/>o nomes un motor per automatitzar?"}
    E -->|"Plataforma"| F["GitLab autoallotjat"]
    E -->|"Motor"| G["Jenkins"]

    B -->|"No"| H{"On viu el codi?"}
    H -->|"GitHub"| I["GitHub Actions<br/>punt de partida"]
    H -->|"GitLab"| J["GitLab CI/CD<br/>punt de partida"]
    H -->|"Diversos o Bitbucket"| K["CircleCI o un altre SaaS<br/>independent"]

    I --> L{"Falta alguna cosa concreta<br/>amb nom?"}
    J --> L
    L -->|"No"| M["Quedar-se. Invertir en el pipeline,<br/>no a triar eina"]
    L -->|"Velocitat de suite gran"| N["Avaluar CircleCI<br/>o millorar primer el que hi ha"]
    L -->|"Maquinari especial"| O["Hibrid: executors propis<br/>o Jenkins nomes per a aixo"]
    L -->|"Molts serveis a Kubernetes"| P["Afegir GitOps: Argo CD o Flux<br/>no canviar de CI"]

Dues branques mereixen comentari perquè són les que més s'erren a la pràctica.

"Falta alguna cosa concreta amb nom": l'exigència d'anomenar-ho és deliberada. "Ens agradaria alguna cosa millor" no és un requisit. "El job d'e2e triga 14 minuts per repartiment desigual i no tenim històric de temps" sí que ho és, i —fixa-t'hi— probablement s'arregla sense canviar d'eina.

"Molts serveis a Kubernetes" porta a afegir GitOps, no a canviar de CI. És un error molt comú: el problema és el model de desplegament (06-05), no el motor de CI, i canviar el segon no arregla el primer.

  1. Cost total de propietat, amb números

Comparar "20 euros al mes" amb "una màquina que ja tenim" és la manera més habitual d'equivocar-se. L'exercici correcte inclou les persones.

Escenari: equip de 12 desenvolupadors, 40 execucions de pipeline al dia, 12 minuts de còmput per execució en 4 jobs paral·lels ≈ 35 minuts-màquina per execució.

Consum mensual = 40 execucions/dia × 21 dies × 35 min ≈ 29.400 minuts-màquina
Concepte SaaS per minut Autoallotjat
Còmput 29.400 min × tarifa per minut 3 màquines sempre enceses
Emmagatzematge (artefactes, memòria cau) Facturat per GB Discos i còpies
Llicències Inclòs o per usuari × 12 Segons eina i nivell
Operació ~0 h/mes 8-16 h/mes: actualitzacions, plugins, agents, incidents
Guàrdia 0 Part d'una rotació, o algú de facto
Posada en marxa Hores 2-6 setmanes d'una persona
Cost d'indisponibilitat Del proveïdor Teu, i l'equip aturat mentre dura

La fórmula que cal fer servir, i el número que gairebé sempre decideix:

TCO_autoallotjat = infraestructura + llicències
                 + (hores_operació/mes × cost_hora_carregat)
                 + amortització(posada_en_marxa)
                 + risc(indisponibilitat × freqüència)

TCO_saas         = còmput + emmagatzematge + llicències_per_usuari
                 + hores_gestió_lleugera

Amb un cost carregat per hora d'una persona de plataforma —salari més impostos, eines i espai—, 10 hores al mes d'operació solen superar per si soles la factura completa d'un SaaS per a un equip d'aquesta mida. Aquest és el resultat que sorprèn i el que cal portar a la conversa amb qui decideix. I el punt d'equilibri es desplaça amb la mida: amb 200 desenvolupadors i un ús molt intensiu, les mateixes 10-20 hores mensuals es reparteixen entre molt més consum i l'autoallotjat pot guanyar amb claredat.

Tres avisos perquè el càlcul sigui honest:

  • No t'inventis tarifes. Les de cada proveïdor canvien per pla, regió i tipus de màquina; consulta-les el dia que facis el càlcul i anota la data.
  • Compta els multiplicadors. macOS i màquines grans no costen el mateix per minut; un pipeline amb molt macOS (05-02) canvia el resultat completament.
  • Inclou el que el SaaS t'estalvia en integracions. Si l'alternativa exigeix mantenir sincronització d'identitats i webhooks, això són hores que van a la columna de l'autoallotjat, no a cap altra.

  1. El cost de canviar d'eina i com reduir-lo

Una migració de CI/CD en un repositori real és de setmanes, no de dies, i el repartiment de l'esforç és sistemàticament el mateix:

Part del pipeline Cost de migrar Proporció típica
Lògica de build, test, desplegament Baix si és en scripts; alt si és al YAML 40-60 % del contingut
Orquestració (jobs, dependències, matriu, disparadors) Reescriptura mecànica 20-30 %
Integracions (actions/orbs/plugins de tercers) Reconstrucció 10-20 %
Secrets i identitat federada Reconfigurar i rotar 5-10 %
Aprenentatge de l'equip Setmanes de menys fluïdesa Difús i real

La palanca que de veritat mou aquest número la va anticipar la 06-04 i val la pena repetir-la: treu la lògica del YAML i deixa'l com a orquestrador prim.

# Fràgil: 60 línies de lògica dins del YAML d'una eina concreta
- run: |
    npm ci --prefer-offline
    npx prettier --check .
    npm run lint -- --max-warnings 0
    npx tsc --noEmit
    npm test -- --coverage --shard=${{ matrix.shard }}/4
    node scripts/comprovar-cobertura.js --minim 80
# Makefile — interfície estable, independent de l'eina
.PHONY: instal·lar qualitat test build imatge

instal·lar:
	npm ci --prefer-offline

qualitat: instal·lar
	npx prettier --check .
	npm run lint -- --max-warnings 0
	npx tsc --noEmit

test: instal·lar
	npm test -- --coverage --shard=$(SHARD)/$(TOTAL)
	node scripts/comprovar-cobertura.js --minim 80

imatge:
	docker buildx build --file apps/api/Dockerfile \
	  --cache-from type=registry,ref=$(ECR)/$(IMATGE):cache \
	  --tag $(ECR)/$(IMATGE):$(SHA) --push .
# El YAML, en qualsevol eina, es torna trivial
- run: make qualitat
- run: make test SHARD=${{ matrix.shard }} TOTAL=4

Beneficis, i aquest és l'argument important: no depenen que arribis a migrar.

  • El desenvolupador executa exactament el mateix en local. Desapareix la classe sencera de fallades "només passa al CI", que és de les que més temps consumeixen.
  • La lògica és codi revisable i testejable, no una cadena dins d'un YAML que ningú no llegeix al PR.
  • El pipeline es torna llegible: un ci.yml amb make qualitat i make test s'entén d'un cop d'ull.
  • I sí, migrar passa de setmanes a dies.

El límit honest: no tot surt del YAML. Disparadors, matrius, permisos, entorns, aprovacions, concurrència i memòria cau són propis de cada eina, i abstreure'ls exigeix una capa d'indirecció que costa més del que estalvia. L'objectiu raonable no és la portabilitat total, sinó que el gruix de l'esforç de migració sigui reescriure orquestració, no reconstruir lògica.

  1. Migració entre eines, per fases

Quan la migració està decidida, el patró que funciona és el mateix de la 05-04: increments amb valor propi i sense congelar l'equip.

Fase Què es fa Quan passar a la següent Risc
1. Inventari Tots els fluxos de treball, què fa cadascun, qui en depèn, quins secrets fa servir, quines integracions té. I què està mort Quan estigui escrit i revisat Cap; ometre-la és l'error clàssic
2. Pipeline paral·lel El nou s'executa al costat del vell a cada PR, sense ser obligatori. Es comparen resultats 2-3 setmanes amb resultats coincidents Cost doble de còmput temporal
3. Canvi del senyal obligatori El check obligatori passa a ser el nou; el vell queda informatiu Quan ningú no miri ja el vell El més alt: aquí es descobreix el que faltava
4. Migrar el CD Desplegament al final, i per entorns: primer staging, després producció Quan staging porti setmanes estable Alt: afecta producció
5. Retirada Esborrar el pipeline vell, desactivar el servei, revocar tots els secrets, actualitzar documentació i insígnies Baix, si les fases prèvies es van fer

Quatre regles que eviten els desastres habituals:

El CD es migra l'últim, sempre. El CI es pot duplicar sense conseqüències; un desplegament duplicat o a mitges sí que en té. I dins del CD, primer staging.

Mai no es migra tot alhora en organitzacions amb molts repositoris. Es tria un repositori pilot —representatiu però no crític—, s'aprèn amb ell, s'escriu una plantilla i es propaga.

Els secrets es roten, no es copien. És el moment natural per fer-ho i per descobrir quins ja no calia que existissin. I a la fase 5, revocar els del sistema vell és part de la migració, no un extra.

Què no migrar, que és tan important com què migrar: fluxos de treball que ningú no mira, jobs desactivats des de fa mesos, integracions amb sistemes que ja no existeixen, matrius de versions sense suport, i la lògica que "estava per si de cas". Una migració és la millor ocasió que tindràs per esborrar; desaprofitar-la és traslladar el deute intacte i afegir-hi el cost del trasllat.

  1. Triar per moda, o pel que feia servir la teva antiga empresa

Dos biaixos que produeixen decisions cares i que convé anomenar en veu alta perquè gairebé mai no es diuen.

El biaix de la conferència. Es veu una xerrada excel·lent sobre una eina en una empresa amb 400 enginyers, cinc persones de plataforma i un problema d'escala que no tens, i es conclou que és el que cal fer servir. La pregunta que ho desactiva: quin problema meu, amb nom, resol això que avui no estigui resolt? Si no hi ha resposta concreta, és admiració, no un requisit. És el mateix parany que la 06-05 assenyalava amb Kubernetes, i la resposta és idèntica: la complexitat es justifica amb un problema, no amb qui més la fa servir.

El biaix del nouvingut. Algú entra a l'equip des d'una empresa on feien servir X i proposa migrar a X. De vegades té raó —porta experiència real que l'equip no té—, però el biaix és previsible: coneix X en profunditat i l'eina actual amb prou feines, així que compara el millor d'una amb el pitjor de l'altra. La prova que ho desactiva: demanar-li que primer domini el que hi ha i després llisti, amb noms, què li falta. Si al cap de dos mesos la llista continua dempeus i és concreta, la proposta mereix una avaluació seriosa. La majoria de les vegades la llista es redueix a dos elements, i tots dos es resolen configurant millor el que ja hi ha.

I un tercer parany més subtil: canviar d'eina per no arreglar el pipeline. Un pipeline lent per una prova inestable sense quarantena, memòria cau mal configurada i jobs sense timeout continuarà sent lent a l'eina nova, amb la diferència que ara ningú no sap on mirar. Abans d'avaluar alternatives, aplica el de la 04-04: mesura, separa cua d'execució, i arregla el que és teu. Si després d'això el problema persisteix i és de l'eina, ja tens dades per a la conversa.

Errors Comuns i Consells

Comparar per llista de funcionalitats. Totes tenen gairebé tot. La decisió és al context, no a la taula.

Ignorar on viu el codi. És el criteri de més pes i el que més se subestima a les discussions d'equip.

Comptar només la factura. Les hores d'operació són cost real; en equips mitjans solen superar el SaaS que es volia evitar.

Creure que un executor autoallotjat satisfà una restricció de compliment. El pla de control continua a fora. Llegeix la norma abans de dissenyar.

Migrar el CD abans que el CI. El CI es duplica sense dany; un desplegament, no.

Migrar un a un sense aprofitar. Sense needs, sense arreglar la memòria cau, sense esborrar el que és mort: es trasllada el deute i es paga el trasllat.

Copiar els secrets en comptes de rotar-los. I no revocar els del sistema vell en acabar.

Triar una eina que ningú no operarà. Un Jenkins sense amo és pitjor que no tenir CI, perquè dona un senyal en què la gent confia.

Confondre "més potent" amb "millor per a nosaltres". La potència deixa de ser el factor limitant molt aviat.

Consell transversal que resumeix el mòdul: inverteix a entendre el problema —artefacte immutable, promoció per digest, portes de qualitat, retroalimentació ràpida, mínim privilegi— i tracta l'eina com a intercanviable. Qui domina el problema aprèn una eina nova en dues setmanes; qui només domina una sintaxi comença de zero cada vegada que canvia de feina.

Exercicis

Exercici 1. Tres escenaris. Per a cadascun, aplica els sis criteris en ordre, recomana una eina (o combinació) i justifica quin criteri va ser decisiu i quins van resultar irrellevants:

  • (a) Startup de 6 persones, codi a GitHub, aplicació web Node desplegada a Vercel i una API a ECS. Sense restriccions legals. Ningú no vol operar infraestructura.
  • (b) Empresa de 300 persones al sector sanitari. El codi no pot sortir de la seva xarxa per contracte amb els seus clients. Ja tenen Jenkins amb 180 jobs freestyle. Equip de plataforma de 4 persones. Volen "modernitzar-se".
  • (c) Empresa de producte de 40 persones, codi a GitLab autoallotjat, 12 microserveis a Kubernetes, aplicació mòbil iOS i Android, i un equip de plataforma de 2 persones que està desbordat.

Exercici 2. Calcula el TCO comparat per a un equip de 25 desenvolupadors amb 80 execucions diàries de 15 minuts en 5 jobs paral·lels. Compara SaaS per minut davant de Jenkins autoallotjat en màquines pròpies. Enumera totes les partides —incloses les que no apareixen en cap factura— i explica quin supòsit hauria de canviar per invertir el resultat.

Exercici 3. La Marta et demana un pla: reduir la dependència de Reservalia respecte de GitHub Actions sense migrar i sense aturar el desenvolupament. Proposa les accions concretes, el seu cost, el seu benefici amb independència que la migració arribi a passar, i on és el punt en què deixar d'invertir. Estima l'abans i el després del cost d'una migració hipotètica.

Solucions

Solució 1.

(a) Startup de 6 persones.

Criteri Resultat
1. Restriccions Cap → no filtra
2. Codi i identitat GitHub → decisiu
3. Qui opera Ningú → descarta tot el que sigui autoallotjat
4. Maquinari Res especial → irrellevant
5. Pressupost Repositori privat, poc volum: els minuts inclosos probablement cobreixen
6. Maduresa Baixa: convé el que és opinat i ben documentat

Recomanació: GitHub Actions, sense més anàlisi. Decisius: criteris 2 i 3, que apunten al mateix lloc. Irrellevants: el 4 i, gairebé, el 5. El consell que acompanya la recomanació és més valuós que ella: amb 6 persones, el temps gastat a avaluar eines és temps robat al pipeline; fes servir el que està integrat i dedica aquest esforç a posar portes de qualitat, desplegament automatitzat i mètriques DORA (01-05).

(b) Empresa sanitària de 300 persones.

Criteri Resultat
1. Restriccions El codi no surt de la xarxa → decisiu, filtra primer: només autoallotjat
2. Codi i identitat Depèn d'on sigui; si és GitHub Enterprise Server o GitLab autoallotjat, apunta al seu CI integrat
3. Qui opera 4 persones: hi ha equip. Viable
4. Maquinari Per verificar; en salut sol haver-hi integracions amb sistemes antics
5. Pressupost Capex + persones, ja assumit
6. Maduresa Mitjana-baixa: 180 jobs freestyle indiquen pràctiques de fa una dècada

Recomanació: no triar eina encara. El diagnòstic és que "modernitzar-se" no significa canviar d'eina, significa passar de freestyle a pipeline as code (04-05, 06-01), i això es fa dins de Jenkins, sense migrar res. Pla per fases: (1) inventari dels 180 jobs, amb l'expectativa fonamentada que un terç està mort; (2) Jenkinsfile als 20 més usats, amb pipeline paral·lel al freestyle; (3) JCasC i agents efímers per acabar amb la deriva de configuració; (4) Shared Library per al que es repeteix. En acabar, si encara hi ha raons, es reavalua GitLab autoallotjat amb dades reals sobre què falta.

Decisiu: criteri 1, que descarta tot el SaaS. Irrellevant: qualsevol comparació amb GitHub Actions o CircleCI, que van quedar fora al primer filtre. I la lliçó de mètode: la millora més gran disponible aquí no requereix canviar d'eina, i proposar una migració hauria gastat mesos sense resoldre el problema real, que és que la configuració viu en formularis d'un servidor.

(c) Empresa de producte de 40 persones.

Criteri Resultat
1. Restriccions Cap de declarada
2. Codi i identitat GitLab autoallotjat → GitLab CI és el punt de partida
3. Qui opera 2 persones desbordades → la dada més important
4. Maquinari macOS per a iOS → requereix solució específica
5. Pressupost Ja paguen la instància; el marge és a no afegir operació
6. Maduresa Alta: 12 microserveis a Kubernetes

Recomanació: quedar-se a GitLab CI i no afegir cap eina, amb tres accions concretes. Per a macOS, executors macOS gestionats per un tercer o el servei SaaS de GitLab per a aquells jobs concrets: comprar màquines Apple i operar-les amb un equip desbordat és exactament el que no s'ha de fer (05-02). Per als 12 microserveis, include d'un component compartit ancorat a versió, en comptes de 12 fitxers divergents (05-03, 04-05). Per a Kubernetes, GitOps amb Argo CD o Flux, que a més treu les credencials del clúster del CI (06-05).

Decisiu: criteri 3. L'equip de plataforma desbordat és la restricció que governa totes les decisions, i qualsevol recomanació que afegeixi operació és incorrecta per definició, per bona que sigui tècnicament. Irrellevant: comparar GitLab CI amb CircleCI o Actions; cap avantatge no compensaria afegir una integració externa a un equip que no dona l'abast.

Solució 2.

Consum: 80 × 21 × 15 × 5 = 126.000 minuts-màquina/mes ≈ 2.100 hores-màquina, que equivalen a unes 3 màquines al 100 % d'ocupació, i com que la càrrega és en horari laboral, a la pràctica calen 5-6 màquines per no tenir cua a les hores punta.

Partida SaaS per minut Jenkins autoallotjat
Còmput 126.000 min × tarifa vigent 6 màquines (ocioses de nit i el cap de setmana)
Emmagatzematge Artefactes i memòria cau per GB Discos, còpies de seguretat, el seu emmagatzematge
Xarxa Inclosa Trànsit de sortida en descarregar imatges i dependències
Llicències Per usuari segons pla Jenkins és lliure; sistema operatiu i monitoratge sí que costen
Posada en marxa 1-2 dies 3-6 setmanes d'una persona
Operació mensual 1-2 h (gestió lleugera) 12-20 h: actualitzacions, plugins, CVE, agents, disc
Guàrdia 0 Part d'una rotació
Indisponibilitat Del proveïdor; sense control Teva; amb 25 persones aturades mentre dura
Formació Baixa Mitjana: Groovy, plugins, JCasC
Estalvi nocturn Automàtic (no es paga el que no es fa servir) Cap: les màquines estan enceses igualment

Càlcul: amb un cost carregat per hora d'una persona de plataforma, 16 hores mensuals d'operació solen equivaler a una xifra del mateix ordre que la factura sencera del SaaS per a aquest volum, abans de comptar màquines, emmagatzematge i posada en marxa. Afegint l'amortització de les 4-6 setmanes inicials durant el primer any, l'autoallotjat surt clarament per sobre.

Quins supòsits invertirien el resultat:

  1. Un volum molt més gran. Amb 500.000 minuts-màquina al mes, les hores d'operació no creixen proporcionalment i el cost per minut propi baixa molt. És l'economia d'escala que fa que les empreses molt grans autoallotgin.
  2. Maquinari ja disponible i amortitzat, amb capacitat ociosa real i personal que ja l'opera per a altres coses.
  3. Una restricció de compliment que faci irrellevant la comparació: llavors no és una decisió econòmica.
  4. Màquines molt més potents o especialitzades —GPU, molta memòria— on el multiplicador del SaaS és alt i una màquina pròpia s'amortitza ràpid.
  5. Jobs molt llargs i continus que mantinguin les màquines ocupades també fora de l'horari laboral, eliminant l'avantatge de pagar només per ús.

Conclusió defensable: per a 25 desenvolupadors i aquest volum, SaaS, i l'argument decisiu no és la factura de còmput —que fins i tot pot ser més gran— sinó les 12-20 hores mensuals d'una persona que no cal dedicar a operar el CI. Aquest és el número que cal portar a la reunió.

Solució 3.

Objectiu ben plantejat: no és "poder migrar", és reduir l'acoblament a canvi de beneficis que rendeixen des del primer dia. Si una acció només aporta valor en cas de migració, no entra al pla.

# Acció Cost Benefici immediat (encara que no migrem mai) Reducció del cost de migrar
1 Moure la lògica dels run llargs a scripts/*.sh i npm scripts, amb un Makefile com a interfície (make qualitat, make test, make imatge) 3 dies Executable en local: desapareixen les fallades "només al CI"; lògica revisable i testejable; ci.yml llegible Alta
2 Substituir actions de tercers que només embolcallen una CLI per la CLI directa; fixar per SHA les que quedin i documentar per què hi és cadascuna 2 dies Menys superfície de subministrament (04-03); menys trencaments per canvis aliens Mitjana-alta
3 Documentar el contracte de desplegament: què rep desplegar.sh (digest, entorn), què garanteix, com es verifica 1 dia Qualsevol de l'equip pot desplegar d'emergència sense el pipeline; és també el pla B de la 03-05 Mitjana
4 Registre de decisions del pipeline: per què OIDC, per què Environments, per què aquesta memòria cau 0,5 dies Onboarding i revisions més ràpides; evita replantejar el mateix cada trimestre Mitjana
5 Prova periòdica: executar make ci en una màquina neta sense GitHub Actions 0,5 dies Verifica que la portabilitat és real i no teòrica; detecta dependències ocultes de l'entorn de l'executor Alta
Capa d'abstracció sobre disparadors, entorns i permisos Setmanes Cap Baixa

On aturar-se: després del punt 5. L'última fila és la frontera, i el criteri és explícit: una capa d'abstracció sobre el que és específic de l'eina costa més que la migració que evitaria i afegeix indirecció permanent que empitjora la llegibilitat —just el que la 04-05 advertia sobre extreure abstraccions prematures—.

Abans i després:

Avui Després del pla (7 dies de feina)
Lògica al YAML ~55 % ~10 %
Actions de tercers 11 4, fixades per SHA i justificades
Reproduïble en local Parcial Sí, verificat periòdicament
Migració hipotètica 3-4 setmanes 5-8 dies

La frase per a la Marta, que és el que cal dir a la reunió: "Set dies de feina. La migració passaria d'un mes a una setmana, però això és l'efecte secundari: el que comprem de veritat és que l'equip pugui executar el pipeline al seu portàtil, que la lògica es revisi com a codi i que el ci.yml s'entengui d'un cop d'ull. Si no migrem mai, continua sent rendible. I no anem més enllà: construir una capa d'abstracció sobre GitHub Actions costaria més que la migració que evitaria."

Conclusió i tancament del mòdul

La conclusió del mòdul se sosté sobre una comprovació empírica que has fet sis vegades: el mateix pipeline de Reservalia cap a totes les eines, perquè el problema és el mateix a tot arreu. Instal·lar de manera reproduïble, verificar en paral·lel amb retroalimentació ràpida, construir un artefacte immutable, escanejar-lo, publicar-lo identificat pel seu contingut, promocionar-lo per digest a través d'una porta i poder tornar enrere. El que canvia és la sintaxi, el nom de les peces i què et regala la plataforma. Per això la taula d'equivalències de l'apartat 3 val més que qualsevol tutorial d'una eina concreta: et permet llegir un .gitlab-ci.yml o un Jenkinsfile el primer dia d'una feina nova.

El que cada eina va ensenyar, i que un s'emporta encara que no hi torni: Jenkins, que el control total es paga amb operació real i que un motor de propòsit general integra qualsevol cosa a canvi de no portar res resolt. GitLab, que una plataforma integrada regala traçabilitat, credencials i entorns, i cobra en acoblament. CircleCI, que la velocitat d'un pipeline és un problema d'enginyeria amb solucions concretes —repartiment per temps, memòria cau explícita, classes de recurs— i que la separació entre workspace, memòria cau i artefactes aclareix una confusió que dura anys. Travis, que el model de fases fixes basta per a CI i no per a CD, que el negoci del teu proveïdor pot canviar sota els teus peus, i que un secret confiat a un tercer és un secret la seguretat del qual no controles. Docker i Kubernetes, que el substrat importa tant com l'orquestrador, que el digest mana sobre el tag, i que la complexitat es justifica amb un problema i no amb qui més la fa servir. I GitHub Actions, que l'eina que fas servir cada dia també té límits, asimetries perilloses i una superfície de subministrament que cal vigilar.

Els criteris, en l'ordre que importa: les restriccions no negociables filtren primer; on viuen el codi i la identitat decideixen el 80 % del que queda; qui l'operarà descarta opcions; el maquinari afegeix peces híbrides; el pressupost i la seva forma afinen; i la maduresa de l'equip decideix quanta corda donar-se. La qualitat tècnica no hi apareix, perquè a aquestes altures ja està decidit. I el cost que gairebé ningú no calcula —les hores de persones— és el que sol invertir el resultat del full de càlcul.

Amb això es tanca el mòdul 6 i, amb ell, la part conceptual del curs. Has recorregut els principis (mòduls 1 a 4), quatre contextos reals (mòdul 5) i la maquinària (mòdul 6). El que queda és fer-ho tu. El mòdul 7 és enterament pràctic: cinc exercicis guiats que construeixen, pas a pas, un pipeline d'extrem a extrem —el pipeline bàsic, les proves automatitzades, el desplegament en producció, el monitoratge i la retroalimentació, i l'enfortiment amb seguretat i secrets— i un projecte final on muntes el teu de complet, amb les portes, l'artefacte immutable, el desplegament amb rollback i les mètriques per saber si està funcionant. Aquí és on tot l'anterior deixa de ser lectura. Comença per l'Exercici 1: Pipeline Bàsic, que arrenca just on va arrencar la 02-02, però aquesta vegada l'escrius tu.

Curs de CI/CD: Integració i Desplegament Continu

Mòdul 1: Introducció al CI/CD

Mòdul 2: Integració Contínua (CI)

Mòdul 3: Desplegament Continu (CD)

Mòdul 4: Pràctiques Avançades de CI/CD

Mòdul 5: Implementació de CI/CD en Projectes Reals

Mòdul 6: Eines i Tecnologies

Mòdul 7: Exercicis Pràctics

Mòdul 8: Recursos Addicionals

© Copyright 2026. Tots els drets reservats