diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4354ed1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM python:3.12-slim + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git \ + curl \ + jq \ + maven \ # For Maven support + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /app + +# Clone dirty-waters +RUN git clone https://github.com/chains-project/dirty-waters.git +WORKDIR /app/dirty-waters + +# Install dirty-waters and its dependencies +RUN pip install -r requirements.txt + +# Create entrypoint script +COPY entrypoint.sh . +RUN chmod +x entrypoint.sh + +ENTRYPOINT ["/app/dirty-waters/entrypoint.sh"] diff --git a/README.md b/README.md index 5f4bdf8..41a3e44 100644 --- a/README.md +++ b/README.md @@ -1 +1,52 @@ -# dirty-waters-action \ No newline at end of file +# dirty-waters-action + +## GitHub Action Usage + +Add this workflow to your repository to analyze dependencies in your pull requests: + +```yaml +name: Dirty Waters Analysis +on: + pull_request: + paths: + - 'package.json' + - 'package-lock.json' + - 'yarn.lock' + - 'pnpm-lock.yaml' + - 'pom.xml' +jobs: + analyze: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v4 + - uses: chains-project/dirty-waters-action@v1 + with: + project_repo: ${{ github.repository }} + version_old: ${{ github.event.pull_request.base.ref }} + version_new: ${{ github.event.pull_request.head.ref }} + package_manager: npm + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + + +The action will: +1. Run on pull requests that modify dependency files +2. Analyze dependencies for software supply chain issues +3. Post results as a PR comment +4. Break CI if high severity issues are found +5. Upload detailed reports as artifacts + +### Inputs + +| Input | Description | Required | Default | +|-------|-------------|----------|---------| +| project_repo | Repository name (owner/repo) | Yes | - | +| version_old | Base version/ref to analyze | Yes | - | +| version_new | New version/ref for diff analysis | No | - | +| package_manager | Package manager (npm, yarn-classic, yarn-berry, pnpm, maven) | Yes | - | +| fail_on_high_severity | Fail CI on high severity issues | No | true | +| comment_on_pr | Post results as PR comment | No | true | diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..7ae3d02 --- /dev/null +++ b/action.yml @@ -0,0 +1,42 @@ +name: 'Dirty Waters Analysis' +description: 'Analyze software supply chain issues in your dependencies' +branding: + icon: 'shield' + color: 'blue' + +inputs: + project_repo: + description: 'Project repository name' + required: true + version_old: + description: 'Old release version to analyze' + required: true + version_new: + description: 'New release version for differential analysis' + required: false + package_manager: + description: 'Package manager used in the project' + required: true + fail_on_high_severity: + description: 'Break CI if high severity issues are found' + required: false + default: 'true' + comment_on_pr: + description: 'Post analysis results as a PR comment' + required: false + default: 'true' + +runs: + using: 'docker' + image: 'Dockerfile' + args: + - '-p' + - '${{ inputs.project_repo }}' + - '-v' + - '${{ inputs.version_old }}' + - '-vn' + - '${{ inputs.version_new }}' + - '-pm' + - '${{ inputs.package_manager }}' + - '-s' + - '${{ inputs.version_new != '''' && ''-d'' || '''' }}' diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..45422d7 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,83 @@ +#!/bin/bash +set -e + +# Check if GITHUB_TOKEN is set +if [ -z "$GITHUB_TOKEN" ]; then + echo "Error: GITHUB_TOKEN is not set" + exit 1 +fi + +export GITHUB_API_TOKEN=$GITHUB_TOKEN + +# Change to the tool directory +cd /app/dirty-waters/tool + +# Extract inputs from environment variables (GitHub Actions sets these automatically) +PROJECT_REPO="${INPUT_PROJECT_REPO}" +VERSION_OLD="${INPUT_VERSION_OLD}" +VERSION_NEW="${INPUT_VERSION_NEW}" +PACKAGE_MANAGER="${INPUT_PACKAGE_MANAGER}" + +# Build the command +CMD="python main.py -p ${PROJECT_REPO} -v ${VERSION_OLD} -s -pm ${PACKAGE_MANAGER}" + +# Add differential analysis if version_new is provided +if [ -n "$VERSION_NEW" ]; then + CMD="$CMD -vn ${VERSION_NEW} -d" +fi + +echo "Running command: $CMD" +eval $CMD + +# Check if any reports were generated +if [ ! -d "results" ]; then + echo "No reports were generated" + exit 1 +fi + +# Get the latest reports +latest_static_report=$(ls -t results/*_static_summary.md | head -n1) +latest_diff_report=$(ls -t results/*_diff_summary.md | head -n1 || true) + +# Prepare the comment content +COMMENT="## Dirty Waters Analysis Results\n\n" +COMMENT+="### Static Analysis\n" +COMMENT+=$(cat "$latest_static_report") + +if [ -n "$latest_diff_report" ]; then + COMMENT+="\n\n### Differential Analysis\n" + COMMENT+=$(cat "$latest_diff_report") +fi + +# Post comment if we're in a PR +if [ "$GITHUB_EVENT_NAME" == "pull_request" ]; then + PR_NUMBER=$(jq -r .pull_request.number "$GITHUB_EVENT_PATH") + REPO_FULL_NAME=$(jq -r .repository.full_name "$GITHUB_EVENT_PATH") + + # Post comment to PR + curl -X POST \ + -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO_FULL_NAME/issues/$PR_NUMBER/comments" \ + -d "{\"body\":$(echo "$COMMENT" | jq -R -s .)}" +fi + +# Move reports to GitHub workspace +mv results/* $GITHUB_WORKSPACE/ + +# Check for high severity issues if enabled +if [ "$INPUT_FAIL_ON_HIGH_SEVERITY" == "true" ]; then + high_severity_count=0 + no_source_code=$(grep -c "Packages with no Source Code URL(⚠️⚠️⚠️):" "$latest_static_report" || true) + github_404=$(grep -c "Packages with Github URLs that are 404(⚠️⚠️⚠️):" "$latest_static_report" || true) + inaccessible_tags=$(grep -c "Packages with inaccessible GitHub tags(⚠️⚠️⚠️):" "$latest_static_report" || true) + + high_severity_count=$((no_source_code + github_404 + inaccessible_tags)) + + if [ $high_severity_count -gt 0 ]; then + echo "::error::Found $high_severity_count high severity supply chain issues!" + exit 1 + fi +fi + +echo "Analysis completed successfully"