Skip to content

Commit

Permalink
Merge pull request #11286 from gopidesupavan/fix-monorepo-version-ref…
Browse files Browse the repository at this point in the history
…erence

Support for path based tag structure in github_actions module for monorepo structures.
  • Loading branch information
randhircs authored Jan 16, 2025
2 parents 66caeef + 5463710 commit 127a958
Show file tree
Hide file tree
Showing 11 changed files with 592 additions and 4 deletions.
5 changes: 3 additions & 2 deletions github_actions/lib/dependabot/github_actions/file_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@ def build_github_dependency(file, string)
sig { params(file: Dependabot::DependencyFile, string: String, hostname: String).returns(Dependabot::Dependency) }
def github_dependency(file, string, hostname)
details = T.must(string.match(GITHUB_REPO_REFERENCE)).named_captures
name = "#{details.fetch(OWNER_KEY)}/#{details.fetch(REPO_KEY)}"
repo_name = "#{details.fetch(OWNER_KEY)}/#{details.fetch(REPO_KEY)}"
ref = details.fetch(REF_KEY)
version = version_class.new(ref).to_s if version_class.correct?(ref)
name = version_class.path_based?(ref) ? string : repo_name
Dependency.new(
name: name,
version: version,
Expand All @@ -122,7 +123,7 @@ def github_dependency(file, string, hostname)
groups: [],
source: {
type: "git",
url: "https://#{hostname}/#{name}".downcase,
url: "https://#{hostname}/#{repo_name}".downcase,
ref: ref,
branch: nil
},
Expand Down
9 changes: 7 additions & 2 deletions github_actions/lib/dependabot/github_actions/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ def self.new(version)

sig { params(version: VersionParameter).returns(VersionParameter) }
def self.remove_leading_v(version)
return version unless version.to_s.match?(/\Av([0-9])/)
return version unless version.to_s.match?(%r{\A(?:.*/)?v?([0-9])})

version.to_s.delete_prefix("v")
version.to_s.sub(%r{\A(?:.*/)?v?}, "")
end

sig { params(version: VersionParameter).returns(T::Boolean) }
def self.path_based?(version)
version.to_s.match?(%r{\A.+/v?([0-9])})
end

sig { override.params(version: VersionParameter).returns(T::Boolean) }
Expand Down
280 changes: 280 additions & 0 deletions github_actions/spec/dependabot/github_actions/file_parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,286 @@ def mock_service_pack_request(nwo)
end
end
end

context "with path based semver tag pinned to workflow action" do
let(:workflow_file_fixture_name) { "workflow_monorepo_path_based_semver.yml" }

let(:service_pack_url) do
"https://github.com/gopidesupavan/monorepo-actions.git/info/refs" \
"?service=git-upload-pack"
end

before do
stub_request(:get, service_pack_url)
.to_return(
status: 200,
body: fixture("git", "upload_packs", "github-monorepo-path-based"),
headers: {
"content-type" => "application/x-git-upload-pack-advertisement"
}
)
end

it "has dependencies" do
expect(dependencies.count).to be(2)
end

describe "the path based first dependency" do
subject(:dependency) { dependencies.first }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/gopidesupavan/monorepo-actions",
ref: "init/v1.0.0",
branch: nil
},
metadata: { declaration_string: "gopidesupavan/monorepo-actions/first/init@init/v1.0.0" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("gopidesupavan/monorepo-actions/first/init@init/v1.0.0")
expect(dependency.version).to eq("1.0.0")
expect(dependency.requirements).to eq(expected_requirements)
end
end

describe "the path based last dependency" do
subject(:dependency) { dependencies.last }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/gopidesupavan/monorepo-actions",
ref: "run/v2.0.0",
branch: nil
},
metadata: { declaration_string: "gopidesupavan/monorepo-actions/first/run@run/v2.0.0" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("gopidesupavan/monorepo-actions/first/run@run/v2.0.0")
expect(dependency.version).to eq("2.0.0")
expect(dependency.requirements).to eq(expected_requirements)
end
end
end

context "with path based without semver tag pinned to workflow action" do
let(:workflow_file_fixture_name) { "workflow_monorepo_path_based_without_semver.yml" }

let(:service_pack_url) do
"https://github.com/gopidesupavan/monorepo-actions.git/info/refs" \
"?service=git-upload-pack"
end

before do
stub_request(:get, service_pack_url)
.to_return(
status: 200,
body: fixture("git", "upload_packs", "github-monorepo-path-based"),
headers: {
"content-type" => "application/x-git-upload-pack-advertisement"
}
)
end

it "has dependencies" do
expect(dependencies.count).to be(1)
end

describe "the path based first dependency" do
subject(:dependency) { dependencies.first }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/gopidesupavan/monorepo-actions",
ref: "exec/1.0.0",
branch: nil
},
metadata: { declaration_string: "gopidesupavan/monorepo-actions/second/exec@exec/1.0.0" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("gopidesupavan/monorepo-actions/second/exec@exec/1.0.0")
expect(dependency.version).to eq("1.0.0")
expect(dependency.requirements).to eq(expected_requirements)
end
end
end

context "with mix of path based semver tag pinned to workflow action and direct ref" do
let(:workflow_file_fixture_name) { "workflow_monorepo_path_based_semver_and_direct_ref.yml" }

let(:service_pack_url) do
"https://github.com/gopidesupavan/monorepo-actions.git/info/refs" \
"?service=git-upload-pack"
end

before do
stub_request(:get, service_pack_url)
.to_return(
status: 200,
body: fixture("git", "upload_packs", "github-monorepo-path-based"),
headers: {
"content-type" => "application/x-git-upload-pack-advertisement"
}
)
mock_service_pack_request("actions/checkout")
end

it "has dependencies" do
expect(dependencies.count).to be(3)
end

describe "the path based first dependency" do
subject(:dependency) { dependencies.first }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/gopidesupavan/monorepo-actions",
ref: "init/v1.0.0",
branch: nil
},
metadata: { declaration_string: "gopidesupavan/monorepo-actions/first/init@init/v1.0.0" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("gopidesupavan/monorepo-actions/first/init@init/v1.0.0")
expect(dependency.version).to eq("1.0.0")
expect(dependency.requirements).to eq(expected_requirements)
end
end

describe "the path based last dependency" do
subject(:dependency) { dependencies.last }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/actions/checkout",
ref: "v1",
branch: nil
},
metadata: { declaration_string: "actions/checkout@v1" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("actions/checkout")
expect(dependency.version).to eq("1")
expect(dependency.requirements).to eq(expected_requirements)
end
end
end

context "with mix of path based without semver tag pinned to workflow action and direct ref" do
let(:workflow_file_fixture_name) { "workflow_monorepo_path_based_without_semver_and_direct_ref.yml" }

let(:service_pack_url) do
"https://github.com/gopidesupavan/monorepo-actions.git/info/refs" \
"?service=git-upload-pack"
end

before do
stub_request(:get, service_pack_url)
.to_return(
status: 200,
body: fixture("git", "upload_packs", "github-monorepo-path-based"),
headers: {
"content-type" => "application/x-git-upload-pack-advertisement"
}
)
mock_service_pack_request("actions/checkout")
end

it "has dependencies" do
expect(dependencies.count).to be(2)
end

describe "the path based first dependency" do
subject(:dependency) { dependencies.first }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/gopidesupavan/monorepo-actions",
ref: "init/1.0.0",
branch: nil
},
metadata: { declaration_string: "gopidesupavan/monorepo-actions/first/init@init/1.0.0" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("gopidesupavan/monorepo-actions/first/init@init/1.0.0")
expect(dependency.version).to eq("1.0.0")
expect(dependency.requirements).to eq(expected_requirements)
end
end

describe "the path based last dependency" do
subject(:dependency) { dependencies.last }

let(:expected_requirements) do
[{
requirement: nil,
groups: [],
file: ".github/workflows/workflow.yml",
source: {
type: "git",
url: "https://github.com/actions/checkout",
ref: "v1",
branch: nil
},
metadata: { declaration_string: "actions/checkout@v1" }
}]
end

it "has the right details" do
expect(dependency).to be_a(Dependabot::Dependency)
expect(dependency.name).to eq("actions/checkout")
expect(dependency.version).to eq("1")
expect(dependency.requirements).to eq(expected_requirements)
end
end
end
end

describe "#ecosystem" do
Expand Down
Loading

0 comments on commit 127a958

Please sign in to comment.