diff --git a/.github/workflows/auto-merge-release.yml b/.github/workflows/auto-merge-release.yml index fc2c328bd..a55e909a0 100644 --- a/.github/workflows/auto-merge-release.yml +++ b/.github/workflows/auto-merge-release.yml @@ -40,12 +40,11 @@ jobs: env: GH_TOKEN: ${{ github.token }} REPO_OWNER: ${{ github.repository_owner }} - HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} run: | PR_JSON=$(gh api "repos/${{ github.repository }}/pulls" \ -X GET \ -f state=open \ - -f "head=${REPO_OWNER}:release-please--branches--${HEAD_BRANCH}" \ + -f "head=${REPO_OWNER}:release-please--branches--main" \ --jq '.[0] // empty') if [ -z "$PR_JSON" ]; then diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index 4f2c46742..b6fb2b13b 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -2,115 +2,14 @@ name: Commitlint on: pull_request: - branches: [ main, 6.x ] + branches: [ main ] types: [opened, synchronize, reopened] jobs: branch-name: if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.head_ref, 'dependabot/') }} uses: nullplatform/actions-nullplatform/.github/workflows/branch-validation.yml@main - with: - pattern: '^(feat|feature|fix|docs|style|refactor|perf|test|build|ci|chore|revert|package)/.+$' commitlint: if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.head_ref, 'dependabot/') }} uses: nullplatform/actions-nullplatform/.github/workflows/conventional-commit.yml@main - - base-branch-check: - name: Validate base branch for branch type - if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.head_ref, 'dependabot/') }} - runs-on: ubuntu-24.04 - steps: - - name: Check base branch matches branch type - env: - HEAD_BRANCH: ${{ github.head_ref }} - BASE_BRANCH: ${{ github.base_ref }} - run: | - # ci/* queda exceptuada: los cambios de infraestructura de CI no - # están atados a una línea de versión, se propagan a mano entre - # main y 6.x cuando hace falta (ver Tarea 14 del plan de este cambio). - if [[ "$HEAD_BRANCH" == ci/* ]]; then - echo "Branch '$HEAD_BRANCH' is a CI/infra branch — base branch rule not enforced." - exit 0 - fi - - if [[ "$HEAD_BRANCH" == package/* ]]; then - if [[ "$BASE_BRANCH" != "main" ]]; then - echo "::error::package/* branches must target 'main', not '$BASE_BRANCH'." - exit 1 - fi - else - if [[ "$BASE_BRANCH" != "6.x" ]]; then - echo "::error::Only package/* branches may target 'main'. '$HEAD_BRANCH' must target '6.x', not '$BASE_BRANCH'." - exit 1 - fi - fi - - echo "Base branch '$BASE_BRANCH' is correct for '$HEAD_BRANCH'." - - fork-point-check: - name: Validate branch actually forked from the correct line - if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.head_ref, 'dependabot/') }} - runs-on: ubuntu-24.04 - permissions: - contents: read - steps: - - name: Checkout head commit with full history - uses: actions/checkout@v6 - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - - - name: Check head diverges from its declared base, not from the other line - env: - HEAD_BRANCH: ${{ github.head_ref }} - BASE_BRANCH: ${{ github.base_ref }} - run: | - # base-branch-check only validates that the branch NAME is paired - # with the right base — it can't see where the branch actually - # forked from. A feat/* branch created from main (instead of 6.x) - # would still pass that check, but merging it would smuggle every - # main-only change (including the breaking change 6.x is meant to - # be free of) into 6.x. This job checks the real git ancestry. - # OTHER_BRANCH is derived from BASE_BRANCH (not from HEAD_BRANCH's - # name) so this check stays sound on ci/* branches too, which - # base-branch-check deliberately doesn't gate (it may target - # either line). - if [[ "$BASE_BRANCH" == "main" ]]; then - OTHER_BRANCH="6.x" - else - OTHER_BRANCH="main" - fi - - MB_BASE=$(git merge-base HEAD "origin/${BASE_BRANCH}") - MB_OTHER=$(git merge-base HEAD "origin/${OTHER_BRANCH}") - - if git merge-base --is-ancestor "$MB_OTHER" "$MB_BASE"; then - echo "OK: '$HEAD_BRANCH' diverges from '$BASE_BRANCH', not from '$OTHER_BRANCH'." - else - echo "::error::'$HEAD_BRANCH' (targeting '$BASE_BRANCH') contains commits from '$OTHER_BRANCH' that are not in '$BASE_BRANCH' — either it was created from '$OTHER_BRANCH' instead of '$BASE_BRANCH', or '$OTHER_BRANCH' was merged into it deliberately. Either way, merging this PR as-is would pull those changes (including any breaking changes '$OTHER_BRANCH' has that '$BASE_BRANCH' doesn't) into '$BASE_BRANCH'. Fix: rebase onto 'origin/$BASE_BRANCH' from this branch's real fork point — git rebase --onto origin/$BASE_BRANCH $MB_OTHER $HEAD_BRANCH — or, if '$OTHER_BRANCH' was merged in on purpose, drop that merge first." - exit 1 - fi - - no-breaking-changes: - name: Block breaking changes (temporary policy) - if: ${{ !startsWith(github.head_ref, 'release-please--') && !startsWith(github.head_ref, 'dependabot/') }} - runs-on: ubuntu-24.04 - permissions: - pull-requests: read - steps: - - name: Scan PR commits and title for breaking-change markers - env: - GH_TOKEN: ${{ github.token }} - PR_NUMBER: ${{ github.event.pull_request.number }} - PR_TITLE: ${{ github.event.pull_request.title }} - run: | - gh api --paginate "repos/${{ github.repository }}/pulls/$PR_NUMBER/commits" --jq '.[].commit.message' > commit_messages.txt - echo "$PR_TITLE" >> commit_messages.txt - - if grep -qE '^[a-zA-Z]+(\([^)]*\))?!:' commit_messages.txt || grep -qE 'BREAKING[ -]CHANGE:' commit_messages.txt; then - echo "::error::Breaking changes are temporarily blocked on this repository (no '!:' headers or 'BREAKING CHANGE:'/'BREAKING-CHANGE:' footers allowed on any branch, in commit messages OR in the PR title — this repo squash-merges using the PR title as the final commit message)." - exit 1 - fi - - echo "No breaking-change markers found." diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 6b8a44c12..174f1ad41 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -2,7 +2,7 @@ name: OpenTofu on: pull_request: - branches: [ main, 6.x ] + branches: [ main ] types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e9ffde37..bff94b789 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,31 +4,19 @@ on: push: branches: - main - - 6.x concurrency: - group: release-${{ github.ref_name }} + group: main-branch-push cancel-in-progress: false jobs: release: - name: Release Please - runs-on: ubuntu-24.04 + uses: nullplatform/actions-nullplatform/.github/workflows/release.yml@main permissions: contents: write pull-requests: write - env: - FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true - steps: - - name: Checkout repository - uses: actions/checkout@v6 - - - name: Release - id: release - uses: googleapis/release-please-action@v5 - with: - release-type: terraform-module - target-branch: ${{ github.ref_name }} + with: + update_readme_versions: false generate-readmes: name: Generate READMEs for Release PR @@ -42,11 +30,10 @@ jobs: id: check_pr env: GH_TOKEN: ${{ github.token }} - REF_NAME: ${{ github.ref_name }} run: | PR_NUMBER=$(gh pr list \ --repo ${{ github.repository }} \ - --head "release-please--branches--${REF_NAME}" \ + --head release-please--branches--main \ --state open \ --json number \ --jq '.[0].number // empty') @@ -64,7 +51,7 @@ jobs: if: steps.check_pr.outputs.pr_exists == 'true' uses: actions/checkout@v6 with: - ref: release-please--branches--${{ github.ref_name }} + ref: release-please--branches--main fetch-depth: 0 - name: Detect changed modules @@ -165,9 +152,6 @@ jobs: - name: Commit and push if: steps.check_pr.outputs.pr_exists == 'true' - env: - HUSKY: 0 - REF_NAME: ${{ github.ref_name }} run: | git config user.email "github-actions[bot]@users.noreply.github.com" git config user.name "github-actions[bot]" @@ -182,6 +166,8 @@ jobs: else git commit -m "docs: update version references in READMEs" fi - git push origin "release-please--branches--${REF_NAME}" + git push origin release-please--branches--main echo "READMEs updated in Release PR #${{ steps.check_pr.outputs.pr_number }}" fi + env: + HUSKY: 0 diff --git a/.github/workflows/tflint-unused.yml b/.github/workflows/tflint-unused.yml index b2be4f8f5..61e169ce3 100644 --- a/.github/workflows/tflint-unused.yml +++ b/.github/workflows/tflint-unused.yml @@ -2,7 +2,7 @@ name: tflint-unused-declarations on: pull_request: - branches: [ main, 6.x ] + branches: [ main ] types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/tofu-test.yml b/.github/workflows/tofu-test.yml index 8e4e97e7f..9ad421932 100644 --- a/.github/workflows/tofu-test.yml +++ b/.github/workflows/tofu-test.yml @@ -2,7 +2,7 @@ name: Tofu Unit Tests on: pull_request: - branches: [ main, 6.x ] + branches: [ main ] types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index e1b51c93a..ae956986f 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -4,11 +4,9 @@ on: pull_request: branches: - main - - 6.x push: branches: - main - - 6.x paths: - '**/*.tf' diff --git a/.husky/pre-commit b/.husky/pre-commit index de7000db7..652d36178 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -22,14 +22,14 @@ fi # Validate branch name BRANCH=$(git rev-parse --abbrev-ref HEAD) -PATTERN="^(feat|feature|fix|docs|style|refactor|perf|test|build|ci|chore|revert|package)/.+$" +PATTERN="^(feat|feature|fix|docs|style|refactor|perf|test|build|ci|chore|revert)/.+$" -if [ "$BRANCH" != "main" ] && [ "$BRANCH" != "6.x" ] && ! echo "$BRANCH" | grep -Eq "$PATTERN"; then +if [ "$BRANCH" != "main" ] && ! echo "$BRANCH" | grep -Eq "$PATTERN"; then echo "Invalid branch name: $BRANCH" echo "" echo "Branch name must follow the pattern: type/description" - echo " Examples: feat/add-login, fix/bug-123, docs/readme, package/add-lambda" + echo " Examples: feat/add-login, fix/bug-123, docs/readme" echo "" - echo "Valid types: feat, feature, fix, docs, style, refactor, perf, test, build, ci, chore, revert, package" + echo "Valid types: feat, feature, fix, docs, style, refactor, perf, test, build, ci, chore, revert" exit 1 fi diff --git a/docs/ci/dual-release-line-rollback.md b/docs/ci/dual-release-line-rollback.md deleted file mode 100644 index f4ae9e77b..000000000 --- a/docs/ci/dual-release-line-rollback.md +++ /dev/null @@ -1,194 +0,0 @@ -# Rollback runbook: dual release line (`package` → 7.x, resto → 6.x) - -> **Para un agente (Claude u otro) que llega a este archivo sin contexto previo de la conversación en la que se creó:** este documento es autosuficiente. Seguí los pasos en orden. Antes de ejecutar CUALQUIER paso marcado como destructivo o visible para otros (push, merge, borrar una rama), **confirmá explícitamente con la persona que te pidió el rollback** — no asumas autorización solo por la existencia de este archivo. - -## Qué es esto y por qué existe - -En 2026-08 se introdujo un esquema temporal de doble línea de versión en este -repo: -- Ramas `package/*` → mergean a `main` → tagean sobre la línea `7.x`. -- Cualquier otra rama (`feat/*`, `fix/*`, `docs/*`, etc.) → mergean a una - rama larga `6.x` (forkeada del tag `v6.11.2`) → tagean sobre la línea - `6.x`. -- Breaking changes bloqueados en ambas líneas (sin excepción). - -El motivo: `main` ya tenía publicado `v7.0.0` con un breaking change real -(PR #491), y se necesitaba seguir dando soporte/lanzando fixes y features -normales sin forzar a esos consumidores a saltar de major, mientras el -trabajo que sí requería la nueva major avanzaba de forma aislada en -`package/*`. - -**Esto es temporal por diseño.** Este runbook describe cómo desarmarlo -cuando el equipo decida que ya no hace falta. - -**Nota de un fix de seguimiento:** la primera versión de este esquema tenía -un bug real — `release-please-action` no calculaba versión sobre `6.x`, -sino sobre `main`, porque `target-branch` no se pasaba explícito y por -default cae en la rama default del repo (no en la rama que disparó el -workflow, como se asumió originalmente). Un commit de seguimiento (mismo -substring "dual release line" en el título) lo corrigió pasando -`target-branch: ${{ github.ref_name }}`, y de paso separó el job `release` -de este repo del workflow reusable de `actions-nullplatform` (que no -expone ese input) para poder setearlo. Ver Paso 1 para encontrar todos los -commits relevantes. - -## Lo que este rollback SÍ hace y lo que NO hace - -- **SÍ**: elimina los checks y triggers de CI agregados (el chequeo de base - branch, el chequeo de que la rama realmente forkeó de la línea correcta, - el bloqueo de breaking changes, el `package` en el pattern de - branch-validation, los triggers extra de `6.x` en todos los workflows). -- **NO**: borra la rama `6.x` ni ninguno de sus commits/tags/releases. Todo - el trabajo real (fixes, features, releases 6.x.x) que se haya mergeado a - `6.x` mientras este esquema estuvo activo queda intacto — revertir la - infraestructura de CI no revierte el trabajo de producto hecho sobre esa - línea. -- La decisión de **qué hacer con la rama `6.x` en sí** (archivarla, seguir - manteniéndola, mergearla hacia `main`, promoverla a nuevo `main`, etc.) es - una decisión de negocio/arquitectura que este runbook NO toma por vos — - ver la sección "Decisión pendiente: destino de `6.x`" al final. - -## Paso 1: Encontrar los commits que introdujeron/ajustaron este esquema - -El esquema se introdujo en un PR titulado `"ci: temporary dual release line -(package -> 7.x, resto -> 6.x)"`, mergeado con `--squash` (un único commit -en `main`, propagado a `6.x` vía `cherry-pick`). Después recibió un fix de -seguimiento (mismo substring "dual release line" en el título) que corrige -el cálculo de versión de la línea `6.x` (ver más abajo) y agrega hardening -adicional. Puede haber más de un commit relevante por rama — buscá todos: - -Run (por separado en cada rama, para no mezclar commits que no pertenecen -a ninguna de las dos líneas): -```bash -git fetch origin -q -git log --oneline origin/main --grep="dual release line" -git log --oneline origin/6.x --grep="dual release line" -``` -Anotá los SHAs de cada comando por separado. Si hay más de uno por rama, -revertilos en los Pasos 2/3 **del más nuevo al más viejo** (un `git revert` -por SHA, en ese orden). - -## Paso 2: Revertir en `main` - -Run (repetir por cada SHA encontrado en `main`, del más nuevo al más viejo): -```bash -git checkout main && git pull origin main -q -git revert --no-edit -``` -Cuando termines de revertir todos los SHAs encontrados en `main`, seguí al -Paso 3/4. Si algún revert tiene conflictos (porque -alguno de estos archivos se modificó después por otro motivo), resolvelos -usando la sección "Fallback manual" de abajo como referencia de qué -contenido final se espera en cada archivo, y después: -```bash -git add -git revert --continue -``` - -## Paso 3: Revertir en `6.x` - -Run (repetir por cada SHA encontrado en `6.x`, del más nuevo al más viejo): -```bash -git checkout 6.x && git pull origin 6.x -q -git revert --no-edit -``` -Mismo criterio que el Paso 2 si hay conflictos. - -## Paso 4: Push (requiere confirmación explícita antes de ejecutar) - -```bash -git push origin main -git push origin 6.x -``` - -## Fallback manual (si `git revert` no aplica limpio) - -Si por conflictos preferís revertir a mano, estos son los cambios exactos a -deshacer, archivo por archivo: - -### `.github/workflows/commitlint.yml` -- Volver `on.pull_request.branches` a `[ main ]` (sacar `6.x`). -- Sacar el bloque `with: pattern: ...` del job `branch-name` (que vuelva a - usar el pattern default de la reusable workflow, sin `package`). -- Borrar los jobs `base-branch-check`, `fork-point-check` y - `no-breaking-changes` completos. - -### `.husky/pre-commit` -- Volver `PATTERN` a: - `"^(feat|feature|fix|docs|style|refactor|perf|test|build|ci|chore|revert)/.+$"` - (sacar `|package`). -- Volver la condición a: - `if [ "$BRANCH" != "main" ] && ! echo "$BRANCH" | grep -Eq "$PATTERN"; then` - (sacar `&& [ "$BRANCH" != "6.x" ]`). -- Sacar `package` de la lista impresa de "Valid types". - -### `.github/workflows/release.yml` -- Volver el trigger a: - ```yaml - on: - push: - branches: - - main - ``` -- Volver la concurrency a: - ```yaml - concurrency: - group: main-branch-push - cancel-in-progress: false - ``` -- Volver el job `release` a delegar en el workflow reusable (un fix de - seguimiento lo cambió para llamar a `googleapis/release-please-action@v5` - directo, porque necesitaba pasarle `target-branch` y el workflow reusable - de `actions-nullplatform` no expone ese input): - ```yaml - release: - uses: nullplatform/actions-nullplatform/.github/workflows/release.yml@main - permissions: - contents: write - pull-requests: write - with: - update_readme_versions: false - ``` -- En el job `generate-readmes`, sacar los `env: REF_NAME: ${{ github.ref_name }}` - que el fix de seguimiento agregó en los steps "Check if Release Please PR - exists" y "Commit and push", y volver a interpolar `${{ github.ref_name }}` - directo en esos dos `run:`, con el valor final literal - `release-please--branches--main` en ambos. - -### `.github/workflows/auto-merge-release.yml` -- Sacar `HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}` del - bloque `env:` del step (quedan solo `GH_TOKEN` y `REPO_OWNER`). -- Volver `-f "head=${REPO_OWNER}:release-please--branches--${HEAD_BRANCH}"` - a `-f "head=${REPO_OWNER}:release-please--branches--main"` (literal). - -### `.github/workflows/linter.yml`, `.github/workflows/tofu-test.yml`, `.github/workflows/tflint-unused.yml` -- Volver `branches: [ main, 6.x ]` a `branches: [ main ]` en cada uno. - -### `.github/workflows/trivy.yml` -- Volver ambos triggers (`pull_request.branches` y `push.branches`) de - `[main, 6.x]` a `[main]`. - -### Este mismo archivo y su compañero de diseño -- Este runbook puede borrarse del repo una vez completado el rollback, o - dejarse como registro histórico — a criterio del equipo. - -## Decisión pendiente: destino de la rama `6.x` - -Este runbook deliberadamente NO incluye pasos automáticos para esto, porque -depende de una decisión de producto/arquitectura que no se puede inferir -del código: - -- **Si `7.x`/`package` convergió y es la única línea futura**: comunicar al - equipo que `6.x` queda congelada/deprecada. Evaluar si conviene mergear - el historial de `6.x` hacia `main` primero (para no perder fixes que solo - existan ahí) antes de archivar o borrar la rama. Borrar una rama con - historial real requiere confirmación explícita — no lo hagas sin - preguntar. -- **Si se decide mantener `6.x` como línea de soporte de largo plazo**: este - rollback de CI puede no ser lo que se quiere — replantear con quien pidió - el rollback si realmente quiere sacar el mecanismo o solo ajustarlo. -- **Si se decide que `6.x` pasa a ser la línea principal** (descartando el - trabajo de `7.x`/`package`): esto es un cambio mucho más invasivo - (reescribir qué rama es el default branch del repo, qué pasa con los - tags `7.x` ya publicados, etc.) — fuera del alcance de este runbook, - pedir instrucciones explícitas antes de tocar nada.