Skip to content

fix(ci): guard de release compara desde a última release, não o push #135

fix(ci): guard de release compara desde a última release, não o push

fix(ci): guard de release compara desde a última release, não o push #135

Workflow file for this run

name: CI/CD
# Canonical CI/CD orchestrator — mirrors platform's split-workflow shape.
# Each concern lives in its own reusable workflow under `.github/workflows/`:
#
# _checks.yml — parallel CI checks (lint, typecheck, format, build, test)
# _release.yml — semantic-release with packages_changed guard
# _publish.yml — npm publish pinned to release_sha
# _deploy-site.yml — Cloudflare Pages deploy + Slack notify (repos with sites)
# review.yml — automated Anthropic → OpenAI code review
# publish-tag.yml — manual recovery (workflow_dispatch)
#
# Per-repo customization flows through `.precisa.json`:
# publishesToNpm + publishPackages[] gate the `publish` job
# hasSite + siteProjectName + siteFilter gate the `deploy-site` job
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
# `contents: write` porque _release.yml (reusable) precisa criar
# commits e tags via semantic-release. Workflows reusáveis só
# conseguem pedir permissões que o caller também concede.
contents: write
issues: write
pull-requests: write
id-token: write
# `models: read` pelo mesmo motivo: review.yml chama GitHub Models
# via GITHUB_TOKEN no fallback de providers.
models: read
# Cancela só em PR. O `push` deste workflow só dispara na branch padrão, e lá
# o run publica no npm: cancelar no meio deixa a tag criada sem a versão
# publicada. Foi o que aconteceu no fhir-brasil, onde cinco tags (v0.16.6 a
# v0.17.3) ficaram sem publicar porque cada merge cancelava o publish do merge
# anterior — e o commit `chore(release)` do semantic-release dispara mais um
# run, que cancela o próprio publish que o criou.
#
# Chavear por `event_name` em vez de comparar a branch evita depender de
# `github.event.repository.default_branch`, que nem todo contexto de gatilho
# popula — e, se viesse vazio, a comparação daria `true` e voltaria a cancelar
# na branch padrão, justamente o que este comentário existe para impedir.
# Assim, qualquer evento inesperado cai no lado seguro (não cancela).
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
# ── CI checks (every PR and push) ──────────────────────────────
checks:
uses: ./.github/workflows/_checks.yml
secrets: inherit
# ── Automated code review (PR only, after checks) ──────────────
review:
needs: checks
if: github.event_name == 'pull_request'
uses: ./.github/workflows/review.yml
with:
pr_number: ${{ github.event.pull_request.number }}
secrets: inherit
# ── Release (main only, guarded on package changes) ────────────
release:
needs: checks
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
uses: ./.github/workflows/_release.yml
secrets: inherit
# ── Publish to npm (when release created a new version) ────────
publish:
needs: release
if: needs.release.outputs.released == 'true'
uses: ./.github/workflows/_publish.yml
with:
release_sha: ${{ needs.release.outputs.release_sha }}
# Newline-separated list of package directories. One per line.
packages: |
packages/cli
secrets: inherit
# ── Deploy site (Cloudflare Pages + Slack notify) ──────────────
deploy-site:
needs: checks
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
uses: ./.github/workflows/_deploy-site.yml
with:
project_name: 'datasus-viz'
site_filter: '@datasus-viz/site'
site_source_path: 'site/'
secrets: inherit