|
| 1 | +name: Build and Push Docker Images |
| 2 | + |
| 3 | +on: |
| 4 | + pull_request: |
| 5 | + types: |
| 6 | + - closed |
| 7 | + branches: |
| 8 | + - main |
| 9 | + |
| 10 | +jobs: |
| 11 | + check_version_update: |
| 12 | + name: Check Version Updates |
| 13 | + if: github.event.pull_request.merged |
| 14 | + runs-on: ubuntu-latest |
| 15 | + outputs: |
| 16 | + build_backend: ${{ steps.version_check.outputs.build_backend }} |
| 17 | + build_frontend: ${{ steps.version_check.outputs.build_frontend }} |
| 18 | + backend_version: ${{ steps.version_check.outputs.backend_version }} |
| 19 | + frontend_version: ${{ steps.version_check.outputs.frontend_version }} |
| 20 | + steps: |
| 21 | + - name: Check out the repo |
| 22 | + uses: actions/checkout@v5 |
| 23 | + with: |
| 24 | + fetch-depth: 2 # Need at least 2 commits to compare |
| 25 | + |
| 26 | + - name: Detect version changes |
| 27 | + id: version_check |
| 28 | + run: | |
| 29 | + echo "🔍 Checking for version changes..." |
| 30 | +
|
| 31 | + # Get current commit and previous commit |
| 32 | + CURRENT_COMMIT=$(git rev-parse HEAD) |
| 33 | + # Previous commit refers to the latest commit on main before the PR |
| 34 | + # was merged |
| 35 | + PREVIOUS_COMMIT=$(git rev-parse HEAD~1) |
| 36 | +
|
| 37 | + echo "Current commit: $CURRENT_COMMIT" |
| 38 | + echo "Previous commit: $PREVIOUS_COMMIT" |
| 39 | +
|
| 40 | + # Initialize build flags and version variables |
| 41 | + BUILD_BACKEND=false |
| 42 | + BUILD_FRONTEND=false |
| 43 | + # Extract current versions for backend and frontend |
| 44 | + BACKEND_VERSION=$(grep '^version = ' backend-agent/pyproject.toml | sed "s/version = '\(.*\)'/\1/") |
| 45 | + FRONTEND_VERSION=$(grep '"version":' frontend/package.json | sed 's/.*"version": "\(.*\)".*/\1/') |
| 46 | +
|
| 47 | + # Check if backend version file changed |
| 48 | + if git diff --name-only $PREVIOUS_COMMIT $CURRENT_COMMIT | grep -q 'backend-agent/pyproject.toml'; then |
| 49 | + # Extract previous backend version |
| 50 | + PREVIOUS_BACKEND_VERSION=$(git show $PREVIOUS_COMMIT:backend-agent/pyproject.toml | grep '^version = ' | sed "s/version = '\(.*\)'/\1/") |
| 51 | + echo "Backend version - Current: $BACKEND_VERSION, Previous: $PREVIOUS_BACKEND_VERSION" |
| 52 | +
|
| 53 | + if [ "$BACKEND_VERSION" != "$PREVIOUS_BACKEND_VERSION" ]; then |
| 54 | + # The version has changed, set flag to build backend |
| 55 | + BUILD_BACKEND=true |
| 56 | + echo "✅ Backend version changed: $PREVIOUS_BACKEND_VERSION → $BACKEND_VERSION" |
| 57 | + else |
| 58 | + echo "❎ Backend version unchanged: $BACKEND_VERSION. Skip docker backend." |
| 59 | + fi |
| 60 | + fi |
| 61 | +
|
| 62 | + # Check if frontend version file changed |
| 63 | + if git diff --name-only $PREVIOUS_COMMIT $CURRENT_COMMIT | grep -q 'frontend/package.json'; then |
| 64 | + # Extract previous frontend version |
| 65 | + PREVIOUS_FRONTEND_VERSION=$(git show $PREVIOUS_COMMIT:frontend/package.json | grep '"version":' | sed 's/.*"version": "\(.*\)".*/\1/') |
| 66 | + echo "Frontend version - Current: $FRONTEND_VERSION, Previous: $PREVIOUS_FRONTEND_VERSION" |
| 67 | +
|
| 68 | + if [ "$FRONTEND_VERSION" != "$PREVIOUS_FRONTEND_VERSION" ]; then |
| 69 | + # The version has changed, set flag to build frontend |
| 70 | + BUILD_FRONTEND=true |
| 71 | + echo "✅ Frontend version changed: $PREVIOUS_FRONTEND_VERSION → $FRONTEND_VERSION" |
| 72 | + else |
| 73 | + echo "❎ Frontend version unchanged: $FRONTEND_VERSION. Skip docker frontend." |
| 74 | + fi |
| 75 | + fi |
| 76 | +
|
| 77 | + # Set build outputs |
| 78 | + echo "build_backend=$BUILD_BACKEND" >> $GITHUB_OUTPUT |
| 79 | + echo "build_frontend=$BUILD_FRONTEND" >> $GITHUB_OUTPUT |
| 80 | + echo "backend_version=$BACKEND_VERSION" >> $GITHUB_OUTPUT |
| 81 | + echo "frontend_version=$FRONTEND_VERSION" >> $GITHUB_OUTPUT |
| 82 | +
|
| 83 | + if [ "$BUILD_BACKEND" = "false" ] && [ "$BUILD_FRONTEND" = "false" ]; then |
| 84 | + echo "⚠️ No version changes detected. Skipping builds." |
| 85 | + fi |
| 86 | +
|
| 87 | + build-backend: |
| 88 | + name: Build and Push Backend Docker Image |
| 89 | + if: github.event.pull_request.merged && needs.check_version_update.outputs.build_backend == 'true' |
| 90 | + needs: check_version_update |
| 91 | + runs-on: ubuntu-latest |
| 92 | + steps: |
| 93 | + - name: Check out the repo |
| 94 | + uses: actions/checkout@v5 |
| 95 | + |
| 96 | + - name: Set up Docker Buildx |
| 97 | + uses: docker/setup-buildx-action@v3 |
| 98 | + |
| 99 | + - name: Log in to Docker Registry |
| 100 | + uses: docker/login-action@v3 |
| 101 | + with: |
| 102 | + registry: ${{ secrets.DOCKER_REGISTRY_URL }} |
| 103 | + username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} |
| 104 | + password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} |
| 105 | + |
| 106 | + - name: 🐳 Build and push Backend Docker image |
| 107 | + uses: docker/build-push-action@v6 |
| 108 | + with: |
| 109 | + context: ./backend-agent |
| 110 | + file: ./backend-agent/Dockerfile |
| 111 | + push: true |
| 112 | + tags: | |
| 113 | + ${{ secrets.DOCKER_REGISTRY_URL }}/stars-backend:${{ needs.check_version_update.outputs.backend_version }} |
| 114 | + ${{ secrets.DOCKER_REGISTRY_URL }}/stars-backend:latest |
| 115 | + cache-from: type=gha |
| 116 | + cache-to: type=gha,mode=max |
| 117 | + |
| 118 | + - name: Backend Build Summary |
| 119 | + run: | |
| 120 | + echo "Backend Build Complete" |
| 121 | + echo "✅ Backend: stars-backend:${{ needs.check_version_update.outputs.backend_version }}" |
| 122 | +
|
| 123 | + build-frontend: |
| 124 | + name: Build and Push Frontend Docker Image |
| 125 | + if: github.event.pull_request.merged && needs.check_version_update.outputs.build_frontend == 'true' |
| 126 | + needs: check_version_update |
| 127 | + runs-on: ubuntu-latest |
| 128 | + steps: |
| 129 | + - name: Check out the repo |
| 130 | + uses: actions/checkout@v5 |
| 131 | + |
| 132 | + - name: Set up Node.js for Frontend build |
| 133 | + uses: actions/setup-node@v5 |
| 134 | + with: |
| 135 | + node-version: '24' |
| 136 | + cache: 'npm' |
| 137 | + cache-dependency-path: frontend/package-lock.json |
| 138 | + |
| 139 | + - name: Build Angular application |
| 140 | + run: | |
| 141 | + cd frontend |
| 142 | + npm ci |
| 143 | + npm run build -- --configuration production |
| 144 | + # Verify build output exists |
| 145 | + ls -la dist/ |
| 146 | +
|
| 147 | + - name: Set up Docker Buildx |
| 148 | + uses: docker/setup-buildx-action@v3 |
| 149 | + |
| 150 | + - name: Log in to Docker Registry |
| 151 | + uses: docker/login-action@v3 |
| 152 | + with: |
| 153 | + registry: ${{ secrets.DOCKER_REGISTRY_URL }} |
| 154 | + username: ${{ secrets.DOCKER_REGISTRY_USERNAME }} |
| 155 | + password: ${{ secrets.DOCKER_REGISTRY_TOKEN }} |
| 156 | + |
| 157 | + - name: 🐳 Build and push Frontend Docker image |
| 158 | + uses: docker/build-push-action@v6 |
| 159 | + with: |
| 160 | + context: ./frontend |
| 161 | + file: ./frontend/Dockerfile |
| 162 | + push: true |
| 163 | + tags: | |
| 164 | + ${{ secrets.DOCKER_REGISTRY_URL }}/stars-frontend:${{ needs.check_version_update.outputs.frontend_version }} |
| 165 | + ${{ secrets.DOCKER_REGISTRY_URL }}/stars-frontend:latest |
| 166 | + cache-from: type=gha |
| 167 | + cache-to: type=gha,mode=max |
| 168 | + |
| 169 | + - name: Frontend Build Summary |
| 170 | + run: | |
| 171 | + echo "Frontend Build Complete" |
| 172 | + echo "✅ Frontend: stars-frontend:${{ needs.check_version_update.outputs.frontend_version }}" |
| 173 | +
|
| 174 | + build-summary: |
| 175 | + name: Build Pipeline Summary |
| 176 | + needs: [check_version_update, build-backend, build-frontend] |
| 177 | + runs-on: ubuntu-latest |
| 178 | + # Allow this job to run even if backend or frontend jobs are skipped |
| 179 | + if: always() && github.event.pull_request.merged |
| 180 | + steps: |
| 181 | + - name: Pipeline Summary |
| 182 | + run: | |
| 183 | + echo "STARS Build Pipeline Summary" |
| 184 | + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" |
| 185 | + # Backend |
| 186 | + if [ "${{ needs.check_version_update.outputs.build_backend }}" = "true" ]; then |
| 187 | + if [ "${{ needs.build-backend.result }}" = "success" ]; then |
| 188 | + echo "✅ Backend: stars-backend:${{ needs.check_version_update.outputs.backend_version }}" |
| 189 | + else |
| 190 | + echo "❌ Backend: Build failed" |
| 191 | + fi |
| 192 | + else |
| 193 | + echo "⏭️ (SKIP) Backend: No version change detected" |
| 194 | + fi |
| 195 | + # Frontend |
| 196 | + if [ "${{ needs.check_version_update.outputs.build_frontend }}" = "true" ]; then |
| 197 | + if [ "${{ needs.build-frontend.result }}" = "success" ]; then |
| 198 | + echo "✅ Frontend: stars-frontend:${{ needs.check_version_update.outputs.frontend_version }}" |
| 199 | + else |
| 200 | + echo "❌ Frontend: Build failed" |
| 201 | + fi |
| 202 | + else |
| 203 | + echo "⏭️ (SKIP) Frontend: No version change detected" |
| 204 | + fi |
| 205 | + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" |
0 commit comments