Skip to content

perf(ci): reduzir build de 17m para ~6m com clone raso, caches e paralelismo - #22

Merged
Ddiidev merged 3 commits into
mainfrom
ci-build-performance
Sep 24, 2026
Merged

Ddiidev merged 3 commits into
mainfrom
ci-build-performance

Conversation

@Ddiidev

@Ddiidev Ddiidev commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Por que

A pipeline levava 17m01s para um app pequeno. A causa era o git clone https://github.com/vlang/vc.git: um repo de 1,83 GB (versiona o v.c gerado, 10,7 MB, a cada commit) clonado duas vezes por run (no runner e dentro da imagem), respondendo por 51% da pipeline (525s de 1021s). Do repo inteiro so 3 arquivos sao usados: v.c, v_win.c e README.md.

O que mudou

  1. Busca rasa do commit pinado (Dockerfile + workflow): fetch --depth 1 origin <sha> no lugar do clone completo. Pins e assercoes git rev-parse HEAD identicos.
  2. Cache do toolchain V (actions/cache de /tmp/v, chave por pin): so recompila quando o pin muda.
  3. Cache de layers do buildx (type=gha,mode=max): reaproveita apk + toolchain V musl entre runs.
  4. Testes nativos em paralelo com o build da imagem: a trilha nativa (apt, V, testes, contratos) roda em segundo plano enquanto o docker buildx build roda em primeiro plano, num passo unico com wait nas duas no final.
  5. Filtro de gatilho: push restrito a main. Antes, um push de branch com PR aberto disparava os dois eventos (push e pull_request) para o mesmo commit, rodando a pipeline inteira duas vezes.

O gate de publicacao continua preservado (a espera acontece antes do Publicar tag imutavel) e nenhum pin do toolchain muda.

Resultado

Dois runs reais depois das mudancas:

Etapa Antes Depois (medido)
Preparo do V no runner 299s 3s (cache quente)
Bootstrap do V dentro da imagem 340s 39s a 47s
Compilar o app 271s 207s a 272s
Pipeline total 17m01s 4m49s e 6m01s
Runs por push de PR 2 1

Os dois passaram, com 5 passed nos testes V e 4/4 contratos. A variacao de 207s a 272s na compilacao e do runner (mesmo codigo, mesmas flags), entao o ganho confiavel e estrutural: bootstrap de 340s para 39-47s e uma execucao por push em vez de duas.

Ponto de atencao

Mudanca de comportamento: commits de branch deixam de publicar tag no GHCR. Agora publica o que entra no main, ou seja a tag passou a ser sha-<merge commit> e nao mais sha-<commit do branch>. No deploy-production.yml, use o SHA do commit no main. Se o fluxo de subir um commit de PR no A/B antes do merge for necessario, este item precisa ser revertido.

O cache de layers do buildx deu miss no run de PR, o que e esperado e nao indica ma configuracao: o cache do GHA e escopado por ref, entao refs/pull/N/merge nao le o que um push de branch escreveu. O ganho vem na direcao main para PR (cache criado no main fica disponivel para os PRs, e nao o contrario). Como o main ainda nao rodou com esse cache, o primeiro PR sempre paga o custo cheio.

Fora do escopo: o workflow testa com V ee3ef57 e o Dockerfile publica com cf7a81e, ou seja, os testes validam um compilador diferente do que gera o binario. Nao alterei isso aqui.

O workflow disparava em push (sem filtro de branch) e em pull_request, entao
um push de branch com PR aberto rodava a pipeline inteira duas vezes para o
mesmo commit, serializadas pelo grupo de concorrencia e custando ~4m49s cada.

Com o filtro, o main continua validado e publicando a imagem no push, e as
branches de feature passam a rodar uma vez, via pull_request (que ja dispara
a cada novo push do PR).

Efeito colateral: commits de branch deixam de publicar tag sha-<commit> no
GHCR; apenas o que chega ao main publica.
@Ddiidev
Ddiidev merged commit 856b28d into main Sep 24, 2026
1 check passed
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.

1 participant