Partilhar: WhatsApp
aulify
UC UC00617 · T. Desenv. Software

Ficha 02 · Workflow profissional, GitHub avançado

Convenções, hooks, Actions, segurança
Versão · Aluno
Tempo · 60 minutos
Cotação · 100 pontos
Aluno(a)
Turma
Data
Objectivos da ficha

Parte I · Convenções

Exercício 1 · Conventional commits (15 pts)

Reescreve estas mensagens de commit seguindo Conventional Commits:

a) "fixed bug in login" b) "added new payment method" c) "updated readme" d) "refactored user model" e) "fixed typos"

Reescrito com Conventional Commits:

a) fix(auth): correct invalid credentials error on login

b) feat(payments): add PayPal payment method

c) docs(readme): update installation section

d) refactor(user): simplify validation logic in User model

e) docs: fix typos throughout codebase

Estrutura:

<type>(<scope>): <subject>

[body]

[footer]

Types principais: - feat: nova funcionalidade. - fix: correcção bug. - docs: documentação. - style: formatação (sem mudança de lógica). - refactor: refactoring (sem mudança funcional). - test: testes. - chore: manutenção (dependencies, build). - perf: melhoria de performance. - build: build system. - ci: CI configuration.

Scope (opcional): - Módulo/área afectada: auth, cart, ui, api, etc. - Coloca entre parêntesis após o type.

Subject: - Imperativo presente: "add" não "added". - Sem ponto final. - Minúsculas. - < 50 caracteres.

Body (opcional, para mudanças complexas): - Explica por que, não o quê (que está no diff). - Linha em branco após subject. - < 72 caracteres por linha.

Footer (opcional): - Closes #123 para fechar issues. - BREAKING CHANGE: ... para incompatibilidades.

Exemplos completos:

feat(auth): add multi-factor authentication

Implement TOTP-based MFA using Google Authenticator.
Users can now enable MFA in their profile settings.
Includes backup codes for recovery.

Closes #234
fix(checkout): correct tax calculation for EU

Tax was being calculated using US rates for EU orders.
Now uses country-specific rates from TaxService.

Affects all orders to EU since v2.1.0.

Fixes #567
BREAKING CHANGE: feat(api): remove deprecated v1 endpoints

All v1 API endpoints have been removed.
Clients must migrate to v2.

Migration guide: docs/migration-v1-to-v2.md

Vantagens:

  1. Histórico legível: scan fácil dos commits.
  2. Changelog automático: ferramentas geram baseado nos types.
  3. Semantic versioning automático:
  4. feat → minor version.
  5. fix → patch version.
  6. BREAKING CHANGE → major version.
  7. Filtrar commits: git log --grep="^feat" mostra só features.
  8. Consistência entre equipa.

Ferramentas: - commitizen (cz commit): assistente interactivo. - commitlint: valida mensagens (em hook). - standard-version / release-please: gera CHANGELOG automaticamente.

Exercício 2 · Branch naming (10 pts)

Sugere nomes apropriados para branches em cada cenário:

a) Adicionar página de perfil de utilizador. b) Corrigir bug onde botão de submit não funciona. c) Actualizar versão do React. d) Refactorizar código de autenticação. e) Adicionar testes para módulo de pagamentos.

Branch Names — Conventional Naming:

a) Página de perfil: - feature/user-profile-page - feature/add-profile-page

b) Bug no submit: - fix/submit-button-broken - fix/issue-123-submit-button (linkando issue) - bugfix/submit-button

c) Update React: - chore/update-react-to-18 - deps/react-18 - chore/upgrade-react

d) Refactor autenticação: - refactor/auth-module - refactor/simplify-auth-flow

e) Tests de pagamentos: - test/add-payment-tests - test/payment-coverage

Convenções:

Prefixos por tipo: - feature/ ou feat/ — nova funcionalidade. - fix/ ou bugfix/ — correcção bug. - chore/ — manutenção. - refactor/ — refactoring. - test/ — testes. - docs/ — documentação. - hotfix/ — correcção urgente em produção. - release/ — preparação de release.

Estrutura: - kebab-case (palavras separadas por hífenes). - descritivo mas conciso. - sem espaços (Git não permite).

Opcionalmente incluir issue number: - fix/123-submit-button - feature/issue-456-user-profile

Para projectos com muitos developers: - <username>/<feature>: - joana/add-login - pedro/fix-cart

Útil para identificar dono visualmente.

Para Jira / similar: - <ticket>/<description>: - JIRA-123/add-login - JIRA-456/fix-cart

Automatiza linking com Jira.

Más práticas a evitar:

temp — vago, esquece-se. ❌ test1, test2 — sem informação. ❌ joana-branch — quem és tu não importa. ❌ bug — qual bug? ❌ WIP — work in progress (use comentário do PR). ❌ Acentos / espaços / caracteres especiais. ❌ Maiúsculas inconsistentes (Feature/Login vs feature/login).

Manutenção:

Parte II · GitHub avançado

Exercício 3 · GitHub Actions (15 pts)

Escreve workflow GitHub Actions para: - Correr testes em cada push e PR. - Testar em Node.js 18 e 20. - Linter (ESLint). - Build do projecto.

GitHub Actions Workflow — CI

Ficheiro: .github/workflows/ci.yml

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  test:
    name: Test on Node ${{ matrix.node-version }}
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18, 20]
      fail-fast: false

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test -- --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
        if: matrix.node-version == 20

  build:
    name: Build
    runs-on: ubuntu-latest
    needs: test

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build project
        run: npm run build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-output
          path: dist/
          retention-days: 7

Explicação:

name: nome do workflow visível na UI.

on: - push: corre quando alguém faz push. - pull_request: corre quando PR é aberto/actualizado. - branches: filtra quais branches triggerem.

jobs: trabalhos paralelos.

test job: - strategy.matrix: corre N versões em paralelo. - Node 18 e 20: testa em ambas. - fail-fast: false: não cancela todos se um falhar.

Steps: 1. Checkout: clona código. 2. Setup Node: instala versão específica. 3. Cache: poupa tempo em runs seguintes. 4. npm ci: install com lockfile (reproduzível). 5. Lint: ESLint. 6. Test: corre testes com cobertura. 7. Upload coverage: Codecov para visualização.

build job: - needs: test: só corre se test passar. - Build final. - Upload artifacts: build files acessíveis no UI.

Outros workflows úteis:

Deploy automático (em merge para main):

name: Deploy to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm run build
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}
          vercel-args: '--prod'

Dependabot updates auto-merge:

name: Dependabot Auto-Merge

on: pull_request

jobs:
  dependabot:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - uses: dependabot/fetch-metadata@v1
        id: meta
      - name: Auto-merge patch updates
        if: steps.meta.outputs.update-type == 'version-update:semver-patch'
        run: gh pr merge --auto --merge "$PR_URL"
        env:
          PR_URL: ${{ github.event.pull_request.html_url }}
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Security scan:

name: Security Scan

on:
  push:
    branches: [main]
  schedule:
    - cron: '0 0 * * 0'  # Weekly

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Snyk
        uses: snyk/actions/node@master
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Custos: - Repos públicos: ilimitado, grátis. - Repos privados: 2000 min/mês grátis (depois 0.008$/min Linux).

Marketplace: github.com/marketplace?type=actions — milhares de actions prontos.

Boas práticas: - Cache sempre que possível. - Matrix para múltiplas versões. - Secrets em GitHub Secrets, nunca no código. - Reusable workflows para DRY. - Manual triggers com workflow_dispatch se útil.

Resultado: - Cada PR mostra status dos checks. - Bloqueia merge se falhar. - Garante qualidade. - Reduz bugs em produção.

Exercício 4 · Issues e Projects (10 pts)

Como usar GitHub Issues + Projects para gerir projecto de software?

Gestão de Projecto — GitHub Issues + Projects

Issues:

O que são: unidade de trabalho rastreável (bug, feature, task).

Estrutura típica:

Título: - Descritivo, conciso. - "Login button not working on Safari" (não "bug").

Description: - Contexto. - Steps to reproduce (para bugs). - Expected vs actual behavior. - Screenshots.

Labels: - bug, feature, documentation. - priority: high/medium/low. - status: in-progress/blocked. - good first issue (para contribuidores externos).

Assignees: quem trabalha.

Milestone: agrupar para release.

Linked PRs: PRs que resolvem este issue.

Templates de issues:

.github/ISSUE_TEMPLATE/bug_report.md:

---
name: Bug report
about: Create a report to help us improve
labels: bug
---

## Describe the bug

A clear description.

## To Reproduce

Steps to reproduce:
1. Go to '...'
2. Click on '...'
3. See error

## Expected behavior

What you expected.

## Screenshots

If applicable.

## Environment

- OS: [e.g. iOS 15]
- Browser: [e.g. Chrome 98]
- Version: [e.g. 2.4.1]

.github/ISSUE_TEMPLATE/feature_request.md:

---
name: Feature request
about: Suggest an idea
labels: enhancement
---

## Is your feature request related to a problem?

A description of the problem.

## Describe the solution

What you want to happen.

## Alternatives considered

Other solutions you've thought about.

## Additional context

Any other context or screenshots.

Projects (GitHub Projects v2):

O que é: kanban / table view para organizar issues e PRs.

Setup:

  1. Profile/OrgProjectsNew project.
  2. Template: Board (kanban), Table, Roadmap.

Estrutura típica:

Colunas (Kanban): - 📋 Backlog: ideias futuras. - 🎯 To Do: priorizado para próximo. - 🔄 In Progress: a trabalhar agora. - 👀 In Review: aguardar code review. - ✅ Done: concluído.

Fields customizáveis: - Priority (Low / Medium / High / Critical). - Estimate (story points: 1, 2, 3, 5, 8, 13). - Sprint (Sprint 23, 24, 25). - Type (Bug / Feature / Task). - Assignee.

Views múltiplos: - Board view: kanban visual. - Table view: tabela com filtros. - Roadmap view: timeline (Gantt-like).

Automatizações: - Quando PR aberto → mover para "In Review". - Quando PR merged → mover para "Done". - Quando issue closed → mover para "Done".


Workflow exemplo — Equipa Scrum:

Início do sprint: 1. Refinement: equipa revê backlog. 2. Priorizar: top issues priorizadas. 3. Estimate: story points. 4. Sprint planning: mover issues para "Sprint X".

Durante sprint: 1. Daily: olhar board, mover cards. 2. Trabalhar: - Pegar issue de "To Do" → "In Progress". - Atribuir a si próprio. - Criar branch: feature/issue-123-add-x. - Trabalhar, commitar. - Abrir PR linkando issue (Closes #123). - Issue automaticamente vai para "In Review". 3. Code review: - Reviewer aprova. - Merge. - Issue auto-fecha (devido a "Closes #123"). - Vai para "Done".

Fim de sprint: 1. Sprint review: demo das features. 2. Retrospective: análise. 3. Próximo sprint.


Labels strategy:

Por tipo: - bug (vermelho). - enhancement / feature (verde). - documentation (azul). - question (roxo).

Por prioridade: - priority: critical (vermelho escuro). - priority: high (laranja). - priority: medium (amarelo). - priority: low (cinza).

Por status: - status: blocked (vermelho). - status: needs-info (amarelo). - status: ready (verde).

Por área: - area: frontend. - area: backend. - area: design.

Especiais: - good first issue (atrair contribuidores). - help wanted. - wontfix. - duplicate.


Milestones:

Para releases: - v1.0.0: features para release 1.0. - v1.1.0: próxima minor. - v2.0.0: próxima major.

Para sprints: - Sprint 23 (2-2 weeks).

Para iniciativas: - Q1 2026 Goals. - Mobile App Launch.


Boas práticas:

1 issue por unidade de trabalho (não juntar 3 bugs num). ✅ Linkar PRs a issues (Closes #123). ✅ Atualizar status (mover cards). ✅ Comentar progresso em issues grandes. ✅ Fechar issues quando feitos.

❌ Issues vagas ("fix things"). ❌ Issues que ninguém vê (não atribuídos, sem labels). ❌ Issues abandonadas (rever periodicamente).


Para projectos open-source:


Integrações úteis:

GitHub CLI:

# Criar issue
gh issue create --title "Bug X" --body "..."

# Listar
gh issue list

# Ver
gh issue view 123

# Comentar
gh issue comment 123 --body "..."

# Fechar
gh issue close 123

Muito mais rápido que UI web.


Resultado:

GitHub Issues + Projects = ferramenta poderosa e gratuita para gestão de projecto, especialmente para equipas tech. Substitui Jira, Trello para muitos casos.

Parte III · Segurança

Exercício 5 · Secrets (15 pts)

Acidentalmente commitaste API key num ficheiro .env. O que fazer?

Recuperação — API Key Commitada Acidentalmente

⚠️ ATENÇÃO: secret commitada é comprometida, mesmo que apagas depois. Histórico Git mantém-na.

Passo 1 — REVOGAR API key imediatamente (máxima prioridade):

Ir ao serviço (AWS, Stripe, Google, etc.): 1. Settings → API keys. 2. Revoke / Delete a chave compromised. 3. Generate new key.

Tempo: 5 minutos. Crítico.

Por que primeiro: - Bot scrapers fazem scan de GitHub procurando keys 24/7. - Em horas, key pode ser usada para activities maliciosas (mining crypto, spam, etc.). - Custo pode acumular rapidamente (AWS bills de milhares por uso fraudulento).

Passo 2 — Adicionar .env ao .gitignore:

echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: add .env to gitignore"

Passo 3 — Remover .env do tracking:

git rm --cached .env
git commit -m "chore: remove .env from tracking"
git push

--cached remove do Git mas mantém o ficheiro localmente.

Passo 4 — Limpar histórico (key continua no histórico até aqui):

Opção A — BFG Repo-Cleaner (mais fácil):

# Instalar BFG (Java required)
brew install bfg  # Mac
# Ou download de github.com/rtyley/bfg-repo-cleaner

# Backup do repo
git clone --mirror git@github.com:user/repo.git
cd repo.git

# Substituir texto sensível por marcador
echo "OLD_API_KEY==>REDACTED" > replacements.txt
bfg --replace-text replacements.txt

# Limpeza
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# Force push
git push --force

Opção B — git filter-branch (built-in, mais complexo):

git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch .env" \
  --prune-empty --tag-name-filter cat -- --all

# Cleanup
git reflog expire --expire=now --all
git gc --prune=now --aggressive

# Force push
git push --force --all
git push --force --tags

Opção C — git filter-repo (recomendado moderno):

# Instalar
brew install git-filter-repo

# Remover ficheiro do histórico
git filter-repo --invert-paths --path .env

# Force push
git remote add origin git@github.com:user/repo.git  # re-add se necessário
git push --force --all

⚠️ AVISOS:

Passo 5 — Comunicar à equipa:

Subject: ⚠️ Force push needed  please re-clone repo

Hi team,

I accidentally committed an API key. I'm rewriting Git history to remove it.

What you need to do:

1. Save any uncommitted work to a temporary location.
2. Delete your local copy of the repo.
3. Re-clone: git clone git@github.com:org/repo.git
4. Resume work.

I'll force-push in 15 minutes. Please confirm when ready.

The compromised key has been revoked. New key is in 1Password.

Sorry for the inconvenience!
João

Passo 6 — Audit (verificar uso fraudulento):

Procurar: - Calls de IPs desconhecidos. - Uso fora do normal. - Custos inesperados.

Se houve uso fraudulento: - Reportar ao provider (podem reverter charges). - Documentar para legal/security team.

Passo 7 — Adicionar prevenção:

Git hooks (pre-commit):

# Usar pre-commit framework
brew install pre-commit
cd repo
echo "
repos:
  - repo: https://github.com/Yelp/detect-secrets
    rev: v1.4.0
    hooks:
      - id: detect-secrets
" > .pre-commit-config.yaml

pre-commit install

Agora cada commit é scanned para secrets.

GitGuardian / Snyk: - Serviços que monitorizam repos para secrets exposed. - Free tier para individuals. - Alertas em tempo real.

Boa prática: - .env.example (commitable) com variáveis listadas mas valores em branco. - .env (não commitable) com valores reais.

.env.example:

DATABASE_URL=
API_KEY=
SECRET_KEY=

.env (local, não commitado):

DATABASE_URL=postgres://user:pass@localhost:5432/db
API_KEY=sk-1234567890abcdef
SECRET_KEY=my-secret-here

Lições aprendidas:

  1. Antes de cada commit, verificar git status para confirmar o que está a ser commitado.
  2. .env ao .gitignore desde o primeiro commit.
  3. Hooks pre-commit automatizam prevenção.
  4. Secrets managers (1Password, HashiCorp Vault) em vez de ficheiros locais.
  5. Educação contínua da equipa.

Custos potenciais sem revogar rapidamente:

Tempo é crítico. Revogar primeiro, limpar depois.


Resumo:

  1. ⚠️ Revogar key (5 min).
  2. .gitignore + remove tracking (2 min).
  3. Limpar histórico (BFG, 15 min).
  4. Force push + avisar equipa (10 min).
  5. Audit uso fraudulento.
  6. Implementar prevenção.

Total: ~30 min de trabalho, mas poupa potencial desastre.

Exercício 6 · 2FA + SSH (10 pts)

Como configurar GitHub para máxima segurança?

Segurança Máxima no GitHub

1. Password forte: - Mínimo 16 caracteres. - Misto de letras (maiús + minus), números, símbolos. - Único (não usado noutros sites). - Password manager (1Password, Bitwarden) gera + guarda.

2. Autenticação Dois Factores (2FA) — OBRIGATÓRIO desde 2023:

Opção A — TOTP (recomendado): - App: Google Authenticator, Authy, 1Password. - Settings → Password and authentication → Two-factor authentication. - Scan QR code com app. - Guardar recovery codes (offline, em local seguro).

Opção B — Security key (mais seguro): - YubiKey ou similar. - Hardware physical. - Imune a phishing.

Opção C — Passkeys (moderno): - Biometria do device (Touch ID, Face ID). - Sem password.

Não usar SMS (vulnerável a SIM-swap).

3. SSH key authentication:

Setup (já visto, recap):

# Gerar
ssh-keygen -t ed25519 -C "email@example.com"

# Adicionar ao agent
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Copiar pública
cat ~/.ssh/id_ed25519.pub | pbcopy  # Mac
cat ~/.ssh/id_ed25519.pub | xclip   # Linux

# No GitHub: Settings → SSH and GPG keys → New SSH key

# Testar
ssh -T git@github.com

Vantagens vs HTTPS + token: - Sem password a cada push. - Cifragem forte (ed25519 melhor que RSA). - Auditable: ver onde a chave foi usada.

4. GPG signing commits:

Verificar autoria dos commits:

# Gerar chave GPG
gpg --full-generate-key

# Listar
gpg --list-secret-keys --keyid-format LONG

# Copiar (formato armor)
gpg --armor --export YOUR_KEY_ID

# Adicionar ao GitHub: Settings → SSH and GPG keys → New GPG key

# Configurar Git para usar
git config --global user.signingkey YOUR_KEY_ID
git config --global commit.gpgsign true

Commits aparecem "Verified" no GitHub.

5. Revisão de SSH keys:

Periodicamente: - Settings → SSH keys: ver lista de chaves. - Remover chaves de devices antigos / vendidos. - Datas de criação visíveis.

6. Sessions activas:

7. Authorized applications:

8. Notifications de security:

9. Repos com proteções:

Para cada repo importante:

Branch protection rules (main): - Settings → Branches → Add rule. - Require pull request reviews (1+ approvers). - Require status checks to pass. - Require conversation resolution. - Require signed commits (se usar GPG). - No force pushes. - No deletions.

10. Dependabot:

11. Secret scanning:

12. Code scanning (GitHub Advanced Security):

13. Recovery codes:

Ao activar 2FA, GitHub gera 10 recovery codes.

Guardar: - Imprimir e guardar em local seguro. - Password manager (encriptado). - Não em ficheiro plain text no PC.

Cada código usado uma vez. Se perderes 2FA device, podes recuperar conta.

14. Audit log (organizações):

15. IP allowlist (Enterprise):


Checklist mensal de segurança:


Se conta comprometida:

  1. Mudar password imediatamente.
  2. Reset 2FA se necessário.
  3. Rever SSH keys e remover suspeitas.
  4. Audit log para ver actividade.
  5. Contactar GitHub Support (suporte@github.com).
  6. Notificar colaboradores se org affected.

Princípio: defense in depth. Múltiplas camadas de segurança protegem mesmo se uma falha.

Parte IV · Workflow

Exercício 7 · Resolver problema (15 pts)

Trabalhas numa equipa de 5. Há semanas que estás a fazer commits directamente para main, sem PRs. Várias vezes quebrou o build de outros. Como melhorar workflow?

Implementar Workflow Profissional na Equipa

Diagnóstico:

Problemas actuais: - Sem branches → conflitos directos. - Sem PRs → sem code review. - Sem CI → builds quebrados não detectados. - Sem testes obrigatórios → bugs em produção. - Sem proteções → main é instável.

Resultado: equipa pisa-se mutuamente, qualidade baixa, frustração alta.


Plano de implementação (4-6 semanas):

Semana 1 — Educação + planeamento:

Reunião de equipa (1h): - Apresentar problemas (com dados: quantas vezes build quebrou, etc.). - Propor nova abordagem (GitHub Flow). - Discutir benefícios. - Obter buy-in da equipa (essencial — sem isto, falha).

Decisões a tomar: - Branching strategy: GitHub Flow (mais simples) ou Git Flow (mais formal)? - PR requirements: 1 ou 2 approvers? - Tests obrigatórios? - Merge strategy: squash, merge commit, rebase?

Conventional commits: adoptar?

Semana 2 — Setup técnico:

1. Configurar branch protection rules no GitHub:

Para main: - ☑ Require pull request reviews (1 approver mínimo). - ☑ Dismiss stale reviews when new commits pushed. - ☑ Require status checks to pass. - ☑ Require branches to be up to date. - ☑ Require conversation resolution. - ☑ Include administrators (todos seguem regras, incluindo chefes). - ☐ Restrict who can push (apenas via PR).

2. Setup CI básico:

.github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm test
      - run: npm run build

3. PR template:

.github/pull_request_template.md:

## Description

[What does this PR do?]

## Type

- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation

## Testing

[How was this tested?]

## Checklist

- [ ] Tests added
- [ ] Documentation updated
- [ ] Self-review done

4. Code owners (opcional):

.github/CODEOWNERS:

# Auto-assign reviewers based on files

/frontend/    @joana @pedro
/backend/     @pedro @maria
/docs/        @ana

Semana 3 — Workshop + começar:

Workshop hands-on (2h): - Demo do novo workflow. - Cada um clona repo, cria branch, faz PR exemplo. - Resolver dúvidas. - Documento de referência (cheat sheet).

Documento WORKFLOW.md no repo:

# Team Workflow

## Daily flow

1. `git checkout main && git pull`
2. `git checkout -b feature/your-feature`
3. Work, commit (use conventional commits)
4. `git push -u origin feature/your-feature`
5. Open PR on GitHub
6. Address review comments
7. Merge when approved + CI green

## PR rules

- Small (< 400 lines)
- Clear description
- Tests included
- 1 reviewer minimum

## Commit messages

Use conventional commits:
- feat: new feature
- fix: bug fix
- docs: documentation
- chore: maintenance

Começar com workflow novo: - A partir de Segunda, todas mudanças via PR. - Sem excepções (excepto hotfix emergência, com regra clara).

Semana 4-6 — Adopção + ajustes:

Suporte: - Programador sénior disponível para ajudar com PRs. - Pair programming nos primeiros PRs. - Code review pedagógico (explicar por que mudanças sugeridas).

Retrospectiva semanal (curta, 30 min): - O que está a funcionar? - O que é frustrante? - Como ajustar?

Ajustes comuns: - Se PRs demoram demais para review: definir SLA (ex: < 24h). - Se PRs ficam grandes: educar para PRs pequenos. - Se conflitos persistem: melhor coordenação.

Métricas a monitorizar:

Métrica Antes 4 semanas 8 semanas
Builds quebrados / semana 3-4 1 0
Bugs em produção 5/sprint 3/sprint 1/sprint
Tempo de review (média) N/A 8h 4h
PRs merged / semana N/A 15 25
Conflitos / semana 4-5 2 1

Desafios comuns e como gerir:

Desafio 1 — "Isto é mais lento":

Resposta: - Sim, individualmente pode parecer. - Mas equipa como um todo é mais rápida (menos bugs, menos retrabalho). - Builds quebrados que afectam todos custam mais que tempo de PR.

Mostrar com dados após 4 semanas.

Desafio 2 — "Tenho hotfix urgente":

Definir processo de hotfix: - Branch hotfix/<descrição> direto de main. - PR ainda obrigatório, mas review pode ser expedito (15 min). - 1 approver suficiente. - Merge → deploy imediato. - Outras mudanças aguardam.

Desafio 3 — "Não sei fazer code review":

Formação: - Sessão sobre code review (1h). - Materiais: artigos, vídeos. - Pair review nos primeiros (sénior + júnior).

Desafio 4 — "Tests demoram":

Optimizar CI: - Cache de dependencies. - Tests em paralelo. - Skip tests irrelevantes ao PR. - Targets: < 5 min para CI total.

Desafio 5 — "Conflito constante no main":


Sucessos a celebrar:


Long-term evolution:

3 meses depois: - Adicionar integration tests ao CI. - Code coverage mínimo. - Security scanning. - Performance benchmarks.

6 meses depois: - Continuous deployment (auto-deploy de main). - Feature flags para releases controladas. - Monitoring + alertas.

1 ano: - Equipa madura. - DORA metrics monitorizadas. - High-performing team.


Cultura:

A componente mais importante:

Tolerância a erros (todos cometem). ✅ Aprendizagem contínua. ✅ Respeito mútuo em code reviews. ✅ Celebrar pequenas vitórias. ✅ Iteração constante (workflow evolui).

Não punir quem comete erro de workflow. ❌ Não tornar PRs em ataques pessoais. ❌ Não desistir se primeira semana é difícil.


Resultado esperado:

Em 2-3 meses: - Builds estáveis. - Menos bugs em produção. - Equipa colabora melhor. - Cada um aprende com os outros (code reviews). - Mais confiança em pushes. - Onboarding de novos developers facilitado (workflow documentado).

Investimento inicial paga-se em semanas.

Exercício 8 · Projecto prático (10 pts)

Cria pequeno projecto demo em GitHub para mostrar competências Git/GitHub no teu portfolio:

Projecto Portfolio — Demo Git/GitHub Skills

Conceito: pequena app (calculator, todo list, etc.) bem-feita demonstrando boas práticas Git/GitHub.

Stack sugerida (escolher conforme tua stack): - Frontend: HTML + CSS + JavaScript / React / Vue. - Backend: Node.js + Express / Python + Flask. - DB (se aplicável): SQLite / PostgreSQL.

Estrutura do repo:

my-portfolio-project/
├── .github/
   ├── workflows/
      ├── ci.yml
      └── deploy.yml
   ├── ISSUE_TEMPLATE/
      ├── bug_report.md
      └── feature_request.md
   ├── pull_request_template.md
   └── CODEOWNERS
├── src/
   ├── components/
   ├── utils/
   └── index.js
├── tests/
   └── unit/
├── docs/
   ├── architecture.md
   └── api.md
├── .gitignore
├── .env.example
├── package.json
├── README.md
├── CONTRIBUTING.md
├── LICENSE
├── CHANGELOG.md
└── CODE_OF_CONDUCT.md

Elementos essenciais a demonstrar:

1. README impecável:

# Awesome Calculator

[![CI](badge)] [![Coverage](badge)] [![License: MIT](badge)]

Modern calculator app with history, themes, and keyboard shortcuts.

![Demo GIF](docs/demo.gif)

## Features

- ✅ Basic arithmetic
- ✅ Scientific functions (sin, cos, sqrt, etc.)
- ✅ History (last 100 operations)
- ✅ Light/Dark theme
- ✅ Keyboard shortcuts
- ✅ Mobile responsive

## Live Demo

[awesome-calculator.vercel.app](https://example.com)

## Quick Start

```bash
git clone https://github.com/user/awesome-calculator.git
cd awesome-calculator
npm install
npm run dev

Tech Stack

Documentation

License

MIT — see LICENSE

Author

João Silva — @joaosilva

**2. Convenção de commits**:

Histórico mostra:

feat(calc): add scientific functions feat(ui): implement dark theme fix(calc): correct floating point precision docs(readme): update installation steps test(calc): add tests for division by zero chore: bump dependencies

Reviewer / employer pode ver: sabes convencional commits.

**3. Branches e PRs**:

Mesmo trabalhando sozinho:
- Cada feature em branch.
- PRs com descrição.
- Self-merge (justificado em projecto solo).

Mostra: conheces o workflow profissional.

**4. CI/CD**:

`.github/workflows/ci.yml` corre em cada push:
- Linter.
- Tests.
- Build.

Badge no README mostra status.

**5. Tests**:

Cobertura > 80%:
```javascript
// tests/calculator.test.js
import { describe, it, expect } from 'vitest';
import { Calculator } from '../src/calculator';

describe('Calculator', () => {
  it('should add two numbers', () => {
    expect(new Calculator().add(2, 3)).toBe(5);
  });

  it('should handle division by zero', () => {
    expect(() => new Calculator().divide(10, 0))
      .toThrow('Cannot divide by zero');
  });
});

6. Documentação:

7. Issues:

Algumas issues abertas/fechadas mostrando: - Features planeadas. - Bugs resolvidos com PRs linkados. - Labels usados.

8. Releases:

git tag -a v1.0.0 -m "Initial release"
git push --tags

GitHub mostra release com: - Notas detalhadas. - Assets (downloadable). - Changelog.

9. License:

LICENSE file com MIT (ou outra apropriada).

10. Deploy:

App publicada em: - Vercel (frontend). - Netlify (frontend). - Heroku / Railway / Render (full-stack). - GitHub Pages (static).

Link no README + repo description.


Diferenciadores extras (para impressionar):

Pre-commit hooks (Husky):

// package.json
"husky": {
  "hooks": {
    "pre-commit": "npm test && npm run lint",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}

Conventional commits enforcement: - commitlint config.

Dependabot configurado: - .github/dependabot.yml.

Security policy: - SECURITY.md explicando como reportar vulnerabilidades.

Code of Conduct: - CODE_OF_CONDUCT.md.

Funding: - .github/FUNDING.yml (links para sponsors).

Templates profissionais para issues e PRs.

Storybook (UI components).

Live preview deploys (Vercel para cada PR).


Tempo investido:

Retorno:


Tópicos para o projecto:

Ideias que mostram skills:

Escolher algo que gostes — vais investir tempo.


Apresentação no CV:

Personal Projects
─────────────────

Awesome Calculator (2026)
  React, TypeScript, Vitest
  github.com/user/awesome-calculator
  Live: awesome-calculator.vercel.app

  - Implemented from scratch in React + TypeScript
  - 95% test coverage with Vitest
  - CI/CD pipeline with GitHub Actions
  - Conventional commits, branching strategy
  - Comprehensive documentation

Princípio fundamental:

Quality > Quantity.

1 projecto excelente > 10 projectos medíocres.

Mostra: - Sabes fazer Git/GitHub profissionalmente. - Disciplina. - Atenção a detalhes. - Pensamento estruturado.

Estas são exactamente as qualidades que employers procuram em developers.