Você já tem um job de build que produz um wheel e um repositório privado que deve recebê-lo. O erro é deixar um segundo job reconstruir a partir de um branch e chamar o resultado da mesma release. Mova o arquivo que foi testado, nomeie-o pelo resumo e mantenha a credencial de upload do lado de dentro. O passo a passo abaixo acompanha um artefato de um runner de CI público até um publicador interno.

Construa onde o código-fonte já está

Execute o build no job que já tem o código-fonte, a toolchain e a suíte de testes. Nada em um repositório privado exige que esse job o alcance. Instale o frontend de build no ambiente que o projeto já usa e então produza os dois formatos de distribuição, se o projeto publica os dois.

python -m build --sdist --wheel --outdir dist
python -m twine check dist/*

Mantenha o diretório de saída pequeno e descartável. As únicas coisas que valem levar adiante são os arquivos que o próximo job vai publicar, mais os hashes deles. Todo o resto, incluindo ambientes virtuais e caches, pode ser reconstruído a partir da revisão de código registrada. Um artefato enxuto também é mais fácil de revisar, porque cada arquivo nele é um arquivo que alguém pode inspecionar.

Registre o que os produziu: o nome do pacote e a versão a partir dos nomes dos arquivos, a revisão de código e a execução de workflow que os criou. Uma string de versão sozinha não identifica um arquivo, porque a mesma versão pode ser construída duas vezes a partir de commits diferentes. Escreva a revisão ao lado dos nomes dos arquivos na descrição do artefato e trate esse registro como parte da entrega.

Mova bytes, não instruções de reconstrução

Um segundo build é um segundo produto. Timestamps, dependências empacotadas e versões de ferramentas podem mudar os bytes, então uma reconstrução precisa da própria evidência de teste e da própria revisão. Promova os arquivos revisados em vez disso.

Envie os arquivos de distribuição para o armazenamento de artefatos que sua plataforma de CI oferece e dê ao job interno uma referência a esse artefato específico, não a um nome de branch.

sha256sum dist/*.whl dist/*.tar.gz
# keep the digests beside the run id in the artifact description

Se sua plataforma suporta proveniência assinada, peça que ela ateste o artefato e depois verifique o repositório, o workflow e a revisão de código esperados. A documentação de atestações do GitHub descreve declarações nesse formato. Uma assinatura válida é evidência de origem, não uma varredura de vulnerabilidades e não uma decisão de autorização.

Verifique do lado de dentro antes de enviar

O job interno começa verificando se o arquivo que recebeu é o arquivo que foi aprovado. Compare resumos com o registro do job de build, não com um valor recalculado a partir do que chegou.

sha256sum -c digests.txt
python -m twine check dist/*

Depois leia os metadados. O nome do pacote, a versão e as dependências declaradas devem corresponder à revisão que você aprovou. Um wheel cujo nome parece certo mas cujos pins de dependência mudaram é um pacote diferente usando o mesmo rótulo. Se os metadados mudaram, trate o artefato como não aprovado e descubra qual build o produziu.

Se os resumos não correspondem, pare. Não envie e não conserte o arquivo reconstruindo-o no lugar; isso apaga a evidência de que algo mudou no trajeto. Uma divergência significa que o armazenamento de artefatos, a etapa de download ou o registro está errado, e cada um deles merece uma explicação antes de uma release ser publicada.

Lide com a resposta de versão duplicada

Repositórios privados costumam recusar sobrescrever uma versão existente, e essa recusa é um recurso. Quando um upload falha porque a versão existe, inspecione o registro do repositório para essa versão e compare os arquivos que ele guarda com os resumos que você pretendia publicar.

Uma versão existente pode significar que um upload anterior teve sucesso e a resposta se perdeu, ou que alguém publicou conteúdo diferente sob o mesmo número.

Não exclua a versão e não invente um número novo para passar pelo erro. Decida com o dono da release se o conteúdo armazenado é aceitável e registre o resultado. Se o conteúdo difere, você tem um problema de versionamento, não um problema de pipeline.

Mantenha a credencial de upload de um lado só

Somente o publicador interno precisa de credenciais do repositório, e apenas durante o upload. Restrinja o token ao repositório de destino e às operações de upload, guarde-o no cofre de segredos do sistema interno e deixe-o totalmente fora do job de build. Se o job de build pode publicar, então qualquer um que possa mudar o build pode publicar.

Restrinja também quais workflows internos podem iniciar o publicador. Um gatilho manual com aprovação obrigatória é um padrão razoável para releases; um push para qualquer branch não é.

A release concluída deve deixar três coisas: os arquivos de distribuição, seus resumos com a revisão de código e um registro do repositório mostrando a mesma versão.

Artigos relacionados