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
54 changes: 54 additions & 0 deletions .github/workflows/powershell-pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,57 @@ jobs:
- name: Run QL tests
run: |
codeql test run --threads=0 powershell/ql/test

powershell-bazel-build:
name: powershell-bazel-build
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
if: github.repository == 'microsoft/codeql'
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Build extractor pack
shell: bash
# On Windows `bash` is MSYS2, which reads the `:` in `//powershell:install` as a Unix
# path-list separator and rewrites the label to `/powershell:install`. Excluding args
# prefixed with `//` leaves Bazel labels alone.
env:
MSYS2_ARG_CONV_EXCL: "//"
run: |
bazel build //powershell/...
# `install` resolves its destination through the BUILD file in the runfiles tree, which
# only leads back to the workspace where runfiles are symlinks. On Windows they are
# copies, so without an explicit destination the pack lands in a temporary directory.
bazel run //powershell:install -- --destdir "$GITHUB_WORKSPACE/powershell/extractor-pack"
- name: Setup CodeQL
uses: ./.github/actions/fetch-codeql
with:
channel: release
# Proves the packaged extractor runs with all its native assets on this platform.
- name: Smoke test the extractor
shell: bash
run: |
codeql test run --threads=0 --search-path powershell/extractor-pack \
powershell/ql/test/library-tests/ssa
# Windows' filesystem is case-insensitive, so two pack entries differing only in case
# collide on extraction. Cross-build the win64 pack here because the collision comes from
# RID-specific NuGet payloads and is invisible on a native Linux build.
- name: Check the win64 pack for case-insensitive duplicates
if: matrix.os == 'ubuntu-latest'
shell: bash
env:
MSYS2_ARG_CONV_EXCL: "//"
run: |
bazel run //powershell:install --@rules_dotnet//dotnet:rid=win-x64 \
-- --destdir "$GITHUB_WORKSPACE/powershell/extractor-pack-win"
duplicates="$(cd powershell/extractor-pack-win && find . -type f | tr '[:upper:]' '[:lower:]' | sort | uniq -d)"
if [ -n "$duplicates" ]; then
echo "::error::paths differing only by case in the win64 pack:"
echo "$duplicates"
exit 1
fi
5 changes: 4 additions & 1 deletion MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ bazel_dep(name = "nlohmann_json", version = "3.12.0.bcr.1", repo_name = "json")
bazel_dep(name = "fmt", version = "12.1.0-codeql.1")
bazel_dep(name = "rules_kotlin", version = "2.2.2-codeql.1")
bazel_dep(name = "gazelle", version = "0.50.0")
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.1")
bazel_dep(name = "rules_dotnet", version = "0.21.5-codeql.2")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
bazel_dep(name = "rules_rust", version = "0.69.0")
bazel_dep(name = "rules_swift", version = "4.0.0-rc5-codeql.1")
Expand Down Expand Up @@ -187,6 +187,9 @@ register_toolchains("@dotnet_toolchains//:all")
csharp_main_extension = use_extension("//csharp:paket.main_extension.bzl", "main_extension")
use_repo(csharp_main_extension, "paket.main")

powershell_extension = use_extension("//powershell:paket.powershell_extension.bzl", "powershell_extension")
use_repo(powershell_extension, "paket.powershell")

pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "codegen_deps",
Expand Down
4 changes: 2 additions & 2 deletions csharp/scripts/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ py_binary(
py_binary(
name = "gen-assembly-info",
srcs = ["gen-assembly-info.py"],
visibility = ["//csharp:__subpackages__"],
visibility = ["//visibility:public"],
deps = ["@rules_python//python/runfiles"],
)

Expand All @@ -19,5 +19,5 @@ genrule(
outs = ["GitAssemblyInfo.cs"],
cmd = "$(execpath :gen-git-assembly-info) $@ $(SRCS)",
tools = [":gen-git-assembly-info"],
visibility = ["//csharp:__subpackages__"],
visibility = ["//visibility:public"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"rules_dotnet"

module(
name = "rules_dotnet",
version = "0.21.5-codeql.2",
bazel_compatibility = [">=8.0.0"],
compatibility_level = 0,
)

dotnet = use_extension("@rules_dotnet//dotnet:extensions.bzl", "dotnet")
dotnet.toolchain(dotnet_version = "10.0.100")
dotnet.toolchain(
name = "dotnet_apphost",
dotnet_version = "10.0.100",
)
use_repo(dotnet, "dotnet_toolchains")

# These toolchains are used to build the apphost shimmer
use_repo(dotnet, "dotnet_apphost_x86_64-unknown-linux-gnu")
use_repo(dotnet, "dotnet_apphost_arm64-unknown-linux-gnu")
use_repo(dotnet, "dotnet_apphost_aarch64-apple-darwin")
use_repo(dotnet, "dotnet_apphost_x86_64-apple-darwin")
use_repo(dotnet, "dotnet_apphost_x86_64-pc-windows-msvc")
use_repo(dotnet, "dotnet_apphost_arm64-pc-windows-msvc")

register_toolchains("@dotnet_toolchains//:all")

paket2bazel_dependencies_extension = use_extension("@rules_dotnet//dotnet:paket.paket2bazel_dependencies_extension.bzl", "paket2bazel_dependencies_extension")
use_repo(paket2bazel_dependencies_extension, "paket.paket2bazel_dependencies")

rules_dotnet_nuget_packages_extension = use_extension("@rules_dotnet//dotnet:paket.rules_dotnet_nuget_packages_extension.bzl", "rules_dotnet_nuget_packages_extension")
use_repo(rules_dotnet_nuget_packages_extension, "paket.rules_dotnet_nuget_packages")

targeting_packs_extension = use_extension("@rules_dotnet//dotnet/private/sdk/targeting_packs:dotnet.targeting_packs_extension.bzl", "targeting_packs_extension")
use_repo(targeting_packs_extension, "dotnet.targeting_packs")

runtime_packs_extension = use_extension("@rules_dotnet//dotnet/private/sdk/runtime_packs:dotnet.runtime_packs_extension.bzl", "runtime_packs_extension")
use_repo(runtime_packs_extension, "dotnet.runtime_packs")

apphost_packs_extension = use_extension("@rules_dotnet//dotnet/private/sdk/apphost_packs:dotnet.apphost_packs_extension.bzl", "apphost_packs_extension")
use_repo(apphost_packs_extension, "dotnet.apphost_packs")

bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "bazel_lib", version = "3.0.0")
bazel_dep(name = "rules_shell", version = "0.6.1")

# Dev dependencies
bazel_dep(name = "rules_pkg", version = "1.1.0", dev_dependency = True)
bazel_dep(name = "gazelle", version = "0.44.0", dev_dependency = True, repo_name = "bazel_gazelle")
bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.7.1", dev_dependency = True)
bazel_dep(name = "rules_cc", version = "0.1.2", dev_dependency = True)
bazel_dep(name = "rules_testing", version = "0.8.0", dev_dependency = True)
bazel_dep(name = "bazel_ci_rules", version = "1.0.0", dev_dependency = True)
bazel_dep(name = "dotnet_test_resources_other_repo", version = "", dev_dependency = True)
local_path_override(
module_name = "dotnet_test_resources_other_repo",
path = "dotnet/private/tests/resources/other_repo",
)

rules_dotnet_dev_nuget_packages_extension = use_extension("@rules_dotnet//dotnet:paket.rules_dotnet_dev_nuget_packages_extension.bzl", "rules_dotnet_dev_nuget_packages_extension", dev_dependency = True)
use_repo(rules_dotnet_dev_nuget_packages_extension, "paket.rules_dotnet_dev_nuget_packages")

rules_dotnet_nuget_resource_assemblies_tests_extension = use_extension("@rules_dotnet//dotnet:paket.rules_dotnet_nuget_resource_assemblies_tests_extension.bzl", "rules_dotnet_nuget_resource_assemblies_tests_extension", dev_dependency = True)
use_repo(rules_dotnet_nuget_resource_assemblies_tests_extension, "paket.rules_dotnet_nuget_resource_assemblies_tests")

internal_dev_deps = use_extension("@rules_dotnet//dotnet:internal_dev_deps.bzl", "internal_dev_deps", dev_dependency = True)
use_repo(internal_dev_deps, "buildkite_config")

rules_dotnet_nuget_tool_tests_extension = use_extension("@rules_dotnet//dotnet:paket.rules_dotnet_nuget_tool_tests_extension.bzl", "rules_dotnet_nuget_tool_tests_extension", dev_dependency = True)
use_repo(rules_dotnet_nuget_tool_tests_extension, "paket.rules_dotnet_nuget_tool_tests")
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
`tfm_filegroup` binds a TFM to a RID without gating on it in two cases:

* when a TFM maps to a single RID the alias points straight at that RID's files, so
e.g. `Microsoft.Management.Infrastructure.Runtime.Unix` is published for every RID.
Its `Microsoft.Management.Infrastructure.dll` then collides with the lowercase
`microsoft.management.infrastructure.dll` from `...Runtime.Win` on case-insensitive
filesystems. Route these through the same `select` as the multi-RID case.
* when a TFM only has RIDs and no compatible sibling the `select` has no
`//conditions:default`, which fails analysis on every other platform.
`rid_filegroup` already resolves to an empty list in that situation; do the same here.

--- a/dotnet/private/rules/nuget/nuget_archive.bzl
+++ b/dotnet/private/rules/nuget/nuget_archive.bzl
@@ -621,15 +621,10 @@
# that are incompatible with the current configuration
tfm_target_mapping = {}
for (tfm, rids) in tfm_rids.items():
- if len(rids) == 1:
- actual = None
- if rids[0] == "default":
- actual = "%s_%s_files" % (name, tfm)
- else:
- actual = "%s_%s_%s_files" % (name, tfm, rids[0])
+ if len(rids) == 1 and rids[0] == "default":
native.alias(
name = "%s_%s_alias" % (name, tfm),
- actual = actual,
+ actual = "%s_%s_files" % (name, tfm),
visibility = ["//visibility:public"],
)
tfm_target_mapping[tfm] = ":%s_%s_alias" % (name, tfm)
@@ -642,6 +637,14 @@
next_tfm = get_highest_compatible_target_framework(tfm, [t for t in tfm_rids.keys() if t != tfm])
if next_tfm:
map["//conditions:default"] = ":%s_%s_alias" % (name, next_tfm)
+ else:
+ empty = "%s_%s_empty" % (name, tfm)
+ native.filegroup(
+ name = empty,
+ srcs = [],
+ visibility = ["//visibility:public"],
+ )
+ map["//conditions:default"] = ":%s" % empty
native.alias(
name = "%s_%s_alias" % (name, tfm),
actual = select(map),
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
--- a/dotnet/private/rules/nuget/nuget_archive.bzl 2025-09-04 16:14:49.402400198 +0200
+++ b/dotnet/private/rules/nuget/nuget_archive.bzl 2025-09-04 16:12:16.577010334 +0200
@@ -123,7 +123,7 @@
return

# If the folder is empty we do nothing
- if file.endswith(tfm) or file.endswith(tfm + "/"):
+ if file.find("/", tfm_end + 1) != -1:
return

group = groups[group_name]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"integrity": "sha256-fgvSYSFAtQh+MuDzTji3iWR642WwefGCSzCLLUtZyFE=",
"strip_prefix": "rules_dotnet-0.21.5",
"url": "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/bazel-contrib/rules_dotnet/releases/download/v0.21.5/rules_dotnet-v0.21.5.tar.gz",
"patches": {
"revert_additional_files_in_nuget_archive.patch": "sha256-FzMKXeHVhIBXQRCNFB0EANDszgJc/BBaPgWCzkbW9Ck=",
"gate_rid_specific_tfm_groups.patch": "sha256-rEDTV56GnexS1ijgYhxcrWRM0TIMuoS9IESqGUEyR0Q="
},
"patch_strip": 1
}
3 changes: 2 additions & 1 deletion misc/bazel/registry/modules/rules_dotnet/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"github:bazel-contrib/rules_dotnet"
],
"versions": [
"0.21.5-codeql.1"
"0.21.5-codeql.1",
"0.21.5-codeql.2"
],
"yanked_versions": {}
}
22 changes: 22 additions & 0 deletions misc/bazel/semmle_code_stub/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Stand-in for the `git_info` target provided by the internal repository, so that targets
# depending on it (e.g. `//csharp/scripts:git-assembly-info-src`) can be built from this
# repository in isolation.
genrule(
name = "git-info-files",
outs = [
"git-describe-all.log",
"git-ql-describe-all.log",
"git-ql-rev-parse.log",
],
cmd = """
echo unknown > $(location git-describe-all.log)
echo no-git > $(location git-ql-describe-all.log)
echo unknown > $(location git-ql-rev-parse.log)
""",
)

filegroup(
name = "git_info",
srcs = [":git-info-files"],
visibility = ["//visibility:public"],
)
12 changes: 12 additions & 0 deletions powershell/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"paket": {
"version": "10.3.1",
"commands": [
"paket"
]
}
}
}
1 change: 1 addition & 0 deletions powershell/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
extractor/**/bin/*
extractor/**/obj/*
paket-files/
42 changes: 42 additions & 0 deletions powershell/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
load("//misc/bazel:pkg.bzl", "codeql_pack")

package(default_visibility = ["//visibility:public"])

alias(
name = "dbscheme",
actual = "//powershell/ql/lib:dbscheme",
)

alias(
name = "dbscheme-stats",
actual = "//powershell/ql/lib:dbscheme-stats",
)

pkg_files(
name = "dbscheme-group",
srcs = [
":dbscheme",
":dbscheme-stats",
],
strip_prefix = None,
)

pkg_files(
name = "extra-files",
srcs = [
":codeql-extractor.yml",
"//:LICENSE",
],
)

codeql_pack(
name = "powershell",
srcs = [
":dbscheme-group",
":extra-files",
"//powershell/downgrades",
"//powershell/extractor/Semmle.Extraction.PowerShell.Standalone",
"//powershell/tools",
],
)
2 changes: 2 additions & 0 deletions powershell/codeql-extractor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ column_kind: "utf16"
legacy_qltest_extraction: true
build_modes:
- none
default_queries:
- microsoft/powershell-queries
file_types:
- name: powershell
display_name: powershellscripts
Expand Down
12 changes: 12 additions & 0 deletions powershell/downgrades/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
load("@rules_pkg//:mappings.bzl", "pkg_files", "strip_prefix")

pkg_files(
name = "downgrades",
srcs = glob(
["**"],
exclude = ["BUILD.bazel"],
),
prefix = "downgrades",
strip_prefix = strip_prefix.from_pkg(),
visibility = ["//powershell:__pkg__"],
)
Empty file.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load(
"//misc/bazel:csharp.bzl",
"codeql_csharp_binary",
)

codeql_csharp_binary(
name = "Semmle.Extraction.PowerShell.Standalone",
srcs = glob([
"*.cs",
]),
visibility = ["//powershell:__subpackages__"],
deps = [
"//powershell/extractor/Semmle.Extraction.PowerShell",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<AssemblyName>Semmle.Extraction.PowerShell.Standalone</AssemblyName>
<RootNamespace>Semmle.Extraction.PowerShell.Standalone</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
Expand Down
Loading
Loading