Merge branch 'hotfix/ci' into renovate/development-weekly-non-major-updates

This commit is contained in:
Jeremy
2026-02-06 12:02:20 -05:00
committed by GitHub
129 changed files with 9247 additions and 5375 deletions

View File

@@ -8,6 +8,11 @@ on:
workflows: ["Docker Build, Publish & Test"]
types:
- completed
branches: [main, development, 'feature/**', 'hotfix/**']
push:
branches: [main, development, 'feature/**', 'hotfix/**']
pull_request:
branches: [main, development, 'feature/**', 'hotfix/**']
workflow_dispatch:
inputs:
@@ -17,7 +22,7 @@ on:
type: string
concurrency:
group: security-pr-${{ github.event.workflow_run.head_branch || github.ref }}
group: security-pr-${{ github.event.workflow_run.event || github.event_name }}-${{ github.event.workflow_run.head_branch || github.ref }}
cancel-in-progress: true
jobs:
@@ -28,6 +33,8 @@ jobs:
# Run for: manual dispatch, PR builds, or any push builds from docker-build
if: >-
github.event_name == 'workflow_dispatch' ||
github.event_name == 'push' ||
github.event_name == 'pull_request' ||
((github.event.workflow_run.event == 'pull_request' || github.event.workflow_run.event == 'push') &&
github.event.workflow_run.conclusion == 'success')
@@ -59,8 +66,8 @@ jobs:
exit 0
fi
# Extract PR number from workflow_run context
HEAD_SHA="${{ github.event.workflow_run.head_sha }}"
# Extract PR number from context
HEAD_SHA="${{ github.event.workflow_run.head_sha || github.event.pull_request.head.sha || github.sha }}"
echo "🔍 Looking for PR with head SHA: ${HEAD_SHA}"
# Query GitHub API for PR associated with this commit
@@ -79,16 +86,24 @@ jobs:
fi
# Check if this is a push event (not a PR)
if [[ "${{ github.event.workflow_run.event }}" == "push" ]]; then
if [[ "${{ github.event.workflow_run.event }}" == "push" || "${{ github.event_name }}" == "push" ]]; then
HEAD_BRANCH="${{ github.event.workflow_run.head_branch || github.ref_name }}"
echo "is_push=true" >> "$GITHUB_OUTPUT"
echo "✅ Detected push build from branch: ${{ github.event.workflow_run.head_branch }}"
echo "✅ Detected push build from branch: ${HEAD_BRANCH}"
else
echo "is_push=false" >> "$GITHUB_OUTPUT"
fi
- name: Build Docker image (Local)
if: github.event_name == 'push' || github.event_name == 'pull_request'
run: |
echo "Building image locally for security scan..."
docker build -t charon:local .
echo "✅ Successfully built charon:local"
- name: Check for PR image artifact
id: check-artifact
if: steps.pr-info.outputs.pr_number != '' || steps.pr-info.outputs.is_push == 'true'
if: (steps.pr-info.outputs.pr_number != '' || steps.pr-info.outputs.is_push == 'true') && github.event_name != 'push' && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
@@ -116,6 +131,21 @@ jobs:
echo "artifact_exists=false" >> "$GITHUB_OUTPUT"
exit 0
fi
elif [[ -z "${RUN_ID}" ]]; then
# If triggered by push/pull_request, RUN_ID is empty. Find recent run for this commit.
HEAD_SHA="${{ github.event.workflow_run.head_sha || github.event.pull_request.head.sha || github.sha }}"
echo "🔍 Searching for workflow run for SHA: ${HEAD_SHA}"
# Retry a few times as the run might be just starting or finishing
for i in {1..3}; do
RUN_ID=$(gh api \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"/repos/${{ github.repository }}/actions/workflows/docker-build.yml/runs?head_sha=${HEAD_SHA}&status=success&per_page=1" \
--jq '.workflow_runs[0].id // empty' 2>/dev/null || echo "")
if [[ -n "${RUN_ID}" ]]; then break; fi
echo "⏳ Waiting for workflow run to appear/complete... ($i/3)"
sleep 5
done
fi
echo "run_id=${RUN_ID}" >> "$GITHUB_OUTPUT"
@@ -138,7 +168,7 @@ jobs:
fi
- name: Skip if no artifact
if: (steps.pr-info.outputs.pr_number == '' && steps.pr-info.outputs.is_push != 'true') || steps.check-artifact.outputs.artifact_exists != 'true'
if: ((steps.pr-info.outputs.pr_number == '' && steps.pr-info.outputs.is_push != 'true') || steps.check-artifact.outputs.artifact_exists != 'true') && github.event_name != 'push' && github.event_name != 'pull_request'
run: |
echo " Skipping security scan - no PR image artifact available"
echo "This is expected for:"
@@ -165,9 +195,31 @@ jobs:
docker images | grep charon
- name: Extract charon binary from container
if: steps.check-artifact.outputs.artifact_exists == 'true'
if: steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request'
id: extract
run: |
# Use local image for Push/PR events
if [[ "${{ github.event_name }}" == "push" || "${{ github.event_name }}" == "pull_request" ]]; then
echo "Using local image: charon:local"
CONTAINER_ID=$(docker create "charon:local")
echo "container_id=${CONTAINER_ID}" >> "$GITHUB_OUTPUT"
# Extract the charon binary
mkdir -p ./scan-target
docker cp "${CONTAINER_ID}:/app/charon" ./scan-target/charon
docker rm "${CONTAINER_ID}"
if [[ -f "./scan-target/charon" ]]; then
echo "✅ Binary extracted successfully"
ls -lh ./scan-target/charon
echo "binary_path=./scan-target" >> "$GITHUB_OUTPUT"
else
echo "❌ Failed to extract binary"
exit 1
fi
exit 0
fi
# Normalize image name for reference
IMAGE_NAME=$(echo "${{ github.repository_owner }}/charon" | tr '[:upper:]' '[:lower:]')
if [[ "${{ steps.pr-info.outputs.is_push }}" == "true" ]]; then
@@ -220,7 +272,7 @@ jobs:
fi
- name: Run Trivy filesystem scan (SARIF output)
if: steps.check-artifact.outputs.artifact_exists == 'true'
if: steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request'
# aquasecurity/trivy-action v0.33.1
uses: aquasecurity/trivy-action@22438a435773de8c97dc0958cc0b823c45b064ac
with:
@@ -232,7 +284,7 @@ jobs:
continue-on-error: true
- name: Upload Trivy SARIF to GitHub Security
if: steps.check-artifact.outputs.artifact_exists == 'true'
if: steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request'
# github/codeql-action v4
uses: github/codeql-action/upload-sarif@b13d724d35ff0a814e21683638ed68ed34cf53d1
with:
@@ -241,7 +293,7 @@ jobs:
continue-on-error: true
- name: Run Trivy filesystem scan (fail on CRITICAL/HIGH)
if: steps.check-artifact.outputs.artifact_exists == 'true'
if: steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request'
# aquasecurity/trivy-action v0.33.1
uses: aquasecurity/trivy-action@22438a435773de8c97dc0958cc0b823c45b064ac
with:
@@ -252,7 +304,7 @@ jobs:
exit-code: '1'
- name: Upload scan artifacts
if: always() && steps.check-artifact.outputs.artifact_exists == 'true'
if: always() && (steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request')
# actions/upload-artifact v4.4.3
uses: actions/upload-artifact@47309c993abb98030a35d55ef7ff34b7fa1074b5
with:
@@ -262,7 +314,7 @@ jobs:
retention-days: 14
- name: Create job summary
if: always() && steps.check-artifact.outputs.artifact_exists == 'true'
if: always() && (steps.check-artifact.outputs.artifact_exists == 'true' || github.event_name == 'push' || github.event_name == 'pull_request')
run: |
if [[ "${{ steps.pr-info.outputs.is_push }}" == "true" ]]; then
echo "## 🔒 Security Scan Results - Branch: ${{ github.event.workflow_run.head_branch }}" >> $GITHUB_STEP_SUMMARY