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
- Per què "quina és la millor?" està mal plantejada
- El mateix pipeline, sis vegades: recapitulació
- Taula d'equivalències de vocabulari
- Comparativa per dimensions
- Els criteris de decisió, ordenats per pes real
- Un arbre de decisió
- Cost total de propietat, amb números
- El cost de canviar d'eina i com reduir-lo
- Migració entre eines, per fases
- Triar per moda, o pel que feia servir la teva antiga empresa
- Errors Comuns i Consells
- Exercicis
- Conclusió i tancament del mòdul
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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ó.
| 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ó_lleugeraAmb 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.
- 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=4Beneficis, 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.ymlambmake qualitatimake tests'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.
- 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.
- 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:
- 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.
- Maquinari ja disponible i amortitzat, amb capacitat ociosa real i personal que ja l'opera per a altres coses.
- Una restricció de compliment que faci irrellevant la comparació: llavors no és una decisió econòmica.
- 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.
- 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
- Conceptes Bàsics de CI/CD
- Beneficis del CI/CD
- Eines Populars de CI/CD
- El Projecte del Curs: l'Aplicació que Automatitzarem
- Mètriques DORA: Com es Mesura el Lliurament de Programari
Mòdul 2: Integració Contínua (CI)
- Introducció a la Integració Contínua
- Configuració d'un Entorn de CI
- Automatització de la Construcció
- Proves Automatitzades
- Qualitat de Codi i Anàlisi Estàtica
- Artefactes, Versionat i Promoció
- Integració amb el Control de Versions
Mòdul 3: Desplegament Continu (CD)
- Introducció al Desplegament Continu
- Automatització del Desplegament
- Infraestructura com a Codi i Entorns Reproduïbles
- Estratègies de Desplegament
- Feature Flags, Rollback i Recuperació davant Errors
- Monitoratge i Retroalimentació
Mòdul 4: Pràctiques Avançades de CI/CD
- Pipelines de CI/CD
- Gestió de Dependències
- Seguretat en CI/CD
- Escalabilitat i Rendiment
- Pipeline as Code: Plantilles, Reutilització i Proves del Pipeline
- Bases de Dades al Pipeline: Migracions Segures
Mòdul 5: Implementació de CI/CD en Projectes Reals
- Cas d'Estudi: Projecte Web
- Cas d'Estudi: Aplicació Mòbil
- Cas d'Estudi: Microserveis
- Cas d'Estudi: Modernitzar un Projecte Legacy
Mòdul 6: Eines i Tecnologies
- Jenkins
- GitLab CI/CD
- CircleCI
- Travis CI
- Docker i Kubernetes
- GitHub Actions a Fons
- Comparativa i Criteris per Triar Eina
Mòdul 7: Exercicis Pràctics
- Exercici 1: Configuració d'un Pipeline Bàsic
- Exercici 2: Integració de Proves Automatitzades
- Exercici 3: Desplegament en un Entorn de Producció
- Exercici 4: Monitoratge i Retroalimentació
- Exercici 5: Enfortir el Pipeline amb Seguretat i Secrets
- Projecte Final: Pipeline Complet d'Extrem a Extrem
