Contribuindo para omegaUp
Obrigado pelo seu interesse em contribuir com o omegaUp! Esta página orienta você em todo o ciclo de uma contribuição: bifurcação e clonagem, manter sua cópia local honesta antes de tocar em qualquer coisa, ramificar, abrir uma boa solicitação de pull e consertar uma depois de já ter enviado algo de que não se orgulha. Nada aqui é exótico — é o fluxo de trabalho diário que a equipe de manutenção realmente usa, com o raciocínio anexado para que você possa improvisar com segurança quando sua situação não corresponder ao caminho feliz.
Antes de escrever uma linha de código, convidamos você a ler as Diretrizes de codificação. Vale a pena internalizar sua estrela norte desde o início: é preferível explicar por que as coisas são feitas da maneira como são feitas, em vez de o que o código faz. Segui-los torna sua alteração muito mais fácil para um revisor ler e mesclar, de modo que o esforço será recompensado na mesma semana.
Por que você nunca se compromete com main
Depois de bifurcar omegaUp, a ramificação main em sua bifurcação deve sempre permanecer um espelho byte por byte da ramificação main de omegaup/omegaup, que contém as alterações mais recentes que a equipe de revisão já aprovou. Essa é a razão da regra que você verá repetida em todos os lugares: nunca confirme diretamente com main. Depois que seus commits chegam ao main e o main upstream segue em frente, é genuinamente doloroso arrastar seu main de volta para um estado limpo - você acaba rebaseando, redefinindo ou empurrando à força para sair de um buraco que cavou sem motivo. Em vez disso, crie uma ramificação separada para cada alteração que você pretende enviar como uma solicitação pull e deixe o main fazer nada além de rastrear o upstream.
Pré-requisitos
Antes de começar:
- Configure seu ambiente de desenvolvimento
- Leia as Diretrizes de codificação
- Saiba como obter ajuda se tiver dúvidas
Todo PR precisa de um problema atribuído
Obrigatório antes de abrir um PR
Cada solicitação pull deve estar vinculada a um problema existente do GitHub que é atribuído a você. Isso não é burocracia por si só – é como a equipe evita que duas pessoas construam silenciosamente a mesma solução, e isso é aplicado pela automação, de modo que um PR sem nenhum problema atribuído por trás dele não pode ser mesclado, não importa quão bom seja o código.
Como atribuir um problema
Primeiro, encontre ou crie um problema. Navegue pelos problemas existentes ou, se estiver corrigindo algo que ninguém registrou ainda, abra um novo problema descrevendo o bug ou recurso para que haja algo para apontar seu PR.
Então ** reivindique **. omegaUp executa o bot takanome-dev/assign-issue-action precisamente para que você não precise esperar que um mantenedor clique em "atribuir" em cada ticket. Comente o assunto com:
/assign— atribua o problema a você mesmo./unassign— retire-se do problema quando não puder continuar, para que outra pessoa possa resolver o problema.
O bot também pode se oferecer para atribuir o problema quando seu comentário deixar óbvio que você deseja trabalhar nele.
Por fim, faça referência ao problema na descrição do seu PR com Fixes #1234 ou Closes #1234 (usando seu número real do problema). O GitHub lê essa linha e fecha o problema automaticamente no momento em que seu PR é mesclado, para que o rastreador permaneça honesto, sem que ninguém o resolva manualmente.
Um PR sem problema atribuído falhará em suas verificações
Se o seu PR não estiver vinculado a um problema atribuído a você, as verificações automatizadas falharão e o PR não poderá ser mesclado. Reivindique o problema primeiro.
Os limites de atribuição e por que eles existem
O bot impõe alguns prazos para que problemas reivindicados, mas abandonados, não apodreçam indefinidamente e bloqueiem outros contribuidores:
- Você pode manter no máximo 5 problemas atribuídos a você de uma só vez em todo o repositório. O limite evita que qualquer pessoa acumule pendências.
- Depois de ser atribuído, você deve abrir uma solicitação pull — um rascunho PR conta — dentro de 7 dias. A janela é o que transforma o “eu vou lá” em um progresso real ou em uma questão liberada.
- Um lembrete é postado na metade, aproximadamente 3,5 dias, para que uma semana agitada não lhe custe o problema de surpresa.
- Se não existir nenhum PR até o dia 7, você será desatribuído automaticamente e bloqueado de autoatribuir o mesmo problema novamente; se você ainda quiser depois disso, pergunte a um mantenedor.
Há uma exceção deliberada: se você foi o autor do problema e já tem pelo menos 10 PRs mesclados neste repositório, você pode autoatribuir seus próprios problemas sem que eles sejam contabilizados no limite de 5 atribuições ativas — você conquistou a confiança e o problema é seu. A regra de 7 dias para um PR ainda se aplica mesmo assim, e edições de autoria de outras pessoas ainda contam para o seu limite de 5.
Não perca uma tarefa que você pretendia manter
Comente /assign e abra um rascunho PR no mesmo dia - isso satisfaz a regra dos 7 dias imediatamente e dá a você todo o tempo necessário para terminar. Se você realmente precisar de mais tempo, peça a um mantenedor para adicionar o rótulo 📌 Pinned, que isenta o problema da varredura de cancelamento automático de atribuição.
Configure seu fork e controles remotos (uma vez)
Você só faz isso uma vez por clone. omegaUp usa os mesmos dois nomes remotos que o fluxo de trabalho padrão do fork do GitHub, então cada tutorial e ferramenta git que você já conhece continua funcionando:
origin— seu fork,https://github.com/YOURUSERNAME/omegaup.git: de onde você envia ramificações e abre pull requests.upstream— o repositório canônico,https://github.com/omegaup/omegaup.git: de onde você extrai as alterações aprovadas pela equipe de revisão.
Páginas wiki mais antigas trocaram esses nomes
Algumas das páginas wiki mais antigas do omegaUp usavam origin para o repositório canônico e um segundo controle remoto para o fork - o oposto da convenção aqui. Este site segue a convenção padrão acima (origin = seu fork, upstream = canônico). Se você estiver fazendo referência cruzada de uma página antiga e um comando for lido de trás para frente, é por isso.
1. Bifurque o repositório
Visite github.com/omegaup/omegaup e clique no botão Fork para criar sua própria cópia do omegaup/omegaup.
2. Clone seu garfo
git clone https://github.com/YOURUSERNAME/omegaup.git
cd omegaup
3. Adicione upstream e verifique
Seu novo clone já tem origin apontando para seu fork. Adicione upstream para poder buscar as alterações do repositório canônico:
git remote add upstream https://github.com/omegaup/omegaup.git
git remote -v
origin em seu fork e upstream no repositório canônico:
origin https://github.com/YOURUSERNAME/omegaup.git (fetch)
origin https://github.com/YOURUSERNAME/omegaup.git (push)
upstream https://github.com/omegaup/omegaup.git (fetch)
upstream https://github.com/omegaup/omegaup.git (push)
origin apontar para algum lugar errado - mais comumente porque você clonou o URL canônico em vez de seu fork - aponte-o novamente sem clonar novamente:
git remote set-url origin https://github.com/YOURUSERNAME/omegaup.git
Mantenha seu main atualizado antes de começar
Vale a pena repetir: você não deve fazer alterações no main, porque é muito difícil retorná-lo a um estado decente depois que as alterações forem mescladas. Mas é uma boa ideia sincronizá-lo de tempos em tempos — sempre antes de iniciar uma nova mudança — para que seu trabalho comece a partir do mesmo commit que a equipe de revisão está analisando:
git checkout main # Switch back to main if you were on a feature branch
git fetch upstream # Download the latest omegaup/main
git pull --rebase upstream main # Replay upstream's commits under yours, keeping main linear
git push origin main # Update your fork's main to match
Se git push origin main for rejeitado
Um push rejeitado para main significa que você quebrou a regra e cometeu algo diretamente no main - seu main e o main do upstream agora divergiram. A solução limpa é mover esses commits para uma ramificação de recursos e redefinir main de volta para upstream/main; pergunte a um mantenedor se não tiver certeza de como. Somente se você entender exatamente o que está descartando, deverá substituir o main do seu fork por git push origin main --force-with-lease. A verdadeira lição é aquela que está no topo desta página: em primeiro lugar, não faça commit no main - em vez disso, ramifique.
Iniciar uma nova mudança
1. Ramifique o main upstream mais recente
Crie sua ramificação diretamente do upstream/main para que ela comece a partir do código aprovado pela revisão e, em seguida, envie-a para o seu fork imediatamente para que haja um local para ela no GitHub:
git fetch upstream
git checkout -b feature-name upstream/main # New branch, synced with omegaUp's main
git push -u origin feature-name # Publish it to your fork; -u sets up tracking
Nomeie o branch após a mudança
Nomes descritivos como fix-login-bug ou add-dark-mode-toggle informam rapidamente aos revisores para que serve a filial e mantêm sua própria lista de filiais navegável meses depois.
2. Faça suas alterações
Escreva seu código seguindo as diretrizes de codificação, adicione testes para o que você alterou e certifique-se de que o pacote existente ainda seja aprovado. Uma mudança nos testes é uma mudança em que o revisor pode confiar.
3. Defina sua identidade git (apenas na primeira vez)
Se você nunca configurou o git nesta máquina, faça isso uma vez para que seus commits sejam atribuídos corretamente:
git config --global user.email "your-email@domain.com"
git config --global user.name "your-username"
4. Comprometa-se
git add .
git commit -m "Write a clear description of what changed and why"
5. Execute os validadores antes de enviar
Execute o linter fora do contêiner, na raiz do repositório:
./stuff/lint.sh
stuff/lint.sh descobre quais arquivos você alterou (é diferente de upstream/main ou origin/main se você não tiver nenhum controle remoto upstream) e executa a passagem fix apenas sobre esses arquivos, girando o contêiner omegaup/hook_tools fixado para fazer a formatação real e verificações estáticas para cada idioma que o omegaUp usa. Ele alinha o código, elimina prazos e valida. Se você deseja apenas verificar sem reescrever os arquivos, passe validate explicitamente: ./stuff/lint.sh validate.
Ele deve ser executado fora do contêiner
stuff/lint.sh se recusa a ser executado quando seu diretório de trabalho é /opt/omegaup (o caminho em que o código reside dentro do contêiner de desenvolvimento) e imprime Running ./stuff/lint.sh inside a container is not supported.. Ele precisa do Docker do seu host para iniciar a imagem de ferramentas de gancho, então execute-o a partir do shell do host, não de dentro do docker exec.
O gancho pré-empurrado executa isso para você
omegaUp instala um git hook pre-push que executa stuff/lint.sh ... validate automaticamente, portanto, um push com erros de lint é interrompido antes de sair de sua máquina. Executar o linter primeiro significa apenas encontrar e corrigir problemas de acordo com sua própria programação, em vez de ter o push bounce.
Abra a solicitação pull
1. Empurre seu branch
git push -u origin feature-name
-u vincula sua ramificação local à ramificação em seu fork (origin), portanto, cada push posterior será apenas git push sem argumentos - o rastreamento já está definido.
2. Abra o PR no GitHub
Vá para seu fork em https://github.com/YOURUSERNAME/omegaup, use o seletor de branch para mudar para feature-name e clique em Pull request. O GitHub se oferecerá para abrir o PR contra o main do omegaup/omegaup - é exatamente onde você deseja.
3. Escreva a descrição
Uma boa descrição é o que faz com que seu PR seja revisado rapidamente. Inclua o que a mudança faz, o problema que ela resolve, o que realmente mudou e como você sabe que funciona:
## Description
Brief description of what this PR does.
## Related Issue
Fixes #1234 <!-- Replace with your real issue number -->
## Changes Made
- Change 1
- Change 2
## Testing
How you tested the change.
## Screenshots (if applicable)
Before/after images for any UI change.
Sempre faça referência ao assunto
A linha Fixes #1234 / Closes #1234 não é uma decoração opcional - é o que vincula o PR ao problema atribuído (satisfazendo a verificação automatizada) e o que fecha o problema automaticamente quando o PR é mesclado.
Atualizar um PR após revisão
Os revisores deixarão comentários. Aborde-os da mesma forma que você fez a alteração original – confirme no mesmo branch e faça push. Não há -u desta vez porque a filial já está rastreando origin:
git add .
git commit -m "Address review: <what you changed>"
git push
Corrija um PR que você já enviou
Às vezes você empurra e só então percebe que o branch carrega três commits "wip", "oops" e "typo", ou o commit superior tem uma mensagem que você prefere não imortalizar. Como este é o seu branch de recurso e não o histórico compartilhado, você está livre para reescrevê-lo e forçar o push. A única regra rígida é a mesma de qualquer outro lugar nesta página: reescreva apenas o histórico em sua própria ramificação de recursos - nunca force o push para main no repositório canônico.
Altere apenas a mensagem do último commit
Se a mensagem no seu commit mais recente estiver errada, altere-a — isso abre o seu editor na mensagem existente:
git commit --amend
Old commit message
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
git log, que agora deve mostrar sua nova mensagem nesse commit. Se você já executou o commit, o controle remoto ainda possui a versão antiga, então atualize-o:
git push --force-with-lease
--force-with-lease é a forma segura de --force: ele se recusa a sobrescrever a ramificação remota se alguém a tiver pressionado desde a última vez que você a buscou, portanto, um push forçado nunca pode atrapalhar silenciosamente o trabalho de um colaborador.
Esmague os commits descartáveis
Para dobrar uma série de commits confusos em um commit limpo, rebase interativamente o último n deles:
git rebase -i HEAD~n
n por quantos commits você deseja recolher. Git abre um editor listando os mais antigos primeiro:
pick commit-1
pick commit-2
pick commit-3
...
pick commit-n
pick — que é o commit cuja mensagem sobrevive — e mude cada linha abaixo dele de pick para fixup (ou apenas f), que dobra as alterações do commit na linha acima dele e descarta sua mensagem:
pick commit-1
f commit-2
f commit-3
...
f commit-n
git push --force-with-lease
Depois de enviar
Assim que o PR é aberto, uma sequência previsível se desenrola. GitHub Actions executa uma bateria completa de testes e validações - certifique-se de que todos fiquem verdes, já que um cheque vermelho é a primeira coisa que um revisor irá rejeitar no PR. Em seguida, um membro da equipe omegaUp analisa seu código; resolva tudo o que eles levantarem, enviando mais commits para o mesmo branch. Depois de aprovado e mesclado, há mais uma espera: os PRs mesclados vão para produção na implantação de fim de semana, portanto, sua alteração entra em vigor após o próximo fim de semana, e não no instante em que é mesclada.
Limpar após uma mesclagem
Depois que seu PR for mesclado, a filial terá feito seu trabalho. Exclua-o localmente:
git branch -D feature-name
git push origin --delete feature-name
git branch -a. Remova essas referências mortas para que git branch -a pare de listar ramificações que não existem mais:
git remote prune origin --dry-run # Preview what would be pruned
git remote prune origin # Actually remove the stale references
Dicas ambientais que você pode encontrar no primeiro empurrão
Esses são os obstáculos de configuração que os colaboradores iniciantes costumam encontrar. Cada um mostra o sintoma para que você possa combinar o seu e depois a correção.
A localidade da VM não é en_US.UTF-8
A VM de desenvolvimento não é fornecida com en_US.UTF-8 como localidade padrão, o que algumas ferramentas reclamam. Corrija-o seguindo este guia do askubuntu.
Dependências PHP ausentes
Um novo checkout não tem diretório vendor/, então as dependências do PHP estão faltando até você instalá-las:
composer install
FileNotFoundError: ... 'mysql' ao pressionar
Se o seu push for abortado com algo assim:
FileNotFoundError: [Errno 2] No such file or directory: 'mysql'
error: failed to push some refs to 'https://github.com/YOURUSERNAME/omegaup.git'
mysql e não conseguiu encontrá-lo - o MySQL não está instalado em seu host. O servidor MySQL é executado dentro do contêiner de desenvolvimento, mas o cliente que o gancho invoca deve residir no host, fora do contêiner. Instale os dois pacotes lá:
sudo apt install mysql-client mysql-server
cat > ~/.mysql.docker.cnf <<EOF
[client]
port=13306
host=127.0.0.1
protocol=tcp
user=root
password=omegaup
EOF
ln -sf ~/.mysql.docker.cnf .my.cnf
.my.cnf vinculado, o cliente lê essa configuração automaticamente e o gancho pré-push pode alcançar o banco de dados.
Para onde ir em seguida
- Diretrizes de codificação — os padrões que facilitam a revisão do seu PR.
- Comandos úteis — a referência diária de comandos de desenvolvimento.
- Guia de teste — como escrever e executar os testes que seu PR precisa.
- Como obter ajuda — onde perguntar quando você tiver dúvidas.
- Visão geral da arquitetura — como as peças que você está alterando se encaixam.
- Junte-se ao servidor Discord para conversar com a comunidade.
Pronto para fazer sua primeira contribuição? Reivindique um problema, ramifique upstream/main e abra seu PR.