Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ce00d41
Add a test for not removing features from skipped ports, see related …
BillyONeal Oct 21, 2025
ddf8c35
Extract calculate_ci_requested_specs function and fix the bug.
BillyONeal Oct 21, 2025
39579e5
Added test sanity check.
BillyONeal Oct 21, 2025
d2e5ab3
Merge remote-tracking branch 'origin/main' into ci-skip-baseline-feat…
BillyONeal Oct 23, 2025
13fa6bc
Eliminate ExclusionsPredicate and extract RandomizerInstance.
BillyONeal Oct 23, 2025
7da5f07
Deoptionalize package_abi()
BillyONeal Oct 23, 2025
83286ec
fixup ci randomizer
BillyONeal Oct 24, 2025
ef28223
Simplify exclusionmap slightly, also record intentionally excluded sp…
BillyONeal Oct 24, 2025
1177c7d
wip
BillyONeal Oct 24, 2025
f39e414
Update src/vcpkg/commands.ci.cpp
BillyONeal Oct 30, 2025
afe1b14
Apply suggestion from @ras0219-msft
BillyONeal Oct 30, 2025
babd750
Another @ras0219-msft suggestion
BillyONeal Oct 30, 2025
aaa0ea7
wip
BillyONeal Oct 31, 2025
848b828
wip
BillyONeal Nov 1, 2025
fa9941a
wip
BillyONeal Nov 4, 2025
63aa137
Merge remote-tracking branch 'origin/main' into ci-skip-baseline-feat…
BillyONeal Nov 4, 2025
ec5581a
Merge remote-tracking branch 'origin/main' into ci-skip-baseline-feat…
BillyONeal Nov 4, 2025
5fa7e82
WIP every report mechanism working except msgCiBaselineUnexpectedFail…
BillyONeal Nov 5, 2025
502ea32
Merge remote-tracking branch 'origin/main' into ci-skip-baseline-feat…
BillyONeal Nov 5, 2025
52c149c
Fix remaining test failures, remove "all results" from the report at …
BillyONeal Nov 6, 2025
f3befa5
Test fixes. Note that CiBaselineUnexpectedPassCascade is deleted and …
BillyONeal Nov 6, 2025
4ca3651
Use Throw-IfNonContains and add assertions for counts
BillyONeal Nov 10, 2025
20ea65c
Merge remote-tracking branch 'origin/main' into ci-skip-baseline-feat…
BillyONeal Nov 10, 2025
788d96d
Add xunit test.
BillyONeal Nov 10, 2025
29ca402
Code review feedback from @ras0219-msft
BillyONeal Nov 12, 2025
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
5 changes: 5 additions & 0 deletions azure-pipelines/e2e-assets/ci-skipped-features/baseline.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
skipped-depends:arm64-osx=skip
skipped-depends:x64-linux=skip
skipped-depends:x64-osx=skip
skipped-depends:x64-windows=skip
skipped-depends:x86-windows=skip
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
message(FATAL_ERROR "This port is skipped and should not be attempted.")
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "skipped-depends",
"version": "1.0.0",
"dependencies": [
{
"name": "skipped-features",
"default-features": false,
"features": [
"fail-if-included"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
if ("fail-if-included" IN_LIST FEATURES)
message(FATAL_ERROR "The feature 'fail-if-included' should not be included.")
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "skipped-features",
"version": "1.0.0",
"features": {
"fail-if-included": {
"description": "This feature should cause a failure if it is included in the build."
}
}
}
24 changes: 18 additions & 6 deletions azure-pipelines/end-to-end-tests-dir/ci.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ $Output = Run-VcpkgAndCaptureOutput ci --dry-run --triplet=$Triplet --x-builtin-
Throw-IfNotFailed
$ErrorOutput = Run-VcpkgAndCaptureStdErr ci --dry-run --triplet=$Triplet --x-builtin-ports-root="$PSScriptRoot/../e2e-ports/ci" --binarysource=clear --ci-baseline="$PSScriptRoot/../e2e-assets/ci/ci.baseline.txt"
Throw-IfNotFailed
if (-not ($Output.Contains("dep-on-feature-not-sup:${Triplet}: cascade"))) {
if (-not ($Output.Contains("dep-on-feature-not-sup:${Triplet}: cascade"))) {
throw 'dep-on-feature-not-sup must cascade because it depends on a features that is not supported'
}
if (-not ($Output.Contains("not-sup-host-b:${Triplet}: skip"))) {
if (-not ($Output.Contains("not-sup-host-b:${Triplet}: unsupported"))) {
throw 'not-sup-host-b must be skipped because it is not supported'
}
if (-not ($Output.Contains("feature-not-sup:${Triplet}: *"))) {
if (-not ($Output.Contains("feature-not-sup:${Triplet}: *:"))) {
throw 'feature-not-sup must be built because the port that causes this port to skip should not be installed'
}
if (-not ($Output.Contains("feature-dep-missing:${Triplet}: *"))) {
if (-not ($Output.Contains("feature-dep-missing:${Triplet}: *:"))) {
throw 'feature-dep-missing must be built because the broken feature is not selected.'
}
if ($Output.Split("*").Length -ne 4) {
Expand All @@ -35,7 +35,7 @@ Throw-IfNotFailed
if (-not ($ErrorOutput.Contains("REGRESSION: not-sup-host-b:${Triplet} is marked as pass but not supported for ${Triplet}."))) {
throw "feature-not-sup's baseline pass entry should result in a regression because the port is not supported"
}
if (-not ($ErrorOutput.Contains("REGRESSION: dep-on-feature-not-sup:${Triplet} is marked as pass but one dependency is not supported for ${Triplet}."))) {
if (-not ($ErrorOutput.Contains("REGRESSION: dep-on-feature-not-sup:${Triplet} cascaded, but it is required to pass. ("))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually a change in behavior: before, a cascade implied by ci.baseline.txt behaved differently than a "surprise" cascade, the new behavior treats all cascades the same. I think the old behavior was a bug based on the fact that we were implementing how that stuff got reported multiple times and all cascades should be the same for reporting purposes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

The red bits are changed.

throw "feature-not-sup's baseline pass entry should result in a regression because the port is cascade for this triplet"
}

Expand Down Expand Up @@ -65,7 +65,7 @@ if (-not ($Output.Contains("vcpkg.json:3:17: error: Trailing comma"))) {
Remove-Problem-Matchers
$emptyDir = "$TestingRoot/empty"
New-Item -ItemType Directory -Path $emptyDir -Force | Out-Null
$Output = Run-VcpkgAndCaptureOutput ci --triplet=$Triplet --x-builtin-ports-root="$emptyDir" --binarysource=clear --overlay-ports="$PSScriptRoot/../e2e-ports/duplicate-file-a" --overlay-ports="$PSScriptRoot/../e2e-ports/duplicate-file-b"
$Output = Run-VcpkgAndCaptureOutput ci @commonArgs --x-builtin-ports-root="$emptyDir" --binarysource=clear --overlay-ports="$PSScriptRoot/../e2e-ports/duplicate-file-a" --overlay-ports="$PSScriptRoot/../e2e-ports/duplicate-file-b"
Throw-IfNotFailed
Restore-Problem-Matchers

Expand All @@ -87,3 +87,15 @@ Throw-IfFailed
if ($Output.Contains("base-port:${Triplet}: SUCCEEDED:")) {
throw 'base-port must not be rebuilt again'
}

# test that features included only by skipped ports are not included
Remove-Problem-Matchers
Refresh-TestRoot
$Output = Run-VcpkgAndCaptureOutput ci @commonArgs --x-builtin-ports-root="$PSScriptRoot/../e2e-assets/ci-skipped-features" --binarysource=clear --ci-baseline="$PSScriptRoot/../e2e-assets/ci-skipped-features/baseline.txt"
Throw-IfFailed
if (-not ($Output -match 'skipped-features:[^:]+: \*:' -and $Output -match 'Building skipped-features:[^@]+@1\.0\.0\.\.\.')) {
throw 'did not attempt to build skipped-features'
}

Restore-Problem-Matchers

1 change: 1 addition & 0 deletions include/vcpkg/base/checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace vcpkg::Checks
}

// If expression is false, call exit_fail.
VCPKG_SAL_ANNOTATION(_Post_satisfies_(_Old_(expression)))
void check_exit(const LineInfo& line_info, bool expression);

// if expression is false, call exit_with_message.
Expand Down
2 changes: 0 additions & 2 deletions include/vcpkg/base/json.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

#include <vcpkg/base/fwd/files.h>
#include <vcpkg/base/fwd/json.h>

#include <vcpkg/base/expected.h>
Expand Down Expand Up @@ -336,7 +335,6 @@ namespace vcpkg::Json
};

ExpectedL<ParsedJson> parse(StringView text, StringView origin);
ParsedJson parse_file(LineInfo li, const ReadOnlyFilesystem&, const Path&);
ExpectedL<Json::Object> parse_object(StringView text, StringView origin);

std::string stringify(const Value&);
Expand Down
32 changes: 24 additions & 8 deletions include/vcpkg/base/message-data.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ DECLARE_MESSAGE(ARegistryPathMustStartWithDollar,
"",
"A registry path must start with `$` to mean the registry root; for example, `$/foo/bar`.")
DECLARE_MESSAGE(ARelaxedVersionString, (), "", "a relaxed version string")
DECLARE_MESSAGE(
RequestedPortsNotInCIPlan,
(),
"",
"one or more ports requested to be installed were not present in the action plan. (Probably a vcpkg bug)")
DECLARE_MESSAGE(ArtifactsBootstrapFailed, (), "", "vcpkg-artifacts is not installed and could not be bootstrapped.")
DECLARE_MESSAGE(ArtifactsOptionIncompatibility, (msg::option), "", "--{option} has no effect on find artifact.")
DECLARE_MESSAGE(ArtifactsOptionJson,
Expand Down Expand Up @@ -379,6 +384,11 @@ DECLARE_MESSAGE(BuildResultBuildFailed,
(),
"Printed after the name of an installed entity to indicate that it failed to build.",
"BUILD_FAILED")
DECLARE_MESSAGE(BuildResultCached,
(),
"Printed after the name of an installed entity to indicate that it was not installed because it "
"already existed in a binary cache.",
"CACHED")
DECLARE_MESSAGE(
BuildResultCacheMissing,
(),
Expand All @@ -400,6 +410,15 @@ DECLARE_MESSAGE(BuildResultExcluded,
"Printed after the name of an installed entity to indicate that the user explicitly "
"requested it not be installed.",
"EXCLUDED")
DECLARE_MESSAGE(BuildResultExcludedByDryRun,
(),
"Printed after the name of an entity that would be installed, but is not due to --dry-run.",
"EXCLUDED_BY_DRY_RUN")
DECLARE_MESSAGE(BuildResultExcludedByParent,
(),
"Printed after the name of an installed entity to indicate that it isn't tested due to an ABI hash in "
"--parent-hashes.",
"EXCLUDED_BY_PARENT")
DECLARE_MESSAGE(
BuildResultFileConflicts,
(),
Expand Down Expand Up @@ -427,6 +446,11 @@ DECLARE_MESSAGE(BuildResultSummaryLine,
(msg::build_result, msg::count),
"Displayed to show a count of results of a build_result in a summary.",
"{build_result}: {count}")
DECLARE_MESSAGE(
BuildResultUnsupported,
(),
"Printed after the name of an installed entity to indicate that it was not included due to a \"supports\" clause.",
"UNSUPPORTED")
DECLARE_MESSAGE(BuildTreesRootDir, (), "", "Buildtrees directory (experimental)")
DECLARE_MESSAGE(BuildTroubleshootingMessage1,
(),
Expand Down Expand Up @@ -467,10 +491,6 @@ DECLARE_MESSAGE(CiBaselineDisallowedCascade,
(msg::spec, msg::path),
"",
"REGRESSION: {spec} cascaded, but it is required to pass. ({path}).")
DECLARE_MESSAGE(CiBaselineIndependentRegression,
(msg::spec, msg::build_result),
"",
"REGRESSION: Independent {spec} failed with {build_result}.")
DECLARE_MESSAGE(CiBaselineRegression,
(msg::spec, msg::build_result, msg::path),
"",
Expand All @@ -495,10 +515,6 @@ DECLARE_MESSAGE(CiBaselineUnexpectedPass,
(msg::spec, msg::path),
"",
"PASSING, REMOVE FROM FAIL LIST: {spec} ({path}).")
DECLARE_MESSAGE(CiBaselineUnexpectedPassCascade,
(msg::spec, msg::triplet),
"",
"REGRESSION: {spec} is marked as pass but one dependency is not supported for {triplet}.")
DECLARE_MESSAGE(CiBaselineUnexpectedPassUnsupported,
(msg::spec, msg::triplet),
"",
Expand Down
3 changes: 2 additions & 1 deletion include/vcpkg/base/messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ namespace vcpkg
{
LocalizedString() = default;
operator StringView() const noexcept;
const std::string& data() const noexcept;
const std::string& data() const& noexcept;
std::string&& data() && noexcept;
const std::string& to_string() const noexcept;
std::string extract_data();

Expand Down
12 changes: 2 additions & 10 deletions include/vcpkg/ci-baseline.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,8 @@ namespace vcpkg
{
std::vector<TripletExclusions> triplets;

void insert(Triplet triplet);
void insert(Triplet triplet, SortedVector<std::string>&& exclusions);
};

struct ExclusionPredicate
{
const ExclusionsMap* data;

bool operator()(const PackageSpec& spec) const;
bool is_excluded(const PackageSpec& spec) const;
};

std::vector<CiBaselineLine> parse_ci_baseline(StringView text, StringView origin, ParseMessages& messages);
Expand All @@ -69,6 +62,5 @@ namespace vcpkg
BuildResult result,
const CiBaselineData& cidata,
const std::string* cifile,
bool allow_unexpected_passing,
bool is_independent);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RE: Removal of the "independent" concept, see discussion #1830

bool allow_unexpected_passing);
}
4 changes: 4 additions & 0 deletions include/vcpkg/commands.build.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ namespace vcpkg
int file_conflicts = 0;
int cascaded_due_to_missing_dependencies = 0;
int excluded = 0;
int excluded_by_parent = 0;
int excluded_by_dry_run = 0;
int unsupported = 0;
int cache_missing = 0;
int cached = 0;
int downloaded = 0;
int removed = 0;

Expand Down
27 changes: 21 additions & 6 deletions include/vcpkg/commands.install.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,33 @@ namespace vcpkg

const BinaryParagraph* get_binary_paragraph() const;
const PackageSpec& get_spec() const { return m_spec; }
Optional<const std::string&> get_abi() const
const std::string* package_abi() const
{
return m_install_action ? m_install_action->package_abi() : nullopt;
if (m_install_action)
{
return m_install_action->package_abi();
}

return nullptr;
}
const std::string& package_abi_or_exit(LineInfo li) const
{
auto pabi = package_abi();
if (!pabi)
{
Checks::unreachable(li);
}

return *pabi;
}
bool is_user_requested_install() const;
Optional<ExtendedBuildResult> build_result;
vcpkg::ElapsedTime timing;
std::chrono::system_clock::time_point start_time;
Optional<const InstallPlanAction&> get_install_plan_action() const
{
return m_install_action ? Optional<const InstallPlanAction&>(*m_install_action) : nullopt;
}
const InstallPlanAction* get_maybe_install_plan_action() const { return m_install_action; }

std::string to_string() const;
void to_string(std::string& out_str) const;

private:
const InstallPlanAction* m_install_action;
Expand Down
3 changes: 2 additions & 1 deletion include/vcpkg/dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ namespace vcpkg

const std::string& public_abi() const;
bool has_package_abi() const;
Optional<const std::string&> package_abi() const;
const std::string* package_abi() const;
const std::string& package_abi_or_exit(LineInfo li) const;
const PreBuildInfo& pre_build_info(LineInfo li) const;
Version version() const;
std::string display_name() const;
Expand Down
4 changes: 4 additions & 0 deletions include/vcpkg/fwd/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ namespace vcpkg
FileConflicts,
CascadedDueToMissingDependencies,
Excluded,
ExcludedByParent,
ExcludedByDryRun,
Unsupported,
CacheMissing,
Cached,
Comment on lines 12 to +17
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ras0219-msft These are the names you said you wanted to bikeshed, go for it

Downloaded,
Removed
};
Expand Down
1 change: 0 additions & 1 deletion include/vcpkg/fwd/ci-baseline.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace vcpkg
struct CiBaselineLine;
struct TripletExclusions;
struct ExclusionsMap;
struct ExclusionPredicate;

enum class CiBaselineState
{
Expand Down
1 change: 1 addition & 0 deletions include/vcpkg/paragraphs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <vcpkg/base/fwd/expected.h>
#include <vcpkg/base/fwd/files.h>
#include <vcpkg/base/fwd/stringview.h>

#include <vcpkg/fwd/binaryparagraph.h>
Expand Down
24 changes: 18 additions & 6 deletions include/vcpkg/xunitwriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@

namespace vcpkg
{
struct CiBuiltResult
{
std::string package_abi;
InternalFeatureSet feature_list;
std::chrono::system_clock::time_point start_time;
ElapsedTime timing;
};

struct CiResult
{
BuildResult code;
Optional<CiBuiltResult> build;

std::string to_string() const;
void to_string(std::string& out_str) const;
};

struct XunitTest;

// https://xunit.net/docs/format-xml-v2
Expand All @@ -22,12 +39,7 @@ namespace vcpkg
// Out of line con/destructor avoids exposing XunitTest
XunitWriter();
~XunitWriter();
void add_test_results(const PackageSpec& spec,
BuildResult build_result,
const ElapsedTime& elapsed_time,
const std::chrono::system_clock::time_point& start_time,
const std::string& abi_tag,
const std::vector<std::string>& features);
void add_test_results(const PackageSpec& spec, const CiResult& result);

std::string build_xml(Triplet controlling_triplet) const;

Expand Down
Loading
Loading