[{"data":1,"prerenderedAt":1813},["ShallowReactive",2],{"navigation:en":3,"\u002Fblog\u002Fgit-ramas-stage-production-primer-lanzamiento":129},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":10},"Nuxfire Docs","\u002Fdocs","docs\u002F0.index",[9,11],{"title":5,"path":6,"stem":7,"icon":10},"i-ph-squares-four-duotone",{"title":12,"path":13,"stem":14,"children":15,"icon":18},"Flow Videos","\u002Fdocs\u002Fflow-videos","docs\u002Fflow-videos\u002F0.index",[16,19,36,67,93],{"title":17,"path":13,"stem":14,"icon":18},"Serelius Flow Video","i-ph-video-camera-duotone",{"title":20,"icon":21,"path":22,"stem":23,"children":24,"page":35},"Getting Started","i-ph-rocket-launch-duotone","\u002Fdocs\u002Fflow-videos\u002Fgetting-started","docs\u002Fflow-videos\u002F1.getting-started",[25,30],{"title":26,"path":27,"stem":28,"icon":29},"Overview","\u002Fdocs\u002Fflow-videos\u002Fgetting-started\u002Foverview","docs\u002Fflow-videos\u002F1.getting-started\u002F0.overview","i-ph-play-circle-duotone",{"title":31,"path":32,"stem":33,"icon":34},"Global Features","\u002Fdocs\u002Fflow-videos\u002Fgetting-started\u002Fglobal-features","docs\u002Fflow-videos\u002F1.getting-started\u002F1.global-features","i-ph-gear-six-duotone",false,{"title":37,"icon":38,"path":39,"stem":40,"children":41,"page":35},"Pipeline","i-ph-film-strip-duotone","\u002Fdocs\u002Fflow-videos\u002Fpipeline","docs\u002Fflow-videos\u002F2.pipeline",[42,47,52,57,62],{"title":43,"path":44,"stem":45,"icon":46},"Phase 1 — Script","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fscript","docs\u002Fflow-videos\u002F2.pipeline\u002F1.script","i-ph-scroll-duotone",{"title":48,"path":49,"stem":50,"icon":51},"Phase 2 — Style & Identity","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fstyle-and-identity","docs\u002Fflow-videos\u002F2.pipeline\u002F2.style-and-identity","i-ph-palette-duotone",{"title":53,"path":54,"stem":55,"icon":56},"Phase 3 — Storyboard","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fstoryboard","docs\u002Fflow-videos\u002F2.pipeline\u002F3.storyboard","i-ph-image-duotone",{"title":58,"path":59,"stem":60,"icon":61},"Phase 4 — Videos","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Fvideos","docs\u002Fflow-videos\u002F2.pipeline\u002F4.videos","i-ph-video-duotone",{"title":63,"path":64,"stem":65,"icon":66},"Phase 5 — Final Assembly","\u002Fdocs\u002Fflow-videos\u002Fpipeline\u002Ffinal-assembly","docs\u002Fflow-videos\u002F2.pipeline\u002F5.final-assembly","i-ph-scissors-duotone",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":35},"Settings & Models","i-ph-sliders-duotone","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models","docs\u002Fflow-videos\u002F3.settings-and-models",[73,78,83,88],{"title":74,"path":75,"stem":76,"icon":77},"Settings","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fsettings","docs\u002Fflow-videos\u002F3.settings-and-models\u002F0.settings","i-ph-sliders-horizontal-duotone",{"title":79,"path":80,"stem":81,"icon":82},"AI Models & Limits","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fmodels-and-limits","docs\u002Fflow-videos\u002F3.settings-and-models\u002F1.models-and-limits","i-ph-cpu-duotone",{"title":84,"path":85,"stem":86,"icon":87},"Option Catalogs","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fcatalogs","docs\u002Fflow-videos\u002F3.settings-and-models\u002F2.catalogs","i-ph-list-bullets-duotone",{"title":89,"path":90,"stem":91,"icon":92},"Pipeline Calibration","\u002Fdocs\u002Fflow-videos\u002Fsettings-and-models\u002Fcalibration","docs\u002Fflow-videos\u002F3.settings-and-models\u002F3.calibration","i-ph-gauge-duotone",{"title":94,"icon":95,"path":96,"stem":97,"children":98,"page":35},"Reference","i-ph-book-open-duotone","\u002Fdocs\u002Fflow-videos\u002Freference","docs\u002Fflow-videos\u002F4.reference",[99,104,109,114,119,124],{"title":100,"path":101,"stem":102,"icon":103},"Delivered Files","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fdelivered-files","docs\u002Fflow-videos\u002F4.reference\u002F0.delivered-files","i-ph-folder-duotone",{"title":105,"path":106,"stem":107,"icon":108},"Supported Video Types","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fvideo-types","docs\u002Fflow-videos\u002F4.reference\u002F1.video-types","i-ph-television-duotone",{"title":110,"path":111,"stem":112,"icon":113},"What the Tool Does NOT Do","\u002Fdocs\u002Fflow-videos\u002Freference\u002Flimitations","docs\u002Fflow-videos\u002F4.reference\u002F2.limitations","i-ph-prohibit-duotone",{"title":115,"path":116,"stem":117,"icon":118},"Business Models","\u002Fdocs\u002Fflow-videos\u002Freference\u002Fbusiness-models","docs\u002Fflow-videos\u002F4.reference\u002F3.business-models","i-ph-briefcase-duotone",{"title":120,"path":121,"stem":122,"icon":123},"FAQ & Glossary","\u002Fdocs\u002Fflow-videos\u002Freference\u002Ffaq-and-glossary","docs\u002Fflow-videos\u002F4.reference\u002F4.faq-and-glossary","i-ph-question-duotone",{"title":125,"path":126,"stem":127,"icon":128},"Technical and Architectural Audit","\u002Fdocs\u002Fflow-videos\u002Freference\u002Faudit","docs\u002Fflow-videos\u002F4.reference\u002F5.audit","i-ph-shield-check-duotone",{"id":130,"title":131,"author":132,"authorType":133,"body":134,"category":1789,"date":1790,"description":1791,"extension":1792,"image":1793,"lang":1794,"meta":1795,"navigation":1687,"ogImage":1796,"path":1797,"readTime":1798,"seo":1799,"stem":1800,"tags":1801,"translations":1808,"updated":133,"__hash__":1812},"blog\u002Fblog\u002Fgit-ramas-stage-production-primer-lanzamiento.md","Git para su Primer Lanzamiento: Ramas stage y production, del Repositorio Vacío a Producción","Equipo Nuxfire",null,{"type":135,"value":136,"toc":1769},"minimark",[137,151,154,159,169,172,222,235,239,275,279,358,370,375,381,385,407,413,419,495,516,538,544,548,554,560,578,605,612,632,638,657,661,667,673,679,717,723,740,744,750,759,772,786,805,815,833,852,855,874,883,887,893,897,907,911,917,960,966,994,1016,1020,1026,1066,1076,1086,1106,1137,1141,1147,1151,1157,1179,1190,1206,1212,1258,1264,1297,1300,1346,1355,1359,1365,1369,1378,1404,1413,1455,1462,1466,1472,1476,1482,1529,1539,1543,1549,1553,1672,1676,1755,1765],[138,139,140,141,145,146,150],"p",{},"Ha extraído el código fuente de Nuxfire y está a punto de desplegar su primer producto. Antes de ejecutar un solo comando ",[142,143,144],"code",{},"sst",", dedique veinte minutos a lo que decide si los próximos cien despliegues serán tranquilos o estresantes: ",[147,148,149],"strong",{},"cómo se relacionan sus ramas de Git con lo que está en producción",".",[138,152,153],{},"Este manual construye un modelo pequeño y estricto. Cada comando de Git que aparece aquí se ejecutó de principio a fin en un repositorio de prueba antes de publicarlo; las opciones de GitHub CLI provienen de su manual oficial. Cada paso incluye los comandos manuales y un prompt corto que puede pegar en un agente de IA de su IDE (Cursor, Claude Code, Copilot y similares).",[155,156,158],"h2",{"id":157},"el-modelo-en-un-minuto","El modelo en un minuto",[160,161,167],"pre",{"className":162,"code":164,"language":165,"meta":166},[163],"language-text","feature\u002Fx ──▶ stage ──(validated)──▶ production\n              default branch          moves ONLY by fast-forward\n              you work here           = what you approved for live\n","text","",[142,168,164],{"__ignoreMap":166},[138,170,171],{},"Dos ramas de larga duración y cinco reglas:",[173,174,175,185,196,204,212],"ol",{},[176,177,178,184],"li",{},[147,179,180,181,150],{},"Todo el trabajo ocurre en ",[142,182,183],{},"stage"," Es la rama predeterminada, así que los pull requests y los clones llegan a ella.",[176,186,187,195],{},[147,188,189,192,193,150],{},[142,190,191],{},"production"," solo avanza por fast-forward desde ",[142,194,183],{}," Sin commits de merge y sin commits directos.",[176,197,198,203],{},[147,199,200,201,150],{},"Nunca haga force-push sobre ",[142,202,191],{}," Si un push es rechazado, es la red de seguridad funcionando.",[176,205,206,211],{},[147,207,208,209,150],{},"Despliegue producción desde la rama ",[142,210,191],{}," Un despliegue publica lo que tenga en checkout en su máquina, así que la rama en la que está es la verdad.",[176,213,214,217,218,221],{},[147,215,216],{},"Etiquete con un tag cada release que salió a producción"," (",[142,219,220],{},"v1.0.0","). La rama dice \"aprobado\", el tag dice \"confirmado en producción\".",[138,223,224,225,228,229,231,232,234],{},"¿Por qué no conservar también ",[142,226,227],{},"main","? Una tercera rama de larga duración es una tercera respuesta a \"¿cuál es el código más reciente?\". Nuxfire ya nombra sus etapas de despliegue ",[142,230,183],{}," y ",[142,233,191],{},", así que las ramas replican esos nombres y no hay nada que traducir mentalmente.",[155,236,238],{"id":237},"qué-necesita","Qué necesita",[240,241,242,256,263],"ul",{},[176,243,244,245,248,249,252,253,150],{},"Git ",[147,246,247],{},"2.28 o superior"," (para ",[142,250,251],{},"git init -b","). Compruébelo con ",[142,254,255],{},"git --version",[176,257,258,259,262],{},"Una cuenta de GitHub (personal u organización). GitHub CLI (",[142,260,261],{},"gh",") es opcional; cada paso muestra también el camino por la interfaz web.",[176,264,265,266,269,270,150],{},"La carpeta de Nuxfire extraída y ",[142,267,268],{},"bun install"," ejecutado, como en ",[271,272,274],"a",{"href":273},"\u002Fdocs\u002Fsaas-starter-kit\u002Fgetting-started\u002Finstallation","Instalación",[155,276,278],{"id":277},"paso-1-dígale-a-git-quién-es-usted","Paso 1: dígale a Git quién es usted",[160,280,284],{"className":281,"code":282,"language":283,"meta":166,"style":166},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark monokai","git --version\ngit config --global user.name \"Your Name\"\ngit config --global user.email \"you@example.com\"\ngit config --global init.defaultBranch stage\n","bash",[142,285,286,299,324,343],{"__ignoreMap":166},[287,288,291,295],"span",{"class":289,"line":290},"line",1,[287,292,294],{"class":293},"sR7ES","git",[287,296,298],{"class":297},"sFhLe"," --version\n",[287,300,302,304,308,311,314,318,321],{"class":289,"line":301},2,[287,303,294],{"class":293},[287,305,307],{"class":306},"sLACW"," config",[287,309,310],{"class":297}," --global",[287,312,313],{"class":306}," user.name",[287,315,317],{"class":316},"siCPE"," \"",[287,319,320],{"class":306},"Your Name",[287,322,323],{"class":316},"\"\n",[287,325,327,329,331,333,336,338,341],{"class":289,"line":326},3,[287,328,294],{"class":293},[287,330,307],{"class":306},[287,332,310],{"class":297},[287,334,335],{"class":306}," user.email",[287,337,317],{"class":316},[287,339,340],{"class":306},"you@example.com",[287,342,323],{"class":316},[287,344,346,348,350,352,355],{"class":289,"line":345},4,[287,347,294],{"class":293},[287,349,307],{"class":306},[287,351,310],{"class":297},[287,353,354],{"class":306}," init.defaultBranch",[287,356,357],{"class":306}," stage\n",[138,359,360,361,363,364,367,368,150],{},"La última línea hace que todo repositorio nuevo que cree empiece en ",[142,362,183],{}," en lugar de ",[142,365,366],{},"master"," o ",[142,369,227],{},[138,371,372],{},[147,373,374],{},"Prompt para agentes de IA:",[160,376,379],{"className":377,"code":378,"language":165,"meta":166},[163],"Check `git --version` (2.28 or newer is required). Show my global git\nuser.name and user.email. If either is empty, ask me for the values\nbefore setting them. Do not change anything else.\n",[142,380,378],{"__ignoreMap":166},[155,382,384],{"id":383},"paso-2-proteja-sus-secretos-y-haga-el-primer-commit","Paso 2: proteja sus secretos y haga el primer commit",[138,386,387,388,391,392,231,395,398,399,402,403,406],{},"Su carpeta ya contiene archivos que ",[147,389,390],{},"nunca"," deben llegar a Git: ",[142,393,394],{},".env.production",[142,396,397],{},".env.stage"," guardan credenciales reales (la comprobación previa del despliegue incluso verifica que los valores de la base de datos estén rellenos), y ",[142,400,401],{},".sst"," es el estado local del despliegue. El ",[142,404,405],{},".gitignore"," de Nuxfire los cubre:",[160,408,411],{"className":409,"code":410,"language":165,"meta":166},[163],".env\n.env.*\n!.env.example\n.sst\n",[142,412,410],{"__ignoreMap":166},[138,414,415,416,418],{},"Cree el repositorio en ",[142,417,183],{},", demuestre que las reglas funcionan y solo entonces añada todo:",[160,420,422],{"className":281,"code":421,"language":283,"meta":166,"style":166},"git init -b stage\ngit check-ignore -v .env.production .env.stage .sst\ngit add -A\ngit diff --cached --name-only | grep -E \"(^|\u002F)\\.env\"\n",[142,423,424,436,455,465],{"__ignoreMap":166},[287,425,426,428,431,434],{"class":289,"line":290},[287,427,294],{"class":293},[287,429,430],{"class":306}," init",[287,432,433],{"class":297}," -b",[287,435,357],{"class":306},[287,437,438,440,443,446,449,452],{"class":289,"line":301},[287,439,294],{"class":293},[287,441,442],{"class":306}," check-ignore",[287,444,445],{"class":297}," -v",[287,447,448],{"class":306}," .env.production",[287,450,451],{"class":306}," .env.stage",[287,453,454],{"class":306}," .sst\n",[287,456,457,459,462],{"class":289,"line":326},[287,458,294],{"class":293},[287,460,461],{"class":306}," add",[287,463,464],{"class":297}," -A\n",[287,466,467,469,472,475,478,482,485,488,490,493],{"class":289,"line":345},[287,468,294],{"class":293},[287,470,471],{"class":306}," diff",[287,473,474],{"class":297}," --cached",[287,476,477],{"class":297}," --name-only",[287,479,481],{"class":480},"sGXK2"," |",[287,483,484],{"class":293}," grep",[287,486,487],{"class":297}," -E",[287,489,317],{"class":316},[287,491,492],{"class":306},"(^|\u002F)\\.env",[287,494,323],{"class":316},[138,496,497,500,501,504,505,508,509,512,513,515],{},[142,498,499],{},"check-ignore"," debe imprimir la regla que coincide con cada archivo. El último comando debe imprimir ",[147,502,503],{},"únicamente"," ",[142,506,507],{},".env.example",". Si aparece cualquier otro archivo ",[142,510,511],{},".env*",", deténgase y corrija ",[142,514,405],{}," antes de hacer el commit.",[160,517,519],{"className":281,"code":518,"language":283,"meta":166,"style":166},"git commit -m \"chore: initial commit from Nuxfire\"\n",[142,520,521],{"__ignoreMap":166},[287,522,523,525,528,531,533,536],{"class":289,"line":290},[287,524,294],{"class":293},[287,526,527],{"class":306}," commit",[287,529,530],{"class":297}," -m",[287,532,317],{"class":316},[287,534,535],{"class":306},"chore: initial commit from Nuxfire",[287,537,323],{"class":316},[539,540,541],"blockquote",{},[138,542,543],{},"Si alguna vez se sube un secreto en un commit, borrar el archivo no basta: sigue en el historial. Trate la credencial como comprometida, rótela primero y solo después limpie el historial.",[138,545,546],{},[147,547,374],{},[160,549,552],{"className":550,"code":551,"language":165,"meta":166},[163],"In the project root, run `git init -b stage` only if there is no .git\nfolder. With `git check-ignore -v`, verify that .env.production,\n.env.stage and .sst are ignored and that .env.example is not. Run\n`git add -A` and print `git diff --cached --name-only`. STOP and warn me\nif any .env* file other than .env.example is listed. If it is clean,\ncommit with the message \"chore: initial commit from Nuxfire\".\n",[142,553,551],{"__ignoreMap":166},[155,555,557,558],{"id":556},"paso-3-cree-el-repositorio-en-github-y-suba-stage","Paso 3: cree el repositorio en GitHub y suba ",[142,559,183],{},[138,561,562,563,566,567,569,570,573,574,577],{},"Cree un repositorio ",[147,564,565],{},"privado y vacío",": sin README, sin ",[142,568,405],{},", sin licencia. En el navegador use ",[147,571,572],{},"New repository",", elija ",[147,575,576],{},"Private"," y deje sin marcar las opciones de inicialización. O con la CLI, desde la carpeta del proyecto:",[160,579,581],{"className":281,"code":580,"language":283,"meta":166,"style":166},"gh repo create my-product --private --source=. --remote=origin\n",[142,582,583],{"__ignoreMap":166},[287,584,585,587,590,593,596,599,602],{"class":289,"line":290},[287,586,261],{"class":293},[287,588,589],{"class":306}," repo",[287,591,592],{"class":306}," create",[287,594,595],{"class":306}," my-product",[287,597,598],{"class":297}," --private",[287,600,601],{"class":297}," --source=.",[287,603,604],{"class":297}," --remote=origin\n",[138,606,607,608,611],{},"La CLI añade el remoto ",[142,609,610],{},"origin"," por usted. Sin ella, añádalo manualmente con la URL que le muestra GitHub:",[160,613,615],{"className":281,"code":614,"language":283,"meta":166,"style":166},"git remote add origin git@github.com:YOUR-USER\u002Fmy-product.git\n",[142,616,617],{"__ignoreMap":166},[287,618,619,621,624,626,629],{"class":289,"line":290},[287,620,294],{"class":293},[287,622,623],{"class":306}," remote",[287,625,461],{"class":306},[287,627,628],{"class":306}," origin",[287,630,631],{"class":306}," git@github.com:YOUR-USER\u002Fmy-product.git\n",[138,633,634,635,637],{},"En ambos casos, publique ",[142,636,183],{}," y configure el seguimiento del remoto:",[160,639,641],{"className":281,"code":640,"language":283,"meta":166,"style":166},"git push -u origin stage\n",[142,642,643],{"__ignoreMap":166},[287,644,645,647,650,653,655],{"class":289,"line":290},[287,646,294],{"class":293},[287,648,649],{"class":306}," push",[287,651,652],{"class":297}," -u",[287,654,628],{"class":306},[287,656,357],{"class":306},[138,658,659],{},[147,660,374],{},[160,662,665],{"className":663,"code":664,"language":165,"meta":166},[163],"Create a PRIVATE, empty GitHub repository named \u003Cname> under \u003Cowner>\n(no README, no .gitignore, no license), add it as `origin`, and push the\n`stage` branch with upstream tracking. Use `gh` if it is installed;\notherwise print the exact commands for me to run. Never use --force.\n",[142,666,664],{"__ignoreMap":166},[155,668,670,671],{"id":669},"paso-4-cree-production","Paso 4: cree ",[142,672,191],{},[138,674,675,676,678],{},"Cree la rama a partir de ",[142,677,183],{},", en el mismo commit, publíquela y vuelva:",[160,680,682],{"className":281,"code":681,"language":283,"meta":166,"style":166},"git switch -c production\ngit push -u origin production\ngit switch stage\n",[142,683,684,697,709],{"__ignoreMap":166},[287,685,686,688,691,694],{"class":289,"line":290},[287,687,294],{"class":293},[287,689,690],{"class":306}," switch",[287,692,693],{"class":297}," -c",[287,695,696],{"class":306}," production\n",[287,698,699,701,703,705,707],{"class":289,"line":301},[287,700,294],{"class":293},[287,702,649],{"class":306},[287,704,652],{"class":297},[287,706,628],{"class":306},[287,708,696],{"class":306},[287,710,711,713,715],{"class":289,"line":326},[287,712,294],{"class":293},[287,714,690],{"class":306},[287,716,357],{"class":306},[138,718,719,720,722],{},"Ahora añada una protección local para que ",[142,721,191],{}," solo pueda avanzar por fast-forward. Git rechazará cualquier merge que no sea un fast-forward:",[160,724,726],{"className":281,"code":725,"language":283,"meta":166,"style":166},"git config branch.production.mergeOptions --ff-only\n",[142,727,728],{"__ignoreMap":166},[287,729,730,732,734,737],{"class":289,"line":290},[287,731,294],{"class":293},[287,733,307],{"class":306},[287,735,736],{"class":306}," branch.production.mergeOptions",[287,738,739],{"class":297}," --ff-only\n",[138,741,742],{},[147,743,374],{},[160,745,748],{"className":746,"code":747,"language":165,"meta":166},[163],"Create branch `production` from `stage`, push it with upstream tracking,\nswitch back to `stage`, then run\n`git config branch.production.mergeOptions --ff-only`.\nConfirm the result with `git branch -vv`.\n",[142,749,747],{"__ignoreMap":166},[155,751,753,754,756,757],{"id":752},"paso-5-haga-de-stage-la-rama-predeterminada-y-elimine-main","Paso 5: haga de ",[142,755,183],{}," la rama predeterminada y elimine ",[142,758,227],{},[138,760,761,762,764,765,768,769,771],{},"Quien decide la rama predeterminada es GitHub, no su Git local. Incluso en un repositorio vacío puede seguir siendo ",[142,763,227],{},", así que compruébelo de forma explícita. GitHub exige ",[147,766,767],{},"más de una rama"," para cambiar la predeterminada, y por eso ",[142,770,191],{}," tenía que existir antes.",[138,773,774,775,778,779,781,782,785],{},"En el navegador: ",[147,776,777],{},"Settings → Branches → Default branch",", pulse el icono de cambio, elija ",[142,780,183],{},", ",[147,783,784],{},"Update"," y confirme. Con la CLI:",[160,787,789],{"className":281,"code":788,"language":283,"meta":166,"style":166},"gh repo edit --default-branch stage\n",[142,790,791],{"__ignoreMap":166},[287,792,793,795,797,800,803],{"class":289,"line":290},[287,794,261],{"class":293},[287,796,589],{"class":306},[287,798,799],{"class":306}," edit",[287,801,802],{"class":297}," --default-branch",[287,804,357],{"class":306},[138,806,807,808,810,811,814],{},"Después mire qué existe en el remoto y, si ",[142,809,227],{}," está ahí (por ejemplo, porque el repositorio se creó con un README), elimínela. Hágalo ",[147,812,813],{},"después"," de cambiar la predeterminada, nunca antes:",[160,816,818],{"className":281,"code":817,"language":283,"meta":166,"style":166},"git ls-remote --heads origin\n",[142,819,820],{"__ignoreMap":166},[287,821,822,824,827,830],{"class":289,"line":290},[287,823,294],{"class":293},[287,825,826],{"class":306}," ls-remote",[287,828,829],{"class":297}," --heads",[287,831,832],{"class":306}," origin\n",[160,834,836],{"className":281,"code":835,"language":283,"meta":166,"style":166},"git push origin --delete main\n",[142,837,838],{"__ignoreMap":166},[287,839,840,842,844,846,849],{"class":289,"line":290},[287,841,294],{"class":293},[287,843,649],{"class":306},[287,845,628],{"class":306},[287,847,848],{"class":297}," --delete",[287,850,851],{"class":306}," main\n",[138,853,854],{},"Por último, actualice su puntero local a la rama predeterminada del remoto:",[160,856,858],{"className":281,"code":857,"language":283,"meta":166,"style":166},"git remote set-head origin --auto\n",[142,859,860],{"__ignoreMap":166},[287,861,862,864,866,869,871],{"class":289,"line":290},[287,863,294],{"class":293},[287,865,623],{"class":306},[287,867,868],{"class":306}," set-head",[287,870,628],{"class":306},[287,872,873],{"class":297}," --auto\n",[138,875,876,877,879,880,882],{},"Si ",[142,878,227],{}," se creó con un README, tiene un historial sin relación con el suyo. No la fusione en ",[142,881,183],{},"; simplemente elimínela.",[138,884,885],{},[147,886,374],{},[160,888,891],{"className":889,"code":890,"language":165,"meta":166},[163],"Check which branch is the GitHub default with\n`gh repo view --json defaultBranchRef`. If it is not `stage`, run\n`gh repo edit --default-branch stage`. Then run\n`git ls-remote --heads origin`. If `main` exists, tell me and WAIT for my\nconfirmation before running `git push origin --delete main`. Finish with\n`git remote set-head origin --auto`.\n",[142,892,890],{"__ignoreMap":166},[155,894,896],{"id":895},"paso-6-protecciones-en-github-si-su-plan-las-incluye","Paso 6: protecciones en GitHub (si su plan las incluye)",[138,898,899,900,903,904,906],{},"La protección local ",[142,901,902],{},"--ff-only"," no cuesta nada y no depende de ningún plan. En GitHub, la protección de ramas y los rulesets dependen de su plan y de la visibilidad del repositorio (los rulesets están documentados para los planes GitHub Team y GitHub Enterprise). Si el suyo los ofrece, proteja ",[142,905,191],{}," bloqueando los force pushes y restringiendo las eliminaciones. Si no, el proceso y la protección local bastan siempre que nunca haga force-push.",[155,908,910],{"id":909},"paso-7-el-día-a-día","Paso 7: el día a día",[138,912,913,914,916],{},"Si trabaja solo, haga commit en ",[142,915,183],{}," y súbalo:",[160,918,920],{"className":281,"code":919,"language":283,"meta":166,"style":166},"git switch stage\ngit add -A\ngit commit -m \"feat: describe the change\"\ngit push\n",[142,921,922,930,938,953],{"__ignoreMap":166},[287,923,924,926,928],{"class":289,"line":290},[287,925,294],{"class":293},[287,927,690],{"class":306},[287,929,357],{"class":306},[287,931,932,934,936],{"class":289,"line":301},[287,933,294],{"class":293},[287,935,461],{"class":306},[287,937,464],{"class":297},[287,939,940,942,944,946,948,951],{"class":289,"line":326},[287,941,294],{"class":293},[287,943,527],{"class":306},[287,945,530],{"class":297},[287,947,317],{"class":316},[287,949,950],{"class":306},"feat: describe the change",[287,952,323],{"class":316},[287,954,955,957],{"class":289,"line":345},[287,956,294],{"class":293},[287,958,959],{"class":306}," push\n",[138,961,962,963,965],{},"Si trabaja en equipo, use ramas cortas y pull requests hacia ",[142,964,183],{},":",[160,967,969],{"className":281,"code":968,"language":283,"meta":166,"style":166},"git switch -c feat\u002Fbilling-copy\ngit push -u origin feat\u002Fbilling-copy\n",[142,970,971,982],{"__ignoreMap":166},[287,972,973,975,977,979],{"class":289,"line":290},[287,974,294],{"class":293},[287,976,690],{"class":306},[287,978,693],{"class":297},[287,980,981],{"class":306}," feat\u002Fbilling-copy\n",[287,983,984,986,988,990,992],{"class":289,"line":301},[287,985,294],{"class":293},[287,987,649],{"class":306},[287,989,652],{"class":297},[287,991,628],{"class":306},[287,993,981],{"class":306},[138,995,996,997,217,1003,781,1006,781,1009,781,1012,1015],{},"Use ",[271,998,1002],{"href":999,"rel":1000},"https:\u002F\u002Fwww.conventionalcommits.org\u002F",[1001],"nofollow","Conventional Commits",[142,1004,1005],{},"feat:",[142,1007,1008],{},"fix:",[142,1010,1011],{},"docs:",[142,1013,1014],{},"chore:","). El historial del propio Nuxfire los sigue, lo que deja las notas de release casi gratis.",[155,1017,1019],{"id":1018},"paso-8-la-puerta-antes-de-su-primer-lanzamiento","Paso 8: la puerta antes de su primer lanzamiento",[138,1021,1022,1023,1025],{},"Nada llega a ",[142,1024,191],{}," sin pasar siempre por las mismas comprobaciones:",[160,1027,1029],{"className":281,"code":1028,"language":283,"meta":166,"style":166},"bun install\nbun run test\nbun run doctor -- --stage production\n",[142,1030,1031,1039,1049],{"__ignoreMap":166},[287,1032,1033,1036],{"class":289,"line":290},[287,1034,1035],{"class":293},"bun",[287,1037,1038],{"class":306}," install\n",[287,1040,1041,1043,1046],{"class":289,"line":301},[287,1042,1035],{"class":293},[287,1044,1045],{"class":306}," run",[287,1047,1048],{"class":306}," test\n",[287,1050,1051,1053,1055,1058,1061,1064],{"class":289,"line":326},[287,1052,1035],{"class":293},[287,1054,1045],{"class":306},[287,1056,1057],{"class":306}," doctor",[287,1059,1060],{"class":297}," --",[287,1062,1063],{"class":297}," --stage",[287,1065,696],{"class":306},[138,1067,1068,1071,1072,1075],{},[142,1069,1070],{},"doctor"," es la comprobación previa del despliegue: valida su token de Cloudflare, sus valores ",[142,1073,1074],{},"BRAND_*",", los secretos de la base de datos y la zona del dominio, e indica la corrección exacta de cada problema antes de que pierda minutos en un despliegue que va a fallar.",[138,1077,1078,1079,1082,1083,965],{},"Para un primer producto, despliegue una ",[147,1080,1081],{},"etapa de validación"," antes de producción. Una etapa que no es de producción obtiene sus propios Workers, conexión de base de datos y secretos, y responde en ",[142,1084,1085],{},"\u003Cstage>.dev.\u003Csu-dominio>",[160,1087,1089],{"className":281,"code":1088,"language":283,"meta":166,"style":166},"bun run deploy -- --stage stage\n",[142,1090,1091],{"__ignoreMap":166},[287,1092,1093,1095,1097,1100,1102,1104],{"class":289,"line":290},[287,1094,1035],{"class":293},[287,1096,1045],{"class":306},[287,1098,1099],{"class":306}," deploy",[287,1101,1060],{"class":297},[287,1103,1063],{"class":297},[287,1105,357],{"class":306},[138,1107,1108,1109,1112,1113,781,1117,231,1121,1125,1126,504,1129,1132,1133,1136],{},"El ",[142,1110,1111],{},"--"," es necesario para que la opción llegue al script. El token y los secretos se explican en ",[271,1114,1116],{"href":1115},"\u002Fdocs\u002Fsaas-starter-kit\u002Fgetting-started\u002Fcloudflare-access","Acceso a Cloudflare",[271,1118,1120],{"href":1119},"\u002Fdocs\u002Fsaas-starter-kit\u002Fgetting-started\u002Fsecrets","Secrets",[271,1122,1124],{"href":1123},"\u002Fdocs\u002Fsaas-starter-kit\u002Fgetting-started\u002Fdeploy","Despliegue",". Conviene conocer desde ya un requisito exclusivo de producción: el dominio raíz y ",[142,1127,1128],{},"www",[147,1130,1131],{},"no"," pueden tener ningún registro A, AAAA o CNAME en su DNS; de lo contrario, Cloudflare rechaza el dominio personalizado (error ",[142,1134,1135],{},"100117",").",[138,1138,1139],{},[147,1140,374],{},[160,1142,1145],{"className":1143,"code":1144,"language":165,"meta":166},[163],"Run `bun install`, `bun run test` and\n`bun run doctor -- --stage production`. Report every failure with its\nexact message and the fix. Do NOT deploy anything.\n",[142,1146,1144],{"__ignoreMap":166},[155,1148,1150],{"id":1149},"paso-9-el-primer-lanzamiento","Paso 9: el primer lanzamiento",[138,1152,1153,1154,1156],{},"Todo está en verde en ",[142,1155,183],{},". Promuévala:",[160,1158,1160],{"className":281,"code":1159,"language":283,"meta":166,"style":166},"git status\ngit push origin stage\n",[142,1161,1162,1169],{"__ignoreMap":166},[287,1163,1164,1166],{"class":289,"line":290},[287,1165,294],{"class":293},[287,1167,1168],{"class":306}," status\n",[287,1170,1171,1173,1175,1177],{"class":289,"line":301},[287,1172,294],{"class":293},[287,1174,649],{"class":306},[287,1176,628],{"class":306},[287,1178,357],{"class":306},[138,1180,1181,1184,1185,1187,1188,965],{},[142,1182,1183],{},"git status"," debe indicar que el árbol de trabajo está limpio. Ahora avance ",[142,1186,191],{}," por fast-forward exactamente al mismo commit, sin salir de ",[142,1189,183],{},[160,1191,1193],{"className":281,"code":1192,"language":283,"meta":166,"style":166},"git push origin stage:production\n",[142,1194,1195],{"__ignoreMap":166},[287,1196,1197,1199,1201,1203],{"class":289,"line":290},[287,1198,294],{"class":293},[287,1200,649],{"class":306},[287,1202,628],{"class":306},[287,1204,1205],{"class":306}," stage:production\n",[138,1207,1208,1209,1211],{},"Ese push solo se acepta si es un fast-forward puro. Compruebe que las dos ramas son idénticas y cambie a ",[142,1210,191],{},", porque es la rama desde la que despliega:",[160,1213,1215],{"className":281,"code":1214,"language":283,"meta":166,"style":166},"git fetch origin\ngit diff --stat stage origin\u002Fproduction\ngit switch production\ngit pull --ff-only\n",[142,1216,1217,1226,1241,1249],{"__ignoreMap":166},[287,1218,1219,1221,1224],{"class":289,"line":290},[287,1220,294],{"class":293},[287,1222,1223],{"class":306}," fetch",[287,1225,832],{"class":306},[287,1227,1228,1230,1232,1235,1238],{"class":289,"line":301},[287,1229,294],{"class":293},[287,1231,471],{"class":306},[287,1233,1234],{"class":297}," --stat",[287,1236,1237],{"class":306}," stage",[287,1239,1240],{"class":306}," origin\u002Fproduction\n",[287,1242,1243,1245,1247],{"class":289,"line":326},[287,1244,294],{"class":293},[287,1246,690],{"class":306},[287,1248,696],{"class":306},[287,1250,1251,1253,1256],{"class":289,"line":345},[287,1252,294],{"class":293},[287,1254,1255],{"class":306}," pull",[287,1257,739],{"class":297},[138,1259,1108,1260,1263],{},[142,1261,1262],{},"diff"," no debe imprimir nada. Ejecute la comprobación previa una vez más y despliegue:",[160,1265,1267],{"className":281,"code":1266,"language":283,"meta":166,"style":166},"bun run doctor -- --stage production\nbun run deploy -- --stage production\n",[142,1268,1269,1283],{"__ignoreMap":166},[287,1270,1271,1273,1275,1277,1279,1281],{"class":289,"line":290},[287,1272,1035],{"class":293},[287,1274,1045],{"class":306},[287,1276,1057],{"class":306},[287,1278,1060],{"class":297},[287,1280,1063],{"class":297},[287,1282,696],{"class":306},[287,1284,1285,1287,1289,1291,1293,1295],{"class":289,"line":301},[287,1286,1035],{"class":293},[287,1288,1045],{"class":306},[287,1290,1099],{"class":306},[287,1292,1060],{"class":297},[287,1294,1063],{"class":297},[287,1296,696],{"class":306},[138,1298,1299],{},"Solo cuando el despliegue termine bien, etiquete el release y vuelva al trabajo:",[160,1301,1303],{"className":281,"code":1302,"language":283,"meta":166,"style":166},"git tag -a v1.0.0 -m \"First production release\"\ngit push origin v1.0.0\ngit switch stage\n",[142,1304,1305,1327,1338],{"__ignoreMap":166},[287,1306,1307,1309,1312,1315,1318,1320,1322,1325],{"class":289,"line":290},[287,1308,294],{"class":293},[287,1310,1311],{"class":306}," tag",[287,1313,1314],{"class":297}," -a",[287,1316,1317],{"class":306}," v1.0.0",[287,1319,530],{"class":297},[287,1321,317],{"class":316},[287,1323,1324],{"class":306},"First production release",[287,1326,323],{"class":316},[287,1328,1329,1331,1333,1335],{"class":289,"line":301},[287,1330,294],{"class":293},[287,1332,649],{"class":306},[287,1334,628],{"class":306},[287,1336,1337],{"class":306}," v1.0.0\n",[287,1339,1340,1342,1344],{"class":289,"line":326},[287,1341,294],{"class":293},[287,1343,690],{"class":306},[287,1345,357],{"class":306},[138,1347,1348,1349,1351,1352,1354],{},"Si el despliegue falla, no edite ",[142,1350,191],{},". Corrija hacia adelante en ",[142,1353,183],{},", vuelva a pasar la puerta y repita el fast-forward. La rama puede quedar brevemente por delante de lo que está en producción, y la ausencia del tag se lo indica exactamente.",[138,1356,1357],{},[147,1358,374],{},[160,1360,1363],{"className":1361,"code":1362,"language":165,"meta":166},[163],"Release checklist for the first release. Stop at the first failure:\n1. `git status` must be clean and on `stage`.\n2. `git push origin stage`.\n3. `git push origin stage:production`. If it is rejected, STOP and show\n   me `git log --oneline stage..production`. Never force.\n4. `git switch production && git pull --ff-only`.\n5. `bun run doctor -- --stage production`.\n6. Ask me for explicit confirmation, then run\n   `bun run deploy -- --stage production`.\n7. Only after a successful deploy: `git tag -a v1.0.0 -m \"First\n   production release\"` and `git push origin v1.0.0`.\n8. `git switch stage`.\n",[142,1364,1362],{"__ignoreMap":166},[155,1366,1368],{"id":1367},"paso-10-evite-que-las-dos-ramas-se-separen","Paso 10: evite que las dos ramas se separen",[138,1370,1371,1372,1374,1375,1377],{},"El modo de fallo que le ocurre a todo el mundo una vez: una corrección cae en ",[142,1373,191],{}," (o un despliegue sale de ",[142,1376,183],{},") y las ramas dejan de describir el mismo código sin que nadie lo note. La comprobación es una línea y siempre debe imprimir nada:",[160,1379,1381],{"className":281,"code":1380,"language":283,"meta":166,"style":166},"git fetch origin\ngit log --oneline stage..origin\u002Fproduction\n",[142,1382,1383,1391],{"__ignoreMap":166},[287,1384,1385,1387,1389],{"class":289,"line":290},[287,1386,294],{"class":293},[287,1388,1223],{"class":306},[287,1390,832],{"class":306},[287,1392,1393,1395,1398,1401],{"class":289,"line":301},[287,1394,294],{"class":293},[287,1396,1397],{"class":306}," log",[287,1399,1400],{"class":297}," --oneline",[287,1402,1403],{"class":306}," stage..origin\u002Fproduction\n",[138,1405,1406,1407,1409,1410,1412],{},"Si imprime commits, ",[142,1408,191],{}," tiene trabajo que ",[142,1411,183],{}," no tiene. Una promoción será rechazada, y eso es correcto. Traiga el trabajo de vuelta, publíquelo y avance de nuevo:",[160,1414,1416],{"className":281,"code":1415,"language":283,"meta":166,"style":166},"git switch stage\ngit merge origin\u002Fproduction\ngit push origin stage\ngit push origin stage:production\n",[142,1417,1418,1426,1435,1445],{"__ignoreMap":166},[287,1419,1420,1422,1424],{"class":289,"line":290},[287,1421,294],{"class":293},[287,1423,690],{"class":306},[287,1425,357],{"class":306},[287,1427,1428,1430,1433],{"class":289,"line":301},[287,1429,294],{"class":293},[287,1431,1432],{"class":306}," merge",[287,1434,1240],{"class":306},[287,1436,1437,1439,1441,1443],{"class":289,"line":326},[287,1438,294],{"class":293},[287,1440,649],{"class":306},[287,1442,628],{"class":306},[287,1444,357],{"class":306},[287,1446,1447,1449,1451,1453],{"class":289,"line":345},[287,1448,294],{"class":293},[287,1450,649],{"class":306},[287,1452,628],{"class":306},[287,1454,1205],{"class":306},[138,1456,1457,1458,1461],{},"Si el merge informa de conflictos, resuélvalos, vuelva a pasar la puerta y haga el commit antes de subir. Nunca lo resuelva con ",[142,1459,1460],{},"--force",": borraría justamente los commits que quiere conservar.",[138,1463,1464],{},[147,1465,374],{},[160,1467,1470],{"className":1468,"code":1469,"language":165,"meta":166},[163],"Run `git fetch origin`, then `git log --oneline stage..origin\u002Fproduction`.\nIf it prints anything: merge origin\u002Fproduction into stage, resolve any\nconflicts together with me, run `bun run test`, push stage, then\nfast-forward production with `git push origin stage:production`.\nNever use --force.\n",[142,1471,1469],{"__ignoreMap":166},[155,1473,1475],{"id":1474},"volver-atrás","Volver atrás",[138,1477,1478,1479,1481],{},"No reescriba ",[142,1480,191],{},". Redespliegue el código de un tag anterior:",[160,1483,1485],{"className":281,"code":1484,"language":283,"meta":166,"style":166},"git tag --sort=-creatordate\ngit switch --detach v1.0.0\nbun run deploy -- --stage production\ngit switch stage\n",[142,1486,1487,1496,1507,1521],{"__ignoreMap":166},[287,1488,1489,1491,1493],{"class":289,"line":290},[287,1490,294],{"class":293},[287,1492,1311],{"class":306},[287,1494,1495],{"class":297}," --sort=-creatordate\n",[287,1497,1498,1500,1502,1505],{"class":289,"line":301},[287,1499,294],{"class":293},[287,1501,690],{"class":306},[287,1503,1504],{"class":297}," --detach",[287,1506,1337],{"class":306},[287,1508,1509,1511,1513,1515,1517,1519],{"class":289,"line":326},[287,1510,1035],{"class":293},[287,1512,1045],{"class":306},[287,1514,1099],{"class":306},[287,1516,1060],{"class":297},[287,1518,1063],{"class":297},[287,1520,696],{"class":306},[287,1522,1523,1525,1527],{"class":289,"line":345},[287,1524,294],{"class":293},[287,1526,690],{"class":306},[287,1528,357],{"class":306},[138,1530,1531,1532,1535,1536,1538],{},"Esto restaura el ",[147,1533,1534],{},"código",". Las migraciones de la base de datos se aplican en cada despliegue y no se revierten, así que planifique los cambios de esquema primero como aditivos (añada una columna, publique el código que la usa, elimine la antigua más tarde). Después corrija hacia adelante en ",[142,1537,183],{}," y promueva un nuevo release.",[138,1540,1541],{},[147,1542,374],{},[160,1544,1547],{"className":1545,"code":1546,"language":165,"meta":166},[163],"Do NOT touch the `production` branch. Show me\n`git tag --sort=-creatordate | head`, ask which tag to restore, run\n`git switch --detach \u003Ctag>`, and ask for my explicit confirmation before\n`bun run deploy -- --stage production`. Afterwards run `git switch stage`.\n",[142,1548,1546],{"__ignoreMap":166},[155,1550,1552],{"id":1551},"cuando-algo-sale-mal","Cuando algo sale mal",[1554,1555,1556,1572],"table",{},[1557,1558,1559],"thead",{},[1560,1561,1562,1566,1569],"tr",{},[1563,1564,1565],"th",{},"Lo que ve",[1563,1567,1568],{},"Qué significa",[1563,1570,1571],{},"Qué hacer",[1573,1574,1575,1594,1609,1625,1644,1658],"tbody",{},[1560,1576,1577,1583,1591],{},[1578,1579,1580],"td",{},[142,1581,1582],{},"[rejected] stage -> production (non-fast-forward)",[1578,1584,1585,1587,1588,1590],{},[142,1586,191],{}," tiene commits que ",[142,1589,183],{}," no tiene",[1578,1592,1593],{},"Paso 10. Nunca use force.",[1560,1595,1596,1601,1606],{},[1578,1597,1598],{},[142,1599,1600],{},"fatal: Not possible to fast-forward, aborting.",[1578,1602,1603,1604],{},"La protección local detuvo un merge en ",[142,1605,191],{},[1578,1607,1608],{},"Misma causa y misma solución que arriba",[1560,1610,1611,1616,1619],{},[1578,1612,1613,1614],{},"GitHub no le deja eliminar ",[142,1615,227],{},[1578,1617,1618],{},"Normalmente sigue siendo la rama predeterminada",[1578,1620,1621,1622,1624],{},"Cambie primero la predeterminada a ",[142,1623,183],{}," (Paso 5)",[1560,1626,1627,1636,1641],{},[1578,1628,1629,1630,1632,1633],{},"Un archivo ",[142,1631,511],{}," aparece en ",[142,1634,1635],{},"git diff --cached",[1578,1637,1638,1639],{},"Falta una regla en ",[142,1640,405],{},[1578,1642,1643],{},"Corríjalo antes del commit, nunca después",[1560,1645,1646,1649,1652],{},[1578,1647,1648],{},"Desplegó desde la rama equivocada",[1578,1650,1651],{},"El despliegue publica el árbol en checkout",[1578,1653,1654,1657],{},[142,1655,1656],{},"git branch --show-current"," antes de cada despliegue",[1560,1659,1660,1666,1669],{},[1578,1661,1662,1663,1665],{},"Error de dominio ",[142,1664,1135],{}," en el primer despliegue de producción",[1578,1667,1668],{},"El hostname ya tiene un registro DNS",[1578,1670,1671],{},"Elimine el registro A, AAAA o CNAME y despliegue de nuevo",[155,1673,1675],{"id":1674},"lista-de-verificación","Lista de verificación",[240,1677,1680,1694,1705,1716,1728,1740,1749],{"className":1678},[1679],"contains-task-list",[176,1681,1684,1689,1690,231,1692],{"className":1682},[1683],"task-list-item",[1685,1686],"input",{"disabled":1687,"type":1688},true,"checkbox"," El repositorio es privado y en el remoto solo existen ",[142,1691,183],{},[142,1693,191],{},[176,1695,1697,504,1699,1701,1702,1704],{"className":1696},[1683],[1685,1698],{"disabled":1687,"type":1688},[142,1700,183],{}," es la rama predeterminada y ",[142,1703,227],{}," ya no existe",[176,1706,1708,504,1710,1713,1714],{"className":1707},[1683],[1685,1709],{"disabled":1687,"type":1688},[142,1711,1712],{},"git config branch.production.mergeOptions"," imprime ",[142,1715,902],{},[176,1717,1719,1721,1722,1724,1725,1727],{"className":1718},[1683],[1685,1720],{"disabled":1687,"type":1688}," Ningún archivo ",[142,1723,511],{},", salvo ",[142,1726,507],{},", está versionado",[176,1729,1731,504,1733,231,1736,1739],{"className":1730},[1683],[1685,1732],{"disabled":1687,"type":1688},[142,1734,1735],{},"bun run test",[142,1737,1738],{},"bun run doctor -- --stage production"," están en verde",[176,1741,1743,504,1745,1748],{"className":1742},[1683],[1685,1744],{"disabled":1687,"type":1688},[142,1746,1747],{},"git diff --stat stage origin\u002Fproduction"," no imprime nada antes de desplegar",[176,1750,1752,1754],{"className":1751},[1683],[1685,1753],{"disabled":1687,"type":1688}," El release solo se etiqueta después de que el despliegue termine bien",[138,1756,1757,1758,1760,1761,231,1763,150],{},"De vuelta a la configuración: continúe con ",[271,1759,1116],{"href":1115}," para crear el token de API, después ",[271,1762,1120],{"href":1119},[271,1764,1124],{"href":1123},[1766,1767,1768],"style",{},"html pre.shiki code .sR7ES, html code.shiki .sR7ES{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0;--shiki-sepia:#A6E22E}html pre.shiki code .sFhLe, html code.shiki .sFhLe{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF;--shiki-sepia:#AE81FF}html pre.shiki code .sLACW, html code.shiki .sLACW{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html pre.shiki code .siCPE, html code.shiki .siCPE{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF;--shiki-sepia:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sGXK2, html code.shiki .sGXK2{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583;--shiki-sepia:#F92672}",{"title":166,"searchDepth":301,"depth":301,"links":1770},[1771,1772,1773,1774,1775,1777,1779,1781,1782,1783,1784,1785,1786,1787,1788],{"id":157,"depth":301,"text":158},{"id":237,"depth":301,"text":238},{"id":277,"depth":301,"text":278},{"id":383,"depth":301,"text":384},{"id":556,"depth":301,"text":1776},"Paso 3: cree el repositorio en GitHub y suba stage",{"id":669,"depth":301,"text":1778},"Paso 4: cree production",{"id":752,"depth":301,"text":1780},"Paso 5: haga de stage la rama predeterminada y elimine main",{"id":895,"depth":301,"text":896},{"id":909,"depth":301,"text":910},{"id":1018,"depth":301,"text":1019},{"id":1149,"depth":301,"text":1150},{"id":1367,"depth":301,"text":1368},{"id":1474,"depth":301,"text":1475},{"id":1551,"depth":301,"text":1552},{"id":1674,"depth":301,"text":1675},"DevOps","2026-09-25","Un manual de nivel sénior para quien acaba de adquirir Nuxfire: cree el repositorio, haga de stage la rama predeterminada, elimine main, promueva a production con fast-forward y publique su primera versión de forma segura.","md","\u002Fimages\u002Fblog\u002Fgit-branching-stage-production.svg","es",{},"\u002Fimages\u002Fblog\u002Fgit-branching-stage-production.png","\u002Fblog\u002Fgit-ramas-stage-production-primer-lanzamiento","14 min",{"title":131,"description":1791},"blog\u002Fgit-ramas-stage-production-primer-lanzamiento",[1802,1803,1804,1805,1806,1807],"Git","GitHub","Branching","Release","Deploy","SST",{"en":1809,"pt-br":1810,"es":1811},"git-branching-stage-production-first-release","git-branches-stage-production-primeiro-lancamento","git-ramas-stage-production-primer-lanzamiento","kFgSXbdgvKLfNJ0h-Dr_ifjZNpygdBR-M903HvaAoLk",1794055339777]