diff --git a/Dockerfile b/Dockerfile index cea882f..cc85501 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,10 +6,12 @@ USER root # Copy the entrypoint script and properties used for the action COPY entrypoint.sh /app/entrypoint.sh +COPY scripts /app/scripts/ COPY cleanup.sh /app/cleanup.sh RUN chmod +x /app/entrypoint.sh \ - && chmod +x /app/cleanup.sh + && chmod +x /app/cleanup.sh \ + && chmod +x /app/scripts/ HEALTHCHECK NONE diff --git a/entrypoint.sh b/entrypoint.sh index 2517420..33169b2 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,116 +1,38 @@ #!/bin/bash -output_file=./output.log - # ------------------------------------------------------ -# Multi-registry auth.json creation +# Main Entrypoint Orchestrator # ------------------------------------------------------ -# Expected env vars: -# REGISTRIES="docker.io ghcr.io registry.example.com" -# USERNAME_ and PASSWORD_ -# Example: USERNAME_DOCKER_IO, PASSWORD_DOCKER_IO -# USERNAME_GHCR_IO, PASSWORD_GHCR_IO - -if [[ -n "$REGISTRIES" ]]; then - echo "🔑 Creating multi-registry auth.json..." - mkdir -p /github/home/.config/containers - auths_entries="" - - for reg in $REGISTRIES; do - # Convert registry to env var friendly form (dots & dashes to underscores, uppercase) - env_suffix=$(echo "$reg" | tr '.-' '_' | tr '[:lower:]' '[:upper:]') - - user_var="USERNAME_${env_suffix}" - pass_var="PASSWORD_${env_suffix}" - - user="${!user_var}" - pass="${!pass_var}" - - if [[ -n "$user" && -n "$pass" ]]; then - encoded=$(echo -n "${user}:${pass}" | base64 -w0) - auths_entries+="\"$reg\": {\"auth\": \"$encoded\"}," - echo "✅ Added credentials for $reg" - else - echo "⚠️ Skipping $reg — missing username/password" - fi - done - - # Remove trailing comma and wrap in JSON - auths_entries="${auths_entries%,}" - echo "{\"auths\": {${auths_entries}}}" > /github/home/.config/containers/auth.json - echo "✅ Auth.json created at /github/home/.config/containers/auth.json" -else - echo "⚠️ No REGISTRIES specified, skipping auth.json creation." -fi - -# Parse global params (applied to all commands) -if [ -n "${GLOBAL_PARAMS}" ]; then - eval "global_arr=(${GLOBAL_PARAMS})" -else - global_arr=() -fi - -# Parse scan-specific params -if [ -n "${SCAN_PARAMS}" ]; then - eval "scan_arr=(${SCAN_PARAMS})" -else - scan_arr=() -fi -# Parse utils-specific params -if [ -n "${UTILS_PARAMS}" ]; then - eval "utils_arr=(${UTILS_PARAMS})" -else - utils_arr=() -fi +# 1. Setup Global Variables +export output_file=./output.log +echo "Server URL: $GITHUB_SERVER_URL" -# Parse results-specific params -if [ -n "${RESULTS_PARAMS}" ]; then - eval "results_arr=(${RESULTS_PARAMS})" +# 2. Determine Environment (Cloud vs On-Prem) +if [ "$GITHUB_SERVER_URL" = "https://github.com" ]; then + echo "Detected GitHub Cloud" + export IS_CLOUD=true else - results_arr=() + echo "Detected GitHub Enterprise Server" + export IS_CLOUD=false fi -# Backward compatibility: Support ADDITIONAL_PARAMS -if [ -n "${ADDITIONAL_PARAMS}" ] && [ -z "${SCAN_PARAMS}" ]; then - echo "⚠️ ADDITIONAL_PARAMS is deprecated. Please use SCAN_PARAMS instead." - eval "scan_arr=(${ADDITIONAL_PARAMS})" -fi - -# Combine global + scan-specific params -combined_scan_params=("${global_arr[@]}" "${scan_arr[@]}") - +# A. Multi-Registry Authentication +source /app/scripts/auth.sh -/app/bin/cx scan create --project-name "${PROJECT_NAME}" -s "${SOURCE_DIR}" --branch "${BRANCH#refs/heads/}" --scan-info-format json --agent "Github Action" "${combined_scan_params[@]}" | tee -i $output_file -exitCode=${PIPESTATUS[0]} +# B. Scan Execution +source /app/scripts/scan.sh -scanId=(`grep -E '"(ID)":"((\\"|[^"])*)"' $output_file | cut -d',' -f1 | cut -d':' -f2 | tr -d '"'`) +# C. PR Decoration +source /app/scripts/pr_decoration.sh -echo "cxcli=$(cat $output_file | tr -d '\r\n')" >> $GITHUB_OUTPUT - -if [ -n "$scanId" ] && [ -n "${PR_NUMBER}" ]; then - echo "Creating PR decoration for scan ID:" $scanId - # Combine global + utils-specific params - combined_utils_params=("${global_arr[@]}" "${utils_arr[@]}") - /app/bin/cx utils pr github --scan-id "${scanId}" --namespace "${NAMESPACE}" --repo-name "${REPO_NAME}" --pr-number "${PR_NUMBER}" --token "${GITHUB_TOKEN}" "${combined_utils_params[@]}" -else - echo "PR decoration not created." -fi - - -if [ -n "$scanId" ]; then - # Combine global + results-specific params - combined_results_params=("${global_arr[@]}" "${results_arr[@]}") - /app/bin/cx results show --scan-id "${scanId}" --report-format markdown "${combined_results_params[@]}" - cat ./cx_result.md >$GITHUB_STEP_SUMMARY - rm ./cx_result.md - echo "cxScanID=$scanId" >> $GITHUB_OUTPUT -fi +# D. Results Reporting +source /app/scripts/results.sh -if [ $exitCode -eq 0 ] -then - echo "Scan completed" +# 4. Final Exit Handling +if [ $exitCode -eq 0 ]; then + echo "Scan completed successfully." else - echo "Scan failed" - exit $exitCode + echo "Scan failed." + exit $exitCode fi \ No newline at end of file diff --git a/scripts/auth.sh b/scripts/auth.sh new file mode 100644 index 0000000..9ad1626 --- /dev/null +++ b/scripts/auth.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# ------------------------------------------------------ +# Logic: Handle Registry Authentication +# ------------------------------------------------------ + +if [[ -n "$REGISTRIES" ]]; then + echo "🔑 Creating multi-registry auth.json..." + mkdir -p /github/home/.config/containers + auths_entries="" + + for reg in $REGISTRIES; do + # Convert registry to env var friendly form (dots & dashes to underscores, uppercase) + env_suffix=$(echo "$reg" | tr '.-' '_' | tr '[:lower:]' '[:upper:]') + + user_var="USERNAME_${env_suffix}" + pass_var="PASSWORD_${env_suffix}" + + user="${!user_var}" + pass="${!pass_var}" + + if [[ -n "$user" && -n "$pass" ]]; then + encoded=$(echo -n "${user}:${pass}" | base64 -w0) + auths_entries+="\"$reg\": {\"auth\": \"$encoded\"}," + echo "✅ Added credentials for $reg" + else + echo "⚠️ Skipping $reg — missing username/password" + fi + done + + # Remove trailing comma and wrap in JSON + auths_entries="${auths_entries%,}" + echo "{\"auths\": {${auths_entries}}}" > /github/home/.config/containers/auth.json + echo "✅ Auth.json created at /github/home/.config/containers/auth.json" +else + echo "⚠️ No REGISTRIES specified, skipping auth.json creation." +fi diff --git a/scripts/pr_decoration.sh b/scripts/pr_decoration.sh new file mode 100644 index 0000000..330f0ff --- /dev/null +++ b/scripts/pr_decoration.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +# ------------------------------------------------------ +# Logic: PR Decoration +# ------------------------------------------------------ + +# Parse utils-specific params +if [ -n "${UTILS_PARAMS}" ]; then + eval "utils_arr=(${UTILS_PARAMS})" +else + utils_arr=() +fi + +combined_utils_params=("${global_arr[@]}" "${utils_arr[@]}") + +# Detect if customer manually set code-repository-url +USER_PROVIDED_CODE_REPO_URL=false +for param in "${combined_utils_params[@]}"; do + if [[ "$param" == "--code-repository-url" ]] || [[ "$param" == --code-repository-url=* ]]; then + USER_PROVIDED_CODE_REPO_URL=true + break + fi +done + +if [ -n "$scanId" ] && [ -n "${PR_NUMBER}" ]; then + echo "Creating PR decoration for scan ID: $scanId" + + # Build base command + base_cmd=( + /app/bin/cx utils pr github + --scan-id "${scanId}" + --namespace "${NAMESPACE}" + --repo-name "${REPO_NAME}" + --pr-number "${PR_NUMBER}" + --token "${GITHUB_TOKEN}" + ) + + # 1. If user manually provided --code-repository-url, use it exactly as-is + if [ "$USER_PROVIDED_CODE_REPO_URL" = true ]; then + echo "User provided custom --code-repository-url. Using it." + + # 2. Else if on-prem server (IS_CLOUD=false), add our default on-prem URL + elif [ "$IS_CLOUD" = false ]; then + echo "Detected On-Prem GitHub. Adding default code-repository-url." + base_cmd+=(--code-repository-url "${GITHUB_SERVER_URL}") + + # 3. Else Cloud,do nothing + else + echo "GitHub Cloud detected. No extra code-repository-url needed." + fi + + # Append ALL utils parameters (including user's custom params) + base_cmd+=("${combined_utils_params[@]}") + + # Execute + "${base_cmd[@]}" + +else + echo "PR decoration not created" +fi diff --git a/scripts/results.sh b/scripts/results.sh new file mode 100644 index 0000000..bd08575 --- /dev/null +++ b/scripts/results.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# ------------------------------------------------------ +# Logic: Generate Results/Report +# ------------------------------------------------------ + +if [ -n "$scanId" ]; then + # Parse results-specific params + if [ -n "${RESULTS_PARAMS}" ]; then + eval "results_arr=(${RESULTS_PARAMS})" + else + results_arr=() + fi + + # Combine global + results-specific params + combined_results_params=("${global_arr[@]}" "${results_arr[@]}") + + /app/bin/cx results show --scan-id "${scanId}" --report-format markdown "${combined_results_params[@]}" + + cat ./cx_result.md >$GITHUB_STEP_SUMMARY + rm ./cx_result.md + + echo "cxScanID=$scanId" >> $GITHUB_OUTPUT +fi diff --git a/scripts/scan.sh b/scripts/scan.sh new file mode 100644 index 0000000..c61a627 --- /dev/null +++ b/scripts/scan.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# ------------------------------------------------------ +# Logic: Parse Params and Run Scan +# ------------------------------------------------------ + +# Parse global params (applied to all commands) +if [ -n "${GLOBAL_PARAMS}" ]; then + eval "global_arr=(${GLOBAL_PARAMS})" +else + global_arr=() +fi + +# Parse scan-specific params +if [ -n "${SCAN_PARAMS}" ]; then + eval "scan_arr=(${SCAN_PARAMS})" +else + scan_arr=() +fi + +# Backward compatibility: Support ADDITIONAL_PARAMS +if [ -n "${ADDITIONAL_PARAMS}" ] && [ -z "${SCAN_PARAMS}" ]; then + echo "⚠️ ADDITIONAL_PARAMS is deprecated. Please use SCAN_PARAMS instead." + eval "scan_arr=(${ADDITIONAL_PARAMS})" +fi + +# Combine global + scan-specific params +combined_scan_params=("${global_arr[@]}" "${scan_arr[@]}") + +# Execute Scan +/app/bin/cx scan create --project-name "${PROJECT_NAME}" -s "${SOURCE_DIR}" --branch "${BRANCH#refs/heads/}" --scan-info-format json --agent "Github Action" "${combined_scan_params[@]}" | tee -i "$output_file" +exitCode=${PIPESTATUS[0]} + +# Extract Scan ID +scanId=(`grep -E '"(ID)":"((\\"|[^"])*)"' "$output_file" | cut -d',' -f1 | cut -d':' -f2 | tr -d '"'`) + +# Output for GitHub Actions +echo "cxcli=$(cat "$output_file" | tr -d '\r\n')" >> $GITHUB_OUTPUT