chore(ci): revert consolidated pipeline and restore individual workflow triggers
Reverts the experimental consolidated CI pipeline strategy in favor of independent, parallel workflows triggered on pull requests. - Removed .github/workflows/ci-pipeline.yml - Restored 'on: pull_request' triggers to: - docker-build.yml - cerberus-integration.yml - crowdsec-integration.yml - rate-limit-integration.yml - waf-integration.yml - e2e-tests-split.yml - Updated integration workflows to build local Docker images instead of expecting artifacts - Fixed invalid 'env' context usage in e2e-tests-split.yml conditions
This commit is contained in:
93
.github/workflows/cerberus-integration.yml
vendored
93
.github/workflows/cerberus-integration.yml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
description: 'Docker image tag to test (e.g., pr-123-abc1234, latest)'
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
# Prevent race conditions when PR is updated mid-test
|
||||
# Cancels old test runs when new build completes with different SHA
|
||||
@@ -21,98 +22,14 @@ jobs:
|
||||
name: Cerberus Security Stack Integration
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
# Only run if docker-build.yml succeeded, or if manually triggered
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && (github.event.workflow_run.status != 'completed' || github.event.workflow_run.conclusion == 'success')) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
# Determine the correct image tag based on trigger context
|
||||
# For PRs: pr-{number}-{short-sha}, For non-PR: sha-{short-sha}
|
||||
- name: Determine image tag
|
||||
id: determine-tag
|
||||
env:
|
||||
EVENT: ${{ github.event.workflow_run.event || github.event_name }}
|
||||
REF: ${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||||
SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
MANUAL_TAG: ${{ inputs.image_tag }}
|
||||
- name: Build Docker image (Local)
|
||||
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)
|
||||
|
||||
# Use native pull_requests array (no API calls needed)
|
||||
PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number // empty')
|
||||
|
||||
if [[ "$EVENT" == "pull_request" || -n "$PR_NUM" ]]; then
|
||||
|
||||
# Fallback for direct PR trigger
|
||||
if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then
|
||||
PR_NUM="${{ github.event.number }}"
|
||||
fi
|
||||
|
||||
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
|
||||
# Non-PR workflow_run uses short SHA tag (matches docker-build.yml)
|
||||
echo "tag=sha-${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "source_type=sha" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
echo "sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "Determined image tag: $(grep tag= "$GITHUB_OUTPUT")"
|
||||
|
||||
# Pull image from Docker Hub with retry logic
|
||||
- name: Pull Docker image from registry
|
||||
id: pull_image
|
||||
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 10
|
||||
command: |
|
||||
IMAGE_NAME="docker.io/wikid82/charon:${{ steps.determine-tag.outputs.tag }}"
|
||||
echo "Pulling image: $IMAGE_NAME"
|
||||
docker pull "$IMAGE_NAME"
|
||||
docker tag "$IMAGE_NAME" charon:local
|
||||
echo "✅ Successfully pulled from registry"
|
||||
|
||||
# Validate image freshness by checking SHA label
|
||||
- name: Validate image SHA
|
||||
env:
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
LABEL_SHA=$(docker inspect charon:local --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' | cut -c1-7)
|
||||
echo "Expected SHA: $SHA"
|
||||
echo "Image SHA: $LABEL_SHA"
|
||||
|
||||
if [[ "$LABEL_SHA" != "$SHA" ]]; then
|
||||
echo "⚠️ WARNING: Image SHA mismatch!"
|
||||
echo "Image may be stale. Proceeding with caution..."
|
||||
else
|
||||
echo "✅ Image SHA matches expected commit"
|
||||
fi
|
||||
echo "Building image locally for integration tests..."
|
||||
docker build -t charon:local .
|
||||
echo "✅ Successfully built charon:local"
|
||||
|
||||
- name: Run Cerberus integration tests
|
||||
id: cerberus-test
|
||||
|
||||
1037
.github/workflows/ci-pipeline.yml
vendored
1037
.github/workflows/ci-pipeline.yml
vendored
File diff suppressed because it is too large
Load Diff
100
.github/workflows/crowdsec-integration.yml
vendored
100
.github/workflows/crowdsec-integration.yml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
description: 'Docker image tag to test (e.g., pr-123-abc1234, latest)'
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
# Prevent race conditions when PR is updated mid-test
|
||||
# Cancels old test runs when new build completes with different SHA
|
||||
@@ -21,105 +22,14 @@ jobs:
|
||||
name: CrowdSec Bouncer Integration
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
# Only run if docker-build.yml succeeded, or if manually triggered
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && (github.event.workflow_run.status != 'completed' || github.event.workflow_run.conclusion == 'success')) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
# Determine the correct image tag based on trigger context
|
||||
# For PRs: pr-{number}-{short-sha}, For non-PR: sha-{short-sha}
|
||||
- name: Determine image tag
|
||||
id: determine-tag
|
||||
env:
|
||||
EVENT: ${{ github.event.workflow_run.event || github.event_name }}
|
||||
REF: ${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||||
SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
MANUAL_TAG: ${{ inputs.image_tag }}
|
||||
- name: Build Docker image (Local)
|
||||
run: |
|
||||
# Manual trigger uses provided tag
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
if [[ -n "$MANUAL_TAG" ]]; then
|
||||
TAG_VALUE="$MANUAL_TAG"
|
||||
else
|
||||
# Default to latest if no tag provided
|
||||
TAG_VALUE="latest"
|
||||
fi
|
||||
{
|
||||
echo "tag=${TAG_VALUE}"
|
||||
echo "source_type=manual"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract 7-character short SHA
|
||||
SHORT_SHA=$(echo "$SHA" | cut -c1-7)
|
||||
|
||||
# Use native pull_requests array (no API calls needed)
|
||||
PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number // empty')
|
||||
|
||||
if [[ "$EVENT" == "pull_request" || -n "$PR_NUM" ]]; then
|
||||
|
||||
# Fallback for direct PR trigger
|
||||
if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then
|
||||
PR_NUM="${{ github.event.number }}"
|
||||
fi
|
||||
|
||||
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}"
|
||||
echo "source_type=pr"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Non-PR workflow_run uses short SHA tag (matches docker-build.yml)
|
||||
{
|
||||
echo "tag=sha-${SHORT_SHA}"
|
||||
echo "source_type=sha"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
echo "sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "Determined image tag: $(grep tag= "$GITHUB_OUTPUT")"
|
||||
|
||||
# Pull image from Docker Hub with retry logic
|
||||
- name: Pull Docker image from registry
|
||||
id: pull_image
|
||||
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 10
|
||||
command: |
|
||||
IMAGE_NAME="docker.io/wikid82/charon:${{ steps.determine-tag.outputs.tag }}"
|
||||
echo "Pulling image: $IMAGE_NAME"
|
||||
docker pull "$IMAGE_NAME"
|
||||
docker tag "$IMAGE_NAME" charon:local
|
||||
echo "✅ Successfully pulled from registry"
|
||||
|
||||
# Validate image freshness by checking SHA label
|
||||
- name: Validate image SHA
|
||||
env:
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
LABEL_SHA=$(docker inspect charon:local --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' | cut -c1-7)
|
||||
echo "Expected SHA: $SHA"
|
||||
echo "Image SHA: $LABEL_SHA"
|
||||
|
||||
if [[ "$LABEL_SHA" != "$SHA" ]]; then
|
||||
echo "⚠️ WARNING: Image SHA mismatch!"
|
||||
echo "Image may be stale. Proceeding with caution..."
|
||||
else
|
||||
echo "✅ Image SHA matches expected commit"
|
||||
fi
|
||||
echo "Building image locally for integration tests..."
|
||||
docker build -t charon:local .
|
||||
echo "✅ Successfully built charon:local"
|
||||
|
||||
- name: Run CrowdSec integration tests
|
||||
id: crowdsec-test
|
||||
|
||||
8
.github/workflows/docker-build.yml
vendored
8
.github/workflows/docker-build.yml
vendored
@@ -21,6 +21,14 @@ name: Docker Build, Publish & Test
|
||||
# See: docs/plans/current_spec.md (Section 4.1 - docker-build.yml changes)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- development
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- development
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
|
||||
42
.github/workflows/e2e-tests-split.yml
vendored
42
.github/workflows/e2e-tests-split.yml
vendored
@@ -79,6 +79,10 @@ on:
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- development
|
||||
|
||||
env:
|
||||
NODE_VERSION: '20'
|
||||
@@ -86,6 +90,8 @@ env:
|
||||
GOTOOLCHAIN: auto
|
||||
DOCKERHUB_REGISTRY: docker.io
|
||||
IMAGE_NAME: ${{ github.repository_owner }}/charon
|
||||
E2E_BROWSER: ${{ inputs.browser || 'all' }}
|
||||
E2E_TEST_CATEGORY: ${{ inputs.test_category || 'all' }}
|
||||
PLAYWRIGHT_COVERAGE: ${{ (inputs.playwright_coverage && '1') || (vars.PLAYWRIGHT_COVERAGE || '0') }}
|
||||
DEBUG: 'charon:*,charon-test:*'
|
||||
PLAYWRIGHT_DEBUG: '1'
|
||||
@@ -205,8 +211,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'chromium' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'chromium' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -344,7 +350,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload Chromium Security coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: e2e-coverage-chromium-security
|
||||
@@ -381,8 +387,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'firefox' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'firefox' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -528,7 +534,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload Firefox Security coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: e2e-coverage-firefox-security
|
||||
@@ -565,8 +571,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'webkit' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'webkit' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -712,7 +718,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload WebKit Security coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: e2e-coverage-webkit-security
|
||||
@@ -756,8 +762,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'chromium' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'non-security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'chromium' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'non-security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -892,7 +898,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload Chromium coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: e2e-coverage-chromium-shard-${{ matrix.shard }}
|
||||
@@ -929,8 +935,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'firefox' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'non-security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'firefox' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'non-security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -1073,7 +1079,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload Firefox coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
|
||||
with:
|
||||
name: e2e-coverage-firefox-shard-${{ matrix.shard }}
|
||||
@@ -1110,8 +1116,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: |
|
||||
(inputs.browser == 'webkit' || inputs.browser == 'all') &&
|
||||
(inputs.test_category == 'non-security' || inputs.test_category == 'all')
|
||||
((inputs.browser || 'all') == 'webkit' || (inputs.browser || 'all') == 'all') &&
|
||||
((inputs.test_category || 'all') == 'non-security' || (inputs.test_category || 'all') == 'all')
|
||||
timeout-minutes: 20
|
||||
env:
|
||||
CHARON_EMERGENCY_TOKEN: ${{ secrets.CHARON_EMERGENCY_TOKEN }}
|
||||
@@ -1254,7 +1260,7 @@ jobs:
|
||||
retention-days: 14
|
||||
|
||||
- name: Upload WebKit coverage (if enabled)
|
||||
if: always() && env.PLAYWRIGHT_COVERAGE == '1'
|
||||
if: always() && (inputs.playwright_coverage == 'true' || vars.PLAYWRIGHT_COVERAGE == '1')
|
||||
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
|
||||
with:
|
||||
name: e2e-coverage-webkit-shard-${{ matrix.shard }}
|
||||
|
||||
100
.github/workflows/rate-limit-integration.yml
vendored
100
.github/workflows/rate-limit-integration.yml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
description: 'Docker image tag to test (e.g., pr-123-abc1234, latest)'
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
# Prevent race conditions when PR is updated mid-test
|
||||
# Cancels old test runs when new build completes with different SHA
|
||||
@@ -21,105 +22,14 @@ jobs:
|
||||
name: Rate Limiting Integration
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
# Only run if docker-build.yml succeeded, or if manually triggered
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && (github.event.workflow_run.status != 'completed' || github.event.workflow_run.conclusion == 'success')) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
# Determine the correct image tag based on trigger context
|
||||
# For PRs: pr-{number}-{short-sha}, For non-PR: sha-{short-sha}
|
||||
- name: Determine image tag
|
||||
id: determine-tag
|
||||
env:
|
||||
EVENT: ${{ github.event.workflow_run.event || github.event_name }}
|
||||
REF: ${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||||
SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
MANUAL_TAG: ${{ inputs.image_tag }}
|
||||
- name: Build Docker image (Local)
|
||||
run: |
|
||||
# Manual trigger uses provided tag
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
if [[ -n "$MANUAL_TAG" ]]; then
|
||||
TAG_VALUE="$MANUAL_TAG"
|
||||
else
|
||||
# Default to latest if no tag provided
|
||||
TAG_VALUE="latest"
|
||||
fi
|
||||
{
|
||||
echo "tag=${TAG_VALUE}"
|
||||
echo "source_type=manual"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Extract 7-character short SHA
|
||||
SHORT_SHA=$(echo "$SHA" | cut -c1-7)
|
||||
|
||||
# Use native pull_requests array (no API calls needed)
|
||||
PR_NUM=$(echo '${{ toJson(github.event.workflow_run.pull_requests) }}' | jq -r '.[0].number // empty')
|
||||
|
||||
if [[ "$EVENT" == "pull_request" || -n "$PR_NUM" ]]; then
|
||||
|
||||
# Fallback for direct PR trigger
|
||||
if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then
|
||||
PR_NUM="${{ github.event.number }}"
|
||||
fi
|
||||
|
||||
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}"
|
||||
echo "source_type=pr"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Non-PR workflow_run uses short SHA tag (matches docker-build.yml)
|
||||
{
|
||||
echo "tag=sha-${SHORT_SHA}"
|
||||
echo "source_type=sha"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
echo "sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "Determined image tag: $(grep tag= "$GITHUB_OUTPUT")"
|
||||
|
||||
# Pull image from Docker Hub with retry logic
|
||||
- name: Pull Docker image from registry
|
||||
id: pull_image
|
||||
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 10
|
||||
command: |
|
||||
IMAGE_NAME="docker.io/wikid82/charon:${{ steps.determine-tag.outputs.tag }}"
|
||||
echo "Pulling image: $IMAGE_NAME"
|
||||
docker pull "$IMAGE_NAME"
|
||||
docker tag "$IMAGE_NAME" charon:local
|
||||
echo "✅ Successfully pulled from registry"
|
||||
|
||||
# Validate image freshness by checking SHA label
|
||||
- name: Validate image SHA
|
||||
env:
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
LABEL_SHA=$(docker inspect charon:local --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' | cut -c1-7)
|
||||
echo "Expected SHA: $SHA"
|
||||
echo "Image SHA: $LABEL_SHA"
|
||||
|
||||
if [[ "$LABEL_SHA" != "$SHA" ]]; then
|
||||
echo "⚠️ WARNING: Image SHA mismatch!"
|
||||
echo "Image may be stale. Proceeding with caution..."
|
||||
else
|
||||
echo "✅ Image SHA matches expected commit"
|
||||
fi
|
||||
echo "Building image locally for integration tests..."
|
||||
docker build -t charon:local .
|
||||
echo "✅ Successfully built charon:local"
|
||||
|
||||
- name: Run rate limit integration tests
|
||||
id: ratelimit-test
|
||||
|
||||
2
.github/workflows/security-pr.yml
vendored
2
.github/workflows/security-pr.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
description: 'PR number to scan (optional)'
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: security-pr-${{ github.event.workflow_run.event || github.event_name }}-${{ github.event.workflow_run.head_branch || github.ref }}
|
||||
@@ -23,6 +24,7 @@ jobs:
|
||||
# Run for: manual dispatch, PR builds, or any push builds from docker-build
|
||||
if: >-
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
github.event_name == 'pull_request' ||
|
||||
((github.event.workflow_run.event == 'push' || github.event.workflow_run.pull_requests[0].number != null) &&
|
||||
(github.event.workflow_run.status != 'completed' || github.event.workflow_run.conclusion == 'success'))
|
||||
|
||||
|
||||
2
.github/workflows/supply-chain-pr.yml
vendored
2
.github/workflows/supply-chain-pr.yml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
description: "PR number to verify (optional, will auto-detect from workflow_run)"
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: supply-chain-pr-${{ github.event.workflow_run.event || github.event_name }}-${{ github.event.workflow_run.head_branch || github.ref }}
|
||||
@@ -28,6 +29,7 @@ jobs:
|
||||
# Run for: manual dispatch, or successful workflow_run triggered by push/PR
|
||||
if: >
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
github.event_name == 'pull_request' ||
|
||||
(github.event_name == 'workflow_run' &&
|
||||
(github.event.workflow_run.event == 'push' || github.event.workflow_run.pull_requests[0].number != null) &&
|
||||
(github.event.workflow_run.status != 'completed' || github.event.workflow_run.conclusion == 'success'))
|
||||
|
||||
99
.github/workflows/waf-integration.yml
vendored
99
.github/workflows/waf-integration.yml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
description: 'Docker image tag to test (e.g., pr-123-abc1234, latest)'
|
||||
required: false
|
||||
type: string
|
||||
pull_request:
|
||||
|
||||
# Prevent race conditions when PR is updated mid-test
|
||||
# Cancels old test runs when new build completes with different SHA
|
||||
@@ -21,104 +22,14 @@ jobs:
|
||||
name: Coraza WAF Integration
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
# Only run if docker-build.yml succeeded, or if manually triggered
|
||||
if: ${{ github.event_name == 'workflow_dispatch' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
|
||||
# Determine the correct image tag based on trigger context
|
||||
# For PRs: pr-{number}-{short-sha}, For non-PR: sha-{short-sha}
|
||||
- name: Determine image tag
|
||||
id: determine-tag
|
||||
env:
|
||||
EVENT: ${{ github.event.workflow_run.event || github.event_name }}
|
||||
REF: ${{ github.event.workflow_run.head_branch || github.ref_name }}
|
||||
SHA: ${{ github.event.workflow_run.head_sha || github.sha }}
|
||||
MANUAL_TAG: ${{ inputs.image_tag }}
|
||||
- name: Build Docker image (Local)
|
||||
run: |
|
||||
# Manual trigger uses provided tag
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
if [[ -n "$MANUAL_TAG" ]]; then
|
||||
TAG_VALUE="$MANUAL_TAG"
|
||||
else
|
||||
# Default to latest if no tag provided
|
||||
TAG_VALUE="latest"
|
||||
fi
|
||||
{
|
||||
echo "tag=${TAG_VALUE}"
|
||||
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')
|
||||
|
||||
# Fallback for direct PR trigger
|
||||
if [[ -z "$PR_NUM" || "$PR_NUM" == "null" ]]; then
|
||||
PR_NUM="${{ github.event.number }}"
|
||||
fi
|
||||
|
||||
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}"
|
||||
echo "source_type=pr"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Non-PR workflow_run uses short SHA tag (matches docker-build.yml)
|
||||
{
|
||||
echo "tag=sha-${SHORT_SHA}"
|
||||
echo "source_type=sha"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
|
||||
echo "sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT"
|
||||
echo "Determined image tag: $(grep tag= "$GITHUB_OUTPUT")"
|
||||
|
||||
# Pull image from Docker Hub with retry logic
|
||||
- name: Pull Docker image from registry
|
||||
id: pull_image
|
||||
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
|
||||
with:
|
||||
timeout_minutes: 5
|
||||
max_attempts: 3
|
||||
retry_wait_seconds: 10
|
||||
command: |
|
||||
IMAGE_NAME="docker.io/wikid82/charon:${{ steps.determine-tag.outputs.tag }}"
|
||||
echo "Pulling image: $IMAGE_NAME"
|
||||
docker pull "$IMAGE_NAME"
|
||||
docker tag "$IMAGE_NAME" charon:local
|
||||
echo "✅ Successfully pulled from registry"
|
||||
|
||||
# Validate image freshness by checking SHA label
|
||||
- name: Validate image SHA
|
||||
env:
|
||||
SHA: ${{ steps.determine-tag.outputs.sha }}
|
||||
run: |
|
||||
LABEL_SHA=$(docker inspect charon:local --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' | cut -c1-7)
|
||||
echo "Expected SHA: $SHA"
|
||||
echo "Image SHA: $LABEL_SHA"
|
||||
|
||||
if [[ "$LABEL_SHA" != "$SHA" ]]; then
|
||||
echo "⚠️ WARNING: Image SHA mismatch!"
|
||||
echo "Image may be stale. Proceeding with caution..."
|
||||
else
|
||||
echo "✅ Image SHA matches expected commit"
|
||||
fi
|
||||
echo "Building image locally for integration tests..."
|
||||
docker build -t charon:local .
|
||||
echo "✅ Successfully built charon:local"
|
||||
|
||||
- name: Run WAF integration tests
|
||||
id: waf-test
|
||||
|
||||
Reference in New Issue
Block a user