From 6f6e4ed19d2fbcccba548eeaf0d9e2624f41afba Mon Sep 17 00:00:00 2001 From: andersonid Date: Thu, 25 Sep 2025 18:34:20 -0300 Subject: [PATCH] Enhance: GitHub Actions with smart tagging, release script, and comprehensive guide --- .github/workflows/build-only.yml | 85 ++++++++++++-- GITHUB-ACTIONS-GUIDE.md | 186 +++++++++++++++++++++++++++++++ scripts/release.sh | 178 +++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 10 deletions(-) create mode 100644 GITHUB-ACTIONS-GUIDE.md create mode 100755 scripts/release.sh diff --git a/.github/workflows/build-only.yml b/.github/workflows/build-only.yml index 918b0a3..6f8211f 100644 --- a/.github/workflows/build-only.yml +++ b/.github/workflows/build-only.yml @@ -1,11 +1,17 @@ -name: Build and Push Image +name: Build and Push Image to Docker Hub on: push: branches: [ main, develop ] + tags: [ 'v*' ] # Build tags como v1.0.0 pull_request: branches: [ main ] workflow_dispatch: + inputs: + tag: + description: 'Custom tag for the image' + required: false + default: 'latest' env: IMAGE_NAME: resource-governance @@ -39,25 +45,84 @@ jobs: run: | echo "${{ secrets.DOCKERHUB_TOKEN }}" | podman login docker.io -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin + - name: Determine image tags + id: tags + run: | + # Determinar tags baseado no trigger + if [[ "${{ github.event_name }}" == "push" && "${{ github.ref }}" == refs/tags/* ]]; then + # Tag release (ex: v1.0.0) + TAG="${{ github.ref_name }}" + LATEST_TAG="latest" + elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ inputs.tag }}" != "" ]]; then + # Manual dispatch com tag customizada + TAG="${{ inputs.tag }}" + LATEST_TAG="latest" + elif [[ "${{ github.ref }}" == refs/heads/main ]]; then + # Branch main + TAG="${{ github.sha }}" + LATEST_TAG="latest" + elif [[ "${{ github.ref }}" == refs/heads/develop ]]; then + # Branch develop + TAG="develop-${{ github.sha }}" + LATEST_TAG="develop" + else + # Pull request ou outros + TAG="${{ github.sha }}" + LATEST_TAG="pr-${{ github.sha }}" + fi + + echo "tag=$TAG" >> $GITHUB_OUTPUT + echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT + echo "image_tag=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$TAG" >> $GITHUB_OUTPUT + echo "latest_image_tag=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$LATEST_TAG" >> $GITHUB_OUTPUT + + echo "🏷️ Tags determinadas:" + echo " Tag: $TAG" + echo " Latest: $LATEST_TAG" + echo " Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$TAG" + echo " Latest Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:$LATEST_TAG" + - name: Build and push image run: | # Build da imagem com cache - podman build --layers -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} . + echo "🔨 Building image: ${{ steps.tags.outputs.image_tag }}" + podman build --layers -t ${{ steps.tags.outputs.image_tag }} . - # Tag como latest - podman tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + # Tag como latest (se aplicável) + if [[ "${{ steps.tags.outputs.latest_tag }}" != "pr-${{ github.sha }}" ]]; then + echo "🏷️ Tagging as latest: ${{ steps.tags.outputs.latest_image_tag }}" + podman tag ${{ steps.tags.outputs.image_tag }} ${{ steps.tags.outputs.latest_image_tag }} + fi # Push das imagens - podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - podman push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + echo "📤 Pushing image: ${{ steps.tags.outputs.image_tag }}" + podman push ${{ steps.tags.outputs.image_tag }} + + if [[ "${{ steps.tags.outputs.latest_tag }}" != "pr-${{ github.sha }}" ]]; then + echo "📤 Pushing latest: ${{ steps.tags.outputs.latest_image_tag }}" + podman push ${{ steps.tags.outputs.latest_image_tag }} + fi - name: Output deployment info run: | echo "🚀 Image built and pushed successfully!" - echo "📦 Image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}" - echo "📦 Latest: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" + echo "📦 Image: ${{ steps.tags.outputs.image_tag }}" + if [[ "${{ steps.tags.outputs.latest_tag }}" != "pr-${{ github.sha }}" ]]; then + echo "📦 Latest: ${{ steps.tags.outputs.latest_image_tag }}" + fi echo "" echo "🔧 To deploy to your OpenShift cluster:" echo "1. Clone this repository" - echo "2. Run: ./deploy-to-cluster.sh ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}" - echo "3. Or use: ./deploy-zero-downtime.sh ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}" + echo "2. Run: ./deploy-to-cluster.sh ${{ steps.tags.outputs.image_tag }}" + echo "3. Or use: ./deploy-zero-downtime.sh ${{ steps.tags.outputs.image_tag }}" + echo "" + echo "🐳 Docker Hub: https://hub.docker.com/r/${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + + - name: Create GitHub Release (for tags) + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + run: | + echo "🏷️ Creating GitHub Release for ${{ github.ref_name }}" + gh release create ${{ github.ref_name }} \ + --title "Release ${{ github.ref_name }}" \ + --notes "OpenShift Resource Governance ${{ github.ref_name }}" \ + --target main diff --git a/GITHUB-ACTIONS-GUIDE.md b/GITHUB-ACTIONS-GUIDE.md new file mode 100644 index 0000000..0f0b4d7 --- /dev/null +++ b/GITHUB-ACTIONS-GUIDE.md @@ -0,0 +1,186 @@ +# 🚀 GitHub Actions - Guia de Uso + +## 📋 Visão Geral + +O GitHub Actions está configurado para **buildar e fazer push automático** da imagem Docker para o Docker Hub sempre que você fizer push para o repositório. + +## 🔧 Configuração Necessária + +### 1. Secrets do GitHub +Certifique-se de que estes secrets estão configurados no repositório: + +- `DOCKERHUB_USERNAME`: Seu usuário do Docker Hub +- `DOCKERHUB_TOKEN`: Token de acesso do Docker Hub + +**Como configurar:** +1. Vá para: `Settings` → `Secrets and variables` → `Actions` +2. Clique em `New repository secret` +3. Adicione os secrets acima + +### 2. Token do Docker Hub +Para criar um token do Docker Hub: +1. Acesse: https://hub.docker.com/settings/security +2. Clique em `New Access Token` +3. Nome: `github-actions` +4. Permissões: `Read, Write, Delete` +5. Copie o token e adicione como `DOCKERHUB_TOKEN` + +## 🚀 Como Usar + +### 1. Build Automático +**Sempre que você fizer push para `main` ou `develop`:** +- ✅ Build automático da imagem +- ✅ Push para Docker Hub +- ✅ Tag `latest` atualizada + +```bash +# Push para main (atualiza latest) +git push origin main + +# Push para develop (atualiza develop) +git push origin develop +``` + +### 2. Releases com Tags +**Para criar uma release:** + +```bash +# Usar o script de release +./scripts/release.sh patch # 1.0.0 -> 1.0.1 +./scripts/release.sh minor # 1.0.0 -> 1.1.0 +./scripts/release.sh major # 1.0.0 -> 2.0.0 +./scripts/release.sh custom 2.0.0-beta.1 + +# Ou criar tag manualmente +git tag v1.0.0 +git push origin v1.0.0 +``` + +### 3. Build Manual +**Para buildar manualmente:** +1. Vá para: `Actions` → `Build and Push Image to Docker Hub` +2. Clique em `Run workflow` +3. Escolha a branch +4. Opcionalmente, defina uma tag customizada +5. Clique em `Run workflow` + +## 📦 Tags Geradas + +### Branch `main` +- `andersonid/resource-governance:latest` (sempre atualizada) +- `andersonid/resource-governance:COMMIT_SHA` (específica do commit) + +### Branch `develop` +- `andersonid/resource-governance:develop` (sempre atualizada) +- `andersonid/resource-governance:develop-COMMIT_SHA` (específica do commit) + +### Tags (ex: v1.0.0) +- `andersonid/resource-governance:v1.0.0` (específica da tag) +- `andersonid/resource-governance:latest` (atualizada) + +### Pull Requests +- `andersonid/resource-governance:pr-COMMIT_SHA` (apenas para teste) + +## 🔍 Monitoramento + +### Verificar Status do Build +```bash +# Listar últimos builds +gh run list --repo andersonid/openshift-resource-governance --workflow="build-only.yml" + +# Ver logs de um build específico +gh run view RUN_ID --repo andersonid/openshift-resource-governance --log + +# Ver status em tempo real +gh run watch --repo andersonid/openshift-resource-governance +``` + +### Verificar Imagens no Docker Hub +- **Docker Hub**: https://hub.docker.com/r/andersonid/resource-governance/tags +- **GitHub Releases**: https://github.com/andersonid/openshift-resource-governance/releases + +## 🛠️ Troubleshooting + +### Build Falhou +1. **Verificar logs:** + ```bash + gh run view RUN_ID --repo andersonid/openshift-resource-governance --log-failed + ``` + +2. **Problemas comuns:** + - **Docker Hub login falhou**: Verificar `DOCKERHUB_TOKEN` + - **Build falhou**: Verificar sintaxe do código Python + - **Push falhou**: Verificar permissões do token + +### Imagem Não Atualizada +1. **Verificar se o build foi concluído:** + ```bash + gh run list --repo andersonid/openshift-resource-governance --workflow="build-only.yml" --status=completed + ``` + +2. **Verificar tags no Docker Hub:** + ```bash + docker pull andersonid/resource-governance:latest + docker inspect andersonid/resource-governance:latest + ``` + +### Rebuild Manual +Se precisar rebuildar uma versão específica: +```bash +# Fazer push vazio para triggerar build +git commit --allow-empty -m "Trigger rebuild" +git push origin main +``` + +## 📊 Workflow Detalhado + +### 1. Trigger +- **Push para main/develop**: Build automático +- **Tag push**: Build + Release +- **Pull Request**: Build para teste +- **Manual dispatch**: Build com tag customizada + +### 2. Build Process +1. **Checkout** do código +2. **Syntax check** do Python +3. **Setup Podman** (Docker alternative) +4. **Login** no Docker Hub +5. **Determine tags** baseado no trigger +6. **Build** da imagem com cache +7. **Tag** da imagem +8. **Push** para Docker Hub +9. **Create release** (se for tag) + +### 3. Output +- **Imagem Docker** disponível no Docker Hub +- **GitHub Release** (se for tag) +- **Logs detalhados** no GitHub Actions + +## 🎯 Melhores Práticas + +### 1. Versionamento +- Use **semantic versioning** (ex: 1.0.0, 1.0.1, 1.1.0) +- Use o script `./scripts/release.sh` para releases +- Teste em `develop` antes de fazer merge para `main` + +### 2. Deploy +- Use `andersonid/resource-governance:latest` para desenvolvimento +- Use `andersonid/resource-governance:v1.0.0` para produção +- Sempre teste a imagem antes de fazer deploy em produção + +### 3. Monitoramento +- Verifique os logs do GitHub Actions regularmente +- Monitore o Docker Hub para verificar se as imagens estão sendo atualizadas +- Use `gh` CLI para monitoramento rápido + +## 🔗 Links Úteis + +- **GitHub Actions**: https://github.com/andersonid/openshift-resource-governance/actions +- **Docker Hub**: https://hub.docker.com/r/andersonid/resource-governance +- **GitHub Releases**: https://github.com/andersonid/openshift-resource-governance/releases +- **Workflow File**: `.github/workflows/build-only.yml` + +--- + +**Desenvolvido por:** Anderson Nobre +**Suporte:** Abra uma issue no GitHub se tiver problemas diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 0000000..7b87a0d --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,178 @@ +#!/bin/bash + +# Script para criar releases e tags do OpenShift Resource Governance + +set -e + +# Cores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Função para mostrar ajuda +show_help() { + echo "🚀 OpenShift Resource Governance - Release Script" + echo "==================================================" + echo "" + echo "Uso: $0 [COMANDO] [VERSÃO]" + echo "" + echo "Comandos:" + echo " patch Criar release patch (ex: 1.0.0 -> 1.0.1)" + echo " minor Criar release minor (ex: 1.0.0 -> 1.1.0)" + echo " major Criar release major (ex: 1.0.0 -> 2.0.0)" + echo " custom Criar release com versão customizada" + echo " list Listar releases existentes" + echo " help Mostrar esta ajuda" + echo "" + echo "Exemplos:" + echo " $0 patch # 1.0.0 -> 1.0.1" + echo " $0 minor # 1.0.0 -> 1.1.0" + echo " $0 custom 2.0.0-beta.1 # Versão customizada" + echo " $0 list # Listar releases" + echo "" +} + +# Função para obter a versão atual +get_current_version() { + local latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0") + echo "${latest_tag#v}" # Remove o 'v' do início +} + +# Função para incrementar versão +increment_version() { + local version=$1 + local type=$2 + + IFS='.' read -ra VERSION_PARTS <<< "$version" + local major=${VERSION_PARTS[0]} + local minor=${VERSION_PARTS[1]} + local patch=${VERSION_PARTS[2]} + + case $type in + "major") + echo "$((major + 1)).0.0" + ;; + "minor") + echo "$major.$((minor + 1)).0" + ;; + "patch") + echo "$major.$minor.$((patch + 1))" + ;; + *) + echo "$version" + ;; + esac +} + +# Função para validar versão +validate_version() { + local version=$1 + if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$ ]]; then + echo -e "${RED}❌ Versão inválida: $version${NC}" + echo "Formato esperado: X.Y.Z ou X.Y.Z-suffix" + exit 1 + fi +} + +# Função para criar release +create_release() { + local version=$1 + local tag="v$version" + + echo -e "${BLUE}🚀 Criando release $tag${NC}" + echo "" + + # Verificar se já existe + if git tag -l | grep -q "^$tag$"; then + echo -e "${RED}❌ Tag $tag já existe!${NC}" + exit 1 + fi + + # Verificar se há mudanças não commitadas + if ! git diff-index --quiet HEAD --; then + echo -e "${YELLOW}⚠️ Há mudanças não commitadas. Deseja continuar? (y/N)${NC}" + read -r response + if [[ ! "$response" =~ ^[Yy]$ ]]; then + echo "Cancelado." + exit 1 + fi + fi + + # Fazer commit das mudanças se houver + if ! git diff-index --quiet HEAD --; then + echo -e "${BLUE}📝 Fazendo commit das mudanças...${NC}" + git add . + git commit -m "Release $tag" + fi + + # Criar tag + echo -e "${BLUE}🏷️ Criando tag $tag...${NC}" + git tag -a "$tag" -m "Release $tag" + + # Push da tag + echo -e "${BLUE}📤 Fazendo push da tag...${NC}" + git push origin "$tag" + + echo "" + echo -e "${GREEN}✅ Release $tag criado com sucesso!${NC}" + echo "" + echo "🔗 Links úteis:" + echo " GitHub: https://github.com/andersonid/openshift-resource-governance/releases/tag/$tag" + echo " Docker Hub: https://hub.docker.com/r/andersonid/resource-governance/tags" + echo "" + echo "🚀 O GitHub Actions irá automaticamente:" + echo " 1. Buildar a imagem Docker" + echo " 2. Fazer push para Docker Hub" + echo " 3. Criar release no GitHub" + echo "" + echo "⏳ Aguarde alguns minutos e verifique:" + echo " gh run list --repo andersonid/openshift-resource-governance --workflow='build-only.yml'" +} + +# Função para listar releases +list_releases() { + echo -e "${BLUE}📋 Releases existentes:${NC}" + echo "" + git tag -l --sort=-version:refname | head -10 + echo "" + echo "💡 Para ver todos: git tag -l --sort=-version:refname" +} + +# Main +case "${1:-help}" in + "patch") + current_version=$(get_current_version) + new_version=$(increment_version "$current_version" "patch") + validate_version "$new_version" + create_release "$new_version" + ;; + "minor") + current_version=$(get_current_version) + new_version=$(increment_version "$current_version" "minor") + validate_version "$new_version" + create_release "$new_version" + ;; + "major") + current_version=$(get_current_version) + new_version=$(increment_version "$current_version" "major") + validate_version "$new_version" + create_release "$new_version" + ;; + "custom") + if [ -z "$2" ]; then + echo -e "${RED}❌ Versão customizada não fornecida!${NC}" + echo "Uso: $0 custom 2.0.0-beta.1" + exit 1 + fi + validate_version "$2" + create_release "$2" + ;; + "list") + list_releases + ;; + "help"|*) + show_help + ;; +esac