Fixed critical workflow issues preventing builds:
1. Job Dependency Structure:
- build-and-push now properly depends on security-check with always()
- Allows push/tag events to run even when security-check is skipped
- Only pull_request events trigger security-check
- Conditional logic checks needs.security-check.result to handle skipped cases
2. Platform vs Load Conflict:
- Removed platform specification for PR builds (load=true)
- load: true only works with single platform matching host
- Multi-platform (linux/amd64,linux/arm64) only for push events
- Empty string for platforms when using load to avoid conflicts
3. Conditional Logic Improvements:
- push events: always run (security-check skipped)
- workflow_dispatch: always run (security-check skipped)
- pull_request: only run if security-check succeeded and not a fork
- pull_request_target: only run if has 'safe-to-build' label
This ensures:
- Branch pushes work correctly
- Tag builds work correctly
- PRs are security-checked before building
- Fork PRs require manual approval
Fixed two critical build failures:
1. Platform Selection Bug:
- Fixed operator precedence issue in platform conditional
- Was evaluating to boolean 'true' instead of platform string
- Changed: platforms: ${{ ... || ... && 'linux/amd64' || ... }}
- To: platforms: ${{ (... || ...) && 'linux/amd64' || ... }}
- Now correctly uses linux/amd64 for PRs, linux/amd64,linux/arm64 for releases
2. Trivy Multiple Tags Issue:
- Trivy was receiving multiple tags separated by newlines
- Added step to extract first tag from metadata output
- Trivy now scans using single tag reference
- Prevents "multiple targets cannot be specified" error
Both PRs and production builds should now complete successfully.
Changed from SHA-pinned actions to version tags (e.g., @v3, @v4, @v5)
for easier maintenance and automatic security updates via Dependabot.
While SHA pinning provides slightly better supply chain security, version
tags with Dependabot updates provide a better balance of security and
maintainability for most projects.
Updated actions:
- actions/checkout@v4
- docker/setup-buildx-action@v3
- docker/login-action@v3
- docker/metadata-action@v5
- docker/build-push-action@v5
- aquasecurity/trivy-action@0.24.0
- github/codeql-action/upload-sarif@v3
Dependabot will automatically create PRs for security updates.
Security Improvements:
- Fork PR Protection: Builds from forks require manual 'safe-to-build' label approval
- Trivy Vulnerability Scanning: Scan all images for CRITICAL/HIGH vulnerabilities
- SHA-Pinned Actions: All GitHub Actions pinned to specific commits for supply chain security
- SBOM Generation: Generate Software Bill of Materials for all builds
- Provenance Attestation: Record build provenance for supply chain verification
- Security Events Upload: Upload scan results to GitHub Security tab
- Platform Optimization: Single-platform builds for PRs for faster feedback
Additional Security:
- Created SECURITY.md with vulnerability reporting process and security practices
- Added Dependabot configuration for automated dependency updates
- Limited permissions model (contents:read, packages:write, security-events:write)
- No registry push from PR builds (load-only for security scanning)
This addresses concerns about malicious PR builds by:
1. Requiring manual approval for fork PRs
2. Scanning all images before they could be pushed
3. Preventing PR builds from pushing to registry
4. Using verified, SHA-pinned actions
Remove the prefix={{branch}}- from the sha tag type which was causing
invalid tag formats like ":-cbc2c2c" when building pull requests.
The {{branch}} placeholder becomes empty for PRs, leaving only the dash
prefix which creates an invalid Docker tag.
Changed from: type=sha,prefix={{branch}}-
Changed to: type=sha
This generates valid tags like "sha-cbc2c2c" for all events.