diff --git a/.github/workflows/cerberus-integration.yml b/.github/workflows/cerberus-integration.yml index 48a8d2bb..0b918cf6 100644 --- a/.github/workflows/cerberus-integration.yml +++ b/.github/workflows/cerberus-integration.yml @@ -7,11 +7,6 @@ on: workflows: ["Docker Build, Publish & Test"] types: [completed] branches: [main, development, 'feature/**'] # Explicit branch filter prevents unexpected triggers - - pull_request: - branches: [main, development, 'feature/**'] - types: [opened, synchronize, reopened] - # Allow manual trigger for debugging workflow_dispatch: inputs: @@ -31,11 +26,8 @@ jobs: name: Cerberus Security Stack Integration runs-on: ubuntu-latest timeout-minutes: 20 - # Skip if workflow_run failed, or if PR and docker-build is still running - if: | - (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || - (github.event_name == 'pull_request') || - (github.event_name == 'workflow_dispatch') + # Only run if docker-build.yml succeeded, or if manually triggered + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -101,6 +93,62 @@ jobs: echo "source_type=branch" >> $GITHUB_OUTPUT fi + # Determine the correct image tag based on trigger context + # For PRs: pr-{number}-{sha}, For branches: {sanitized-branch}-{sha} + - name: Determine image tag + id: image + env: + EVENT: ${{ github.event.workflow_run.event }} + REF: ${{ github.event.workflow_run.head_branch }} + SHA: ${{ github.event.workflow_run.head_sha }} + MANUAL_TAG: ${{ inputs.image_tag }} + run: | + # Manual trigger uses provided tag + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + if [[ -n "$MANUAL_TAG" ]]; then + echo "tag=${MANUAL_TAG}" >> $GITHUB_OUTPUT + else + # Default to latest if no tag provided + echo "tag=latest" >> $GITHUB_OUTPUT + fi + echo "source_type=manual" >> $GITHUB_OUTPUT + exit 0 + fi + + # Extract 7-character short SHA + SHORT_SHA=$(echo "$SHA" | cut -c1-7) + + if [[ "$EVENT" == "pull_request" ]]; then + # Use native pull_requests array (no API calls needed) + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') + + if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then + echo "❌ ERROR: Could not determine PR number" + echo "Event: $EVENT" + echo "Ref: $REF" + echo "SHA: $SHA" + echo "Pull Requests JSON: ${{ toJson(github.event.workflow_run.pull_requests) }}" + exit 1 + fi + + # Immutable tag with SHA suffix prevents race conditions + echo "tag=pr-${PR_NUM}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=pr" >> $GITHUB_OUTPUT + else + # Branch push: sanitize branch name and append SHA + # Sanitization: lowercase, replace / with -, remove special chars + SANITIZED=$(echo "$REF" | \ + tr '[:upper:]' '[:lower:]' | \ + tr '/' '-' | \ + sed 's/[^a-z0-9-._]/-/g' | \ + sed 's/^-//; s/-$//' | \ + sed 's/--*/-/g' | \ + cut -c1-121) # Leave room for -SHORT_SHA (7 chars) + + echo "tag=${SANITIZED}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=branch" >> $GITHUB_OUTPUT + fi + echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT echo "Determined image tag: $(cat $GITHUB_OUTPUT | grep tag=)" diff --git a/.github/workflows/crowdsec-integration.yml b/.github/workflows/crowdsec-integration.yml index 5973c783..5f972903 100644 --- a/.github/workflows/crowdsec-integration.yml +++ b/.github/workflows/crowdsec-integration.yml @@ -7,11 +7,6 @@ on: workflows: ["Docker Build, Publish & Test"] types: [completed] branches: [main, development, 'feature/**'] # Explicit branch filter prevents unexpected triggers - - pull_request: - branches: [main, development, 'feature/**'] - types: [opened, synchronize, reopened] - # Allow manual trigger for debugging workflow_dispatch: inputs: @@ -31,11 +26,8 @@ jobs: name: CrowdSec Bouncer Integration runs-on: ubuntu-latest timeout-minutes: 15 - # Skip if workflow_run failed, or if PR and docker-build is still running - if: | - (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || - (github.event_name == 'pull_request') || - (github.event_name == 'workflow_dispatch') + # Only run if docker-build.yml succeeded, or if manually triggered + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -121,6 +113,99 @@ jobs: echo "✅ Successfully pulled from registry" continue-on-error: true + # Fallback: Download artifact if registry pull failed + - name: Fallback to artifact download + if: steps.pull_image.outcome == 'failure' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SHA: ${{ steps.image.outputs.sha }} + run: | + echo "⚠️ Registry pull failed, falling back to artifact..." + + # Determine artifact name based on source type + if [[ "${{ steps.image.outputs.source_type }}" == "pr" ]]; then + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') + ARTIFACT_NAME="pr-image-${PR_NUM}" + else + ARTIFACT_NAME="push-image" + fi + + # Determine the correct image tag based on trigger context + # For PRs: pr-{number}-{sha}, For branches: {sanitized-branch}-{sha} + - name: Determine image tag + id: image + env: + EVENT: ${{ github.event.workflow_run.event }} + REF: ${{ github.event.workflow_run.head_branch }} + SHA: ${{ github.event.workflow_run.head_sha }} + MANUAL_TAG: ${{ inputs.image_tag }} + run: | + # Manual trigger uses provided tag + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + if [[ -n "$MANUAL_TAG" ]]; then + echo "tag=${MANUAL_TAG}" >> $GITHUB_OUTPUT + else + # Default to latest if no tag provided + echo "tag=latest" >> $GITHUB_OUTPUT + fi + echo "source_type=manual" >> $GITHUB_OUTPUT + exit 0 + fi + + # Extract 7-character short SHA + SHORT_SHA=$(echo "$SHA" | cut -c1-7) + + if [[ "$EVENT" == "pull_request" ]]; then + # Use native pull_requests array (no API calls needed) + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') + + if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then + echo "❌ ERROR: Could not determine PR number" + echo "Event: $EVENT" + echo "Ref: $REF" + echo "SHA: $SHA" + echo "Pull Requests JSON: ${{ toJson(github.event.workflow_run.pull_requests) }}" + exit 1 + fi + + # Immutable tag with SHA suffix prevents race conditions + echo "tag=pr-${PR_NUM}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=pr" >> $GITHUB_OUTPUT + else + # Branch push: sanitize branch name and append SHA + # Sanitization: lowercase, replace / with -, remove special chars + SANITIZED=$(echo "$REF" | \ + tr '[:upper:]' '[:lower:]' | \ + tr '/' '-' | \ + sed 's/[^a-z0-9-._]/-/g' | \ + sed 's/^-//; s/-$//' | \ + sed 's/--*/-/g' | \ + cut -c1-121) # Leave room for -SHORT_SHA (7 chars) + + echo "tag=${SANITIZED}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=branch" >> $GITHUB_OUTPUT + fi + + echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "Determined image tag: $(cat $GITHUB_OUTPUT | grep tag=)" + + # Pull image from registry with retry logic (dual-source strategy) + # Try registry first (fast), fallback to artifact if registry fails + - name: Pull Docker image from registry + id: pull_image + uses: nick-fields/retry@v3 + with: + timeout_minutes: 5 + max_attempts: 3 + retry_wait_seconds: 10 + command: | + IMAGE_NAME="ghcr.io/${{ github.repository_owner }}/charon:${{ steps.image.outputs.tag }}" + echo "Pulling image: $IMAGE_NAME" + docker pull "$IMAGE_NAME" + docker tag "$IMAGE_NAME" charon:local + echo "✅ Successfully pulled from registry" + continue-on-error: true + # Fallback: Download artifact if registry pull failed - name: Fallback to artifact download if: steps.pull_image.outcome == 'failure' diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 976df772..e4f13c07 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -38,10 +38,6 @@ on: types: [completed] branches: [main, development, 'feature/**'] # Explicit branch filter prevents unexpected triggers - pull_request: - branches: [main, development, 'feature/**'] - types: [opened, synchronize, reopened] - workflow_dispatch: inputs: image_tag: @@ -83,11 +79,8 @@ jobs: name: E2E ${{ matrix.browser }} (Shard ${{ matrix.shard }}/${{ matrix.total-shards }}) runs-on: ubuntu-latest timeout-minutes: 30 - # Skip if workflow_run failed, or if PR and docker-build is still running - if: | - (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || - (github.event_name == 'pull_request') || - (github.event_name == 'workflow_dispatch') + # Only run if docker-build.yml succeeded, or if manually triggered + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} env: # Required for security teardown (emergency reset fallback when ACL blocks API) CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }} @@ -116,9 +109,9 @@ jobs: - name: Determine image tag id: image env: - EVENT: ${{ github.event_name == 'pull_request' && 'pull_request' || github.event.workflow_run.event }} - REF: ${{ github.event_name == 'pull_request' && github.head_ref || github.event.workflow_run.head_branch }} - SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.event.workflow_run.head_sha }} + EVENT: ${{ github.event.workflow_run.event }} + REF: ${{ github.event.workflow_run.head_branch }} + SHA: ${{ github.event.workflow_run.head_sha }} MANUAL_TAG: ${{ inputs.image_tag }} run: | # Manual trigger uses provided tag @@ -137,13 +130,8 @@ jobs: SHORT_SHA=$(echo "$SHA" | cut -c1-7) if [[ "$EVENT" == "pull_request" ]]; then - # Direct PR trigger uses github.event.pull_request.number - # workflow_run trigger uses pull_requests array - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - PR_NUM="${{ github.event.pull_request.number }}" - else - PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') - fi + # Use native pull_requests array (no API calls needed) + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then echo "❌ ERROR: Could not determine PR number" diff --git a/.github/workflows/rate-limit-integration.yml b/.github/workflows/rate-limit-integration.yml index 7e6e3a39..5e309250 100644 --- a/.github/workflows/rate-limit-integration.yml +++ b/.github/workflows/rate-limit-integration.yml @@ -7,11 +7,6 @@ on: workflows: ["Docker Build, Publish & Test"] types: [completed] branches: [main, development, 'feature/**'] # Explicit branch filter prevents unexpected triggers - - pull_request: - branches: [main, development, 'feature/**'] - types: [opened, synchronize, reopened] - # Allow manual trigger for debugging workflow_dispatch: inputs: @@ -31,11 +26,8 @@ jobs: name: Rate Limiting Integration runs-on: ubuntu-latest timeout-minutes: 15 - # Skip if workflow_run failed, or if PR and docker-build is still running - if: | - (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || - (github.event_name == 'pull_request') || - (github.event_name == 'workflow_dispatch') + # Only run if docker-build.yml succeeded, or if manually triggered + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -101,6 +93,62 @@ jobs: echo "source_type=branch" >> $GITHUB_OUTPUT fi + # Determine the correct image tag based on trigger context + # For PRs: pr-{number}-{sha}, For branches: {sanitized-branch}-{sha} + - name: Determine image tag + id: image + env: + EVENT: ${{ github.event.workflow_run.event }} + REF: ${{ github.event.workflow_run.head_branch }} + SHA: ${{ github.event.workflow_run.head_sha }} + MANUAL_TAG: ${{ inputs.image_tag }} + run: | + # Manual trigger uses provided tag + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + if [[ -n "$MANUAL_TAG" ]]; then + echo "tag=${MANUAL_TAG}" >> $GITHUB_OUTPUT + else + # Default to latest if no tag provided + echo "tag=latest" >> $GITHUB_OUTPUT + fi + echo "source_type=manual" >> $GITHUB_OUTPUT + exit 0 + fi + + # Extract 7-character short SHA + SHORT_SHA=$(echo "$SHA" | cut -c1-7) + + if [[ "$EVENT" == "pull_request" ]]; then + # Use native pull_requests array (no API calls needed) + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') + + if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then + echo "❌ ERROR: Could not determine PR number" + echo "Event: $EVENT" + echo "Ref: $REF" + echo "SHA: $SHA" + echo "Pull Requests JSON: ${{ toJson(github.event.workflow_run.pull_requests) }}" + exit 1 + fi + + # Immutable tag with SHA suffix prevents race conditions + echo "tag=pr-${PR_NUM}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=pr" >> $GITHUB_OUTPUT + else + # Branch push: sanitize branch name and append SHA + # Sanitization: lowercase, replace / with -, remove special chars + SANITIZED=$(echo "$REF" | \ + tr '[:upper:]' '[:lower:]' | \ + tr '/' '-' | \ + sed 's/[^a-z0-9-._]/-/g' | \ + sed 's/^-//; s/-$//' | \ + sed 's/--*/-/g' | \ + cut -c1-121) # Leave room for -SHORT_SHA (7 chars) + + echo "tag=${SANITIZED}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=branch" >> $GITHUB_OUTPUT + fi + echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT echo "Determined image tag: $(cat $GITHUB_OUTPUT | grep tag=)" diff --git a/.github/workflows/waf-integration.yml b/.github/workflows/waf-integration.yml index 542374ce..0190b9ca 100644 --- a/.github/workflows/waf-integration.yml +++ b/.github/workflows/waf-integration.yml @@ -7,11 +7,6 @@ on: workflows: ["Docker Build, Publish & Test"] types: [completed] branches: [main, development, 'feature/**'] # Explicit branch filter prevents unexpected triggers - - pull_request: - branches: [main, development, 'feature/**'] - types: [opened, synchronize, reopened] - # Allow manual trigger for debugging workflow_dispatch: inputs: @@ -31,11 +26,8 @@ jobs: name: Coraza WAF Integration runs-on: ubuntu-latest timeout-minutes: 15 - # Skip if workflow_run failed, or if PR and docker-build is still running - if: | - (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || - (github.event_name == 'pull_request') || - (github.event_name == 'workflow_dispatch') + # Only run if docker-build.yml succeeded, or if manually triggered + if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name == 'workflow_dispatch' }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -101,6 +93,62 @@ jobs: echo "source_type=branch" >> $GITHUB_OUTPUT fi + # Determine the correct image tag based on trigger context + # For PRs: pr-{number}-{sha}, For branches: {sanitized-branch}-{sha} + - name: Determine image tag + id: image + env: + EVENT: ${{ github.event.workflow_run.event }} + REF: ${{ github.event.workflow_run.head_branch }} + SHA: ${{ github.event.workflow_run.head_sha }} + MANUAL_TAG: ${{ inputs.image_tag }} + run: | + # Manual trigger uses provided tag + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + if [[ -n "$MANUAL_TAG" ]]; then + echo "tag=${MANUAL_TAG}" >> $GITHUB_OUTPUT + else + # Default to latest if no tag provided + echo "tag=latest" >> $GITHUB_OUTPUT + fi + echo "source_type=manual" >> $GITHUB_OUTPUT + exit 0 + fi + + # Extract 7-character short SHA + SHORT_SHA=$(echo "$SHA" | cut -c1-7) + + if [[ "$EVENT" == "pull_request" ]]; then + # Use native pull_requests array (no API calls needed) + PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number') + + if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then + echo "❌ ERROR: Could not determine PR number" + echo "Event: $EVENT" + echo "Ref: $REF" + echo "SHA: $SHA" + echo "Pull Requests JSON: ${{ toJson(github.event.workflow_run.pull_requests) }}" + exit 1 + fi + + # Immutable tag with SHA suffix prevents race conditions + echo "tag=pr-${PR_NUM}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=pr" >> $GITHUB_OUTPUT + else + # Branch push: sanitize branch name and append SHA + # Sanitization: lowercase, replace / with -, remove special chars + SANITIZED=$(echo "$REF" | \ + tr '[:upper:]' '[:lower:]' | \ + tr '/' '-' | \ + sed 's/[^a-z0-9-._]/-/g' | \ + sed 's/^-//; s/-$//' | \ + sed 's/--*/-/g' | \ + cut -c1-121) # Leave room for -SHORT_SHA (7 chars) + + echo "tag=${SANITIZED}-${SHORT_SHA}" >> $GITHUB_OUTPUT + echo "source_type=branch" >> $GITHUB_OUTPUT + fi + echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT echo "Determined image tag: $(cat $GITHUB_OUTPUT | grep tag=)" diff --git a/.version b/.version index f051c8e1..6b60281a 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -v0.16.13 +v0.17.0