Skip to content

Commit

Permalink
[vcpkg] Implement 'repository' tag for NuGet binary caching (microsof…
Browse files Browse the repository at this point in the history
…t#13228)

This tag is required to correctly interface with GitHub Packages, because GHP shares a single remote for the entire organization and uses the repository field to associate a package with a particular repository.

This tag will be automatically generated if the default GitHub Actions environment variables are present (GITHUB_XYZ) or if the user defines VCPKG_NUGET_REPOSITORY.

Co-authored-by: Robert Schumacher <[email protected]>
  • Loading branch information
ras0219 and ras0219-msft authored Sep 1, 2020
1 parent 46e25a1 commit a053679
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 10 deletions.
15 changes: 14 additions & 1 deletion toolsrc/include/vcpkg/binarycaching.private.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,22 @@ namespace vcpkg
std::string nupkg_filename() const { return Strings::concat(id, '.', version, ".nupkg"); }
};

namespace details
{
struct NuGetRepoInfo
{
std::string repo;
std::string branch;
std::string commit;
};

NuGetRepoInfo get_nuget_repo_info_from_env();
}

std::string generate_nuspec(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action,
const NugetReference& ref);
const NugetReference& ref,
details::NuGetRepoInfo rinfo = details::get_nuget_repo_info_from_env());

struct XmlSerializer
{
Expand Down
82 changes: 74 additions & 8 deletions toolsrc/src/vcpkg-test/binarycaching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@

using namespace vcpkg;

#define REQUIRE_EQUAL_TEXT(lhs, rhs) \
{ \
auto lhs_lines = Strings::split((lhs), '\n'); \
auto rhs_lines = Strings::split((rhs), '\n'); \
for (size_t i = 0; i < lhs_lines.size() && i < rhs_lines.size(); ++i) \
{ \
INFO("on line: " << i); \
REQUIRE(lhs_lines[i] == rhs_lines[i]); \
} \
REQUIRE(lhs_lines.size() == rhs_lines.size()); \
}

TEST_CASE ("reformat_version semver-ish", "[reformat_version]")
{
REQUIRE(reformat_version("0.0.0", "abitag") == "0.0.0-abitag");
Expand Down Expand Up @@ -81,13 +93,14 @@ Build-Depends: bzip

REQUIRE(ref.nupkg_filename() == "zlib2_x64-windows.1.5.0-packageabi.nupkg");

auto nuspec = generate_nuspec(paths, ipa, ref);
{
auto nuspec = generate_nuspec(paths, ipa, ref, {});
#ifdef _WIN32
#define PKGPATH "C:\\zlib2_x64-windows\\**"
#else
#define PKGPATH "/zlib2_x64-windows/**"
#endif
std::string expected = R"(<package>
std::string expected = R"(<package>
<metadata>
<id>zlib2_x64-windows</id>
<version>1.5.0-packageabi</version>
Expand All @@ -106,14 +119,67 @@ Features: a, b
<files><file src=")" PKGPATH R"(" target=""/></files>
</package>
)";
auto expected_lines = Strings::split(expected, '\n');
auto nuspec_lines = Strings::split(nuspec, '\n');
for (size_t i = 0; i < expected_lines.size() && i < nuspec_lines.size(); ++i)
REQUIRE_EQUAL_TEXT(nuspec, expected);
}

{
INFO("on line: " << i);
REQUIRE(nuspec_lines[i] == expected_lines[i]);
auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue"});
#ifdef _WIN32
#define PKGPATH "C:\\zlib2_x64-windows\\**"
#else
#define PKGPATH "/zlib2_x64-windows/**"
#endif
std::string expected = R"(<package>
<metadata>
<id>zlib2_x64-windows</id>
<version>1.5.0-packageabi</version>
<authors>vcpkg</authors>
<description>NOT FOR DIRECT USE. Automatically generated cache package.
a spiffy compression library wrapper
Version: 1.5
Triplet/Compiler hash: tripletabi
Features: a, b
Dependencies:
</description>
<packageTypes><packageType name="vcpkg"/></packageTypes>
<repository type="git" url="urlvalue"/>
</metadata>
<files><file src=")" PKGPATH R"(" target=""/></files>
</package>
)";
REQUIRE_EQUAL_TEXT(nuspec, expected);
}
{
auto nuspec = generate_nuspec(paths, ipa, ref, {"urlvalue", "branchvalue", "commitvalue"});
#ifdef _WIN32
#define PKGPATH "C:\\zlib2_x64-windows\\**"
#else
#define PKGPATH "/zlib2_x64-windows/**"
#endif
std::string expected = R"(<package>
<metadata>
<id>zlib2_x64-windows</id>
<version>1.5.0-packageabi</version>
<authors>vcpkg</authors>
<description>NOT FOR DIRECT USE. Automatically generated cache package.
a spiffy compression library wrapper
Version: 1.5
Triplet/Compiler hash: tripletabi
Features: a, b
Dependencies:
</description>
<packageTypes><packageType name="vcpkg"/></packageTypes>
<repository type="git" url="urlvalue" branch="branchvalue" commit="commitvalue"/>
</metadata>
<files><file src=")" PKGPATH R"(" target=""/></files>
</package>
)";
REQUIRE_EQUAL_TEXT(nuspec, expected);
}
REQUIRE(nuspec_lines.size() == expected_lines.size());
}

TEST_CASE ("XmlSerializer", "[XmlSerializer]")
Expand Down
39 changes: 38 additions & 1 deletion toolsrc/src/vcpkg/binarycaching.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,9 +973,27 @@ std::string vcpkg::reformat_version(const std::string& version, const std::strin
return Strings::concat("0.0.0-", abi_tag);
}

details::NuGetRepoInfo details::get_nuget_repo_info_from_env()
{
auto vcpkg_nuget_repository = System::get_environment_variable("VCPKG_NUGET_REPOSITORY");
if (auto p = vcpkg_nuget_repository.get())
{
return {std::move(*p)};
}
auto gh_repo = System::get_environment_variable("GITHUB_REPOSITORY").value_or("");
if (gh_repo.empty()) return {};
auto gh_server = System::get_environment_variable("GITHUB_SERVER_URL").value_or("");
if (gh_server.empty()) return {};

return {Strings::concat(gh_server, '/', gh_repo, ".git"),
System::get_environment_variable("GITHUB_REF").value_or(""),
System::get_environment_variable("GITHUB_SHA").value_or("")};
}

std::string vcpkg::generate_nuspec(const VcpkgPaths& paths,
const Dependencies::InstallPlanAction& action,
const vcpkg::NugetReference& ref)
const vcpkg::NugetReference& ref,
details::NuGetRepoInfo rinfo)
{
auto& spec = action.spec;
auto& scf = *action.source_control_file_location.value_or_exit(VCPKG_LINE_INFO).source_control_file;
Expand Down Expand Up @@ -1006,6 +1024,13 @@ std::string vcpkg::generate_nuspec(const VcpkgPaths& paths,
xml.open_tag("packageTypes");
xml.start_complex_open_tag("packageType").text_attr("name", "vcpkg").finish_self_closing_complex_tag();
xml.close_tag("packageTypes").line_break();
if (!rinfo.repo.empty())
{
xml.start_complex_open_tag("repository").text_attr("type", "git").text_attr("url", rinfo.repo);
if (!rinfo.branch.empty()) xml.text_attr("branch", rinfo.branch);
if (!rinfo.commit.empty()) xml.text_attr("commit", rinfo.commit);
xml.finish_self_closing_complex_tag().line_break();
}
xml.close_tag("metadata").line_break();
xml.open_tag("files");
xml.start_complex_open_tag("file")
Expand Down Expand Up @@ -1047,6 +1072,18 @@ void vcpkg::help_topic_binary_caching(const VcpkgPaths&)
"downloading binaries and whether on-demand builds will be uploaded to that remote. It can be specified "
"as 'read', 'write', or 'readwrite'.");
tbl.blank();
tbl.text("The `nuget` and `nugetconfig` source providers additionally respect certain environment variables while "
"generating nuget packages. The `metadata.repository` field will be optionally generated like:\n"
"\n"
" <repository type=\"git\" url=\"$VCPKG_NUGET_REPOSITORY\"/>\n"
"or\n"
" <repository type=\"git\"\n"
" url=\"${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git\"\n"
" branch=\"${GITHUB_REF}\"\n"
" commit=\"${GITHUB_SHA}\"/>\n"
"\n"
"if the appropriate environment variables are defined and non-empty.\n");
tbl.blank();
System::print2(tbl.m_str);
const auto& maybe_cachepath = default_cache_path();
if (auto p = maybe_cachepath.get())
Expand Down

0 comments on commit a053679

Please sign in to comment.