Skip to content

chore: clean up project structure and update documentation #25

chore: clean up project structure and update documentation

chore: clean up project structure and update documentation #25

Workflow file for this run

name: Main CI/CD Pipeline
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
workflow_dispatch: # 수동 실행 가능
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
contents: write
packages: write
pages: write
id-token: write
concurrency:
group: "main-${{ github.ref }}"
cancel-in-progress: true
jobs:
# 테스트 (PR 시에만 실행)
test:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
cache: true
- name: Download dependencies
run: make deps
- name: Run linter
run: make lint
- name: Run tests
run: go test -v ./...
- name: Build application
run: make build
# Swagger 문서 생성 및 gh-pages 브랜치에 배포
generate-docs:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
cache: true
- name: Install swag
run: go install github.com/swaggo/swag/cmd/swag@latest
- name: Generate Swagger documentation
run: make swagger
- name: Deploy Swagger docs to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs
publish_branch: gh-pages
force_orphan: true
# Docker 아키텍처별 빌드 및 GHCR 푸시
docker:
runs-on: ubuntu-latest
needs: generate-docs
if: github.event_name == 'push'
timeout-minutes: 20
permissions:
contents: read
packages: write
strategy:
matrix:
include:
- arch: amd64
platform: linux/amd64
fail-fast: false
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:buildx-stable-1
network=host
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=tag
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
flavor: |
latest=false
prefix=
suffix=
- name: Build and push Docker image for ${{ matrix.arch }}
uses: docker/build-push-action@v5
with:
context: .
file: docker/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: ${{ matrix.platform }}
cache-from: type=gha,scope=buildx-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=buildx-${{ matrix.arch }}
provenance: false
sbom: false
build-args: |
TARGETOS=linux
TARGETARCH=${{ matrix.arch }}
BUILDKIT_INLINE_CACHE=1
outputs: type=registry
- name: Verify ${{ matrix.arch }} image
run: |
echo "🔍 Verifying ${{ matrix.arch }} image..."
tags=$(echo '${{ steps.meta.outputs.json }}' | jq -r '.tags[]')
for tag in $tags; do
echo "📦 Image: $tag"
docker buildx imagetools inspect "$tag" --format "{{.Manifest.Architecture}}"
done
env:
DOCKER_METADATA_OUTPUT_JSON: ${{ steps.meta.outputs.json }}
- name: Output ${{ matrix.arch }} image details
run: |
echo "🚀 Successfully built and pushed ${{ matrix.arch }} image:"
echo "📦 Registry: ${{ env.REGISTRY }}"
echo "🏷️ Repository: ${{ env.IMAGE_NAME }}"
echo "🏷️ Tags: ${{ steps.meta.outputs.tags }}"
echo "🏗️ Platform: ${{ matrix.platform }}"
echo ""
echo "📋 Usage examples:"
echo " docker pull --platform ${{ matrix.platform }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
echo " docker run --rm -p 9091:9091 ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest"
# 릴리스 노트 생성 (태그 푸시 시)
release:
runs-on: ubuntu-latest
needs: [generate-docs, docker]
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate release notes
id: release-notes
run: |
echo "notes<<EOF" >> $GITHUB_OUTPUT
echo "## 🚀 KubeMigrate Release ${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "### 📦 Multi-Architecture Docker Images" >> $GITHUB_OUTPUT
echo "- **Registry**: \`ghcr.io/${{ env.IMAGE_NAME }}\`" >> $GITHUB_OUTPUT
echo "- **Tags**: \`${{ github.ref_name }}\`, \`latest\`" >> $GITHUB_OUTPUT
echo "- **Platforms**: \`linux/amd64\` (UPX compressed), \`linux/arm64\`" >> $GITHUB_OUTPUT
echo "- **Optimization**: Architecture-specific Dockerfiles for better performance" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "### 📚 Documentation" >> $GITHUB_OUTPUT
echo "- [API Documentation](https://taking.github.io/kubemigrate/)" >> $GITHUB_OUTPUT
echo "- [GitHub Packages](https://github.com/${{ github.repository }}/pkgs/container/kubemigrate)" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "### 🔧 Usage" >> $GITHUB_OUTPUT
echo '```bash' >> $GITHUB_OUTPUT
echo "# Pull multi-arch image" >> $GITHUB_OUTPUT
echo "docker pull ghcr.io/${{ env.IMAGE_NAME }}:${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "# Run container" >> $GITHUB_OUTPUT
echo "docker run --rm -p 9091:9091 ghcr.io/${{ env.IMAGE_NAME }}:${{ github.ref_name }}" >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "# Verify architecture" >> $GITHUB_OUTPUT
echo "docker run --rm ghcr.io/${{ env.IMAGE_NAME }}:${{ github.ref_name }} uname -m" >> $GITHUB_OUTPUT
echo '```' >> $GITHUB_OUTPUT
echo "" >> $GITHUB_OUTPUT
echo "### 🏗️ Build Features" >> $GITHUB_OUTPUT
echo "- ✅ UPX compressed binary (89% size reduction)" >> $GITHUB_OUTPUT
echo "- ✅ Multi-architecture support" >> $GITHUB_OUTPUT
echo "- ✅ GitHub Container Registry (GHCR)" >> $GITHUB_OUTPUT
echo "- ✅ Automatic security scanning" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
release_name: KubeMigrate ${{ github.ref_name }}
body: ${{ steps.release-notes.outputs.notes }}
draft: false
prerelease: false