From b1707f26c17db8bc9676c3f935e838dafb4d20c3 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 21 Oct 2026 21:49:50 -0300 Subject: [PATCH 1/4] CI roda o zizmor sobre os workflows no job quality --- .github/workflows/tests.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 89478015..6bc6a721 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,14 @@ jobs: with: enable-cache: true + # Auditoria de segurança dos workflows. Com --offline, o zizmor roda só + # as auditorias que leem os arquivos; as online consultam a API do GitHub + # e precisariam de token. A versão fica fixada porque uma versão nova + # pode trazer auditoria nova e reprovar um PR que não mexeu nos + # workflows, e o Dependabot não atualiza versão escrita dentro de run:. + - name: zizmor + run: uvx zizmor@1.30.1 --offline .github/workflows + - name: Ruff format run: uv run --python 3.13 $EXTRAS ruff format --check src tests From bfa27d1dc9588a920ed4f5234eefc823118b9c18 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 21 Oct 2026 21:53:03 -0300 Subject: [PATCH 2/4] =?UTF-8?q?Actions=20fixadas=20por=20commit,=20checkou?= =?UTF-8?q?t=20sem=20credencial=20persistida=20e=20permiss=C3=B5es=20do=20?= =?UTF-8?q?Pages=20s=C3=B3=20no=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docs.yml | 20 +++++++----- .github/workflows/tests.yml | 62 +++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 4ee4b013..57799604 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -14,8 +14,6 @@ on: permissions: contents: read - pages: write - id-token: write concurrency: group: "pages" @@ -25,15 +23,17 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -45,11 +45,17 @@ jobs: run: cp site/sitemap.xml site/en/sitemap.xml - name: Upload artifact - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: ./site deploy: + # Permissões de job substituem as do workflow, e este job não faz + # checkout: precisa só de escrever no Pages e do token OIDC com que o + # deploy-pages prova que a publicação vem deste repositório. + permissions: + pages: write + id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} @@ -58,4 +64,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6bc6a721..b33d7373 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,15 +18,17 @@ jobs: env: EXTRAS: --extra dev --extra all --extra search-all --extra polars --extra excel --extra codex steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -60,15 +62,17 @@ jobs: matrix: python-version: ['3.11', '3.13'] steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -97,7 +101,7 @@ jobs: pytest --cov=dataframeit --cov-branch --cov-report= --cov-fail-under=0 - name: Upload coverage data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: coverage-unit-${{ matrix.python-version }} path: .coverage.unit-${{ matrix.python-version }} @@ -118,15 +122,17 @@ jobs: matrix: extras: ['', 'all excel polars search-all'] steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.11' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -150,15 +156,17 @@ jobs: matrix: python-version: ['3.11', '3.13'] steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: ${{ matrix.python-version }} - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -171,7 +179,7 @@ jobs: pytest --cov=dataframeit --cov-branch --cov-report= --cov-fail-under=0 - name: Upload coverage data - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2 with: name: coverage-codex-${{ matrix.python-version }} path: .coverage.codex-${{ matrix.python-version }} @@ -184,20 +192,22 @@ jobs: needs: [unit, codex-provider] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true - name: Download coverage data - uses: actions/download-artifact@v8 + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 with: pattern: coverage-* merge-multiple: true @@ -210,15 +220,17 @@ jobs: codex-windows: runs-on: windows-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true @@ -232,15 +244,17 @@ jobs: if: github.event_name == 'pull_request' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Setup Python - uses: actions/setup-python@v7 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 with: python-version: '3.13' - name: Setup uv - uses: astral-sh/setup-uv@v10.2.0 + uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0 with: enable-cache: true From b5b4e02f24bbc894b348d68817667d464607cf70 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 21 Oct 2026 21:53:03 -0300 Subject: [PATCH 3/4] =?UTF-8?q?CHANGELOG=20e=20CONTRIBUTING=20registram=20?= =?UTF-8?q?a=20fixa=C3=A7=C3=A3o=20das=20actions=20e=20o=20zizmor=20no=20C?= =?UTF-8?q?I?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ CONTRIBUTING.md | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4c28b0..ce5c7b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,10 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR - `depends_on` em tupla vale como a lista. Antes, era descartado em silêncio, e o aviso dizia que `depends_on` faltava. Forma diferente de texto, lista ou tupla de nomes levanta `ValueError` antes de processar (#150). - A configuração por campo declarada num modelo dentro de `Annotated` aninhado, como `list[Annotated[list["X"], ...]]`, é encontrada pela varredura e pelas validações. A referência adiantada dentro do `Annotated` é resolvida, e os metadados ficam como estavam (#151). +### Segurança + +- Os workflows do CI fixam cada action pelo SHA do commit, com a versão em comentário; o `actions/checkout` deixa de gravar o token do GitHub no `.git/config` do runner (`persist-credentials: false`); e, no `docs.yml`, só o job que publica tem `pages: write` e `id-token: write`. O job `quality` roda o `zizmor`, que reprova o workflow que volte a ter um desses problemas (#209). + ## [0.10.0] - 2026-09-24 ### Adicionado diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a673b909..ea4fd63c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ Os testes não chamam nenhum provider de verdade e não precisam de chave de API 1. Abra uma issue antes de uma mudança grande, para combinar o desenho. 2. Crie uma branch a partir da `main` com o prefixo do tipo de mudança: `feature/`, `fix/`, `docs/` ou `refactor/`. 3. Escreva o teste junto com a mudança. Uma correção de bug vem com o teste que falhava antes dela. -4. Abra o PR contra a `main`. O CI roda lint, testes em Python 3.11 e 3.13, os testes com as versões mínimas das dependências e o build da documentação. +4. Abra o PR contra a `main`. O CI roda lint, a auditoria dos workflows pelo `zizmor`, testes em Python 3.11 e 3.13, os testes com as versões mínimas das dependências e o build da documentação. ## Convenções @@ -33,6 +33,8 @@ As regras de versionamento, de `CHANGELOG.md` e de escrita de documentação est - A documentação descreve o estado atual. O histórico fica no `CHANGELOG.md` e no git, sem notas do tipo "desde a versão X". - O número de versão só muda na preparação de um release. +Os workflows de `.github/workflows/` fixam cada action pelo SHA do commit, com a versão em comentário (`uses: dono/action@ # v1.2.3`), e o `actions/checkout` leva `persist-credentials: false`. O passo `zizmor` do job `quality`, em `tests.yml`, reprova a action que entrar sem isso, e o mesmo comando roda na máquina local. + A documentação tem duas árvores com o mesmo conteúdo: `docs/` em português, que é o idioma padrão do site, e `docs/en/` em inglês. Uma mudança numa página vale para as duas. ## Exemplos From 85b8b79ff21bd7d983c88d263590a640bde3f149 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Wed, 21 Oct 2026 22:41:44 -0300 Subject: [PATCH 4/4] CONTRIBUTING e CHANGELOG dizem o que o zizmor reprova MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit O zizmor --offline reprova a action referida por tag ou branch no lugar do SHA, o actions/checkout sem a chave persist-credentials e a permissão de escrita no nível do workflow. Ele não confere o comentário de versão e aceita persist-credentials: true, e o CONTRIBUTING passa a dizer que essas duas partes da convenção ficam com a revisão do PR. O comentário do passo zizmor troca a razão do --offline pela verdadeira, as consultas à API do GitHub a cada execução, e nomeia as cinco auditorias que ficam de fora. O .pre-commit-config.yaml deixa de dizer que src/ e tests/ são as únicas pastas que o CI confere. --- .github/workflows/tests.yml | 11 +++++++---- .pre-commit-config.yaml | 4 +++- CHANGELOG.md | 2 +- CONTRIBUTING.md | 2 +- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b33d7373..a2e76bbf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,10 +33,13 @@ jobs: enable-cache: true # Auditoria de segurança dos workflows. Com --offline, o zizmor roda só - # as auditorias que leem os arquivos; as online consultam a API do GitHub - # e precisariam de token. A versão fica fixada porque uma versão nova - # pode trazer auditoria nova e reprovar um PR que não mexeu nos - # workflows, e o Dependabot não atualiza versão escrita dentro de run:. + # as auditorias que leem os arquivos. As online consultam a API do GitHub + # a cada execução e ficam de fora: impostor-commit, ref-confusion, + # known-vulnerable-actions, stale-action-refs e ref-version-mismatch. Os + # SHAs fixados foram conferidos contra as tags quando entraram. A versão + # fica fixada porque uma versão nova pode trazer auditoria nova e + # reprovar um PR que não mexeu nos workflows, e o Dependabot não atualiza + # versão escrita dentro de run:. - name: zizmor run: uvx zizmor@1.30.1 --offline .github/workflows diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fd96c8ff..4c284c4c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,9 @@ # Os hooks rodam as mesmas versões do extra dev do pyproject.toml, pelo uv, e # o job quality do CI (tests.yml) roda os mesmos comandos. # Instalação: uv run --extra dev pre-commit install -# Os hooks disparam com mudanças em src/ e tests/, as pastas que o CI confere. +# Os hooks disparam com mudanças em src/ e tests/. Os workflows de +# .github/workflows/ não têm hook: o passo zizmor do job quality os confere, e +# o comando dele roda também na máquina local. files: ^(src|tests)/ repos: - repo: local diff --git a/CHANGELOG.md b/CHANGELOG.md index ce5c7b97..2d865431 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,7 +79,7 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR ### Segurança -- Os workflows do CI fixam cada action pelo SHA do commit, com a versão em comentário; o `actions/checkout` deixa de gravar o token do GitHub no `.git/config` do runner (`persist-credentials: false`); e, no `docs.yml`, só o job que publica tem `pages: write` e `id-token: write`. O job `quality` roda o `zizmor`, que reprova o workflow que volte a ter um desses problemas (#209). +- Os workflows do CI fixam cada action pelo SHA do commit, com a versão em comentário; o `actions/checkout` deixa de gravar o token do GitHub no `.git/config` do runner (`persist-credentials: false`); e, no `docs.yml`, só o job que publica tem `pages: write` e `id-token: write`. O job `quality` roda o `zizmor`, que reprova a action referida por tag ou branch no lugar do SHA, o `actions/checkout` sem a chave `persist-credentials` e a permissão de escrita no nível do workflow (#209). ## [0.10.0] - 2026-09-24 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ea4fd63c..d17d4860 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,7 @@ As regras de versionamento, de `CHANGELOG.md` e de escrita de documentação est - A documentação descreve o estado atual. O histórico fica no `CHANGELOG.md` e no git, sem notas do tipo "desde a versão X". - O número de versão só muda na preparação de um release. -Os workflows de `.github/workflows/` fixam cada action pelo SHA do commit, com a versão em comentário (`uses: dono/action@ # v1.2.3`), e o `actions/checkout` leva `persist-credentials: false`. O passo `zizmor` do job `quality`, em `tests.yml`, reprova a action que entrar sem isso, e o mesmo comando roda na máquina local. +Os workflows de `.github/workflows/` fixam cada action pelo SHA do commit, com a versão em comentário (`uses: dono/action@ # v1.2.3`), e o `actions/checkout` leva `persist-credentials: false`. O passo `zizmor` do job `quality`, em `tests.yml`, reprova a action referida por tag ou branch no lugar do SHA, o `actions/checkout` sem a chave `persist-credentials` e a permissão de escrita no nível do workflow. O `zizmor --offline` não confere o comentário de versão e aceita `persist-credentials: true`, e essas duas partes da convenção ficam a cargo da revisão do PR. O mesmo comando do passo roda na máquina local. A documentação tem duas árvores com o mesmo conteúdo: `docs/` em português, que é o idioma padrão do site, e `docs/en/` em inglês. Uma mudança numa página vale para as duas.