diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml new file mode 100644 index 00000000..df5c2daa --- /dev/null +++ b/.github/workflows/code-analysis.yml @@ -0,0 +1,29 @@ +name: Code Analysis + +on: + pull_request: + +jobs: + static_analysis: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Set Up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build Docker Image + run: docker build --build-arg RUBY_VERSION=3.2.3 -t code-analysis -f Dockerfile.analysis . + + - name: Run Code Analysis + run: | + mkdir -p reports + docker run --rm -v $(pwd)/reports:/app/reports code-analysis + + - name: Upload Reports + uses: actions/upload-artifact@v4 + with: + name: code-analysis-reports + path: reports/ diff --git a/Dockerfile.analysis b/Dockerfile.analysis new file mode 100644 index 00000000..1fd8b466 --- /dev/null +++ b/Dockerfile.analysis @@ -0,0 +1,37 @@ +# Use a base image with Ruby, version set by ARG (default: 3.2) +ARG RUBY_VERSION=3.2 +FROM ruby:$RUBY_VERSION + +# Set environment variables +ENV APP_HOME=/app +WORKDIR $APP_HOME + +# Install necessary packages for Rails and system dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + libpq-dev \ + nodejs \ + yarn \ + && rm -rf /var/lib/apt/lists/* + +# Copy the application files +COPY . . + +# Install Bundler +RUN gem install bundler + +# Install dependencies +RUN bundle install + +# Copy the entrypoint script and set execution permissions +COPY entrypoint.rb /entrypoint.rb +RUN chmod +x /entrypoint.rb + +# Ensure reports directory exists before declaring a volume +RUN mkdir -p $APP_HOME/reports && chmod 777 $APP_HOME/reports + +# Declare a volume for the reports directory +VOLUME ["/app/reports"] + +# Set the entrypoint +ENTRYPOINT ["/entrypoint.rb"] diff --git a/bin/run_code_analysis b/bin/run_code_analysis new file mode 100755 index 00000000..b920d279 --- /dev/null +++ b/bin/run_code_analysis @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby + +require 'optparse' + +# Default Ruby version +ruby_version = "3.2" + +# Parse command-line options +OptionParser.new do |opts| + opts.banner = "Usage: build_and_run.rb --ruby-version " + + opts.on("--ruby-version VERSION", "Specify the Ruby version for the Docker build") do |version| + ruby_version = version + end +end.parse! + +# Docker image name +image_name = "code-analysis" + +puts "🚀 Building Docker image with Ruby #{ruby_version}..." +build_command = "docker build --build-arg RUBY_VERSION=#{ruby_version} -t #{image_name} -f Dockerfile.analysis ." +puts "🔨 Running: #{build_command}" +system(build_command) || abort("❌ Docker build failed!") + +# Ensure reports directory exists on the host +reports_dir = File.expand_path("./reports") +Dir.mkdir(reports_dir) unless Dir.exist?(reports_dir) + +puts "🏃 Running container with reports mounted..." +run_command = "docker run --rm -v #{reports_dir}:/app/reports #{image_name}" +puts "🔧 Running: #{run_command}" +system(run_command) || abort("❌ Docker run failed!") + +puts "✅ Done! Check the 'reports/' directory for analysis results." diff --git a/entrypoint.rb b/entrypoint.rb new file mode 100644 index 00000000..ecd99138 --- /dev/null +++ b/entrypoint.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +require "bundler" + +APP_ROOT = "/app/#{__dir__}" +REPORTS_DIR = File.join(APP_ROOT, "reports") + +puts "Checking for rubycritic and skunk in the bundle..." + +# Check if gems are installed +def gem_installed?(gem_name) + Bundler.locked_gems.dependencies.key?(gem_name) +end + +# Add missing gems and install +missing_gems = [] +missing_gems << "rubycritic" unless gem_installed?("rubycritic") +missing_gems << "skunk" unless gem_installed?("skunk") + +unless missing_gems.empty? + puts "Adding missing gems: #{missing_gems.join(", ")}" + bundle_add_command = "bundle add" + missing_gems.each { |gem| bundle_add_command.concat(" #{gem}") } + system(bundle_add_command) + system("bundle install") +end + +# Ensure the reports directory exists +# Dir.mkdir(REPORTS_DIR) unless Dir.exist?(REPORTS_DIR) +# File.chmod(0777, REPORTS_DIR) + +puts "Running rubycritic and skunk, saving reports to #{REPORTS_DIR}..." + +# Run rubycritic and skunk, directing output to the reports folder +system("bundle exec rubycritic -p #{REPORTS_DIR}/rubycritic") +system("bundle exec skunk -o #{REPORTS_DIR}/skunk-report.txt") + +puts "Analysis complete. Check the reports folder for results."