diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml new file mode 100644 index 0000000..5e09721 --- /dev/null +++ b/.github/workflows/build-and-deploy.yml @@ -0,0 +1,127 @@ +name: Build and Deploy + +on: + release: + types: [published] + +env: + APP_NAME: delta-force-guide-server + IMAGE_REGISTRY: ${{ vars.GITLAB_REGISTRY }} + IMAGE_NAME: ${{ vars.GITLAB_IMAGE_NAME }} + +jobs: + # ================================================================ + # Job 1 — Package: build the JAR with Gradle + # ================================================================ + package: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up JDK 21 (Corretto) + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: corretto + cache: gradle + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Build with Gradle + run: ./gradlew build + + - name: Upload JAR artifact + uses: actions/upload-artifact@v4 + with: + name: app-jar + path: build/libs/delta-force-guide-server-*.jar + retention-days: 1 + + # ================================================================ + # Job 2 — Build & push Docker image to GitHub Container Registry + # ================================================================ + build-and-push: + needs: package + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Download JAR artifact + uses: actions/download-artifact@v4 + with: + name: app-jar + path: build/libs + + - name: Resolve JAR file path + id: jar + run: echo "file=$(ls build/libs/delta-force-guide-server-*.jar | head -1)" >> "$GITHUB_OUTPUT" + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitLab Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.IMAGE_REGISTRY }} + username: ${{ vars.GITLAB_REGISTRY_USER }} + password: ${{ secrets.GITLAB_REGISTRY_PASSWORD }} + + - name: Generate image tags + id: meta + run: | + echo "version=${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT" + echo "latest=${{ env.IMAGE_NAME }}:latest" >> "$GITHUB_OUTPUT" + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + file: Dockerfile.ci + build-args: JAR_FILE=${{ steps.jar.outputs.file }} + push: true + tags: | + ${{ steps.meta.outputs.version }} + ${{ steps.meta.outputs.latest }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # ================================================================ + # Job 3 — Deploy on the target server via SSH + # ================================================================ + deploy: + needs: build-and-push + runs-on: ubuntu-latest + steps: + - name: Deploy via SSH + uses: appleboy/ssh-action@v1.2.0 + with: + host: ${{ secrets.DEPLOY_HOST }} + username: ${{ secrets.DEPLOY_USER }} + key: ${{ secrets.DEPLOY_SSH_KEY }} + script: | + set -e + + echo '=== Pulling image ===' + echo '${{ secrets.GITLAB_REGISTRY_PASSWORD }}' | docker login ${{ env.IMAGE_REGISTRY }} \ + -u ${{ vars.GITLAB_REGISTRY_USER }} --password-stdin + docker pull ${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} + + echo '=== Stopping old container ===' + docker stop ${{ env.APP_NAME }} || true + docker rm ${{ env.APP_NAME }} || true + + echo '=== Starting new container ===' + docker run -d \ + --name ${{ env.APP_NAME }} \ + --restart unless-stopped \ + -p ${DEPLOY_PORT:-8080}:8080 \ + ${{ env.IMAGE_NAME }}:${{ github.event.release.tag_name }} + + echo '=== Cleaning up old images ===' + docker image prune -f + + echo '=== Deployment complete ==='