Skip to content

About

Automação em Python que registra, em um repositório GitHub privado, os commits feitos no Azure DevOps por e-mails de autoria configurados.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

13 Commits

Folders and files

Repository files navigation

Azure DevOps Activity Sync

Tests Sync Azure DevOps activity Version Python Azure DevOps REST API License: MIT Last commit

Automação em Python que registra, em um repositório GitHub privado, os commits feitos no Azure DevOps por e-mails de autoria configurados. Ela consulta todos os projetos, repositórios e branches acessíveis, cria uma linha Markdown para cada commit novo e publica um commit Git no destino por atividade encontrada, datado com o horário do commit original. Dias sem atividade não geram arquivos ou commits artificiais.

O repositório com este código executa o GitHub Actions. Um segundo repositório, separado e privado, guarda os dados:

commit-bridge/                 # código, configuração modelo e workflow
daily-activity/                # exemplo de destino privado
├── activity/2026/10/2026-10-08.md
└── state/synced_commits.json

Cada arquivo diário mostra os commits em uma tabela Markdown:

Data e hora (Brasília) Projeto Repositório Azure Mensagem Hash
2026-10-09 12:30:00 -03:00 Payment API payment-service feat: add invoice validation a1b2c3d4

A data e hora na tabela, a data do arquivo e a data do commit Git de sincronização são as do commit original no Azure, no fuso America/Sao_Paulo. Assim, um commit de junho buscado depois é registrado em junho, no arquivo e no gráfico de contribuições do GitHub. O estado evita duplicatas entre branches e execuções. A mensagem do commit Git de sincronização segue o formato [data/hora] [projeto] [repositório] [mensagem] [hash]. Registros feitos antes dessa regra continuam no arquivo do dia em que foram sincronizados. O reparo manual converte arquivos antigos para tabelas; as mensagens dos commits Git já publicados continuam no histórico original.

Se uma atividade antiga ainda não tiver data/hora ou repositório na linha original, a conversão automática mostrará — nesses campos até a execução do reparo manual com acesso ao Azure.

Requisitos

  • Python 3.12 ou superior e Git para execução local.
  • Acesso de leitura aos projetos e repositórios relevantes no Azure DevOps.
  • Um repositório GitHub para este código e outro privado para as atividades.
  • Autorização da sua organização para exportar nomes de projetos, mensagens e hashes de commits para uma conta GitHub pessoal.

1. Faça um fork e clone o código

Se você quer executar a automação na sua conta, use Fork na página deste repositório no GitHub. O fork será o repositório que executará o workflow. Depois clone o seu fork:

git clone https://github.com/SEU_USUARIO/commit-bridge.git
cd commit-bridge

Se você já possui uma cópia do projeto na sua conta, basta cloná-la; não precisa fazer outro fork. Um clone local, sozinho, não cria um workflow na sua conta GitHub. A disponibilidade do botão Fork para repositórios privados depende das permissões do proprietário.

2. Crie o repositório privado de destino

No GitHub, crie um novo repositório privado para as atividades, por exemplo SEU_USUARIO/daily-activity. Inicialize-o com um README para que tenha uma branch padrão e um commit inicial. Os arquivos activity/ e state/ serão criados pela automação nesse repositório, não no fork do código. O workflow interrompe a execução se o destino não for privado.

3. Crie os tokens de acesso

  1. No Azure DevOps, acesse User settings → Personal access tokens → New Token. Selecione a organização correta, uma validade curta e somente Project and Team (read) e Code (read). Copie o PAT ao criá-lo. Instruções da Microsoft.
  2. No GitHub, acesse Settings → Developer settings → Personal access tokens → Fine-grained tokens. Escolha seu usuário como proprietário, selecione somente o repositório de destino e conceda Contents: Read and write. A permissão Metadata: Read é automática. Copie o token ao criá-lo. Instruções do GitHub.

O GITHUB_TOKEN do workflow pertence ao repositório do código e não substitui o token para acessar um segundo repositório privado.

4. Configure o seu fork no GitHub

No fork do código, abra Settings → Secrets and variables → Actions. Cadastre os valores abaixo em Repository secrets; SYNC_GIT_NAME deve ser criado na aba Variables. Nenhum token deve ser escrito em config.yaml ou enviado em um commit. Como cadastrar secrets.

Tipo Nome Valor de exemplo
Secret AZURE_DEVOPS_PAT PAT do Azure DevOps criado no passo 3
Secret AZURE_DEVOPS_ORGANIZATION minha-organizacao, de dev.azure.com/minha-organizacao
Secret AZURE_AUTHOR_EMAILS eu@empresa.com ou vários e-mails separados por vírgula
Secret ACTIVITY_REPOSITORY SEU_USUARIO/daily-activity
Secret ACTIVITY_REPOSITORY_TOKEN Token GitHub criado no passo 3
Secret SYNC_GIT_EMAIL E-mail associado à sua conta GitHub
Variable SYNC_GIT_NAME Nome que assinará os commits no destino

O config.yaml versionado é um modelo seguro para publicação. Com as listas include: [], a busca cobre todos os projetos, repositórios e branches acessíveis ao PAT; use include e exclude para restringir nomes quando necessário. No Actions, a organização e os e-mails vêm dos secrets e substituem os exemplos do arquivo.

5. Teste e ative a sincronização

  1. Garanta que o workflow esteja na branch padrão do seu fork e que o GitHub Actions esteja habilitado. Em forks de repositórios públicos, workflows agendados começam desabilitados; habilite o workflow antes de esperar a execução automática.
  2. No fork, abra Actions → Sync Azure DevOps activity → Run workflow, marque dry_run: true e execute. Isso testa autenticação e descoberta sem publicar. Por segurança, os logs do Actions não exibem nomes, mensagens, SHAs do Azure nem contagens de atividade.
  3. Para conferir quais commits seriam publicados, use a prévia local descrita abaixo em um ambiente privado. Depois execute o workflow com dry_run: false e confira o repositório de destino. Se não houver commit novo, ele não será modificado.

O agendamento roda a cada hora, no minuto 17 UTC. A consulta normal cobre somente o dia vigente no fuso America/Sao_Paulo, a partir da meia-noite local (lookback_days: 0); aumente esse valor para incluir dias anteriores. Commits feitos pouco antes da meia-noite que só cheguem ao Azure, ou só sejam sincronizados, depois dela ficam fora da janela. Na execução manual, o campo since aceita YYYY-MM-DD em UTC para reprocessar um período mais antigo sem duplicar os commits já registrados; sozinho, ele vai até o momento atual. Para um intervalo fechado, preencha também until (YYYY-MM-DD em UTC, inclusivo), por exemplo since: 2026-06-01 e until: 2026-06-30. until exige since. Localmente, use --since e --until.

Para converter arquivos antigos em tabelas e preencher campos que faltam, execute o workflow manualmente com repair_format: true, deixando dry_run desmarcado e since e until vazios. O reparo consulta no Azure os commits antigos registrados no estado quando precisa de metadados ausentes. Ele não altera o estado de sincronização e cria um único commit de manutenção com autor bot somente se houver arquivos a corrigir. Se algum commit antigo necessário não estiver mais acessível no Azure ou não corresponder ao estado salvo, o reparo falha sem publicar dados incompletos. As mensagens dos commits Git anteriores não são reescritas.

Prévia local detalhada

Clone também o repositório privado de destino, como uma pasta irmã do projeto. Crie uma cópia local da configuração e edite nela a organização e os e-mails:

git clone https://github.com/SEU_USUARIO/daily-activity.git ../daily-activity
python -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
cp config.yaml config.local.yaml
# Edite config.local.yaml; esse arquivo é ignorado pelo Git.
export AZURE_DEVOPS_PAT='SEU_PAT_AZURE'
python -m src.main --config config.local.yaml --destination ../daily-activity --dry-run --show-details

O modo --show-details exibe metadados corporativos no terminal; não o use em um CI público. Uma publicação local também exige GITHUB_COMMIT_EMAIL, GITHUB_COMMIT_NAME, GITHUB_DEFAULT_BRANCH e acesso de push ao remoto do destino.

Como a sincronização evita duplicatas

O cliente usa a API REST 7.1 do Azure DevOps para listar projetos, repositórios, branches e commits, com paginação e retries. O filtro compara author.email; a ordenação usa committer.date. A chave organização:repositório:SHA elimina repetição entre branches. A cada atividade nova, o publicador adiciona a linha Markdown e a chave no estado no mesmo commit Git. Os commits são criados localmente e enviados em lotes de até 100 por push, para que uma busca retroativa grande não dispare centenas de pushes; cada atividade continua sendo um commit separado. Se o push falhar, o log mostra o motivo informado pelo GitHub e o publicador consulta novamente o estado remoto antes de tentar outra vez. Uma execução interrompida pode ser repetida com o mesmo since/until sem duplicar registros.

Commits presentes apenas em branches apagadas antes da busca não são encontrados. Execuções agendadas podem atrasar ou ser descartadas; use since para recuperar commits que ficaram fora da janela padrão. O gráfico do GitHub segue suas regras de atribuição de contribuições, inclusive associação do e-mail do commit à conta.

Antes de publicar o código

O repositório de atividades deve permanecer privado. Revise também o histórico Git e as execuções antigas do Actions antes de tornar o repositório do código público: o histórico e os logs do Actions ficam visíveis. config.local.yaml, .env, tokens e arquivos de atividade não devem entrar no repositório do código.

O workflow Tests roda a suíte a cada push na main e em pull requests. Para rodar os testes localmente:

python -m unittest discover -s tests -v

About

Automação em Python que registra, em um repositório GitHub privado, os commits feitos no Azure DevOps por e-mails de autoria configurados.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages