Skip to content

fix(ci): cadeia de CI (#26) - #1

Draft
matbrgz wants to merge 11 commits into
masterfrom
fix/26-cadeia-ci
Draft

matbrgz wants to merge 11 commits into
masterfrom
fix/26-cadeia-ci

Conversation

@matbrgz

@matbrgz matbrgz commented Oct 10, 2026

Copy link
Copy Markdown
Member

Commit que estava só local, enviado durante a limpeza do ambiente de dev (2026-10-10). Rascunho: revisar antes do merge.

🤖 Generated with Claude Code

marcelometal and others added 11 commits September 18, 2026 22:06
AGENTS.md, CONTRIBUTING.md, SECURITY.md and INSTALL.md were missing from
doc_DATA, so they were left out of "make dist" and "make install". The Windows
installer script gets the same list and drops its references to README.pt_BR
and NEWS, which no longer exist.
A regra `stm_ret` de `src/modules/x86/x86.g` declarava `int etype;` sem
inicializar e chamava `x86.writeCast(etype, expecting_type)` também na
alternativa `TI_NULL` — o `retorne;` sem valor —, na qual `etype` nunca é
atribuída. `X86::writeCast` (`src/modules/x86/X86.cpp:380` e `:386`)
compara esse valor com `TIPO_REAL` para decidir se emite a sequência de
truncamento x87, então lixo de pilha decidia o que entrava no assembly.

Não é caminho de erro: `test/tester.gpt:655` (`funcao_void()`, que termina
em `retorne;`) já exercita isso. Medido em ubuntu:24.04/aarch64, build
`-O0 -g`, com valgrind sobre `test/tester.gpt`:

  antes, `gpt -s`:  2 errors from 2 contexts
    X86::writeCast (X86.cpp:380) <- X86Walker::stm_ret (X86Walker.cpp:901)
    X86::writeCast (X86.cpp:386) <- X86Walker::stm_ret (X86Walker.cpp:901)
  depois, `gpt -s`: 0 errors from 0 contexts
  (o mesmo par some em `gpt -o`: 2 -> 0)

A correção é não chamar `writeCast` quando não houve expressão de retorno,
em vez de só inicializar a variável: sem expressão não há valor na pilha
para converter — de fato o `pop eax` acima já é pulado quando
`expecting_type == TIPO_NULO`. `etype` também passa a nascer `TIPO_NULO`,
como defesa.

Que o valor lido de fato alterava a saída foi comprovado por mutação:
forçando `int etype=TIPO_REAL;` na mesma regra, `tester.asm` ganha 10
instruções x87 (`fnstcw`/`fld`/`fistp`/`fldcw`) no epílogo de
`_funcao_void`. Com a correção, o assembly de `test/tester.gpt` e dos três
`exemplos/*.gpt` é idêntico ao de antes, e `bash test/run_test.sh` passa
antes e depois.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`build-on-push.yml` e `pre-commit.yml` declaravam `push` e `pull_request`
ambos sem filtro de branch. Um push num branch que tem PR aberto dispara os
dois eventos, e o mesmo commit era construido duas vezes -- como se ve em
https://github.com/gportugol/gpt/pull/8/checks.

Com `push` restrito ao `master`, cada commit passa uma vez so: branch de PR
pelo evento `pull_request`, e `master` pelo `push`.

## O que muda para quem empurra branch sem PR

Antes, um push em qualquer branch construia. Agora constroi quando o PR
existe. E o comportamento que a issue pede ("apenas uma execucao de build por
commit quando o PR e criado ou atualizado") e o padrao recomendado pela
propria documentacao do GitHub Actions, mas e uma mudanca de habito -- vale
dizer em voz alta em vez de deixar a pessoa descobrir.

Quem quiser manter o build em branch solto pode trocar por
`push: branches-ignore: [master]` mais `pull_request`, que tambem evita a
duplicata, ao custo de nao construir o merge-commit do PR.

## O `concurrency`

Um push novo cancela a execucao anterior DO MESMO BRANCH. Sem isso, tres
commits seguidos deixam tres builds na fila e quem empurrou espera os tres,
sendo que so o ultimo interessa.

No `master` o cancelamento fica DESLIGADO de proposito: ali cada commit e um
estado publicado, e perder o resultado de um deles esconderia uma quebra.

Fecha gportugol#9.
test/run_test.sh only checked that tester.gpt exits with 42 when interpreted
and as a native binary, and that the assembly and the C translation get
generated. It now runs every program in test/casos through the interpreter, the
native binary and the C translation compiled with gcc, comparing stdout and
exit code with recorded outputs, checks that every program in test/erros is
rejected with the recorded message, and fails when NASM rejects the -s assembly
instead of only warning. The suite exposed two Windows bugs, fixed here: the
Win32 runtime printed with WriteConsoleA, which fails on a redirected handle,
so gpt -o binaries wrote nothing to a file or a pipe (it now uses WriteFile),
and GPTDisplay::toOEM left no room for the terminating null, writing one byte
past its buffer on pure ASCII messages.

The expected outputs are what the current ANTLR2 build produces, known flaws
included (doubled periods, cascading syntax errors), so that a later change of
parser shows each behaviour change as a diff of these files. Mode-specific
expected files cover the places where the backends already disagree, and the
pre-commit whitespace hooks skip the expected outputs, which are compared byte
by byte. A missing NASM stays an explicit skip, and nasm assembles x86 on any
host, so only running the native binary is skipped outside x86. The toOEM
overflow only surfaced with the MSYS2 GCC 16 build on CI; a MinGW GCC 14 build
under Wine does not reproduce it.
gpt exited 0 after two kinds of failure. GPT::interpret() returned 0 when
prologue() failed, so gpt -i printed a syntax or semantic error and still
reported success. The x86 backend emits 32-bit assembly for a flat nasm
binary without consulting the host, and the nasm call was tested only for
-1, which system() returns when it cannot start a shell: off x86, gpt -o
wrote an image that cannot run, and without nasm the shell complained and
gpt exited 0 again. Now -i returns EXIT_FAILURE, -o refuses off x86 and
points at -t, and any non-zero nasm status is an error. The -h help, both
man pages and the LaTeX manual note the -o restriction; run_test.sh skips
the per-case -o runs off x86 and covers the three refusals, each requiring
exit code 1 and gpt's own diagnostic on stderr, so a gpt that never
started or crashed cannot pass.

The host check is a compile-time macro, so it describes the machine gpt
was built for, which is the one it runs on in every native build this
project ships; it holds for i386 and amd64 and fails for arm64, armhf,
riscv64, s390x and ppc64el. -s keeps working everywhere, since emitting
x86 assembly for another machine is legitimate. An algorithm that ends
with 1 still looks like a refusal to the caller, which can read stderr to
tell them apart. The nasm refusal is checked with a nasm that exits 1
rather than a missing one, because emptying PATH on Windows also hides the
MinGW DLLs gpt.exe loads from /mingw64/bin, where nasm.exe lives; both
reach the same system() != 0 branch. The refusal off x86 never runs in CI,
which builds only on x86_64; it was exercised with an arm64 build under
qemu-aarch64.
The workflows reference actions by floating major tags and nothing watches
for new releases, so every action except msys2/setup-msys2 is now one or
more majors behind: build.yml still runs actions/cache@v3, and
release.yml uses actions/download-artifact@v4 while v8 is out. This adds a
weekly Dependabot check for the github-actions ecosystem, which with
directory "/" covers .github/workflows.

All updates, majors included, are grouped into a single pull request to
keep the noise down; the cost is that one incompatible release holds back
the whole group until it is fixed or excluded. The release workflow only
runs when a release is created, so bumps to download-artifact or
action-gh-release are not exercised by pull request CI and need a manual
look before merging.
Bumps the github-actions group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4` | `7` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `7` |
| [actions/cache](https://github.com/actions/cache) | `3` | `6` |
| [actions/setup-python](https://github.com/actions/setup-python) | `5` | `7` |
| [actions/download-artifact](https://github.com/actions/download-artifact) | `4` | `8` |
| [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `2` | `3` |


Updates `actions/checkout` from 4 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v7)

Updates `actions/upload-artifact` from 4 to 7
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

Updates `actions/cache` from 3 to 6
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](actions/cache@v3...v6)

Updates `actions/setup-python` from 5 to 7
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v7)

Updates `actions/download-artifact` from 4 to 8
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](actions/download-artifact@v4...v8)

Updates `softprops/action-gh-release` from 2 to 3
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](softprops/action-gh-release@v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
- dependency-name: softprops/action-gh-release
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
The Windows job fetched the ANTLR 2.7.7 tarball over plain http:// and never
checked it, although that tarball generates the parser compiled into gpt.exe.
The JDK that runs it and the NASM 0.99.05 zip, whose nasm.exe ships inside
gpt-win-x86_64.zip, went unchecked too. Each download is now followed by
sha256sum -c against a pinned hash, so a mismatch stops the step before
extraction; the ANTLR URL uses https://, and every action is pinned to a commit
SHA with its tag in a comment for Dependabot. The workflows default to
contents: read, and only upload-release-assets gets contents: write. That job
now relies on the built-in token: the pinned softprops/action-gh-release reads
its token input, which defaults to github.token, before the GITHUB_TOKEN env,
so the GH_RELEASE_TOKEN PAT was already being ignored.

The cache keys now carry the ANTLR hash and the JDK version, so entries saved
on master from unchecked downloads are never restored again. The ANTLR key
names the JDK because the cached antlr launcher records the absolute path of
the java that configure found, and the jar is compiled by that JDK; a JDK bump
must update both keys. The JDK directory goes to $GITHUB_PATH in Windows form
from a step without if:, so it also applies on cache hits and no longer
rewrites the whole PATH through $GITHUB_ENV. NASM publishes no checksum for
0.99.05, so its hash pins the file as served today rather than a vendor value.
The release path with the built-in token has not run yet: the next release is
its first test, and the GH_RELEASE_TOKEN secret can be revoked once it
succeeds.

Closes gportugol#26

Co-Authored-By: Antigravity <noreply@google.com>
Co-authored-by: Marcelo Jorge Vieira <metal@alucinados.com>
@matbrgz

matbrgz commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

O commit local 14d948d divergia da branch remota e foi salvo em salvo/fix-26-cadeia-ci-local-2026-10-10 (limpeza do ambiente de dev, 2026-10-10). Comparar antes de mesclar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants