Restructures CI/CD pipeline to eliminate redundant Docker image builds across parallel test workflows. Previously, every PR triggered 5 separate builds of identical images, consuming compute resources unnecessarily and contributing to registry storage bloat. Registry storage was growing at 20GB/week due to unmanaged transient tags from multiple parallel builds. While automated cleanup exists, preventing the creation of redundant images is more efficient than cleaning them up. Changes CI/CD orchestration so docker-build.yml is the single source of truth for all Docker images. Integration tests (CrowdSec, Cerberus, WAF, Rate Limiting) and E2E tests now wait for the build to complete via workflow_run triggers, then pull the pre-built image from GHCR. PR and feature branch images receive immutable tags that include commit SHA (pr-123-abc1234, feature-dns-provider-def5678) to prevent race conditions when branches are updated during test execution. Tag sanitization handles special characters, slashes, and name length limits to ensure Docker compatibility. Adds retry logic for registry operations to handle transient GHCR failures, with dual-source fallback to artifact downloads when registry pulls fail. Preserves all existing functionality and backward compatibility while reducing parallel build count from 5× to 1×. Security scanning now covers all PR images (previously skipped), blocking merges on CRITICAL/HIGH vulnerabilities. Concurrency groups prevent stale test runs from consuming resources when PRs are updated mid-execution. Expected impact: 80% reduction in compute resources, 4× faster total CI time (120min → 30min), prevention of uncontrolled registry storage growth, and 100% consistency guarantee (all tests validate the exact same image that would be deployed). Closes #[issue-number-if-exists]
64 lines
2.0 KiB
YAML
64 lines
2.0 KiB
YAML
name: Container Registry Prune
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 3 * * 0' # Weekly: Sundays at 03:00 UTC
|
|
workflow_dispatch:
|
|
inputs:
|
|
registries:
|
|
description: 'Comma-separated registries to prune (ghcr,dockerhub)'
|
|
required: false
|
|
default: 'ghcr,dockerhub'
|
|
keep_days:
|
|
description: 'Number of days to retain images (unprotected)'
|
|
required: false
|
|
default: '30'
|
|
dry_run:
|
|
description: 'If true, only logs candidates and does not delete (default: false for active cleanup)'
|
|
required: false
|
|
default: 'false'
|
|
keep_last_n:
|
|
description: 'Keep last N newest images (global)'
|
|
required: false
|
|
default: '30'
|
|
|
|
permissions:
|
|
packages: write
|
|
contents: read
|
|
|
|
jobs:
|
|
prune:
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
OWNER: ${{ github.repository_owner }}
|
|
IMAGE_NAME: charon
|
|
REGISTRIES: ${{ github.event.inputs.registries || 'ghcr,dockerhub' }}
|
|
KEEP_DAYS: ${{ github.event.inputs.keep_days || '30' }}
|
|
KEEP_LAST_N: ${{ github.event.inputs.keep_last_n || '30' }}
|
|
DRY_RUN: ${{ github.event.inputs.dry_run || 'true' }}
|
|
PROTECTED_REGEX: '["^v","^latest$","^main$","^develop$"]'
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
|
|
|
- name: Install tools
|
|
run: |
|
|
sudo apt-get update && sudo apt-get install -y jq curl
|
|
|
|
- name: Run container prune (dry-run by default)
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
run: |
|
|
chmod +x scripts/prune-container-images.sh
|
|
./scripts/prune-container-images.sh 2>&1 | tee prune-${{ github.run_id }}.log
|
|
|
|
- name: Upload log
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
|
with:
|
|
name: prune-log-${{ github.run_id }}
|
|
path: |
|
|
prune-${{ github.run_id }}.log
|