feat: Added PR check CI/CD and image build CI/CD #2
Workflow file for this run
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: PR Check | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| on: | |
| pull_request: | |
| branches: [main, master, develop] | |
| types: [opened, synchronize, reopened] | |
| env: | |
| NODE_VERSION: "22.9.0" | |
| PNPM_VERSION: "10.20.0" | |
| jobs: | |
| lint-and-build: | |
| name: Lint and Build Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| version: ${{ env.PNPM_VERSION }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: "pnpm" | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run linter | |
| run: pnpm run lint | |
| continue-on-error: false | |
| - name: Build project | |
| run: pnpm run build | |
| continue-on-error: false | |
| env: | |
| NEXT_TELEMETRY_DISABLED: 1 | |
| - name: Generate build summary | |
| if: always() | |
| run: | | |
| echo "## 🏗️ Build & Lint Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Build Status" >> $GITHUB_STEP_SUMMARY | |
| echo "| Check | Status |" >> $GITHUB_STEP_SUMMARY | |
| echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" = "success" ]; then | |
| echo "| Lint | ✅ Passed |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Build | ✅ Passed |" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "| Lint | ❌ Failed |" >> $GITHUB_STEP_SUMMARY | |
| echo "| Build | ❌ Failed |" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Details" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Commit**: \`${{ github.event.pull_request.head.sha }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Branch**: \`${{ github.head_ref }}\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- **Author**: @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY | |
| docker-build-test: | |
| name: Docker Build Test | |
| runs-on: ubuntu-latest | |
| needs: lint-and-build | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Extract metadata | |
| id: meta | |
| uses: docker/metadata-action@v5 | |
| with: | |
| images: fullstack-agent | |
| tags: | | |
| type=ref,event=pr | |
| type=sha,prefix=sha- | |
| - name: Build Docker image (AMD64 only for PR) | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: ./Dockerfile | |
| platforms: linux/amd64 | |
| push: false | |
| tags: ${{ steps.meta.outputs.tags }} | |
| labels: ${{ steps.meta.outputs.labels }} | |
| cache-from: type=gha,scope=pr-amd64 | |
| cache-to: type=gha,mode=max,scope=pr-amd64 | |
| provenance: false | |
| sbom: false | |
| - name: Generate Docker build summary | |
| if: always() | |
| run: | | |
| echo "## 🐳 Docker Build Report" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Build Status" >> $GITHUB_STEP_SUMMARY | |
| if [ "${{ job.status }}" = "success" ]; then | |
| echo "- ✅ Docker image build successful" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Platform: \`linux/amd64\`" >> $GITHUB_STEP_SUMMARY | |
| echo "- ✅ Cache optimization enabled" >> $GITHUB_STEP_SUMMARY | |
| else | |
| echo "- ❌ Docker image build failed" >> $GITHUB_STEP_SUMMARY | |
| echo "" >> $GITHUB_STEP_SUMMARY | |
| echo "### Troubleshooting Tips" >> $GITHUB_STEP_SUMMARY | |
| echo "- Check Dockerfile syntax" >> $GITHUB_STEP_SUMMARY | |
| echo "- Verify dependency versions" >> $GITHUB_STEP_SUMMARY | |
| echo "- Review build context" >> $GITHUB_STEP_SUMMARY | |
| fi | |
| pr-comment: | |
| name: Comment PR Results | |
| runs-on: ubuntu-latest | |
| needs: [lint-and-build, docker-build-test] | |
| if: always() | |
| steps: | |
| - name: Comment on PR | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| // Security: Use context object instead of direct template injection to prevent script injection | |
| const lintBuildResult = '${{ needs.lint-and-build.result }}'; | |
| const dockerResult = '${{ needs.docker-build-test.result }}'; | |
| const prNumber = context.payload.pull_request.number; | |
| const commitSha = context.payload.pull_request.head.sha; | |
| const branchName = context.payload.pull_request.head.ref; | |
| let allPassed = lintBuildResult === 'success' && dockerResult === 'success'; | |
| let emoji = allPassed ? '✅' : '❌'; | |
| let status = allPassed ? 'Passed' : 'Failed'; | |
| let body = `## ${emoji} PR Check Results: ${status}\n\n`; | |
| body += `### Build Checks\n\n`; | |
| body += `| Check | Status |\n`; | |
| body += `|-------|--------|\n`; | |
| body += `| Lint & Build | ${lintBuildResult === 'success' ? '✅ Passed' : '❌ Failed'} |\n`; | |
| body += `| Docker Build | ${dockerResult === 'success' ? '✅ Passed' : '❌ Failed'} |\n\n`; | |
| if (allPassed) { | |
| body += `### ✨ Great work!\n\n`; | |
| body += `All checks passed successfully. Your PR is ready for review.\n\n`; | |
| body += `**Details:**\n`; | |
| body += `- ✅ Code quality verified (linting passed)\n`; | |
| body += `- ✅ Build successful\n`; | |
| body += `- ✅ Docker image build verified (linux/amd64)\n`; | |
| } else { | |
| body += `### ⚠️ Action Required\n\n`; | |
| body += `Some checks failed. Please review the errors and update your PR.\n\n`; | |
| if (lintBuildResult !== 'success') { | |
| body += `**Lint/Build Issues:**\n`; | |
| body += `- Check the "Lint and Build Check" job for details\n`; | |
| body += `- Fix linting errors with \`pnpm run lint:fix\`\n`; | |
| body += `- Ensure the project builds locally with \`pnpm run build\`\n\n`; | |
| } | |
| if (dockerResult !== 'success') { | |
| body += `**Docker Build Issues:**\n`; | |
| body += `- Check the "Docker Build Test" job for details\n`; | |
| body += `- Verify Dockerfile changes\n`; | |
| body += `- Test Docker build locally\n\n`; | |
| } | |
| } | |
| body += `**Commit:** \`${commitSha}\`\n`; | |
| body += `**Branch:** \`${branchName}\`\n`; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| }); | |
| const botComment = comments.find(comment => | |
| comment.user.type === 'Bot' && | |
| comment.body.includes('PR Check Results') | |
| ); | |
| if (botComment) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: botComment.id, | |
| body: body | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: prNumber, | |
| body: body | |
| }); | |
| } |