From 0ee6c13db4330bb401ab293e4278736753c05c9d Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Tue, 11 Mar 2025 09:20:41 -0400 Subject: [PATCH 01/11] Add monthly mode (#7024) Add the monthly mode, and pick up other recent changes. --- .github/workflows/quest-bulk.yml | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quest-bulk.yml b/.github/workflows/quest-bulk.yml index 52c3c7ac684..62251d339ef 100644 --- a/.github/workflows/quest-bulk.yml +++ b/.github/workflows/quest-bulk.yml @@ -1,11 +1,19 @@ name: "bulk quest import" on: + schedule: + - cron: '0 10 * * *' # UTC time, that's 5:00 am EST, 2:00 am PST. + - cron: '0 9 6 * *' # This is the morning of the 6th. + workflow_dispatch: inputs: reason: description: "The reason for running the bulk import workflow" required: true default: "Initial import into Quest (Azure DevOps)" + duration: + description: "The number of days to import issues for. Defaults to 5 days." + required: false + default: "5" jobs: bulk-import: @@ -20,15 +28,25 @@ jobs: run: | echo "Reason: ${{ github.event.inputs.reason }}" + - name: Azure OpenID Connect + id: azure-oidc-auth + uses: dotnet/docs-tools/.github/actions/oidc-auth-flow@main + with: + client-id: ${{ secrets.CLIENT_ID }} + tenant-id: ${{ secrets.TENANT_ID }} + audience: ${{ secrets.OSMP_API_AUDIENCE }} + - name: bulk-sequester - if: ${{ github.event_name == 'workflow_dispatch' }} id: bulk-sequester uses: dotnet/docs-tools/actions/sequester@main env: ImportOptions__ApiKeys__GitHubToken: ${{ secrets.GITHUB_TOKEN }} - ImportOptions__ApiKeys__OSPOKey: ${{ secrets.OSPO_KEY }} ImportOptions__ApiKeys__QuestKey: ${{ secrets.QUEST_KEY }} + ImportOptions__ApiKeys__AzureAccessToken: ${{ steps.azure-oidc-auth.outputs.access-token }} + ImportOptions__ApiKeys__SequesterPrivateKey: ${{ secrets.SEQUESTER_PRIVATEKEY }} + ImportOptions__ApiKeys__SequesterAppID: ${{ secrets.SEQUESTER_APPID }} with: org: ${{ github.repository_owner }} repo: ${{ github.repository }} issue: '-1' + duration: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.duration || github.event.schedule == '0 9 6 * *' && -1 || 5 }} From d58cf5601a690466714a6a361877f61af3c1f2ed Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Thu, 13 Mar 2025 12:53:59 -0400 Subject: [PATCH 02/11] Update samples used in delegates articles (#7028) * Update samples used in delegates articles Contributes to dotnet/docs#45199 These samples haven't been updated since .NET 7. It's time to update them while updating the related articles. * Update csharp/events/Program.cs * Apply suggestions from code review Co-authored-by: David Pine --------- Co-authored-by: David Pine --- csharp/delegates-and-events/FileLogger.cs | 54 +++-- csharp/delegates-and-events/Logger.cs | 74 ++----- csharp/delegates-and-events/Program.cs | 27 +-- .../delegates-and-events.csproj | 6 +- csharp/events/Program.cs | 186 ++++++------------ csharp/events/VersionOne.cs | 21 ++ csharp/events/events.csproj | 6 +- 7 files changed, 135 insertions(+), 239 deletions(-) create mode 100644 csharp/events/VersionOne.cs diff --git a/csharp/delegates-and-events/FileLogger.cs b/csharp/delegates-and-events/FileLogger.cs index 42fdbece740..54cce5e51bf 100644 --- a/csharp/delegates-and-events/FileLogger.cs +++ b/csharp/delegates-and-events/FileLogger.cs @@ -1,40 +1,34 @@ -using System; -using System.IO; +namespace DelegatesAndEvents; -namespace DelegatesAndEvents +public class FileLogger { - // - public class FileLogger + private readonly string _logPath; + public FileLogger(string path) { - private readonly string logPath; - public FileLogger(string path) - { - logPath = path; - Logger.WriteMessage += LogMessage; - } + _logPath = path; + Logger.WriteMessage += LogMessage; + } - public void DetachLog() => Logger.WriteMessage -= LogMessage; - // make sure this can't throw. - private void LogMessage(string msg) + public void DetachLog() => Logger.WriteMessage -= LogMessage; + // make sure this can't throw. + private void LogMessage(string msg) + { + try { - try + using (var log = File.AppendText(_logPath)) { - using (var log = File.AppendText(logPath)) - { - log.WriteLine(msg); - log.Flush(); - } - } - catch (Exception) - { - // Hmm. We caught an exception while - // logging. We can't really log the - // problem (since it's the log that's failing). - // So, while normally, catching an exception - // and doing nothing isn't wise, it's really the - // only reasonable option here. + log.WriteLine(msg); + log.Flush(); } } + catch (Exception) + { + // Hmm. We caught an exception while + // logging. We can't really log the + // problem (since it's the log that's failing). + // So, while normally, catching an exception + // and doing nothing isn't wise, it's really the + // only reasonable option here. + } } - // } diff --git a/csharp/delegates-and-events/Logger.cs b/csharp/delegates-and-events/Logger.cs index 56c718b687d..5873b61fd9b 100644 --- a/csharp/delegates-and-events/Logger.cs +++ b/csharp/delegates-and-events/Logger.cs @@ -1,69 +1,27 @@ -using System; +namespace DelegatesAndEvents; -namespace DelegatesAndEvents +public enum Severity { - - // Logger implementation two - // - public enum Severity - { - Verbose, - Trace, - Information, - Warning, - Error, - Critical - } - // - - // - public static class Logger - { - public static Action WriteMessage; - - public static Severity LogLevel { get; set; } = Severity.Warning; - - public static void LogMessage(Severity s, string component, string msg) - { - if (s < LogLevel) - return; - - var outputMsg = $"{DateTime.Now}\t{s}\t{component}\t{msg}"; - WriteMessage(outputMsg); - } - } - // + Verbose, + Trace, + Information, + Warning, + Error, + Critical } -namespace ImplementationOne +public static class Logger { - // - public static class Logger - { - public static Action WriteMessage; + public static Action? WriteMessage; - public static void LogMessage(string msg) - { - WriteMessage(msg); - } - } - // -} - -namespace ImplementationTwo -{ - using DelegatesAndEvents; + public static Severity LogLevel { get; set; } = Severity.Warning; - // - public static class Logger + public static void LogMessage(Severity s, string component, string msg) { - public static Action WriteMessage; + if ((s < LogLevel) || (WriteMessage is null)) + return; - public static void LogMessage(Severity s, string component, string msg) - { - var outputMsg = $"{DateTime.Now}\t{s}\t{component}\t{msg}"; - WriteMessage(outputMsg); - } + var outputMsg = $"{DateTime.Now}\t{s}\t{component}\t{msg}"; + WriteMessage(outputMsg); } - // } diff --git a/csharp/delegates-and-events/Program.cs b/csharp/delegates-and-events/Program.cs index 1747abf2e9a..78acda6a992 100644 --- a/csharp/delegates-and-events/Program.cs +++ b/csharp/delegates-and-events/Program.cs @@ -1,24 +1,11 @@ -using System; +using DelegatesAndEvents; -namespace DelegatesAndEvents -{ - public class Program - { - public static void Main(string[] args) - { - // - Logger.WriteMessage += LoggingMethods.LogToConsole; - // - // - var file = new FileLogger("log.txt"); - // +Logger.WriteMessage += LoggingMethods.LogToConsole; +var file = new FileLogger("log.txt"); - Logger.LogMessage(Severity.Warning, "Console", "This is a warning message"); +Logger.LogMessage(Severity.Warning, "Console", "This is a warning message"); - Logger.LogMessage(Severity.Information, "Console", "Information message one"); - Logger.LogLevel = Severity.Information; +Logger.LogMessage(Severity.Information, "Console", "Information message one"); +Logger.LogLevel = Severity.Information; - Logger.LogMessage(Severity.Information, "Console", "Information message two"); - } - } -} +Logger.LogMessage(Severity.Information, "Console", "Information message two"); diff --git a/csharp/delegates-and-events/delegates-and-events.csproj b/csharp/delegates-and-events/delegates-and-events.csproj index 299d1386b17..16829f3e536 100644 --- a/csharp/delegates-and-events/delegates-and-events.csproj +++ b/csharp/delegates-and-events/delegates-and-events.csproj @@ -1,8 +1,10 @@ - + - net7.0 + net9.0 Exe + enable + enable diff --git a/csharp/events/Program.cs b/csharp/events/Program.cs index c2f07f0c5bb..10e17c43697 100644 --- a/csharp/events/Program.cs +++ b/csharp/events/Program.cs @@ -1,155 +1,87 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; +var fileLister = new FileSearcher(); +int filesFound = 0; -namespace EventSampleCode +EventHandler onFileFound = (sender, eventArgs) => { - class Program - { - static void Main(string[] args) - { - var fileLister = new FileSearcher(); - int filesFound = 0; + Console.WriteLine(eventArgs.FoundFile); + filesFound++; +}; - // - EventHandler onFileFound = (sender, eventArgs) => - { - Console.WriteLine(eventArgs.FoundFile); - filesFound++; - }; +fileLister.FileFound += onFileFound; - fileLister.FileFound += onFileFound; - // +fileLister.DirectoryChanged += (sender, eventArgs) => +{ + Console.Write($"Entering '{eventArgs.CurrentSearchDirectory}'."); + Console.WriteLine($" {eventArgs.CompletedDirs} of {eventArgs.TotalDirs} completed..."); +}; - // - fileLister.DirectoryChanged += (sender, eventArgs) => - { - Console.Write($"Entering '{eventArgs.CurrentSearchDirectory}'."); - Console.WriteLine($" {eventArgs.CompletedDirs} of {eventArgs.TotalDirs} completed..."); - }; - // +fileLister.Search(".", "*.dll", true); - fileLister.Search(".", "*.dll", true); +fileLister.FileFound -= onFileFound; - // - fileLister.FileFound -= onFileFound; - // - } - } +public class FileFoundArgs : EventArgs +{ + public string FoundFile { get; } + public bool CancelRequested { get; set; } - // - public class FileFoundArgs : EventArgs - { - public string FoundFile { get; } - public bool CancelRequested { get; set; } + public FileFoundArgs(string fileName) => FoundFile = fileName; +} - public FileFoundArgs(string fileName) - { - FoundFile = fileName; - } - } - // +internal class SearchDirectoryArgs : EventArgs +{ + internal string CurrentSearchDirectory { get; } + internal int TotalDirs { get; } + internal int CompletedDirs { get; } - // - internal class SearchDirectoryArgs : EventArgs + internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) { - internal string CurrentSearchDirectory { get; } - internal int TotalDirs { get; } - internal int CompletedDirs { get; } - - internal SearchDirectoryArgs(string dir, int totalDirs, int completedDirs) - { - CurrentSearchDirectory = dir; - TotalDirs = totalDirs; - CompletedDirs = completedDirs; - } + CurrentSearchDirectory = dir; + TotalDirs = totalDirs; + CompletedDirs = completedDirs; } - // +} - public class FileSearcher +public class FileSearcher +{ + public event EventHandler? FileFound; + internal event EventHandler? DirectoryChanged { - // - public event EventHandler FileFound; - // - // - internal event EventHandler DirectoryChanged - { - add { directoryChanged += value; } - remove { directoryChanged -= value; } - } - private EventHandler directoryChanged; - // + add => directoryChanged += value; + remove => directoryChanged -= value; + } + private EventHandler? directoryChanged; - // - public void Search(string directory, string searchPattern, bool searchSubDirs = false) + public void Search(string directory, string searchPattern, bool searchSubDirs = false) + { + if (searchSubDirs) { - if (searchSubDirs) - { - var allDirectories = Directory.GetDirectories(directory, "*.*", SearchOption.AllDirectories); - var completedDirs = 0; - var totalDirs = allDirectories.Length + 1; - foreach (var dir in allDirectories) - { - directoryChanged?.Invoke(this, - new SearchDirectoryArgs(dir, totalDirs, completedDirs++)); - // Search 'dir' and its subdirectories for files that match the search pattern: - SearchDirectory(dir, searchPattern); - } - // Include the Current Directory: - directoryChanged?.Invoke(this, - new SearchDirectoryArgs(directory, totalDirs, completedDirs++)); - SearchDirectory(directory, searchPattern); - } - else + var allDirectories = Directory.GetDirectories(directory, "*.*", SearchOption.AllDirectories); + var completedDirs = 0; + var totalDirs = allDirectories.Length + 1; + foreach (var dir in allDirectories) { - SearchDirectory(directory, searchPattern); + directoryChanged?.Invoke(this, new (dir, totalDirs, completedDirs++)); + // Search 'dir' and its subdirectories for files that match the search pattern: + SearchDirectory(dir, searchPattern); } + // Include the Current Directory: + directoryChanged?.Invoke(this, new (directory, totalDirs, completedDirs++)); + SearchDirectory(directory, searchPattern); } - - private void SearchDirectory(string directory, string searchPattern) + else { - foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) - { - var args = new FileFoundArgs(file); - FileFound?.Invoke(this, args); - if (args.CancelRequested) - break; - } + SearchDirectory(directory, searchPattern); } - // } -} -namespace VersionOne -{ - // - public class FileFoundArgs : EventArgs + private void SearchDirectory(string directory, string searchPattern) { - public string FoundFile { get; } - - public FileFoundArgs(string fileName) + foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) { - FoundFile = fileName; - } - } - // - - // - public class FileSearcher - { - public event EventHandler FileFound; - - public void Search(string directory, string searchPattern) - { - foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) - { - FileFound?.Invoke(this, new FileFoundArgs(file)); - } + var args = new FileFoundArgs(file); + FileFound?.Invoke(this, args); + if (args.CancelRequested) + break; } } - // } diff --git a/csharp/events/VersionOne.cs b/csharp/events/VersionOne.cs new file mode 100644 index 00000000000..f9959043b2a --- /dev/null +++ b/csharp/events/VersionOne.cs @@ -0,0 +1,21 @@ +namespace Events; + +public class FileFoundArgs : EventArgs +{ + public string FoundFile { get; } + + public FileFoundArgs(string fileName) => FoundFile = fileName; +} + +public class FileSearcher +{ + public event EventHandler? FileFound; + + public void Search(string directory, string searchPattern) + { + foreach (var file in Directory.EnumerateFiles(directory, searchPattern)) + { + FileFound?.Invoke(this, new FileFoundArgs(file)); + } + } +} diff --git a/csharp/events/events.csproj b/csharp/events/events.csproj index 299d1386b17..16829f3e536 100644 --- a/csharp/events/events.csproj +++ b/csharp/events/events.csproj @@ -1,8 +1,10 @@ - + - net7.0 + net9.0 Exe + enable + enable From 9c3c2ad29889a0e0583831fc118f1cdaf78db8f2 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Sat, 15 Mar 2025 12:32:03 -0400 Subject: [PATCH 03/11] Change area path (#7030) --- quest-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quest-config.json b/quest-config.json index 36656d18b31..dd95bde57b3 100644 --- a/quest-config.json +++ b/quest-config.json @@ -2,7 +2,7 @@ "AzureDevOps": { "Org": "msft-skilling", "Project": "Content", - "AreaPath": "Production\\Digital and App Innovation\\DotNet and more\\dotnet" + "AreaPath": "Production\\Core AI\\DotNet and more\\dotnet" }, "ImportTriggerLabel": ":world_map: reQUEST", "ImportedLabel": ":pushpin: seQUESTered" From 668e59ab8a9a7f6740015f387895d0ac5833c6b4 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Wed, 19 Mar 2025 07:03:30 -0600 Subject: [PATCH 04/11] Update dotnet-code-metrics.yml (#7032) use forked version of GHA to reduce security surface area. similar to https://github.com/dotnet/aspire/pull/8122/files --- .github/workflows/dotnet-code-metrics.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet-code-metrics.yml b/.github/workflows/dotnet-code-metrics.yml index afc57159292..072aaabb046 100644 --- a/.github/workflows/dotnet-code-metrics.yml +++ b/.github/workflows/dotnet-code-metrics.yml @@ -41,7 +41,7 @@ jobs: dir: ${{ './github-actions/DotNet.GitHubAction' }} - name: Create pull request - uses: peter-evans/create-pull-request@v7.0.8 + uses: dotnet/actions-create-pull-request@v4 if: ${{ steps.dotnet-code-metrics.outputs.updated-metrics }} == 'true' with: title: '${{ steps.dotnet-code-metrics.outputs.summary-title }}' From f98f1e1e8e4ecc15db0a1d59276adf40cd994029 Mon Sep 17 00:00:00 2001 From: Bill Wagner Date: Wed, 19 Mar 2025 14:43:48 -0400 Subject: [PATCH 05/11] Remove Sequester (#7033) * Remove Sequester It hasn't been used in a long time in this repo, so let's just remove it. * remove the config file as well --- .github/workflows/quest-bulk.yml | 52 -------------------------- .github/workflows/quest.yml | 63 -------------------------------- quest-config.json | 9 ----- 3 files changed, 124 deletions(-) delete mode 100644 .github/workflows/quest-bulk.yml delete mode 100644 .github/workflows/quest.yml delete mode 100644 quest-config.json diff --git a/.github/workflows/quest-bulk.yml b/.github/workflows/quest-bulk.yml deleted file mode 100644 index 62251d339ef..00000000000 --- a/.github/workflows/quest-bulk.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: "bulk quest import" -on: - schedule: - - cron: '0 10 * * *' # UTC time, that's 5:00 am EST, 2:00 am PST. - - cron: '0 9 6 * *' # This is the morning of the 6th. - - workflow_dispatch: - inputs: - reason: - description: "The reason for running the bulk import workflow" - required: true - default: "Initial import into Quest (Azure DevOps)" - duration: - description: "The number of days to import issues for. Defaults to 5 days." - required: false - default: "5" - -jobs: - bulk-import: - runs-on: ubuntu-latest - permissions: - contents: write - issues: write - - steps: - - name: "Print manual bulk import run reason" - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - echo "Reason: ${{ github.event.inputs.reason }}" - - - name: Azure OpenID Connect - id: azure-oidc-auth - uses: dotnet/docs-tools/.github/actions/oidc-auth-flow@main - with: - client-id: ${{ secrets.CLIENT_ID }} - tenant-id: ${{ secrets.TENANT_ID }} - audience: ${{ secrets.OSMP_API_AUDIENCE }} - - - name: bulk-sequester - id: bulk-sequester - uses: dotnet/docs-tools/actions/sequester@main - env: - ImportOptions__ApiKeys__GitHubToken: ${{ secrets.GITHUB_TOKEN }} - ImportOptions__ApiKeys__QuestKey: ${{ secrets.QUEST_KEY }} - ImportOptions__ApiKeys__AzureAccessToken: ${{ steps.azure-oidc-auth.outputs.access-token }} - ImportOptions__ApiKeys__SequesterPrivateKey: ${{ secrets.SEQUESTER_PRIVATEKEY }} - ImportOptions__ApiKeys__SequesterAppID: ${{ secrets.SEQUESTER_APPID }} - with: - org: ${{ github.repository_owner }} - repo: ${{ github.repository }} - issue: '-1' - duration: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.duration || github.event.schedule == '0 9 6 * *' && -1 || 5 }} diff --git a/.github/workflows/quest.yml b/.github/workflows/quest.yml deleted file mode 100644 index 3d419c585ac..00000000000 --- a/.github/workflows/quest.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: "quest import" -on: - issues: - types: - [ labeled, closed, reopened, assigned, unassigned ] - workflow_dispatch: - inputs: - reason: - description: "The reason for running the workflow" - required: true - default: "Manual run" - issue: - description: "The issue number to manually test" - required: true - -jobs: - import: - if: | - github.event_name == 'workflow_dispatch' || - github.event.label.name == ':world_map: reQUEST' || - github.event.label.name == ':pushpin: seQUESTered' || - contains(github.event.issue.labels.*.name, ':world_map: reQUEST') || - contains(github.event.issue.labels.*.name, ':pushpin: seQUESTered') - runs-on: ubuntu-latest - permissions: - contents: write - issues: write - - steps: - - name: "Print manual run reason" - if: ${{ github.event_name == 'workflow_dispatch' }} - run: | - echo "Reason: ${{ github.event.inputs.reason }}" - echo "Issue number: ${{ github.event.inputs.issue }}" - - # This step occurs when ran manually, passing the manual issue number input - - name: manual-sequester - if: ${{ github.event_name == 'workflow_dispatch' }} - id: manual-sequester - uses: dotnet/docs-tools/actions/sequester@main - env: - ImportOptions__ApiKeys__GitHubToken: ${{ secrets.GITHUB_TOKEN }} - ImportOptions__ApiKeys__OSPOKey: ${{ secrets.OSPO_KEY }} - ImportOptions__ApiKeys__QuestKey: ${{ secrets.QUEST_KEY }} - with: - org: ${{ github.repository_owner }} - repo: ${{ github.repository }} - issue: ${{ github.event.inputs.issue }} - - # This step occurs automatically, passing the issue number from the event - - name: auto-sequester - if: ${{ github.event_name != 'workflow_dispatch' }} - id: auto-sequester - uses: dotnet/docs-tools/actions/sequester@main - env: - ImportOptions__ApiKeys__GitHubToken: ${{ secrets.GITHUB_TOKEN }} - ImportOptions__ApiKeys__OSPOKey: ${{ secrets.OSPO_KEY }} - ImportOptions__ApiKeys__QuestKey: ${{ secrets.QUEST_KEY }} - with: - org: ${{ github.repository_owner }} - repo: ${{ github.repository }} - issue: ${{ github.event.issue.number }} - diff --git a/quest-config.json b/quest-config.json deleted file mode 100644 index dd95bde57b3..00000000000 --- a/quest-config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "AzureDevOps": { - "Org": "msft-skilling", - "Project": "Content", - "AreaPath": "Production\\Core AI\\DotNet and more\\dotnet" - }, - "ImportTriggerLabel": ":world_map: reQUEST", - "ImportedLabel": ":pushpin: seQUESTered" -} From 060308aedb956d735565d929626f6f94a6d917a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 20:56:30 +0000 Subject: [PATCH 06/11] Bump the dotnet group with 2 updates Bumps the dotnet group with 2 updates: [actions/setup-node](https://github.com/actions/setup-node) and [actions/upload-artifact](https://github.com/actions/upload-artifact). Updates `actions/setup-node` from 4.2.0 to 4.3.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a...cdca7365b2dadb8aad0a33bc7601856ffabcc48e) Updates `actions/upload-artifact` from 4.6.1 to 4.6.2 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1...ea165f8d65b6e75b540449e92b4886f43607fa02) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dotnet ... Signed-off-by: dependabot[bot] --- .github/workflows/markdownlint.yml | 2 +- .github/workflows/snippets5000.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index a8b5763bd5d..ef070e7be03 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #@v2 - name: Use Node.js - uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a #@v1 + uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e #@v1 with: node-version: 12.x - name: Run Markdownlint diff --git a/.github/workflows/snippets5000.yml b/.github/workflows/snippets5000.yml index 7f668ec26ed..b3ad2257654 100644 --- a/.github/workflows/snippets5000.yml +++ b/.github/workflows/snippets5000.yml @@ -62,7 +62,7 @@ jobs: # Update build output json file - name: Upload build results - uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #@v4.6.1 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 #@v4.6.2 with: name: build path: ./output.json From 764ea352662976894b2773d3197d2f14264e7ac0 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 25 Mar 2025 13:46:56 +0100 Subject: [PATCH 07/11] Update test project for MSTest (#7035) --- .../PrimeService.Tests/PrimeService.Tests.csproj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/getting-started/unit-testing-using-mstest/PrimeService.Tests/PrimeService.Tests.csproj b/core/getting-started/unit-testing-using-mstest/PrimeService.Tests/PrimeService.Tests.csproj index 9aeba9204b9..154321e52e0 100644 --- a/core/getting-started/unit-testing-using-mstest/PrimeService.Tests/PrimeService.Tests.csproj +++ b/core/getting-started/unit-testing-using-mstest/PrimeService.Tests/PrimeService.Tests.csproj @@ -1,13 +1,11 @@ - net8.0 + net9.0 - - - + From 3e634d0b7c4e27a90168995d6204a788a79b34fa Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Fri, 4 Apr 2025 00:54:03 +0500 Subject: [PATCH 08/11] Update to .NET 7 paths and add error reporting (#5627) --- core/nativeaot/NativeLibrary/Class1.cs | 56 ------------------- .../NativeLibrary/LibraryFunctions.cs | 54 ++++++++++++++++++ core/nativeaot/NativeLibrary/LoadLibrary.c | 44 +++++++++------ 3 files changed, 82 insertions(+), 72 deletions(-) delete mode 100644 core/nativeaot/NativeLibrary/Class1.cs create mode 100644 core/nativeaot/NativeLibrary/LibraryFunctions.cs diff --git a/core/nativeaot/NativeLibrary/Class1.cs b/core/nativeaot/NativeLibrary/Class1.cs deleted file mode 100644 index 288d8a2dad8..00000000000 --- a/core/nativeaot/NativeLibrary/Class1.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; - -namespace NativeLibrary -{ - public class Class1 - { - // Use common prefix for all entrypoints to avoid symbol name collisions - [UnmanagedCallersOnly(EntryPoint = "aotsample_add")] - public static int Add(int a, int b) - { - return a + b; - } - - [UnmanagedCallersOnly(EntryPoint = "aotsample_write_line")] - public static int WriteLine(IntPtr pString) - { - // The marshalling code is typically auto-generated by a custom tool in larger projects. - try - { - // UnmanagedCallersOnly methods only accept primitive arguments. The primitive arguments - // have to be marshalled manually if necessary. - string str = Marshal.PtrToStringAnsi(pString); - - Console.WriteLine(str); - } - catch - { - // Exceptions escaping out of UnmanagedCallersOnly methods are treated as unhandled exceptions. - // The errors have to be marshalled manually if necessary. - return -1; - } - return 0; - } - - [UnmanagedCallersOnly(EntryPoint = "aotsample_sumstring")] - public static IntPtr sumstring(IntPtr first, IntPtr second) - { - // Parse strings from the passed pointers - string my1String = Marshal.PtrToStringAnsi(first); - string my2String = Marshal.PtrToStringAnsi(second); - - // Concatenate strings - string sum = my1String + my2String; - - // Assign pointer of the concatenated string to sumPointer - IntPtr sumPointer = Marshal.StringToCoTaskMemAnsi(sum); - - // Return pointer - return sumPointer; - } - } -} diff --git a/core/nativeaot/NativeLibrary/LibraryFunctions.cs b/core/nativeaot/NativeLibrary/LibraryFunctions.cs new file mode 100644 index 00000000000..b247e9c2869 --- /dev/null +++ b/core/nativeaot/NativeLibrary/LibraryFunctions.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; + +namespace NativeLibrary; + +public class LibraryFunctions +{ + [UnmanagedCallersOnly(EntryPoint = "add")] + public static int Add(int a, int b) + { + return a + b; + } + + [UnmanagedCallersOnly(EntryPoint = "write_line")] + public static int WriteLine(IntPtr pString) + { + // The marshalling code is typically auto-generated by a custom tool in larger projects. + try + { + // UnmanagedCallersOnly methods only accept primitive arguments. The primitive arguments + // have to be marshalled manually if necessary. + string str = Marshal.PtrToStringAnsi(pString); + + Console.WriteLine(str); + } + catch + { + // Exceptions escaping out of UnmanagedCallersOnly methods are treated as unhandled exceptions. + // The errors have to be marshalled manually if necessary. + return -1; + } + return 0; + } + + [UnmanagedCallersOnly(EntryPoint = "sumstring")] + public static IntPtr sumstring(IntPtr first, IntPtr second) + { + // Parse strings from the passed pointers + string my1String = Marshal.PtrToStringAnsi(first); + string my2String = Marshal.PtrToStringAnsi(second); + + // Concatenate strings + string sum = my1String + my2String; + + // Assign pointer of the concatenated string to sumPointer + IntPtr sumPointer = Marshal.StringToHGlobalAnsi(sum); + + // Return pointer + return sumPointer; + } +} diff --git a/core/nativeaot/NativeLibrary/LoadLibrary.c b/core/nativeaot/NativeLibrary/LoadLibrary.c index e4dedbab995..56a08e6aac1 100644 --- a/core/nativeaot/NativeLibrary/LoadLibrary.c +++ b/core/nativeaot/NativeLibrary/LoadLibrary.c @@ -33,6 +33,8 @@ int callSumFunc(char *path, char *funcName, int a, int b); char *callSumStringFunc(char *path, char *funcName, char *a, char *b); +void* loadSymbol(char *path, char *funcName); + int main() { // Check if the library file exists @@ -54,43 +56,53 @@ int main() CoTaskMemFree(sumstring); } -int callSumFunc(char *path, char *funcName, int firstInt, int secondInt) +void *loadSymbol(char *path, char *funcName) { - // Call sum function defined in C# shared library + // Library loading #ifdef _WIN32 HINSTANCE handle = LoadLibraryA(path); #else void *handle = dlopen(path, RTLD_LAZY); #endif + if (!handle) + { +#ifdef _WIN32 + int errorCode = GetLastError(); + printf("Failed to load library at specified path. Error code: %d\n", errorCode); +#else + puts("Failed to load library at specified path"); +#endif + return NULL; + } + + // Declare a typedef + typedef char *(*myFunc)(char*,char*); + + // Import Symbol named funcName + + // NativeAOT libraries do not support unloading + // See https://github.com/dotnet/corert/issues/7887 + return symLoad(handle, funcName); +} +int callSumFunc(char *path, char *funcName, int firstInt, int secondInt) +{ typedef int(*myFunc)(int,int); - myFunc MyImport = (myFunc)symLoad(handle, funcName); + myFunc MyImport = (myFunc)loadSymbol(path, funcName); int result = MyImport(firstInt, secondInt); - - // NOTE: Native AOT libraries do not support unloading return result; } char *callSumStringFunc(char *path, char *funcName, char *firstString, char *secondString) { - // Library loading - #ifdef _WIN32 - HINSTANCE handle = LoadLibraryA(path); - #else - void *handle = dlopen(path, RTLD_LAZY); - #endif - // Declare a typedef typedef char *(*myFunc)(char*,char*); // Import Symbol named funcName - myFunc MyImport = (myFunc)symLoad(handle, funcName); + myFunc MyImport = (myFunc)loadSymbol(path, funcName); // The C# function will return a pointer char *result = MyImport(firstString, secondString); - - // CoreRT libraries do not support unloading - // See https://github.com/dotnet/corert/issues/7887 return result; } From 2ffc387984a47d1877a6b7c321da1ffed1f1b281 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Thu, 10 Apr 2025 09:58:46 -0700 Subject: [PATCH 09/11] Mark the specific DNNE version to use. (#7038) Delete no longer needed redeclaration of DNNE attributes. Fix warnings by passing .def file to DNNE. --- .../ComWrappersGeneration/Server/DNNE.cs | 27 ------------------- .../Server/Server.csproj | 8 ++++-- 2 files changed, 6 insertions(+), 29 deletions(-) delete mode 100644 core/interop/source-generation/ComWrappersGeneration/Server/DNNE.cs diff --git a/core/interop/source-generation/ComWrappersGeneration/Server/DNNE.cs b/core/interop/source-generation/ComWrappersGeneration/Server/DNNE.cs deleted file mode 100644 index 20b4482294e..00000000000 --- a/core/interop/source-generation/ComWrappersGeneration/Server/DNNE.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace DNNE; - -/// -/// Provide C code to be defined early in the generated C header file. -/// -/// -/// This attribute is respected on an exported method declaration or on a parameter for the method. -/// The following header files will be included prior to the code being defined. -/// - stddef.h -/// - stdint.h -/// - dnne.h -/// -internal class C99DeclCodeAttribute : System.Attribute -{ - public C99DeclCodeAttribute(string code) { } -} - -/// -/// Define the C type to be used. -/// -/// -/// The level of indirection should be included in the supplied string. -/// -internal class C99TypeAttribute : System.Attribute -{ - public C99TypeAttribute(string code) { } -} diff --git a/core/interop/source-generation/ComWrappersGeneration/Server/Server.csproj b/core/interop/source-generation/ComWrappersGeneration/Server/Server.csproj index ed30283e295..722917711f4 100644 --- a/core/interop/source-generation/ComWrappersGeneration/Server/Server.csproj +++ b/core/interop/source-generation/ComWrappersGeneration/Server/Server.csproj @@ -8,13 +8,17 @@ + + - true + true + + Server.def - + From a96f09d039786f0b89eba028fec2809325d2cfdb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 16 Apr 2025 20:51:05 +0000 Subject: [PATCH 10/11] Bump actions/setup-node from 4.3.0 to 4.4.0 in the dotnet group Bumps the dotnet group with 1 update: [actions/setup-node](https://github.com/actions/setup-node). Updates `actions/setup-node` from 4.3.0 to 4.4.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/cdca7365b2dadb8aad0a33bc7601856ffabcc48e...49933ea5288caeca8642d1e84afbd3f7d6820020) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 4.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dotnet ... Signed-off-by: dependabot[bot] --- .github/workflows/markdownlint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/markdownlint.yml b/.github/workflows/markdownlint.yml index ef070e7be03..e45ad51a749 100644 --- a/.github/workflows/markdownlint.yml +++ b/.github/workflows/markdownlint.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #@v2 - name: Use Node.js - uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e #@v1 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #@v1 with: node-version: 12.x - name: Run Markdownlint From 57d88644650df96caa89e7201fd9ad9d0cb62e70 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Mon, 28 Apr 2025 13:02:40 -0700 Subject: [PATCH 11/11] Update LibraryFunctions.cs (#7040) --- core/nativeaot/NativeLibrary/LibraryFunctions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/nativeaot/NativeLibrary/LibraryFunctions.cs b/core/nativeaot/NativeLibrary/LibraryFunctions.cs index b247e9c2869..3080f8cbdba 100644 --- a/core/nativeaot/NativeLibrary/LibraryFunctions.cs +++ b/core/nativeaot/NativeLibrary/LibraryFunctions.cs @@ -8,13 +8,13 @@ namespace NativeLibrary; public class LibraryFunctions { - [UnmanagedCallersOnly(EntryPoint = "add")] + [UnmanagedCallersOnly(EntryPoint = "aotsample_add")] public static int Add(int a, int b) { return a + b; } - [UnmanagedCallersOnly(EntryPoint = "write_line")] + [UnmanagedCallersOnly(EntryPoint = "aotsample_write_line")] public static int WriteLine(IntPtr pString) { // The marshalling code is typically auto-generated by a custom tool in larger projects. @@ -35,7 +35,7 @@ public static int WriteLine(IntPtr pString) return 0; } - [UnmanagedCallersOnly(EntryPoint = "sumstring")] + [UnmanagedCallersOnly(EntryPoint = "aotsample_sumstring")] public static IntPtr sumstring(IntPtr first, IntPtr second) { // Parse strings from the passed pointers