Merge pull request #121 from 98OO/feature/#120-cd-rolling-deployment #78
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Continuous Deploy | |
| on: | |
| push: | |
| branches: [ "main" ] | |
| workflow_dispatch: | |
| env: | |
| CONTAINER_NAME: colla | |
| IMAGE_NAME: ${{ github.repository }} | |
| HEALTH_CHECK_PATH: ${{ secrets.HEALTH_CHECK_PATH }} | |
| HEALTH_CHECK_RETRIES: 5 | |
| HEALTH_CHECK_RETRY_DELAY: 10 | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build-and-upload: | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| image-tag: ${{ steps.meta.outputs.tags }} | |
| steps: | |
| - name: Checkout PR | |
| uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GH_ACCESS_TOKEN }} | |
| submodules: 'recursive' | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: '17' | |
| distribution: 'corretto' | |
| - name: Build | |
| run: | | |
| chmod +x ./gradlew | |
| ./gradlew build | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Extract metadata (tags, labels) for Docker | |
| id: meta | |
| uses: docker/metadata-action@v4 | |
| with: | |
| images: ghcr.io/${{ env.IMAGE_NAME }} | |
| tags: | | |
| type=sha | |
| - name: Build and push | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| deploy-instance1: | |
| needs: build-and-upload | |
| runs-on: [ self-hosted, instance1 ] | |
| outputs: | |
| instance1-status: ${{ steps.health-check.outputs.status }} | |
| steps: | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pull the Docker image | |
| run: docker pull ${{ needs.build-and-upload.outputs.image-tag }} | |
| - name: Generate health check token | |
| id: generate-token | |
| run: | | |
| echo "::add-mask::${{ env.HEALTH_CHECK_TOKEN }}" | |
| echo "token=${{ env.HEALTH_CHECK_TOKEN }}" >> $GITHUB_OUTPUT | |
| - name: Run the Docker container on Instance 1 | |
| run: | | |
| # Stop and remove existing containers | |
| docker stop ${{ env.CONTAINER_NAME }} || true | |
| docker rm ${{ env.CONTAINER_NAME }} || true | |
| # Remove unused images to free up space | |
| docker image prune -f | |
| # Run new container | |
| docker run -d --name ${{ env.CONTAINER_NAME }} -p 80:8080 -v /home/ubuntu/logs:/logs -e TZ=Asia/Seoul -e HEALTH_CHECK_TOKEN=${{ steps.generate-token.outputs.token }} ${{ needs.build-and-upload.outputs.image-tag }} | |
| - name: Health check for Instance 1 | |
| id: health-check | |
| run: | | |
| # Wait for container to start | |
| sleep 20 | |
| # Perform health check with retries | |
| status="DOWN" | |
| for i in $(seq 1 ${{ env.HEALTH_CHECK_RETRIES }}); do | |
| response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/${{ env.HEALTH_CHECK_PATH }}/health) | |
| if [[ "$response" == "200" ]]; then | |
| status="UP" | |
| break | |
| fi | |
| echo "Health check attempt $i failed, retrying in ${{ env.HEALTH_CHECK_RETRY_DELAY }} seconds..." | |
| sleep ${{ env.HEALTH_CHECK_RETRY_DELAY }} | |
| done | |
| echo "status=$status" >> $GITHUB_OUTPUT | |
| if [[ "$status" != "UP" ]]; then | |
| echo "Instance 1 deployment failed health check after ${{ env.HEALTH_CHECK_RETRIES }} attempts" | |
| exit 1 | |
| fi | |
| echo "Instance 1 successfully deployed and health check passed" | |
| deploy-instance2: | |
| needs: [ build-and-upload, deploy-instance1 ] | |
| runs-on: [ self-hosted, instance2 ] | |
| if: needs.deploy-instance1.outputs.instance1-status == 'UP' | |
| steps: | |
| - name: Login to GitHub Container Registry | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pull the Docker image | |
| run: docker pull ${{ needs.build-and-upload.outputs.image-tag }} | |
| - name: Run the Docker container on Instance 2 | |
| run: | | |
| # Stop and remove existing containers | |
| docker stop ${{ env.CONTAINER_NAME }} || true | |
| docker rm ${{ env.CONTAINER_NAME }} || true | |
| # Remove unused images to free up space | |
| docker image prune -f | |
| # Run new container | |
| docker run -d --name ${{ env.CONTAINER_NAME }} -p 80:8080 -v /home/ubuntu/logs:/logs -e TZ=Asia/Seoul ${{ needs.build-and-upload.outputs.image-tag }} |