Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Release Gem

on:
workflow_dispatch:

jobs:
release:
name: Publish to RubyGems
runs-on: ubuntu-latest
environment: release-approval
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4.2'
bundler-cache: true

- name: Build gem
run: gem build orion.gemspec

- name: Publish to RubyGems
run: gem push orion-*.gem
env:
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
37 changes: 33 additions & 4 deletions lib/orion/gems/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@ def initialize(lockfile:, include_dev: false)
def run
content = File.read(@lockfile)
parser = Bundler::LockfileParser.new(content)
security = Orion::Gems::Security.new(lockfile: @lockfile)
dev_dependencies = extract_dev_dependencies
security = Orion::Gems::Security.new(
lockfile: @lockfile,
include_dev: @include_dev,
dev_dependencies: dev_dependencies
)

vuln_map = security.vulnerable_gems_map
vulnerabilities = security.detailed_vulnerabilities
vuln_map = security.vulnerable_gems_map || []
vulnerabilities = security.detailed_vulnerabilities || []

analyzed_gems = parser.specs.filter_map do |spec|
is_dev = dev_dependencies.include?(spec.name)
next if is_dev && !@include_dev

analyzed_gems = parser.specs.map do |spec|
{
name: spec.name,
version: spec.version.to_s,
Expand Down Expand Up @@ -96,6 +104,27 @@ def export_gem_report(gems, vulns, include_vulns: false, filename: "orion_gem_re
write_out(dir, "#{filename}.csv", data)
end
end

def extract_dev_dependencies
# assumption here is that Gemfile is next to lockfile
lockfile_path = Pathname.new(@lockfile).dirname.to_s
gemfile_path = File.join(lockfile_path, "Gemfile")

unless File.exist?(gemfile_path)
warn "[orion]: Gemfile not found at #{gemfile_path}. Skipping dev dependency analysis."
return []
end

begin
definition = Bundler::Definition.build(gemfile_path, @lockfile, nil)
definition.dependencies
.select { |dep| dep.groups.include?(:development) }
.map(&:name)
rescue => e
warn "[orion]: Failed to parse Gemfile for dev dependencies: #{e.class} - #{e.message}"
[]
end
end
end
end
end
14 changes: 12 additions & 2 deletions lib/orion/gems/security.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
module Orion
module Gems
class Security
def initialize(lockfile:)
def initialize(lockfile:, include_dev: false, dev_dependencies: nil)
@lockfile = lockfile
@lockfile_dir = Pathname.new(@lockfile).dirname.to_s
@include_dev = include_dev
@dev_dependencies = dev_dependencies || []
@scan_results = nil

begin
Expand All @@ -27,12 +29,16 @@ def scan!

def vulnerable_gems_map
scan!.each_with_object({}) do |result, hash|
next if skip_dev_gem?(result.gem.name)

hash[result.gem.name] = true
end
end

def detailed_vulnerabilities
scan!.map do |result|
scan!.filter_map do |result|
next if skip_dev_gem?(result.gem.name)

{
name: result.gem.name,
advisory: result.advisory.title,
Expand All @@ -42,6 +48,10 @@ def detailed_vulnerabilities
}
end
end

def skip_dev_gem?(name)
!@include_dev && @dev_dependencies.include?(name)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/orion/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Orion
VERSION = "0.5.1"
VERSION = "0.6.1"
end