feat: improve docker build #1
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: Build, Test and Push Docker Image | ||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| build-args: | ||
| description: "Docker build arguments (multiline format: KEY1=value1\nKEY2=value2)" | ||
| default: "" | ||
| type: string | ||
| image-name: | ||
| description: "Name of Docker Image" | ||
| type: string | ||
| required: true | ||
| image-tag: | ||
| description: "Tag of Docker Image" | ||
| default: "latest" | ||
| type: string | ||
| dockerfile: | ||
| description: "Path to Dockerfile" | ||
| default: "Dockerfile" | ||
| type: string | ||
| context: | ||
| description: "Path to Docker Build Context" | ||
| default: "." | ||
| type: string | ||
| registry: | ||
| description: "Docker Registry" | ||
| default: "docker.io" | ||
| type: string | ||
| push: | ||
| description: "Push Docker Image to Registry" | ||
| default: false | ||
| type: boolean | ||
| security-scan: | ||
| description: "Enable Trivy Security Scan" | ||
| default: true | ||
| type: boolean | ||
| security-report: | ||
| description: 'Security Report Mode (`"sarif"` | `"comment"`; ignored if `security-scan: false`)' | ||
| default: "sarif" | ||
| type: string | ||
| hadolint: | ||
| description: "Enable Hadolint" | ||
| default: true | ||
| type: boolean | ||
| platforms: | ||
| description: "Build platforms" | ||
| default: "linux/amd64,linux/arm64" | ||
| type: string | ||
| secrets: | ||
| username: | ||
| required: false | ||
| password: | ||
| required: false | ||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout Repository | ||
| uses: actions/checkout@v4 | ||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
| - name: Set up QEMU | ||
| uses: docker/setup-qemu-action@v3 | ||
| - name: Login to Docker Hub | ||
| if: ${{ inputs.push }} | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ${{ inputs.registry }} | ||
| username: ${{ secrets.username }} | ||
| password: ${{ secrets.password }} | ||
| - name: Build Docker Image | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| build-args: ${{ inputs.build-args }} | ||
| context: ${{ inputs.context }} | ||
| file: ${{ inputs.dockerfile }} | ||
| platforms: linux/amd64 # Build single platform for security scanning | ||
| push: false # Don't push yet, wait for security checks | ||
| tags: ${{ inputs.image-name }}:${{ inputs.image-tag }} | ||
| outputs: type=docker,dest=vuln-image.tar # Export as tarball for security scanning | ||
| - name: Run Trivy vulnerability scanner | ||
| id: trivy | ||
| if: ${{ inputs.security-scan }} | ||
| uses: aquasecurity/trivy-action@0.29.0 | ||
| with: | ||
| input: vuln-image.tar | ||
| format: ${{ (inputs.security-report == 'sarif' && 'sarif') || 'table' }} | ||
| ignore-unfixed: true | ||
| vuln-type: "os,library" | ||
| severity: "CRITICAL,HIGH" | ||
| hide-progress: true | ||
| output: ${{ (inputs.security-report == 'sarif' && 'trivy-results.sarif') || 'trivy.txt' }} | ||
| - name: Read Trivy report file | ||
| id: read_trivy | ||
| if: github.event_name == 'pull_request' && inputs.security-scan && inputs.security-report == 'comment' | ||
| run: | | ||
| echo "report<<EOF" >> "$GITHUB_OUTPUT" | ||
| cat trivy.txt >> "$GITHUB_OUTPUT" | ||
| echo "EOF" >> "$GITHUB_OUTPUT" | ||
| - name: Find existing Trivy comment | ||
| if: github.event_name == 'pull_request' && inputs.security-scan && inputs.security-report == 'comment' | ||
| id: find_trivy | ||
| uses: peter-evans/find-comment@v3 | ||
| with: | ||
| issue-number: ${{ github.event.pull_request.number }} | ||
| comment-author: "github-actions[bot]" | ||
| body-includes: "Trivy Security Scan Results" | ||
| - name: Create or update Trivy comment | ||
| if: github.event_name == 'pull_request' && inputs.security-scan && inputs.security-report == 'comment' | ||
| uses: peter-evans/create-or-update-comment@v4 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| issue-number: ${{ github.event.pull_request.number }} | ||
| comment-id: ${{ steps.find_trivy.outputs.comment-id }} | ||
| edit-mode: replace | ||
| body: | | ||
| <!-- trivy-scan --> | ||
| ### 🔒 Trivy Security Scan Results | ||
| <details><summary>Click to expand detailed results</summary> | ||
| ```bash | ||
| ${{ steps.read_trivy.outputs.report }} | ||
| ``` | ||
| </details> | ||
| - name: Upload Trivy scan results to GitHub Security tab | ||
| if: github.event_name == 'pull_request' && inputs.security-scan && inputs.security-report == 'sarif' | ||
| uses: github/codeql-action/upload-sarif@v3 | ||
| with: | ||
| sarif_file: "trivy-results.sarif" | ||
| - name: Run Hadolint Dockerfile linter | ||
| id: hadolint | ||
| if: ${{ inputs.hadolint }} | ||
| uses: hadolint/hadolint-action@v3.1.0 | ||
| with: | ||
| dockerfile: ${{ inputs.dockerfile }} | ||
| output-file: hadolint.txt | ||
| no-fail: true | ||
| - name: Read Hadolint report file | ||
| id: read_hadolint | ||
| if: ${{ inputs.hadolint }} | ||
| run: | | ||
| echo "report<<EOF" >> "$GITHUB_OUTPUT" | ||
| cat hadolint.txt >> "$GITHUB_OUTPUT" | ||
| echo "EOF" >> "$GITHUB_OUTPUT" | ||
| cat hadolint.txt | ||
| - name: Find existing Hadolint comment | ||
| id: find_hadolint | ||
| if: ${{ github.event_name == 'pull_request' && inputs.hadolint }} | ||
| uses: peter-evans/find-comment@v3 | ||
| with: | ||
| issue-number: ${{ github.event.pull_request.number }} | ||
| comment-author: "github-actions[bot]" | ||
| body-includes: "Hadolint Dockerfile Lint Results" | ||
| - name: Create or update Hadolint comment | ||
| if: ${{ github.event_name == 'pull_request' && inputs.hadolint && steps.read_hadolint.outputs.report != '' }} | ||
| uses: peter-evans/create-or-update-comment@v4 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| issue-number: ${{ github.event.pull_request.number }} | ||
| comment-id: ${{ steps.find_hadolint.outputs.comment-id }} | ||
| edit-mode: replace | ||
| body: | | ||
| <!-- hadolint-scan --> | ||
| ### 🐳 Hadolint Dockerfile Lint Results | ||
| <details><summary>Click to expand detailed results</summary> | ||
| ```bash | ||
| ${{ steps.read_hadolint.outputs.report }} | ||
| ``` | ||
| </details> | ||
| - name: Fail build on High/Critical Vulnerabilities | ||
| id: security_check | ||
| if: ${{ inputs.security-scan }} | ||
| uses: aquasecurity/trivy-action@0.29.0 | ||
| with: | ||
| input: vuln-image.tar | ||
| format: ${{ (inputs.security-report == 'sarif' && 'sarif') || 'table' }} | ||
| ignore-unfixed: true | ||
| vuln-type: "os,library" | ||
| severity: "CRITICAL,HIGH" | ||
| hide-progress: true | ||
| skip-setup-trivy: true | ||
| exit-code: 1 | ||
| - name: Build and Push Multi-Platform Image | ||
| if: ${{ inputs.push }} | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| build-args: ${{ inputs.build-args }} | ||
| context: ${{ inputs.context }} | ||
| file: ${{ inputs.dockerfile }} | ||
| platforms: ${{ inputs.platforms }} | ||
| push: true | ||
| tags: ${{ inputs.image-name }}:${{ inputs.image-tag }} | ||
| - name: Cleanup | ||
| id: cleanup | ||
| if: always() | ||
| run: | | ||
| rm -f trivy.txt trivy-results.sarif vuln-image.tar | ||
| docker image rm -f ${{ inputs.image-name }}:${{ inputs.image-tag }} | ||