Skip to content

Refactor Codacy workflow for asset retrieval #121

Refactor Codacy workflow for asset retrieval

Refactor Codacy workflow for asset retrieval #121

Workflow file for this run

# Codacy Security Scan (revised: replaced docker action with codacy-cli-v2 install+analyze)
# - Uses codacy-cli-v2 installer to run analyze when the docker image pre-pull succeeds
# Codacy security scan action usage and parameters, see
# https://github.com/codacy/codacy-analysis-cli-action.
# For more information on Codacy Analysis CLI in general, see
# https://github.com/codacy/codacy-analysis-cli.
name: Codacy Security Scan
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '44 7 * * 0'
permissions:
contents: read
jobs:
codacy-security-scan:
name: Codacy Security Scan
runs-on: ubuntu-latest
env:
CLI_VERSION: "4.0.0"
CODACY_CLI_V2_VERSION: ""
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
MAX_PULL_RETRIES: "6"
PULL_RETRY_BASE: "5"
permissions:
contents: read
security-events: write
actions: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for non-UTF-8 files
run: |
find . -type f -exec file --mime {} + | grep -v 'charset=utf-8' || true
- name: Pre-pull Codacy CLI Docker image (with exponential backoff + jitter)
run: |
set -euo pipefail
IMAGE="codacy/codacy-analysis-cli:${CLI_VERSION}"
MAX_RETRIES=${MAX_PULL_RETRIES}
RETRY_BASE=${PULL_RETRY_BASE}
echo "CODACY_DOCKER_OK=false" >> $GITHUB_ENV
for i in $(seq 1 $MAX_RETRIES); do
echo "Attempt $i to pull $IMAGE"
if docker pull "$IMAGE"; then
echo "Successfully pulled $IMAGE"
echo "CODACY_DOCKER_OK=true" >> $GITHUB_ENV
break
fi
if [ "$i" -lt "$MAX_RETRIES" ]; then
# exponential backoff with jitter
sleep_time=$(( RETRY_BASE * 2 ** (i - 1) ))
jitter=$(( (RANDOM % 5) + 1 ))
total_sleep=$(( sleep_time + jitter ))
if [ "$total_sleep" -gt 300 ]; then
total_sleep=300
fi
echo "Failed to pull $IMAGE (attempt $i). Retrying in ${total_sleep}s..."
sleep "$total_sleep"
else
echo "Failed to pull $IMAGE after $i attempts."
fi
done
if [ "${CODACY_DOCKER_OK:-}" != "true" ]; then
echo "::warning::Could not pull $IMAGE after $MAX_RETRIES attempts. Fallback will run."
fi
- name: Run Codacy CLI v2 (install & analyze)
if: env.CODACY_DOCKER_OK == 'true'
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
CODACY_CLI_V2_VERSION: ${{ env.CODACY_CLI_V2_VERSION }}
run: |
set -euo pipefail
echo "Installing codacy-cli-v2 via the official installer script"
if [ -n "${CODACY_CLI_V2_VERSION:-}" ]; then
export CODACY_CLI_V2_VERSION
fi
bash <(curl -Ls https://raw.githubusercontent.com/codacy/codacy-cli-v2/main/codacy-cli.sh)
echo "Running codacy-cli analyze to produce SARIF (results.sarif)"
if [ -n "${CODACY_PROJECT_TOKEN:-}" ]; then
TOKEN_ARG="--project-token ${CODACY_PROJECT_TOKEN}"
else
TOKEN_ARG=""
fi
codacy-cli analyze --format sarif --output results.sarif ${TOKEN_ARG} --gh-code-scanning-compat --verbose || true
- name: Run Codacy Analysis CLI (robust fallback via GitHub Releases API)
if: env.CODACY_DOCKER_OK != 'true'
env:
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
CLI_VERSION: ${{ env.CLI_VERSION }}
run: |
set -euo pipefail
echo "Fallback: attempt to obtain a Codacy Analysis CLI release asset (tag: ${CLI_VERSION})"
REPO="codacy/codacy-analysis-cli"
PREFERRED_TAG="${CLI_VERSION}"
get_release_json() {
tag="$1"
if [ -n "$tag" ]; then
url="https://api.github.com/repos/${REPO}/releases/tags/${tag}"
echo "Querying $url"
curl -sS "$url" || return 1
else
url="https://api.github.com/repos/${REPO}/releases/latest"
echo "Querying $url"
curl -sS "$url" || return 1
fi
}
release_json="$(get_release_json "${PREFERRED_TAG}" || true)"
if [ -z "$release_json" ] || echo "$release_json" | grep -q '"message": "Not Found"'; then
echo "Preferred release '${PREFERRED_TAG}' not found. Falling back to latest release."
release_json="$(get_release_json "" )" || { echo "::error::Could not fetch latest release info"; exit 1; }
fi
# Use jq (installed on ubuntu-latest) to pick the best asset:
# Preference order:
# 1) asset name contains 'codacy-analysis-cli' and ends with .zip
# 2) any .zip asset
# 3) any .jar asset
# 4) first asset
asset_url="$(echo "$release_json" | jq -r '
(.assets[] | select(.name | test("codacy-analysis-cli.*\\.zip"; "i")) | .browser_download_url) //
(.assets[] | select(.name | test("\\.zip$"; "i")) | .browser_download_url) //
(.assets[] | select(.name | test("\\.jar$"; "i")) | .browser_download_url) //
(.assets[] | .browser_download_url)
' | grep -v null | head -n1 || true)"
if [ -z "$asset_url" ]; then
echo "::error::No suitable release asset found in the release. Release JSON:"
echo "$release_json"
exit 1
fi
echo "Selected release asset: ${asset_url}"
ARCHIVE_NAME="$(basename "$asset_url")"
echo "Downloading asset to ${ARCHIVE_NAME}"
curl -fSL "$asset_url" -o "$ARCHIVE_NAME" || { echo "::error::Failed to download ${asset_url}"; exit 1; }
echo "Extracting ${ARCHIVE_NAME}"
if file "$ARCHIVE_NAME" | grep -qi zip; then
unzip -q "$ARCHIVE_NAME"
else
echo "Downloaded asset does not appear to be a zip. Proceeding to check for jar or executable."
fi
# Determine runnable CLI (executable or jar)
if [ -x "./codacy-analysis-cli" ]; then
CMD="./codacy-analysis-cli"
elif ls codacy-analysis-cli-* 2>/dev/null | grep -q '\.jar$'; then
JAR="$(ls codacy-analysis-cli-*.jar | head -n1)"
CMD="java -jar ${JAR}"
elif ls *.jar 2>/dev/null | head -n1 >/dev/null 2>&1; then
JAR="$(ls *.jar | head -n1)"
CMD="java -jar ${JAR}"
else
if [ -f "$ARCHIVE_NAME" ] && [ -x "$ARCHIVE_NAME" ]; then
CMD="./${ARCHIVE_NAME}"
else
candidate="$(ls | grep -i codacy | head -n1 || true)"
if [ -n "$candidate" ]; then
if [ -f "$candidate" ]; then
chmod +x "$candidate" || true
CMD="./${candidate}"
fi
fi
fi
fi
if [ -z "${CMD:-}" ]; then
echo "::error::Could not determine a runnable CLI (executable or jar) after downloading and extracting ${ARCHIVE_NAME}."
ls -la
exit 1
fi
echo "Running Codacy CLI fallback via: $CMD"
if [ -n "${CODACY_PROJECT_TOKEN:-}" ]; then
TOKEN_ARG="--project-token ${CODACY_PROJECT_TOKEN}"
else
TOKEN_ARG=""
fi
$CMD analyze --format sarif --output results.sarif ${TOKEN_ARG} --gh-code-scanning-compat --verbose || true
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif